From gvanrossum@users.sourceforge.net Sun Jul 1 20:06:13 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 01 Jul 2001 12:06:13 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.1.2.3,1.1.2.4 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv15167 Modified Files: Tag: descr-branch PLAN.txt Log Message: Add a note to the dealloc task. Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Attic/PLAN.txt,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -r1.1.2.3 -r1.1.2.4 *** PLAN.txt 2001/06/30 12:25:24 1.1.2.3 --- PLAN.txt 2001/07/01 19:06:11 1.1.2.4 *************** *** 16,20 **** base types until it finds a type whose tp_dealloc is not subtype_dealloc. I think this is not safe. I think the alloc/dealloc ! policy needs to be rethought. Clean up isinstance(), issubclass() and their C equivalents. There --- 16,24 ---- base types until it finds a type whose tp_dealloc is not subtype_dealloc. I think this is not safe. I think the alloc/dealloc ! policy needs to be rethought. *** There's an idea here that I haven't ! worked out yet: just as object creation now has separate API's tp_new, ! tp_alloc, and tp_init, destruction has tp_dealloc and tp_free. (Maybe ! tp_fini should be added to correspond to tp_init?) Something ! could/should be done with this. *** Clean up isinstance(), issubclass() and their C equivalents. There From prescod@users.sourceforge.net Sun Jul 1 20:52:27 2001 From: prescod@users.sourceforge.net (Paul Prescod) Date: Sun, 01 Jul 2001 12:52:27 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0261.txt,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv22633 Modified Files: pep-0261.txt Log Message: Updated terminology and format. Index: pep-0261.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0261.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** pep-0261.txt 2001/06/27 23:12:08 1.2 --- pep-0261.txt 2001/07/01 19:52:25 1.3 *************** *** 12,131 **** Abstract ! Python 2.1 unicode characters can have ordinals only up to 65536. ! These characters are known as Basic Multilinual Plane characters. ! There are now characters in Unicode that live on other "planes". ! The largest addressable character in Unicode has the ordinal ! 2**20 + 2**16 - 1. For readability, we will call this TOPCHAR. Proposed Solution ! One solution would be to merely increase the maximum ordinal to a ! larger value. Unfortunately the only straightforward ! implementation of this idea is to increase the character code unit ! to 4 bytes. This has the effect of doubling the size of most ! Unicode strings. In order to avoid imposing this cost on every ! user, Python 2.2 will allow 4-byte Unicode characters as a ! build-time option. ! The 4-byte option is called "wide Py_UNICODE". The 2-byte option is called "narrow Py_UNICODE". Most things will behave identically in the wide and narrow worlds. ! * the \u and \U literal syntaxes will always generate the same ! data that the unichr function would. They are just different ! syntaxes for the same thing. ! * unichr(i) for 0 <= i <= 2**16 always returns a size-one string. ! * unichr(i) for 2**16+1 <= i <= TOPCHAR will always return a ! string representing the character. ! * BUT on narrow builds of Python, the string will actually be ! composed of two characters called a "surrogate pair". ! * ord() will now accept surrogate pairs and return the ordinal of ! the "wide" character. Open question: should it accept surrogate ! pairs on wide Python builds? * There is an integer value in the sys module that describes the ! largest ordinal for a Unicode character on the current ! interpreter. sys.maxunicode is 2**16-1 on narrow builds of ! Python. On wide builds it could be either TOPCHAR or 2**32-1. ! That's an open question. ! ! * Note that ord() can in some cases return ordinals higher than ! sys.maxunicode because it accepts surrogate pairs on narrow ! Python builds. ! ! * codecs will be upgraded to support "wide characters". On narrow ! Python builds, the codecs will generate surrogate pairs, on wide ! Python builds they will generate a single character. ! ! * new codecs will be written for 4-byte Unicode and older codecs ! will be updated to recognize surrogates and map them to wide ! characters on wide Pythons. ! ! * there are no restrictions on constructing strings that use code ! points "reserved for surrogates" improperly. These are called ! "lone surrogates". The codecs should disallow reading these but ! you could construct them using string literals or unichr(). ! Implementation ! There is a new (experimental) define in Include/unicodeobject.h: ! #undef USE_UCS4_STORAGE ! if defined, Py_UNICODE is set to the same thing as Py_UCS4. ! USE_UCS4_STORAGE ! There is a new configure options: --enable-unicode=ucs2 configures a narrow Py_UNICODE, and uses wchar_t if it fits ! --enable-unicode=ucs4 configures a wide Py_UNICODE likewise ! --enable-unicode configures Py_UNICODE to wchar_t if available, ! and to UCS-4 if not; this is the default The intention is that --disable-unicode, or --enable-unicode=no removes the Unicode type altogether; this is not yet implemented. Notes ! Note that len(unichr(i))==2 for i>=0x10000 on narrow machines. - This means (for example) that the following code is not portable: ! x = 0x10000 ! if unichr(x) in somestring: ! ... ! ! In general, you should be careful using "in" if the character that ! is searched for could have been generated from unichr applied to a ! number greater than 0x10000 or from a string literal greater than ! 0x10000. ! This PEP does NOT imply that people using Unicode need to use a ! 4-byte encoding. It only allows them to do so. For example, ! ASCII is still a legitimate (7-bit) Unicode-encoding. ! Open Questions - "Code points" above TOPCHAR cannot be expressed in two 16-bit - characters. These are not assigned to Unicode characters and - supposedly will never be. Should we allow them to be passed as - arguments to unichr() anyhow? We could allow knowledgable - programmers to use these "unused" characters for whatever they - want, though Unicode does not address them. ! "Lone surrogates" "should not" occur on wide platforms. Should ! ord() still accept them? --- 12,277 ---- Abstract ! Python 2.1 unicode characters can have ordinals only up to 2**16 -1. ! This range corresponds to a range in Unicode known as the Basic ! Multilingual Plane. There are now characters in Unicode that live ! on other "planes". The largest addressable character in Unicode ! has the ordinal 17 * 2**16 - 1 (0x10ffff). For readability, we ! will call this TOPCHAR and call characters in this range "wide ! characters". + Glossary + + Character + + Used by itself, means the addressable units of a Python + Unicode string. + + Code point + + A code point is an integer between 0 and TOPCHAR. + If you imagine Unicode as a mapping from integers to + characters, each integer is a code point. But the + integers between 0 and TOPCHAR that do not map to + characters are also code points. Some will someday + be used for characters. Some are guaranteed never + to be used for characters. + + Codec + + A set of functions for translating between physical + encodings (e.g. on disk or coming in from a network) + into logical Python objects. + + Encoding + + Mechanism for representing abstract characters in terms of + physical bits and bytes. Encodings allow us to store + Unicode characters on disk and transmit them over networks + in a manner that is compatible with other Unicode software. + + Surrogate pair + + Two physical characters that represent a single logical + character. Part of a convention for representing 32-bit + code points in terms of two 16-bit code points. + + Unicode string + + A Python type representing a sequence of code points with + "string semantics" (e.g. case conversions, regular + expression compatibility, etc.) Constructed with the + unicode() function. + + Proposed Solution ! One solution would be to merely increase the maximum ordinal ! to a larger value. Unfortunately the only straightforward ! implementation of this idea is to use 4 bytes per character. ! This has the effect of doubling the size of most Unicode ! strings. In order to avoid imposing this cost on every ! user, Python 2.2 will allow the 4-byte implementation as a ! build-time option. Users can choose whether they care about ! wide characters or prefer to preserve memory. ! The 4-byte option is called "wide Py_UNICODE". The 2-byte option is called "narrow Py_UNICODE". Most things will behave identically in the wide and narrow worlds. + + * unichr(i) for 0 <= i < 2**16 (0x10000) always returns a + length-one string. + + * unichr(i) for 2**16 <= i <= TOPCHAR will return a + length-one string on wide Python builds. On narrow builds it will + raise ValueError. + + ISSUE + + Python currently allows \U literals that cannot be + represented as a single Python character. It generates two + Python characters known as a "surrogate pair". Should this + be disallowed on future narrow Python builds? + + Pro: + + Python already the construction of a surrogate pair + for a large unicode literal character escape sequence. + This is basically designed as a simple way to construct + "wide characters" even in a narrow Python build. It is also + somewhat logical considering that the Unicode-literal syntax + is basically a short-form way of invoking the unicode-escape + codec. + + Con: + + Surrogates could be easily created this way but the user + still needs to be careful about slicing, indexing, printing + etc. Therefore some have suggested that Unicode + literals should not support surrogates. + + + ISSUE + + Should Python allow the construction of characters that do + not correspond to Unicode code points? Unassigned Unicode + code points should obviously be legal (because they could + be assigned at any time). But code points above TOPCHAR are + guaranteed never to be used by Unicode. Should we allow access + to them anyhow? ! Pro: ! If a Python user thinks they know what they're doing why ! should we try to prevent them from violating the Unicode ! spec? After all, we don't stop 8-bit strings from ! containing non-ASCII characters. ! Con: ! Codecs and other Unicode-consuming code will have to be ! careful of these characters which are disallowed by the ! Unicode specification. ! * ord() is always the inverse of unichr() * There is an integer value in the sys module that describes the ! largest ordinal for a character in a Unicode string on the current ! interpreter. sys.maxunicode is 2**16-1 (0xffff) on narrow builds ! of Python and TOPCHAR on wide builds. + ISSUE: Should there be distinct constants for accessing + TOPCHAR and the real upper bound for the domain of + unichr (if they differ)? There has also been a + suggestion of sys.unicodewidth which can take the + values 'wide' and 'narrow'. ! * every Python Unicode character represents exactly one Unicode code ! point (i.e. Python Unicode Character = Abstract Unicode character). ! ! * codecs will be upgraded to support "wide characters" ! (represented directly in UCS-4, and as variable-length sequences ! in UTF-8 and UTF-16). This is the main part of the implementation ! left to be done. ! ! * There is a convention in the Unicode world for encoding a 32-bit ! code point in terms of two 16-bit code points. These are known ! as "surrogate pairs". Python's codecs will adopt this convention ! and encode 32-bit code points as surrogate pairs on narrow Python ! builds. ! ! ISSUE ! ! Should there be a way to tell codecs not to generate ! surrogates and instead treat wide characters as ! errors? ! ! Pro: ! I might want to write code that works only with ! fixed-width characters and does not have to worry about ! surrogates. ! ! Con: ! ! No clear proposal of how to communicate this to codecs. ! ! * there are no restrictions on constructing strings that use ! code points "reserved for surrogates" improperly. These are ! called "isolated surrogates". The codecs should disallow reading ! these from files, but you could construct them using string ! literals or unichr(). ! ! ! Implementation ! There is a new (experimental) define: ! #define PY_UNICODE_SIZE 2 ! There is a new configure option: --enable-unicode=ucs2 configures a narrow Py_UNICODE, and uses wchar_t if it fits ! --enable-unicode=ucs4 configures a wide Py_UNICODE, and uses ! whchar_t if it fits ! --enable-unicode same as "=ucs2" The intention is that --disable-unicode, or --enable-unicode=no removes the Unicode type altogether; this is not yet implemented. + It is also proposed that one day --enable-unicode will just + default to the width of your platforms wchar_t. + Windows builds will be narrow for a while based on the fact that + there have been few requests for wide characters, those requests + are mostly from hard-core programmers with the ability to buy + their own Python and Windows itself is strongly biased towards + 16-bit characters. + + Notes + + This PEP does NOT imply that people using Unicode need to use a + 4-byte encoding for their files on disk or sent over the network. + It only allows them to do so. For example, ASCII is still a + legitimate (7-bit) Unicode-encoding. ! It has been proposed that there should be a module that handles ! surrogates in narrow Python builds for programmers. If someone ! wants to implement that, it will be another PEP. It might also be ! combined with features that allow other kinds of character-, ! word- and line- based indexing. ! Rejected Suggestions ! More or less the status-quo ! ! We could officially say that Python characters are 16-bit and ! require programmers to implement wide characters in their ! application logic by combining surrogate pairs. This is a heavy ! burden because emulating 32-bit characters is likely to be ! very inefficient if it is coded entirely in Python. Plus these ! abstracted pseudo-strings would not be legal as input to the ! regular expression engine. ! ! "Space-efficient Unicode" type ! ! Another class of solution is to use some efficient storage ! internally but present an abstraction of wide characters to ! the programmer. Any of these would require a much more complex ! implementation than the accepted solution. For instance consider ! the impact on the regular expression engine. In theory, we could ! move to this implementation in the future without breaking Python ! code. A future Python could "emulate" wide Python semantics on ! narrow Python. Guido is not willing to undertake the ! implementation right now. ! ! Two types ! ! We could introduce a 32-bit Unicode type alongside the 16-bit ! type. There is a lot of code that expects there to be only a ! single Unicode type. ! ! This PEP represents the least-effort solution. Over the next ! several years, 32-bit Unicode characters will become more common ! and that may either convince us that we need a more sophisticated ! solution or (on the other hand) convince us that simply ! mandating wide Unicode characters is an appropriate solution. ! Right now the two options on the table are do nothing or do ! this. ! + References ! Unicode Glossary: http://www.unicode.org/glossary/ ! Copyright + This document has been placed in the public domain. From gvanrossum@users.sourceforge.net Sun Jul 1 20:52:46 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 01 Jul 2001 12:52:46 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.1.2.4,1.1.2.5 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv22729 Modified Files: Tag: descr-branch PLAN.txt Log Message: Add note about making descriptors subclassable. Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Attic/PLAN.txt,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -C2 -r1.1.2.4 -r1.1.2.5 *** PLAN.txt 2001/07/01 19:06:11 1.1.2.4 --- PLAN.txt 2001/07/01 19:52:44 1.1.2.5 *************** *** 88,92 **** Make more (most?) built-in types subtypable -- with or without ! overridable allocation. Exceptions should be types. This changes the rules, since now almost --- 88,94 ---- Make more (most?) built-in types subtypable -- with or without ! overridable allocation. *** This includes descriptors! It should be ! possible to write descriptors in Python, so metaclasses can do clever ! things with them. *** Exceptions should be types. This changes the rules, since now almost From jackjansen@users.sourceforge.net Sun Jul 1 23:03:57 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sun, 01 Jul 2001 15:03:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/cf cfscan.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/cf In directory usw-pr-cvs1:/tmp/cvs-serv15550/Python/Mac/Modules/cf Modified Files: cfscan.py Log Message: - Use weaklink generators so we can support OSX-only calls without crashing on OS9. - Convert CFString to/from Python strings. Currently always MacRoman, to be fixed later (as is unicode support). Python->CFString conversion is automatic. Index: cfscan.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/cf/cfscan.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** cfscan.py 2001/06/28 22:08:22 1.3 --- cfscan.py 2001/07/01 22:03:55 1.4 *************** *** 84,90 **** "CFStringGetCStringPtr", "CFStringGetCharactersPtr", # OSX only, to be done ! "CFURLCreateWithFileSystemPath", ! "CFURLCreateStringWithFileSystemPath", ] --- 84,92 ---- "CFStringGetCStringPtr", "CFStringGetCharactersPtr", + "CFStringGetCString", + "CFStringGetCharacters", # OSX only, to be done ! ## "CFURLCreateWithFileSystemPath", ! ## "CFURLCreateStringWithFileSystemPath", ] From jackjansen@users.sourceforge.net Sun Jul 1 23:04:04 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sun, 01 Jul 2001 15:04:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/cf cfsupport.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/cf In directory usw-pr-cvs1:/tmp/cvs-serv15581/Python/Mac/Modules/cf Modified Files: cfsupport.py Log Message: - Use weaklink generators so we can support OSX-only calls without crashing on OS9. - Convert CFString to/from Python strings. Currently always MacRoman, to be fixed later (as is unicode support). Python->CFString conversion is automatic. Index: cfsupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/cf/cfsupport.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** cfsupport.py 2001/06/28 22:08:26 1.3 --- cfsupport.py 2001/07/01 22:04:02 1.4 *************** *** 120,124 **** def outputCheckNewArg(self): Output("if (itself == NULL) return PyMac_Error(resNotFound);") - Output("CFRetain(itself);") def outputStructMembers(self): GlobalObjectDefinition.outputStructMembers(self) --- 120,123 ---- *************** *** 244,247 **** --- 243,256 ---- basechain = "&CFTypeRefObj_chain" + def outputCheckConvertArg(self): + Out(""" + if (v == Py_None) { *p_itself = NULL; return 1; } + if (PyString_Check(v)) { + char *cStr = PyString_AsString(v); + *p_itself = CFStringCreateWithCString((CFAllocatorRef)NULL, cStr, 0); + return 1; + } + """) + def outputRepr(self): Output() *************** *** 256,259 **** --- 265,272 ---- basechain = "&CFStringRefObj_chain" + def outputCheckConvertArg(self): + # Mutable, don't allow Python strings + return MyGlobalObjectDefinition.outputCheckConvertArg(self) + def outputRepr(self): Output() *************** *** 310,315 **** # Create the generator classes used to populate the lists ! Function = OSErrFunctionGenerator ! Method = OSErrMethodGenerator # Create and populate the lists --- 323,328 ---- # Create the generator classes used to populate the lists ! Function = OSErrWeakLinkFunctionGenerator ! Method = OSErrWeakLinkMethodGenerator # Create and populate the lists *************** *** 343,346 **** --- 356,380 ---- for f in CFMutableStringRef_methods: CFMutableStringRef_object.add(f) for f in CFURLRef_methods: CFURLRef_object.add(f) + + # Manual generators for getting data out of strings + + getasstring_body = """ + int size = CFStringGetLength(_self->ob_itself)+1; + char *data = malloc(size); + + if( data == NULL ) return PyErr_NoMemory(); + if ( CFStringGetCString(_self->ob_itself, data, size, 0) ) { + _res = (PyObject *)PyString_FromString(data); + } else { + PyErr_SetString(PyExc_RuntimeError, "CFStringGetCString could not fit the string"); + _res = NULL; + } + free(data); + return _res; + """ + + f = ManualGenerator("CFStringGetString", getasstring_body); + f.docstring = lambda: "() -> (string _rv)" + CFStringRef_object.add(f) # ADD add forloop here From jackjansen@users.sourceforge.net Sun Jul 1 23:09:26 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sun, 01 Jul 2001 15:09:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/bgen/bgen bgenGenerator.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/bgen/bgen In directory usw-pr-cvs1:/tmp/cvs-serv16408/Python/Tools/bgen/bgen Modified Files: bgenGenerator.py Log Message: Added WeakLink...Generator classes (should have done that ages ago). These check the c-function pointer for being NULL before calling it and raise UnimplementedError if it is. This allows system libs to be weak-linked, thereby allowing us to generate functions that are only available on some OS versions without getting a NULL dereference if the function isn't available. Index: bgenGenerator.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenGenerator.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -r1.9 -r1.10 *** bgenGenerator.py 2001/05/19 13:59:05 1.9 --- bgenGenerator.py 2001/07/01 22:09:24 1.10 *************** *** 165,168 **** --- 165,169 ---- def functionbody(self): self.declarations() + self.precheck() self.getargs() self.callit() *************** *** 195,198 **** --- 196,202 ---- if arg.mode in (InMode, InOutMode): arg.getargsCheck() + + def precheck(self): + pass def callit(self): From jackjansen@users.sourceforge.net Sun Jul 1 23:09:31 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sun, 01 Jul 2001 15:09:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/bgen/bgen macsupport.py,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/bgen/bgen In directory usw-pr-cvs1:/tmp/cvs-serv16429/Python/Tools/bgen/bgen Modified Files: macsupport.py Log Message: Added WeakLink...Generator classes (should have done that ages ago). These check the c-function pointer for being NULL before calling it and raise UnimplementedError if it is. This allows system libs to be weak-linked, thereby allowing us to generate functions that are only available on some OS versions without getting a NULL dereference if the function isn't available. Index: macsupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/macsupport.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -r1.22 -r1.23 *** macsupport.py 2001/06/27 21:58:40 1.22 --- macsupport.py 2001/07/01 22:09:29 1.23 *************** *** 119,122 **** --- 119,130 ---- #include "macglue.h" #include "pymactoolbox.h" + + /* 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) + """ *************** *** 146,149 **** --- 154,167 ---- class OSErrMethodGenerator(OSErrMixIn, MethodGenerator): pass + class WeakLinkMixIn: + "Mix-in to test the function actually exists (!= NULL) before calling" + + def precheck(self): + Output('PyMac_PRECHECK(%s);', self.name) + + class WeakLinkFunctionGenerator(WeakLinkMixIn, FunctionGenerator): pass + class WeakLinkMethodGenerator(WeakLinkMixIn, MethodGenerator): pass + class OSErrWeakLinkFunctionGenerator(OSErrMixIn, WeakLinkMixIn, FunctionGenerator): pass + class OSErrWeakLinkMethodGenerator(OSErrMixIn, WeakLinkMixIn, MethodGenerator): pass class MacModule(Module): From tim_one@users.sourceforge.net Mon Jul 2 02:38:35 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 01 Jul 2001 18:38:35 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv15192/python/dist/src/Lib/test Modified Files: test_generators.py Log Message: A clever union-find implementation from c.l.py, due to David Eppstein. This is another one that leaks memory without an explict clear! Time to bite this bullet. Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -r1.15 -r1.16 *** test_generators.py 2001/06/30 07:29:44 1.15 --- test_generators.py 2001/07/02 01:38:33 1.16 *************** *** 410,413 **** --- 410,490 ---- >>> me.gi_running 0 + + A clever union-find implementation from c.l.py, due to David Eppstein. + Sent: Friday, June 29, 2001 12:16 PM + To: python-list@python.org + Subject: Re: PEP 255: Simple Generators + + >>> class disjointSet: + ... def __init__(self, name): + ... self.name = name + ... self.parent = None + ... self.generator = self.generate() + ... + ... def generate(self): + ... while not self.parent: + ... yield self + ... for x in self.parent.generator: + ... yield x + ... + ... def find(self): + ... return self.generator.next() + ... + ... def union(self, parent): + ... if self.parent: + ... raise ValueError("Sorry, I'm not a root!") + ... self.parent = parent + ... + ... def __str__(self): + ... return self.name + ... + ... def clear(self): + ... self.__dict__.clear() + + >>> names = "ABCDEFGHIJKLM" + >>> sets = [disjointSet(name) for name in names] + >>> roots = sets[:] + + >>> import random + >>> random.seed(42) + >>> while 1: + ... for s in sets: + ... print "%s->%s" % (s, s.find()), + ... print + ... if len(roots) > 1: + ... s1 = random.choice(roots) + ... roots.remove(s1) + ... s2 = random.choice(roots) + ... s1.union(s2) + ... print "merged", s1, "into", s2 + ... else: + ... break + A->A B->B C->C D->D E->E F->F G->G H->H I->I J->J K->K L->L M->M + merged D into G + A->A B->B C->C D->G E->E F->F G->G H->H I->I J->J K->K L->L M->M + merged C into F + A->A B->B C->F D->G E->E F->F G->G H->H I->I J->J K->K L->L M->M + merged L into A + A->A B->B C->F D->G E->E F->F G->G H->H I->I J->J K->K L->A M->M + merged H into E + A->A B->B C->F D->G E->E F->F G->G H->E I->I J->J K->K L->A M->M + merged B into E + A->A B->E C->F D->G E->E F->F G->G H->E I->I J->J K->K L->A M->M + merged J into G + A->A B->E C->F D->G E->E F->F G->G H->E I->I J->G K->K L->A M->M + merged E into G + A->A B->G C->F D->G E->G F->F G->G H->G I->I J->G K->K L->A M->M + merged M into G + A->A B->G C->F D->G E->G F->F G->G H->G I->I J->G K->K L->A M->G + merged I into K + A->A B->G C->F D->G E->G F->F G->G H->G I->K J->G K->K L->A M->G + merged K into A + A->A B->G C->F D->G E->G F->F G->G H->G I->A J->G K->A L->A M->G + merged F into A + A->A B->G C->A D->G E->G F->A G->G H->G I->A J->G K->A L->A M->G + merged A into G + A->G B->G C->G D->G E->G F->G G->G H->G I->G J->G K->G L->G M->G + >>> for s in sets: # XXX memory leak without this + ... s.clear() """ From tim_one@users.sourceforge.net Mon Jul 2 05:08:41 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 01 Jul 2001 21:08:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild BUILDno.txt,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv9235/python/dist/src/PCbuild Modified Files: BUILDno.txt Log Message: Add tentative 2.1.1 Windows build numbers. Index: BUILDno.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/BUILDno.txt,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -r1.14 -r1.15 *** BUILDno.txt 2001/06/22 02:06:04 1.14 --- BUILDno.txt 2001/07/02 04:08:39 1.15 *************** *** 34,37 **** --- 34,41 ---- Windows Python BUILD numbers ---------------------------- + 20 2.1.1 TENTATIVE + 20-Jul-2001 + 19 2.1.1c1 TENTATIVE + 13-Jul-2001 18 2.0.1 22-Jun-2001 From tim_one@users.sourceforge.net Mon Jul 2 05:31:30 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 01 Jul 2001 21:31:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include patchlevel.h,2.49.2.1,2.49.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv12646/python/dist/src/Include Modified Files: Tag: release21-maint patchlevel.h Log Message: 2.1.1c1 WIndows fiddling, plus patchlevel.h. Index: patchlevel.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/patchlevel.h,v retrieving revision 2.49.2.1 retrieving revision 2.49.2.2 diff -C2 -r2.49.2.1 -r2.49.2.2 *** patchlevel.h 2001/04/17 15:19:29 2.49.2.1 --- patchlevel.h 2001/07/02 04:31:28 2.49.2.2 *************** *** 23,34 **** #define PY_MINOR_VERSION 1 #define PY_MICRO_VERSION 1 ! #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA #define PY_RELEASE_SERIAL 1 /* Version as a string */ ! #define PY_VERSION "2.1.1a1" /* Historic */ ! #define PATCHLEVEL "2.1.1a1" /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. --- 23,34 ---- #define PY_MINOR_VERSION 1 #define PY_MICRO_VERSION 1 ! #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_GAMMA #define PY_RELEASE_SERIAL 1 /* Version as a string */ ! #define PY_VERSION "2.1.1c1" /* Historic */ ! #define PATCHLEVEL "2.1.1c1" /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. From tim_one@users.sourceforge.net Mon Jul 2 05:31:30 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 01 Jul 2001 21:31:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild BUILDno.txt,1.11,1.11.2.1 python20.wse,1.39,1.39.2.1 pythoncore.dsp,1.13,1.13.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv12646/python/dist/src/PCbuild Modified Files: Tag: release21-maint BUILDno.txt python20.wse pythoncore.dsp Log Message: 2.1.1c1 WIndows fiddling, plus patchlevel.h. Index: BUILDno.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/BUILDno.txt,v retrieving revision 1.11 retrieving revision 1.11.2.1 diff -C2 -r1.11 -r1.11.2.1 *** BUILDno.txt 2001/04/16 18:20:30 1.11 --- BUILDno.txt 2001/07/02 04:31:28 1.11.2.1 *************** *** 34,37 **** --- 34,41 ---- Windows Python BUILD numbers ---------------------------- + 20 2.1.1 TENTATIVE + 20-Jul-2001 + 19 2.1.1c1 TENTATIVE + 13-Jul-2001 15 2.1 16-Apr-2001 Index: python20.wse =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/python20.wse,v retrieving revision 1.39 retrieving revision 1.39.2.1 diff -C2 -r1.39 -r1.39.2.1 *** python20.wse 2001/04/16 18:20:30 1.39 --- python20.wse 2001/07/02 04:31:28 1.39.2.1 *************** *** 2,6 **** item: Global Version=5.0 ! Title=Python 2.1 Flags=00010100 Languages=65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 --- 2,6 ---- item: Global Version=5.0 ! Title=Python 2.1.1c1 Flags=00010100 Languages=65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 *************** *** 67,71 **** item: Set Variable Variable=APPTITLE ! Value=Python 2.1 end item: Set Variable --- 67,71 ---- item: Set Variable Variable=APPTITLE ! Value=Python 2.1.1c1 end item: Set Variable Index: pythoncore.dsp =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/pythoncore.dsp,v retrieving revision 1.13 retrieving revision 1.13.2.1 diff -C2 -r1.13 -r1.13.2.1 *** pythoncore.dsp 2001/04/16 18:20:30 1.13 --- pythoncore.dsp 2001/07/02 04:31:28 1.13.2.1 *************** *** 740,748 **** !IF "$(CFG)" == "pythoncore - Win32 Release" ! # ADD CPP /D BUILD=15 !ELSEIF "$(CFG)" == "pythoncore - Win32 Debug" ! # ADD CPP /D BUILD=15 !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Debug" --- 740,748 ---- !IF "$(CFG)" == "pythoncore - Win32 Release" ! # ADD CPP /D BUILD=19 !ELSEIF "$(CFG)" == "pythoncore - Win32 Debug" ! # ADD CPP /D BUILD=19 !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Debug" From tim_one@users.sourceforge.net Mon Jul 2 05:57:32 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 01 Jul 2001 21:57:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib quopri.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv15534/python/dist/src/Lib Modified Files: quopri.py Log Message: Whitespace normalization; the plat-riscos file didn't even get by tabnanny.py. Index: quopri.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/quopri.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -r1.13 -r1.14 *** quopri.py 2001/06/19 22:48:10 1.13 --- quopri.py 2001/07/02 04:57:30 1.14 *************** *** 13,17 **** ! def needsquoting(c, quotetabs): """Decide whether a particular character needs to be quoted. --- 13,17 ---- ! def needsquoting(c, quotetabs): """Decide whether a particular character needs to be quoted. *************** *** 30,35 **** return ESCAPE + HEX[i/16] + HEX[i%16] - def encode(input, output, quotetabs): """Read 'input', apply quoted-printable encoding, and write to 'output'. --- 30,35 ---- return ESCAPE + HEX[i/16] + HEX[i%16] + def encode(input, output, quotetabs): """Read 'input', apply quoted-printable encoding, and write to 'output'. *************** *** 88,93 **** return outfp.getvalue() - def decode(input, output): """Read 'input', apply quoted-printable decoding, and write to 'output'. --- 88,93 ---- return outfp.getvalue() + def decode(input, output): """Read 'input', apply quoted-printable decoding, and write to 'output'. *************** *** 132,136 **** ! # Other helper functions def ishex(c): --- 132,136 ---- ! # Other helper functions def ishex(c): *************** *** 153,158 **** return bits - def main(): import sys --- 153,158 ---- return bits + def main(): import sys *************** *** 197,202 **** sys.exit(sts) - if __name__ == '__main__': main() --- 197,202 ---- sys.exit(sts) + if __name__ == '__main__': main() From tim_one@users.sourceforge.net Mon Jul 2 05:59:37 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 01 Jul 2001 21:59:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/plat-riscos riscosenviron.py,1.3,1.4 riscospath.py,1.2,1.3 rourl2path.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-riscos In directory usw-pr-cvs1:/tmp/cvs-serv15954/python/dist/src/Lib/plat-riscos Modified Files: riscosenviron.py riscospath.py rourl2path.py Log Message: Nuke hard tabs. Index: riscosenviron.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-riscos/riscosenviron.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** riscosenviron.py 2001/03/07 09:08:11 1.3 --- riscosenviron.py 2001/07/02 04:59:35 1.4 *************** *** 43,45 **** else: return failobj - --- 43,44 ---- Index: riscospath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-riscos/riscospath.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** riscospath.py 2001/04/10 22:03:14 1.2 --- riscospath.py 2001/07/02 04:59:35 1.3 *************** *** 20,30 **** try: ! import swi except ImportError: ! class _swi: ! def swi(*a): ! raise AttributeError, 'This function only available under RISC OS' ! block= swi ! swi= _swi() [_false, _true]= range(2) --- 20,30 ---- try: ! import swi except ImportError: ! class _swi: ! def swi(*a): ! raise AttributeError, 'This function only available under RISC OS' ! block= swi ! swi= _swi() [_false, _true]= range(2) *************** *** 46,179 **** def _split(p): ! """ ! split filing system name (including special field) and drive specifier from rest ! of path. This is needed by many riscospath functions. ! """ ! dash= _allowMOSFSNames and p[:1]=='-' ! if dash: ! q= string.find(p, '-', 1)+1 ! else: ! if p[:1]==':': ! q= 0 else: ! q= string.find(p, ':')+1 # q= index of start of non-FS portion of path ! s= string.find(p, '#') ! if s==-1 or s>q: ! s= q # find end of main FS name, not including special field ! else: ! for c in p[dash:s]: ! if c not in string.letters: ! q= 0 ! break # disallow invalid non-special-field characters in FS name ! r= q ! if p[q:q+1]==':': ! r= string.find(p, '.', q+1)+1 ! if r==0: ! r= len(p) # find end of drive name (if any) following FS name (if any) ! return (p[:q], p[q:r], p[r:]) def normcase(p): """ ! Normalize the case of a pathname. This converts to lowercase as the native RISC ! OS filesystems are case-insensitive. However, not all filesystems have to be, ! and there's no simple way to find out what type an FS is argh. ! """ ! return string.lower(p) def isabs(p): """ ! Return whether a path is absolute. Under RISC OS, a file system specifier does ! not make a path absolute, but a drive name or number does, and so does using the ! symbol for root, URD, library, CSD or PSD. This means it is perfectly possible ! to have an "absolute" URL dependent on the current working directory, and ! equally you can have a "relative" URL that's on a completely different device to ! the current one argh. ! """ ! (fs, drive, path)= _split(p) ! return drive!='' or path[:1] in _roots def join(a, *p): ! """ ! Join path elements with the directory separator, replacing the entire path when ! an absolute or FS-changing path part is found. ! """ ! j= a ! for b in p: ! (fs, drive, path)= _split(b) ! if fs!='' or drive!='' or path[:1] in _roots: ! j= b ! else: ! j= j+'.'+b ! return j def split(p): ! """ ! Split a path in head (everything up to the last '.') and tail (the rest). FS ! name must still be dealt with separately since special field may contain '.'. ! """ ! (fs, drive, path)= _split(p) ! q= string.rfind(path, '.') ! if q!=-1: ! return (fs+drive+path[:q], path[q+1:]) ! return ('', p) def splitext(p): ! """ ! Split a path in root and extension. This assumes the 'using slash for dot and ! dot for slash with foreign files' convention common in RISC OS is in force. ! """ ! (tail, head)= split(p) ! if '/' in head: ! q= len(head)-string.rfind(head, '/') ! return (p[:-q], p[-q:]) ! return (p, '') def splitdrive(p): """ ! Split a pathname into a drive specification (including FS name) and the rest of ! the path. The terminating dot of the drive name is included in the drive ! specification. ! """ ! (fs, drive, path)= _split(p) ! return (fs+drive, p) def basename(p): """ ! Return the tail (basename) part of a path. ! """ ! return split(p)[1] def dirname(p): """ ! Return the head (dirname) part of a path. ! """ ! return split(p)[0] def commonprefix(ps): ! """ ! Return the longest prefix of all list elements. Purely string-based; does not ! separate any path parts. Why am I in os.path? ! """ ! if len(ps)==0: ! return '' ! prefix= ps[0] ! for p in ps[1:]: ! prefix= prefix[:len(p)] ! for i in range(len(prefix)): ! if prefix[i] <> p[i]: ! prefix= prefix[:i] ! if i==0: ! return '' ! break ! return prefix --- 46,179 ---- def _split(p): ! """ ! split filing system name (including special field) and drive specifier from rest ! of path. This is needed by many riscospath functions. ! """ ! dash= _allowMOSFSNames and p[:1]=='-' ! if dash: ! q= string.find(p, '-', 1)+1 ! else: ! if p[:1]==':': ! q= 0 ! else: ! q= string.find(p, ':')+1 # q= index of start of non-FS portion of path ! s= string.find(p, '#') ! if s==-1 or s>q: ! s= q # find end of main FS name, not including special field else: ! for c in p[dash:s]: ! if c not in string.letters: ! q= 0 ! break # disallow invalid non-special-field characters in FS name ! r= q ! if p[q:q+1]==':': ! r= string.find(p, '.', q+1)+1 ! if r==0: ! r= len(p) # find end of drive name (if any) following FS name (if any) ! return (p[:q], p[q:r], p[r:]) def normcase(p): + """ + Normalize the case of a pathname. This converts to lowercase as the native RISC + OS filesystems are case-insensitive. However, not all filesystems have to be, + and there's no simple way to find out what type an FS is argh. """ ! return string.lower(p) def isabs(p): + """ + Return whether a path is absolute. Under RISC OS, a file system specifier does + not make a path absolute, but a drive name or number does, and so does using the + symbol for root, URD, library, CSD or PSD. This means it is perfectly possible + to have an "absolute" URL dependent on the current working directory, and + equally you can have a "relative" URL that's on a completely different device to + the current one argh. """ ! (fs, drive, path)= _split(p) ! return drive!='' or path[:1] in _roots def join(a, *p): ! """ ! Join path elements with the directory separator, replacing the entire path when ! an absolute or FS-changing path part is found. ! """ ! j= a ! for b in p: ! (fs, drive, path)= _split(b) ! if fs!='' or drive!='' or path[:1] in _roots: ! j= b ! else: ! j= j+'.'+b ! return j def split(p): ! """ ! Split a path in head (everything up to the last '.') and tail (the rest). FS ! name must still be dealt with separately since special field may contain '.'. ! """ ! (fs, drive, path)= _split(p) ! q= string.rfind(path, '.') ! if q!=-1: ! return (fs+drive+path[:q], path[q+1:]) ! return ('', p) def splitext(p): ! """ ! Split a path in root and extension. This assumes the 'using slash for dot and ! dot for slash with foreign files' convention common in RISC OS is in force. ! """ ! (tail, head)= split(p) ! if '/' in head: ! q= len(head)-string.rfind(head, '/') ! return (p[:-q], p[-q:]) ! return (p, '') def splitdrive(p): + """ + Split a pathname into a drive specification (including FS name) and the rest of + the path. The terminating dot of the drive name is included in the drive + specification. """ ! (fs, drive, path)= _split(p) ! return (fs+drive, p) def basename(p): + """ + Return the tail (basename) part of a path. """ ! return split(p)[1] def dirname(p): + """ + Return the head (dirname) part of a path. """ ! return split(p)[0] def commonprefix(ps): ! """ ! Return the longest prefix of all list elements. Purely string-based; does not ! separate any path parts. Why am I in os.path? ! """ ! if len(ps)==0: ! return '' ! prefix= ps[0] ! for p in ps[1:]: ! prefix= prefix[:len(p)] ! for i in range(len(prefix)): ! if prefix[i] <> p[i]: ! prefix= prefix[:i] ! if i==0: ! return '' ! break ! return prefix *************** *** 181,197 **** def getsize(p): """ ! Return the size of a file, reported by os.stat(). ! """ ! st= os.stat(p) ! return st[stat.ST_SIZE] def getmtime(p): """ ! Return the last modification time of a file, reported by os.stat(). ! """ ! st = os.stat(p) ! return st[stat.ST_MTIME] getatime= getmtime --- 181,197 ---- def getsize(p): + """ + Return the size of a file, reported by os.stat(). """ ! st= os.stat(p) ! return st[stat.ST_SIZE] def getmtime(p): + """ + Return the last modification time of a file, reported by os.stat(). """ ! st = os.stat(p) ! return st[stat.ST_MTIME] getatime= getmtime *************** *** 201,238 **** def exists(p): """ ! Test whether a path exists. ! """ ! try: ! return swi.swi('OS_File', '5s;i', p)!=0 ! except swi.error: ! return 0 def isdir(p): """ ! Is a path a directory? Includes image files. ! """ ! try: ! return swi.swi('OS_File', '5s;i', p) in [2, 3] ! except swi.error: ! return 0 def isfile(p): """ ! Test whether a path is a file, including image files. ! """ ! try: ! return swi.swi('OS_File', '5s;i', p) in [1, 3] ! except swi.error: ! return 0 def islink(p): """ ! RISC OS has no links or mounts. ! """ ! return _false ismount= islink --- 201,238 ---- def exists(p): + """ + Test whether a path exists. """ ! try: ! return swi.swi('OS_File', '5s;i', p)!=0 ! except swi.error: ! return 0 def isdir(p): + """ + Is a path a directory? Includes image files. """ ! try: ! return swi.swi('OS_File', '5s;i', p) in [2, 3] ! except swi.error: ! return 0 def isfile(p): + """ + Test whether a path is a file, including image files. """ ! try: ! return swi.swi('OS_File', '5s;i', p) in [1, 3] ! except swi.error: ! return 0 def islink(p): + """ + RISC OS has no links or mounts. """ ! return _false ismount= islink *************** *** 247,267 **** def samefile(fa, fb): """ ! Test whether two pathnames reference the same actual file. ! """ ! l= 512 ! b= swi.block(l) ! swi.swi('OS_FSControl', 'isb..i', 37, fa, b, l) ! fa= b.ctrlstring() ! swi.swi('OS_FSControl', 'isb..i', 37, fb, b, l) ! fb= b.ctrlstring() ! return fa==fb def sameopenfile(a, b): """ ! Test whether two open file objects reference the same file. ! """ ! return os.fstat(a)[stat.ST_INO]==os.fstat(b)[stat.ST_INO] --- 247,267 ---- def samefile(fa, fb): + """ + Test whether two pathnames reference the same actual file. """ ! l= 512 ! b= swi.block(l) ! swi.swi('OS_FSControl', 'isb..i', 37, fa, b, l) ! fa= b.ctrlstring() ! swi.swi('OS_FSControl', 'isb..i', 37, fb, b, l) ! fb= b.ctrlstring() ! return fa==fb def sameopenfile(a, b): + """ + Test whether two open file objects reference the same file. """ ! return os.fstat(a)[stat.ST_INO]==os.fstat(b)[stat.ST_INO] *************** *** 272,311 **** def expanduser(p): ! (fs, drive, path)= _split(p) ! l= 512 ! b= swi.block(l) ! ! if path[:1]!='@': ! return p ! if fs=='': ! fsno= swi.swi('OS_Args', '00;i') ! swi.swi('OS_FSControl', 'iibi', 33, fsno, b, l) ! fsname= b.ctrlstring() ! else: ! if fs[:1]=='-': ! fsname= fs[1:-1] else: ! fsname= fs[:-1] ! fsname= string.split(fsname, '#', 1)[0] # remove special field from fs ! x= swi.swi('OS_FSControl', 'ib2s.i;.....i', 54, b, fsname, l) ! if x0: ! ups= ups-1 ! else: ! if rhs=='': ! rhs= el else: ! rhs= el+'.'+rhs ! while ups>0: ! ups= ups-1 ! rhs= '^.'+rhs ! return fs+drive+rhs --- 319,344 ---- def normpath(p): + """ + Normalize path, eliminating up-directory ^s. """ ! (fs, drive, path)= _split(p) ! rhs= '' ! ups= 0 ! while path!='': ! (path, el)= split(path) ! if el=='^': ! ups= ups+1 else: ! if ups>0: ! ups= ups-1 ! else: ! if rhs=='': ! rhs= el ! else: ! rhs= el+'.'+rhs ! while ups>0: ! ups= ups-1 ! rhs= '^.'+rhs ! return fs+drive+rhs *************** *** 347,363 **** def walk(top, func, arg): ! """ ! walk(top,func,args) calls func(arg, d, files) for each directory "d" in the tree ! rooted at "top" (including "top" itself). "files" is a list of all the files and ! subdirs in directory "d". ! """ ! try: ! names= os.listdir(top) ! except os.error: ! return ! func(arg, top, names) ! for name in names: ! name= join(top, name) ! if isdir(name) and not islink(name): ! walk(name, func, arg) ! --- 347,362 ---- def walk(top, func, arg): ! """ ! walk(top,func,args) calls func(arg, d, files) for each directory "d" in the tree ! rooted at "top" (including "top" itself). "files" is a list of all the files and ! subdirs in directory "d". ! """ ! try: ! names= os.listdir(top) ! except os.error: ! return ! func(arg, top, names) ! for name in names: ! name= join(top, name) ! if isdir(name) and not islink(name): ! walk(name, func, arg) Index: rourl2path.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-riscos/rourl2path.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** rourl2path.py 2001/03/02 05:55:07 1.1 --- rourl2path.py 2001/07/02 04:59:35 1.2 *************** *** 14,62 **** tp = urllib.splittype(pathname)[0] if tp and tp <> 'file': ! raise RuntimeError, 'Cannot convert non-local URL to pathname' components = string.split(pathname, '/') # Remove . and embedded .. i = 0 while i < len(components): ! if components[i] == '.': ! del components[i] ! elif components[i] == '..' and i > 0 and \ ! components[i-1] not in ('', '..'): ! del components[i-1:i+1] ! i = i-1 ! elif components[i] == '' and i > 0 and components[i-1] <> '': ! del components[i] ! else: ! if components[i]<>'..' and string.find(components[i], '.')<>-1 : ! components[i] = string.join(string.split(components[i],'.'),'/') ! i = i+1 if not components[0]: ! # Absolute unix path, don't start with colon ! return string.join(components[1:], '.') else: ! # relative unix path, start with colon. First replace ! # leading .. by empty strings (giving ::file) ! i = 0 ! while i < len(components) and components[i] == '..': ! components[i] = '^' ! i = i + 1 ! return string.join(components, '.') def pathname2url(pathname): "convert mac pathname to /-delimited pathname" if '/' in pathname: ! raise RuntimeError, "Cannot convert pathname containing slashes" components = string.split(pathname, ':') # Replace empty string ('::') by .. (will result in '/../' later) for i in range(1, len(components)): ! if components[i] == '': ! components[i] = '..' # Truncate names longer than 31 bytes components = map(lambda x: x[:31], components) if os.path.isabs(pathname): ! return '/' + string.join(components, '/') else: ! return string.join(components, '/') def test(): --- 14,62 ---- tp = urllib.splittype(pathname)[0] if tp and tp <> 'file': ! raise RuntimeError, 'Cannot convert non-local URL to pathname' components = string.split(pathname, '/') # Remove . and embedded .. i = 0 while i < len(components): ! if components[i] == '.': ! del components[i] ! elif components[i] == '..' and i > 0 and \ ! components[i-1] not in ('', '..'): ! del components[i-1:i+1] ! i = i-1 ! elif components[i] == '' and i > 0 and components[i-1] <> '': ! del components[i] ! else: ! if components[i]<>'..' and string.find(components[i], '.')<>-1 : ! components[i] = string.join(string.split(components[i],'.'),'/') ! i = i+1 if not components[0]: ! # Absolute unix path, don't start with colon ! return string.join(components[1:], '.') else: ! # relative unix path, start with colon. First replace ! # leading .. by empty strings (giving ::file) ! i = 0 ! while i < len(components) and components[i] == '..': ! components[i] = '^' ! i = i + 1 ! return string.join(components, '.') def pathname2url(pathname): "convert mac pathname to /-delimited pathname" if '/' in pathname: ! raise RuntimeError, "Cannot convert pathname containing slashes" components = string.split(pathname, ':') # Replace empty string ('::') by .. (will result in '/../' later) for i in range(1, len(components)): ! if components[i] == '': ! components[i] = '..' # Truncate names longer than 31 bytes components = map(lambda x: x[:31], components) if os.path.isabs(pathname): ! return '/' + string.join(components, '/') else: ! return string.join(components, '/') def test(): *************** *** 64,81 **** "/SCSI::SCSI4/$/Anwendung/Comm/Apps/!Fresco/Welcome", "../index.html", ! "bar/index.html", ! "/foo/bar/index.html", ! "/foo/bar/", ! "/"]: ! print `url`, '->', `url2pathname(url)` for path in ["drive:", ! "drive:dir:", ! "drive:dir:file", ! "drive:file", ! "file", ! ":file", ! ":dir:", ! ":dir:file"]: ! print `path`, '->', `pathname2url(path)` if __name__ == '__main__': --- 64,81 ---- "/SCSI::SCSI4/$/Anwendung/Comm/Apps/!Fresco/Welcome", "../index.html", ! "bar/index.html", ! "/foo/bar/index.html", ! "/foo/bar/", ! "/"]: ! print `url`, '->', `url2pathname(url)` for path in ["drive:", ! "drive:dir:", ! "drive:dir:file", ! "drive:file", ! "file", ! ":file", ! ":dir:", ! ":dir:file"]: ! print `path`, '->', `pathname2url(path)` if __name__ == '__main__': From fdrake@users.sourceforge.net Mon Jul 2 16:11:36 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 02 Jul 2001 08:11:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc Makefile,1.218.2.1,1.218.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv7863 Modified Files: Tag: release21-maint Makefile Log Message: Update to reflect Python 2.1.1 release planning. Index: Makefile =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile,v retrieving revision 1.218.2.1 retrieving revision 1.218.2.2 diff -C2 -r1.218.2.1 -r1.218.2.2 *** Makefile 2001/04/18 05:24:30 1.218.2.1 --- Makefile 2001/07/02 15:11:34 1.218.2.2 *************** *** 68,72 **** # This is the *documentation* release, and is used to construct the file # names of the downloadable tarballs. ! RELEASE=2.1.1a0 PYTHON= python --- 68,72 ---- # This is the *documentation* release, and is used to construct the file # names of the downloadable tarballs. ! RELEASE=2.1.1c1 PYTHON= python From fdrake@users.sourceforge.net Mon Jul 2 16:11:36 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 02 Jul 2001 08:11:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/texinputs boilerplate.tex,1.58.2.2,1.58.2.3 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory usw-pr-cvs1:/tmp/cvs-serv7863/texinputs Modified Files: Tag: release21-maint boilerplate.tex Log Message: Update to reflect Python 2.1.1 release planning. Index: boilerplate.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/boilerplate.tex,v retrieving revision 1.58.2.2 retrieving revision 1.58.2.3 diff -C2 -r1.58.2.2 -r1.58.2.3 *** boilerplate.tex 2001/06/22 15:52:13 1.58.2.2 --- boilerplate.tex 2001/07/02 15:11:34 1.58.2.3 *************** *** 8,11 **** \date{\today} % XXX update before release! \release{2.1.1} % software release, not documentation ! \setreleaseinfo{a0} % empty for final release \setshortversion{2.1} % major.minor only for software --- 8,11 ---- \date{\today} % XXX update before release! \release{2.1.1} % software release, not documentation ! \setreleaseinfo{c1} % empty for final release \setshortversion{2.1} % major.minor only for software From fdrake@users.sourceforge.net Mon Jul 2 16:12:27 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 02 Jul 2001 08:12:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc ACKS,1.16.4.2,1.16.4.3 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv8135 Modified Files: Tag: release21-maint ACKS Log Message: Added another name. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ACKS,v retrieving revision 1.16.4.2 retrieving revision 1.16.4.3 diff -C2 -r1.16.4.2 -r1.16.4.3 *** ACKS 2001/06/29 15:41:45 1.16.4.2 --- ACKS 2001/07/02 15:12:25 1.16.4.3 *************** *** 169,171 **** --- 169,172 ---- Ka-Ping Yee Moshe Zadka + Milan Zamazal Cheng Zhang From jackjansen@users.sourceforge.net Mon Jul 2 16:34:59 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Mon, 02 Jul 2001 08:34:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Include config.h,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Include In directory usw-pr-cvs1:/tmp/cvs-serv13667/python/Mac/Include Modified Files: config.h Log Message: Added the new unicode defines. Not really tested yet, but Python compiles again at least. Index: config.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Include/config.h,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -r1.32 -r1.33 *** config.h 2001/05/23 08:55:50 1.32 --- config.h 2001/07/02 15:34:57 1.33 *************** *** 200,203 **** --- 200,212 ---- #define HAVE_WCHAR_H 1 + /* Define if you want to have a Unicode type. */ + #define Py_USING_UNICODE 1 + + /* Define as the integral type used for Unicode representation. */ + #define PY_UNICODE_TYPE wchar_t + + /* Define as the size of the unicode type. */ + #define Py_UNICODE_SIZE 2 + /* Define if malloc(0) returns a NULL pointer */ #ifdef USE_MSL_MALLOC From effbot@users.sourceforge.net Mon Jul 2 17:42:52 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Mon, 02 Jul 2001 09:42:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _sre.c,2.55,2.56 sre.h,2.20,2.21 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv29536/Modules Modified Files: _sre.c sre.h Log Message: merged with pythonware's SRE 2.1.1 codebase Index: _sre.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_sre.c,v retrieving revision 2.55 retrieving revision 2.56 diff -C2 -r2.55 -r2.56 *** _sre.c 2001/04/15 19:00:58 2.55 --- _sre.c 2001/07/02 16:42:49 2.56 *************** *** 29,32 **** --- 29,34 ---- * 2001-03-20 fl lots of fixes for 2.1b2 * 2001-04-15 fl export copyright as Python attribute, not global + * 2001-04-28 fl added __copy__ methods (work in progress) + * 2001-05-14 fl fixes for 1.5.2 * * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. *************** *** 44,50 **** static char copyright[] = ! " SRE 2.1b2 Copyright (c) 1997-2001 by Secret Labs AB "; #include "Python.h" #include "sre.h" --- 46,53 ---- static char copyright[] = ! " SRE 2.1.1 Copyright (c) 1997-2001 by Secret Labs AB "; #include "Python.h" + #include "structmember.h" /* offsetof */ #include "sre.h" *************** *** 87,90 **** --- 90,96 ---- #undef USE_INLINE + /* enables copy/deepcopy handling (work in progress) */ + #undef USE_BUILTIN_COPY + #if PY_VERSION_HEX < 0x01060000 #define PyObject_DEL(op) PyMem_DEL((op)) *************** *** 445,448 **** --- 451,455 ---- return this == that; + #if defined(HAVE_UNICODE) case SRE_AT_UNI_BOUNDARY: if (state->beginning == state->end) *************** *** 462,465 **** --- 469,474 ---- SRE_UNI_IS_WORD((int) ptr[0]) : 0; return this == that; + #endif + } *************** *** 1287,1290 **** --- 1296,1301 ---- return NULL; + self->codesize = n; + for (i = 0; i < n; i++) { PyObject *o = PyList_GET_ITEM(code, i); *************** *** 1845,1848 **** --- 1856,1895 ---- } + static PyObject* + pattern_copy(PatternObject* self, PyObject* args) + { + #if USE_BUILTIN_COPY + PatternObject* copy; + int offset; + + /* work in progress */ + + copy = PyObject_NEW_VAR(PatternObject, &Pattern_Type, self->codesize); + if (!copy) + return NULL; + + offset = offsetof(PatternObject, groups); + + Py_XINCREF(self->groupindex); + Py_XINCREF(self->indexgroup); + Py_XINCREF(self->pattern); + + memcpy((char*) copy + offset, (char*) self + offset, + sizeof(PatternObject) + self->codesize * sizeof(SRE_CODE) - offset); + + return (PyObject*) copy; + #else + PyErr_SetString(PyExc_TypeError, "cannot copy this pattern object"); + return NULL; + #endif + } + + static PyObject* + pattern_deepcopy(PatternObject* self, PyObject* args) + { + PyErr_SetString(PyExc_TypeError, "cannot deepcopy this pattern object"); + return NULL; + } + static PyMethodDef pattern_methods[] = { {"match", (PyCFunction) pattern_match, METH_VARARGS|METH_KEYWORDS}, *************** *** 1852,1857 **** {"split", (PyCFunction) pattern_split, METH_VARARGS|METH_KEYWORDS}, {"findall", (PyCFunction) pattern_findall, METH_VARARGS|METH_KEYWORDS}, - /* experimental */ {"scanner", (PyCFunction) pattern_scanner, METH_VARARGS}, {NULL, NULL} }; --- 1899,1905 ---- {"split", (PyCFunction) pattern_split, METH_VARARGS|METH_KEYWORDS}, {"findall", (PyCFunction) pattern_findall, METH_VARARGS|METH_KEYWORDS}, {"scanner", (PyCFunction) pattern_scanner, METH_VARARGS}, + {"__copy__", (PyCFunction) pattern_copy, METH_VARARGS}, + {"__deepcopy__", (PyCFunction) pattern_deepcopy, METH_VARARGS}, {NULL, NULL} }; *************** *** 2212,2215 **** --- 2260,2303 ---- } + static PyObject* + match_copy(MatchObject* self, PyObject* args) + { + #if USE_BUILTIN_COPY + MatchObject* copy; + int slots, offset; + + /* works in progress */ + + slots = 2 * (self->pattern->groups+1); + + copy = PyObject_NEW_VAR(MatchObject, &Match_Type, slots); + if (!copy) + return NULL; + + /* this value a constant, but any compiler should be able to + figure that out all by itself */ + offset = offsetof(MatchObject, string); + + Py_XINCREF(self->pattern); + Py_XINCREF(self->string); + Py_XINCREF(self->regs); + + memcpy((char*) copy + offset, (char*) self + offset, + sizeof(MatchObject) + slots * sizeof(int) - offset); + + return (PyObject*) copy; + #else + PyErr_SetString(PyExc_TypeError, "cannot deepcopy this match object"); + return NULL; + #endif + } + + static PyObject* + match_deepcopy(MatchObject* self, PyObject* args) + { + PyErr_SetString(PyExc_TypeError, "cannot deepcopy this match object"); + return NULL; + } + static PyMethodDef match_methods[] = { {"group", (PyCFunction) match_group, METH_VARARGS}, *************** *** 2220,2223 **** --- 2308,2313 ---- {"groupdict", (PyCFunction) match_groupdict, METH_VARARGS|METH_KEYWORDS}, {"expand", (PyCFunction) match_expand, METH_VARARGS}, + {"__copy__", (PyCFunction) match_copy, METH_VARARGS}, + {"__deepcopy__", (PyCFunction) match_deepcopy, METH_VARARGS}, {NULL, NULL} }; Index: sre.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/sre.h,v retrieving revision 2.20 retrieving revision 2.21 diff -C2 -r2.20 -r2.21 *** sre.h 2001/06/27 18:59:43 2.20 --- sre.h 2001/07/02 16:42:49 2.21 *************** *** 4,8 **** * regular expression matching engine * ! * Copyright (c) 1997-2000 by Secret Labs AB. All rights reserved. * * See the _sre.c file for information on usage and redistribution. --- 4,8 ---- * regular expression matching engine * ! * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. * * See the _sre.c file for information on usage and redistribution. *************** *** 22,28 **** #endif typedef struct { PyObject_VAR_HEAD ! int groups; PyObject* groupindex; PyObject* indexgroup; --- 22,30 ---- #endif + #define SRE_CODE unsigned short + typedef struct { PyObject_VAR_HEAD ! int groups; /* must be first! */ PyObject* groupindex; PyObject* indexgroup; *************** *** 31,34 **** --- 33,37 ---- int flags; /* flags used when compiling pattern source */ /* pattern code */ + int codesize; SRE_CODE code[1]; } PatternObject; *************** *** 38,42 **** typedef struct { PyObject_VAR_HEAD ! PyObject* string; /* link to the target string */ PyObject* regs; /* cached list of matching spans */ PatternObject* pattern; /* link to the regex (pattern) object */ --- 41,45 ---- typedef struct { PyObject_VAR_HEAD ! PyObject* string; /* link to the target string (must be first) */ PyObject* regs; /* cached list of matching spans */ PatternObject* pattern; /* link to the regex (pattern) object */ From fdrake@users.sourceforge.net Mon Jul 2 17:55:44 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 02 Jul 2001 09:55:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib site.py,1.27,1.28 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv32645/Lib Modified Files: site.py Log Message: Avoid using os.path.normcase() on sys.path elements; doing so causes paths to be presented in an unfamiliar case on case-preserving filesystems. This closes SF patch #436173. Index: site.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/site.py,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -r1.27 -r1.28 *** site.py 2001/06/12 16:48:52 1.27 --- site.py 2001/07/02 16:55:42 1.28 *************** *** 67,86 **** def makepath(*paths): ! dir = os.path.join(*paths) ! return os.path.normcase(os.path.abspath(dir)) ! L = sys.modules.values() ! for m in L: if hasattr(m, "__file__") and m.__file__: ! m.__file__ = makepath(m.__file__) ! del m, L # This ensures that the initial path provided by the interpreter contains # only absolute pathnames, even if we're running from the build directory. L = [] for dir in sys.path: ! dir = makepath(dir) ! if dir not in L: L.append(dir) sys.path[:] = L del dir, L --- 67,87 ---- def makepath(*paths): ! dir = os.path.abspath(os.path.join(*paths)) ! return dir, os.path.normcase(dir) ! 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 = {} for dir in sys.path: ! dir, dircase = makepath(dir) ! if not dirs_in_sys_path.has_key(dircase): L.append(dir) + dirs_in_sys_path[dircase] = 1 sys.path[:] = L del dir, L *************** *** 96,101 **** def addsitedir(sitedir): ! sitedir = makepath(sitedir) ! if sitedir not in sys.path: sys.path.append(sitedir) # Add path component try: --- 97,102 ---- def addsitedir(sitedir): ! sitedir, sitedircase = makepath(sitedir) ! if not dirs_in_sys_path.has_key(sitedircase): sys.path.append(sitedir) # Add path component try: *************** *** 103,107 **** except os.error: return - names = map(os.path.normcase, names) names.sort() for name in names: --- 104,107 ---- *************** *** 126,132 **** if dir[-1] == '\n': dir = dir[:-1] ! dir = makepath(sitedir, dir) ! if dir not in sys.path and os.path.exists(dir): sys.path.append(dir) prefixes = [sys.prefix] --- 126,133 ---- if dir[-1] == '\n': dir = dir[:-1] ! dir, dircase = makepath(sitedir, dir) ! if not dirs_in_sys_path.has_key(dircase) and os.path.exists(dir): sys.path.append(dir) + dirs_in_sys_path[dircase] = 1 prefixes = [sys.prefix] *************** *** 136,146 **** if prefix: if os.sep == '/': ! sitedirs = [makepath(prefix, ! "lib", ! "python" + sys.version[:3], ! "site-packages"), ! makepath(prefix, "lib", "site-python")] elif os.sep == ':': ! sitedirs = [makepath(prefix, "lib", "site-packages")] else: sitedirs = [prefix] --- 137,147 ---- if prefix: if os.sep == '/': ! sitedirs = [os.path.join(prefix, ! "lib", ! "python" + sys.version[:3], ! "site-packages"), ! os.path.join(prefix, "lib", "site-python")] elif os.sep == ':': ! sitedirs = [os.path.join(prefix, "lib", "site-packages")] else: sitedirs = [prefix] *************** *** 148,151 **** --- 149,154 ---- if os.path.isdir(sitedir): addsitedir(sitedir) + + del dirs_in_sys_path # Define new built-ins 'quit' and 'exit'. From fdrake@users.sourceforge.net Mon Jul 2 17:56:11 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 02 Jul 2001 09:56:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib site.py,1.26,1.26.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv325/Lib Modified Files: Tag: release21-maint site.py Log Message: Avoid using os.path.normcase() on sys.path elements; doing so causes paths to be presented in an unfamiliar case on case-preserving filesystems. This closes SF patch #436173. Index: site.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/site.py,v retrieving revision 1.26 retrieving revision 1.26.2.1 diff -C2 -r1.26 -r1.26.2.1 *** site.py 2001/03/23 17:53:49 1.26 --- site.py 2001/07/02 16:56:09 1.26.2.1 *************** *** 67,86 **** def makepath(*paths): ! dir = os.path.join(*paths) ! return os.path.normcase(os.path.abspath(dir)) ! L = sys.modules.values() ! for m in L: if hasattr(m, "__file__") and m.__file__: ! m.__file__ = makepath(m.__file__) ! del m, L # This ensures that the initial path provided by the interpreter contains # only absolute pathnames, even if we're running from the build directory. L = [] for dir in sys.path: ! dir = makepath(dir) ! if dir not in L: L.append(dir) sys.path[:] = L del dir, L --- 67,87 ---- def makepath(*paths): ! dir = os.path.abspath(os.path.join(*paths)) ! return dir, os.path.normcase(dir) ! 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 = {} for dir in sys.path: ! dir, dircase = makepath(dir) ! if not dirs_in_sys_path.has_key(dircase): L.append(dir) + dirs_in_sys_path[dircase] = 1 sys.path[:] = L del dir, L *************** *** 96,101 **** def addsitedir(sitedir): ! sitedir = makepath(sitedir) ! if sitedir not in sys.path: sys.path.append(sitedir) # Add path component try: --- 97,102 ---- def addsitedir(sitedir): ! sitedir, sitedircase = makepath(sitedir) ! if not dirs_in_sys_path.has_key(sitedircase): sys.path.append(sitedir) # Add path component try: *************** *** 103,107 **** except os.error: return - names = map(os.path.normcase, names) names.sort() for name in names: --- 104,107 ---- *************** *** 126,132 **** if dir[-1] == '\n': dir = dir[:-1] ! dir = makepath(sitedir, dir) ! if dir not in sys.path and os.path.exists(dir): sys.path.append(dir) prefixes = [sys.prefix] --- 126,133 ---- if dir[-1] == '\n': dir = dir[:-1] ! dir, dircase = makepath(sitedir, dir) ! if not dirs_in_sys_path.has_key(dircase) and os.path.exists(dir): sys.path.append(dir) + dirs_in_sys_path[dircase] = 1 prefixes = [sys.prefix] *************** *** 136,146 **** if prefix: if os.sep == '/': ! sitedirs = [makepath(prefix, ! "lib", ! "python" + sys.version[:3], ! "site-packages"), ! makepath(prefix, "lib", "site-python")] elif os.sep == ':': ! sitedirs = [makepath(prefix, "lib", "site-packages")] else: sitedirs = [prefix] --- 137,147 ---- if prefix: if os.sep == '/': ! sitedirs = [os.path.join(prefix, ! "lib", ! "python" + sys.version[:3], ! "site-packages"), ! os.path.join(prefix, "lib", "site-python")] elif os.sep == ':': ! sitedirs = [os.path.join(prefix, "lib", "site-packages")] else: sitedirs = [prefix] *************** *** 148,151 **** --- 149,154 ---- if os.path.isdir(sitedir): addsitedir(sitedir) + + del dirs_in_sys_path # Define new built-ins 'quit' and 'exit'. From effbot@users.sourceforge.net Mon Jul 2 17:58:40 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Mon, 02 Jul 2001 09:58:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _sre.c,2.56,2.57 sre_constants.h,2.12,2.13 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv555/Modules Modified Files: _sre.c sre_constants.h Log Message: added martin's BIGCHARSET patch to SRE 2.1.1. martin reports 2x speedups for certain unicode character ranges. Index: _sre.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_sre.c,v retrieving revision 2.56 retrieving revision 2.57 diff -C2 -r2.56 -r2.57 *** _sre.c 2001/07/02 16:42:49 2.56 --- _sre.c 2001/07/02 16:58:38 2.57 *************** *** 507,510 **** --- 507,523 ---- break; + case SRE_OP_BIGCHARSET: + /* <256 blockindices> */ + { + int count, block; + count = *(set++); + block = ((unsigned char*)set)[ch >> 8]; + set += 128; + if (set[block*16 + ((ch & 255)>>4)] & (1 << (ch & 15))) + return ok; + set += count*16; + break; + } + case SRE_OP_CATEGORY: /* */ Index: sre_constants.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/sre_constants.h,v retrieving revision 2.12 retrieving revision 2.13 diff -C2 -r2.12 -r2.13 *** sre_constants.h 2001/03/22 15:50:09 2.12 --- sre_constants.h 2001/07/02 16:58:38 2.13 *************** *** 12,16 **** */ ! #define SRE_MAGIC 20010320 #define SRE_OP_FAILURE 0 #define SRE_OP_SUCCESS 1 --- 12,16 ---- */ ! #define SRE_MAGIC 20010701 #define SRE_OP_FAILURE 0 #define SRE_OP_SUCCESS 1 *************** *** 24,45 **** #define SRE_OP_CATEGORY 9 #define SRE_OP_CHARSET 10 ! #define SRE_OP_GROUPREF 11 ! #define SRE_OP_GROUPREF_IGNORE 12 ! #define SRE_OP_IN 13 ! #define SRE_OP_IN_IGNORE 14 ! #define SRE_OP_INFO 15 ! #define SRE_OP_JUMP 16 ! #define SRE_OP_LITERAL 17 ! #define SRE_OP_LITERAL_IGNORE 18 ! #define SRE_OP_MARK 19 ! #define SRE_OP_MAX_UNTIL 20 ! #define SRE_OP_MIN_UNTIL 21 ! #define SRE_OP_NOT_LITERAL 22 ! #define SRE_OP_NOT_LITERAL_IGNORE 23 ! #define SRE_OP_NEGATE 24 ! #define SRE_OP_RANGE 25 ! #define SRE_OP_REPEAT 26 ! #define SRE_OP_REPEAT_ONE 27 ! #define SRE_OP_SUBPATTERN 28 #define SRE_AT_BEGINNING 0 #define SRE_AT_BEGINNING_LINE 1 --- 24,46 ---- #define SRE_OP_CATEGORY 9 #define SRE_OP_CHARSET 10 ! #define SRE_OP_BIGCHARSET 11 ! #define SRE_OP_GROUPREF 12 ! #define SRE_OP_GROUPREF_IGNORE 13 ! #define SRE_OP_IN 14 ! #define SRE_OP_IN_IGNORE 15 ! #define SRE_OP_INFO 16 ! #define SRE_OP_JUMP 17 ! #define SRE_OP_LITERAL 18 ! #define SRE_OP_LITERAL_IGNORE 19 ! #define SRE_OP_MARK 20 ! #define SRE_OP_MAX_UNTIL 21 ! #define SRE_OP_MIN_UNTIL 22 ! #define SRE_OP_NOT_LITERAL 23 ! #define SRE_OP_NOT_LITERAL_IGNORE 24 ! #define SRE_OP_NEGATE 25 ! #define SRE_OP_RANGE 26 ! #define SRE_OP_REPEAT 27 ! #define SRE_OP_REPEAT_ONE 28 ! #define SRE_OP_SUBPATTERN 29 #define SRE_AT_BEGINNING 0 #define SRE_AT_BEGINNING_LINE 1 From effbot@users.sourceforge.net Mon Jul 2 17:58:40 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Mon, 02 Jul 2001 09:58:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib sre_compile.py,1.37,1.38 sre_constants.py,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv555/Lib Modified Files: sre_compile.py sre_constants.py Log Message: added martin's BIGCHARSET patch to SRE 2.1.1. martin reports 2x speedups for certain unicode character ranges. Index: sre_compile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre_compile.py,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -r1.37 -r1.38 *** sre_compile.py 2001/03/22 15:50:10 1.37 --- sre_compile.py 2001/07/02 16:58:38 1.38 *************** *** 157,160 **** --- 157,162 ---- elif op is CHARSET: code.extend(av) + elif op is BIGCHARSET: + code.extend(av) elif op is CATEGORY: if flags & SRE_FLAG_LOCALE: *************** *** 186,190 **** except IndexError: # character set contains unicode characters ! return charset # compress character map i = p = n = 0 --- 188,192 ---- except IndexError: # character set contains unicode characters ! return _optimize_unicode(charset, fixup) # compress character map i = p = n = 0 *************** *** 212,227 **** else: # use bitmap ! data = [] ! m = 1; v = 0 ! for c in charmap: ! if c: ! v = v + m ! m = m << 1 ! if m > MAXCODE: ! data.append(v) ! m = 1; v = 0 out.append((CHARSET, data)) return out return charset def _simple(av): --- 214,288 ---- else: # use bitmap ! data = _mk_bitmap(charmap) out.append((CHARSET, data)) return out return charset + + def _mk_bitmap(bits): + data = [] + m = 1; v = 0 + for c in bits: + if c: + v = v + m + m = m << 1 + if m > MAXCODE: + data.append(v) + m = 1; v = 0 + return data + + # To represent a big charset, first a bitmap of all characters in the + # set is constructed. Then, this bitmap is sliced into chunks of 256 + # characters, duplicate chunks are eliminitated, and each chunk is + # given a number. In the compiled expression, the charset is + # represented by a 16-bit word sequence, consisting of one word for + # the number of different chunks, a sequence of 256 bytes (128 words) + # of chunk numbers indexed by their original chunk position, and a + # sequence of chunks (16 words each). + + # Compression is normally good: in a typical charset, large ranges of + # Unicode will be either completely excluded (e.g. if only cyrillic + # letters are to be matched), or completely included (e.g. if large + # subranges of Kanji match). These ranges will be represented by + # chunks of all one-bits or all zero-bits. + + # Matching can be also done efficiently: the more significant byte of + # the Unicode character is an index into the chunk number, and the + # less significant byte is a bit index in the chunk (just like the + # CHARSET matching). + + def _optimize_unicode(charset, fixup): + charmap = [0]*65536 + negate = 0 + for op, av in charset: + if op is NEGATE: + negate = 1 + elif op is LITERAL: + charmap[fixup(av)] = 1 + elif op is RANGE: + for i in range(fixup(av[0]), fixup(av[1])+1): + charmap[i] = 1 + elif op is CATEGORY: + # XXX: could expand category + return charset # cannot compress + if negate: + for i in range(65536): + charmap[i] = not charmap[i] + comps = {} + mapping = [0]*256 + block = 0 + data = [] + for i in range(256): + chunk = tuple(charmap[i*256:(i+1)*256]) + new = comps.setdefault(chunk, block) + mapping[i] = new + if new == block: + block += 1 + data += _mk_bitmap(chunk) + header = [block] + assert MAXCODE == 65535 + for i in range(128): + header.append(mapping[2*i]+256*mapping[2*i+1]) + data[0:0] = header + return [(BIGCHARSET, data)] def _simple(av): Index: sre_constants.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre_constants.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -r1.28 -r1.29 *** sre_constants.py 2001/03/22 15:50:10 1.28 --- sre_constants.py 2001/07/02 16:58:38 1.29 *************** *** 12,16 **** # update when constants are added or removed ! MAGIC = 20010320 # max code word in this release --- 12,16 ---- # update when constants are added or removed ! MAGIC = 20010701 # max code word in this release *************** *** 34,37 **** --- 34,38 ---- ASSERT_NOT = "assert_not" AT = "at" + BIGCHARSET = "bigcharset" BRANCH = "branch" CALL = "call" *************** *** 104,108 **** CALL, CATEGORY, ! CHARSET, GROUPREF, GROUPREF_IGNORE, IN, IN_IGNORE, --- 105,109 ---- CALL, CATEGORY, ! CHARSET, BIGCHARSET, GROUPREF, GROUPREF_IGNORE, IN, IN_IGNORE, From effbot@users.sourceforge.net Mon Jul 2 18:04:50 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Mon, 02 Jul 2001 10:04:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _sre.c,2.57,2.58 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv2526/Modules Modified Files: _sre.c Log Message: pythonware repository roundtrip (untabification) Index: _sre.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_sre.c,v retrieving revision 2.57 retrieving revision 2.58 diff -C2 -r2.57 -r2.58 *** _sre.c 2001/07/02 16:58:38 2.57 --- _sre.c 2001/07/02 17:04:48 2.58 *************** *** 31,34 **** --- 31,35 ---- * 2001-04-28 fl added __copy__ methods (work in progress) * 2001-05-14 fl fixes for 1.5.2 + * 2001-07-01 fl added BIGCHARSET support (from Martin von Loewis) * * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. *************** *** 507,522 **** break; ! case SRE_OP_BIGCHARSET: ! /* <256 blockindices> */ ! { ! int count, block; ! count = *(set++); ! block = ((unsigned char*)set)[ch >> 8]; ! set += 128; ! if (set[block*16 + ((ch & 255)>>4)] & (1 << (ch & 15))) ! return ok; ! set += count*16; ! break; ! } case SRE_OP_CATEGORY: --- 508,523 ---- break; ! case SRE_OP_BIGCHARSET: ! /* <256 blockindices> */ ! { ! int count, block; ! count = *(set++); ! block = ((unsigned char*)set)[ch >> 8]; ! set += 128; ! if (set[block*16 + ((ch & 255)>>4)] & (1 << (ch & 15))) ! return ok; ! set += count*16; ! break; ! } case SRE_OP_CATEGORY: From gvanrossum@users.sourceforge.net Mon Jul 2 18:08:35 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 02 Jul 2001 10:08:35 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include object.h,2.79.2.20,2.79.2.21 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv3345/Include Modified Files: Tag: descr-branch object.h Log Message: Change the tp_descr_get slot to take three arguments: (self, obj, type). The type is useful to create unbound methods, and I think I have a way to make class methods work that needs this. Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.79.2.20 retrieving revision 2.79.2.21 diff -C2 -r2.79.2.20 -r2.79.2.21 *** object.h 2001/06/29 15:03:54 2.79.2.20 --- object.h 2001/07/02 17:08:33 2.79.2.21 *************** *** 203,207 **** typedef PyObject *(*getiterfunc) (PyObject *); typedef PyObject *(*iternextfunc) (PyObject *); ! typedef PyObject *(*descrgetfunc) (PyObject *, PyObject *); typedef int (*descrsetfunc) (PyObject *, PyObject *, PyObject *); typedef int (*initproc)(PyObject *, PyObject *, PyObject *); --- 203,208 ---- typedef PyObject *(*getiterfunc) (PyObject *); typedef PyObject *(*iternextfunc) (PyObject *); ! typedef PyObject *(*descrgetfunc) (PyObject *, PyObject *, ! struct _typeobject *); typedef int (*descrsetfunc) (PyObject *, PyObject *, PyObject *); typedef int (*initproc)(PyObject *, PyObject *, PyObject *); From gvanrossum@users.sourceforge.net Mon Jul 2 18:08:35 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 02 Jul 2001 10:08:35 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects descrobject.c,1.1.2.11,1.1.2.12 funcobject.c,2.37.4.5,2.37.4.6 object.c,2.124.4.19,2.124.4.20 typeobject.c,2.16.8.54,2.16.8.55 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv3345/Objects Modified Files: Tag: descr-branch descrobject.c funcobject.c object.c typeobject.c Log Message: Change the tp_descr_get slot to take three arguments: (self, obj, type). The type is useful to create unbound methods, and I think I have a way to make class methods work that needs this. Index: descrobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/Attic/descrobject.c,v retrieving revision 1.1.2.11 retrieving revision 1.1.2.12 diff -C2 -r1.1.2.11 -r1.1.2.12 *** descrobject.c 2001/06/29 14:31:11 1.1.2.11 --- descrobject.c 2001/07/02 17:08:33 1.1.2.12 *************** *** 98,102 **** static PyObject * ! descr_get(PyDescrObject *descr, PyObject *obj) { if (obj == NULL) { --- 98,102 ---- static PyObject * ! descr_get(PyDescrObject *descr, PyObject *obj, PyTypeObject *type) { if (obj == NULL) { *************** *** 252,256 **** if (argc == 1) ! return descr_get(descr, self); if (argc == 2) { PyObject *value = PyTuple_GET_ITEM(args, 1); --- 252,256 ---- if (argc == 1) ! return descr_get(descr, self, self->ob_type); if (argc == 2) { PyObject *value = PyTuple_GET_ITEM(args, 1); *************** *** 270,277 **** { PyObject *obj; ! if (!PyArg_ParseTuple(args, "O:get", &obj)) return NULL; ! return descr_get(descr, obj); } --- 270,280 ---- { PyObject *obj; + PyTypeObject *type = NULL; ! if (!PyArg_ParseTuple(args, "O|O!:get", &obj, &PyType_Type, &type)) return NULL; ! if (type == NULL) ! type = obj->ob_type; ! return descr_get(descr, obj, type); } Index: funcobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/funcobject.c,v retrieving revision 2.37.4.5 retrieving revision 2.37.4.6 diff -C2 -r2.37.4.5 -r2.37.4.6 *** funcobject.c 2001/06/06 14:27:54 2.37.4.5 --- funcobject.c 2001/07/02 17:08:33 2.37.4.6 *************** *** 331,342 **** /* Bind a function to an object */ static PyObject * ! func_descr_get(PyObject *func, PyObject *obj) { ! if (obj == NULL) { ! Py_INCREF(func); ! return func; ! } ! else ! return PyMethod_New(func, obj, (PyObject *)obj->ob_type); } --- 331,337 ---- /* Bind a function to an object */ static PyObject * ! func_descr_get(PyObject *func, PyObject *obj, PyTypeObject *type) { ! return PyMethod_New(func, obj, (PyObject *)type); } Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.124.4.19 retrieving revision 2.124.4.20 diff -C2 -r2.124.4.19 -r2.124.4.20 *** object.c 2001/06/29 20:46:51 2.124.4.19 --- object.c 2001/07/02 17:08:33 2.124.4.20 *************** *** 1128,1132 **** f = descr->ob_type->tp_descr_get; if (f != NULL && PyDescr_IsData(descr)) ! return f(descr, obj); } --- 1128,1132 ---- f = descr->ob_type->tp_descr_get; if (f != NULL && PyDescr_IsData(descr)) ! return f(descr, obj, obj->ob_type); } *************** *** 1144,1148 **** if (f != NULL) ! return f(descr, obj); if (descr != NULL) { --- 1144,1148 ---- if (f != NULL) ! return f(descr, obj, obj->ob_type); if (descr != NULL) { Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.54 retrieving revision 2.16.8.55 diff -C2 -r2.16.8.54 -r2.16.8.55 *** typeobject.c 2001/06/29 20:46:51 2.16.8.54 --- typeobject.c 2001/07/02 17:08:33 2.16.8.55 *************** *** 633,637 **** f = descr->ob_type->tp_descr_get; if (f != NULL && PyDescr_IsData(descr)) ! return f(descr, (PyObject *)type); } --- 633,637 ---- f = descr->ob_type->tp_descr_get; if (f != NULL && PyDescr_IsData(descr)) ! return f(descr, (PyObject *)type, metatype); } *************** *** 645,649 **** /* Use the descriptor from the metatype */ if (f != NULL) { ! res = f(descr, NULL); return res; } --- 645,649 ---- /* Use the descriptor from the metatype */ if (f != NULL) { ! res = f(descr, NULL, metatype); return res; } *************** *** 1636,1641 **** static struct wrapperbase tab_descr_get[] = { ! {"__get__", (wrapperfunc)wrap_binaryfunc, ! "descr.__get__(obj) -> value"}, {0} }; --- 1636,1641 ---- static struct wrapperbase tab_descr_get[] = { ! {"__get__", (wrapperfunc)wrap_ternaryfunc, ! "descr.__get__(obj, type) -> value"}, {0} }; *************** *** 2026,2030 **** } ! SLOT1(tp_descr_get, get, PyObject *, O); static int --- 2026,2030 ---- } ! SLOT2(tp_descr_get, get, PyObject *, PyTypeObject *, OO); static int From fdrake@users.sourceforge.net Mon Jul 2 18:16:10 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 02 Jul 2001 10:16:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc ACKS,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv6012/Doc Modified Files: ACKS Log Message: Add another name. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ACKS,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -r1.19 -r1.20 *** ACKS 2001/06/29 15:42:20 1.19 --- ACKS 2001/07/02 17:16:07 1.20 *************** *** 173,175 **** --- 173,176 ---- Ka-Ping Yee Moshe Zadka + Milan Zamazal Cheng Zhang From gvanrossum@users.sourceforge.net Mon Jul 2 19:06:09 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 02 Jul 2001 11:06:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.198.2.4,2.198.2.5 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv18444/Python Modified Files: Tag: descr-branch bltinmodule.c Log Message: Add a new type: 'classmethod'. This needs to be fleshed out a bit more with docstrings and maybe attribute, but it works: >>> class C(object): ... def f(*a): return a ... f = classmethod(f) ... >>> C.f(1, 2) (, 1, 2) >>> C().f(1, 2) (, 1, 2) >>> class D(C): ... pass ... >>> D.f(1, 2) (, 1, 2) >>> D().f(1, 2) (, 1, 2) >>> It doesn't work in classic classes yet (the method binding there needs to be updated). Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.198.2.4 retrieving revision 2.198.2.5 diff -C2 -r2.198.2.4 -r2.198.2.5 *** bltinmodule.c 2001/06/14 18:12:02 2.198.2.4 --- bltinmodule.c 2001/07/02 18:06:06 2.198.2.5 *************** *** 1793,1796 **** --- 1793,1799 ---- Py_NotImplemented) < 0) return NULL; + if (PyDict_SetItemString(dict, "classmethod", + (PyObject *) &PyClassMethod_Type) < 0) + return NULL; #ifndef WITHOUT_COMPLEX if (PyDict_SetItemString(dict, "complex", From gvanrossum@users.sourceforge.net Mon Jul 2 19:06:08 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 02 Jul 2001 11:06:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include funcobject.h,2.23,2.23.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv18444/Include Modified Files: Tag: descr-branch funcobject.h Log Message: Add a new type: 'classmethod'. This needs to be fleshed out a bit more with docstrings and maybe attribute, but it works: >>> class C(object): ... def f(*a): return a ... f = classmethod(f) ... >>> C.f(1, 2) (, 1, 2) >>> C().f(1, 2) (, 1, 2) >>> class D(C): ... pass ... >>> D.f(1, 2) (, 1, 2) >>> D().f(1, 2) (, 1, 2) >>> It doesn't work in classic classes yet (the method binding there needs to be updated). Index: funcobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/funcobject.h,v retrieving revision 2.23 retrieving revision 2.23.4.1 diff -C2 -r2.23 -r2.23.4.1 *** funcobject.h 2001/03/23 04:17:58 2.23 --- funcobject.h 2001/07/02 18:06:06 2.23.4.1 *************** *** 43,46 **** --- 43,49 ---- (((PyFunctionObject *)func) -> func_closure) + /* The classmethod type lives here, too */ + extern DL_IMPORT(PyTypeObject) PyClassMethod_Type; + #ifdef __cplusplus } From gvanrossum@users.sourceforge.net Mon Jul 2 19:06:09 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 02 Jul 2001 11:06:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects funcobject.c,2.37.4.6,2.37.4.7 typeobject.c,2.16.8.55,2.16.8.56 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv18444/Objects Modified Files: Tag: descr-branch funcobject.c typeobject.c Log Message: Add a new type: 'classmethod'. This needs to be fleshed out a bit more with docstrings and maybe attribute, but it works: >>> class C(object): ... def f(*a): return a ... f = classmethod(f) ... >>> C.f(1, 2) (, 1, 2) >>> C().f(1, 2) (, 1, 2) >>> class D(C): ... pass ... >>> D.f(1, 2) (, 1, 2) >>> D().f(1, 2) (, 1, 2) >>> It doesn't work in classic classes yet (the method binding there needs to be updated). Index: funcobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/funcobject.c,v retrieving revision 2.37.4.6 retrieving revision 2.37.4.7 diff -C2 -r2.37.4.6 -r2.37.4.7 *** funcobject.c 2001/07/02 17:08:33 2.37.4.6 --- funcobject.c 2001/07/02 18:06:06 2.37.4.7 *************** *** 374,375 **** --- 374,459 ---- offsetof(PyFunctionObject, func_dict), /* tp_dictoffset */ }; + + + /* Class method object */ + + typedef struct { + PyObject_HEAD; + PyObject *cm_callable; + } classmethod; + + static void + cm_dealloc(classmethod *cm) + { + Py_XDECREF(cm->cm_callable); + PyObject_DEL(cm); + } + + static PyObject * + cm_descr_get(PyObject *self, PyObject *obj, PyTypeObject *type) + { + classmethod *cm = (classmethod *)self; + + if (cm->cm_callable == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "uninitialized classmethod object"); + return NULL; + } + return PyMethod_New(cm->cm_callable, + (PyObject *)type, (PyObject *)(type->ob_type)); + } + + static int + cm_init(PyObject *self, PyObject *args, PyObject *kwds) + { + classmethod *cm = (classmethod *)self; + PyObject *callable; + + if (!PyArg_ParseTuple(args, "O:callable", &callable)) + return -1; + Py_INCREF(callable); + cm->cm_callable = callable; + return 0; + } + + PyTypeObject PyClassMethod_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "classmethod", + sizeof(classmethod), + 0, + (destructor)cm_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_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + cm_descr_get, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + cm_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + }; Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.55 retrieving revision 2.16.8.56 diff -C2 -r2.16.8.55 -r2.16.8.56 *** typeobject.c 2001/07/02 17:08:33 2.16.8.55 --- typeobject.c 2001/07/02 18:06:06 2.16.8.56 *************** *** 639,642 **** --- 639,645 ---- res = _PyType_Lookup(type, name); if (res != NULL) { + f = res->ob_type->tp_descr_get; + if (f != NULL) + return f(res, (PyObject *)NULL, type); Py_INCREF(res); return res; *************** *** 1635,1640 **** }; static struct wrapperbase tab_descr_get[] = { ! {"__get__", (wrapperfunc)wrap_ternaryfunc, "descr.__get__(obj, type) -> value"}, {0} --- 1638,1657 ---- }; + static PyObject * + wrap_descr_get(PyObject *self, PyObject *args, void *wrapped) + { + descrgetfunc func = (descrgetfunc)wrapped; + PyObject *obj; + PyTypeObject *type = NULL; + + if (!PyArg_ParseTuple(args, "O|O!", &obj, &PyType_Type, &type)) + return NULL; + if (type == NULL) + type = obj->ob_type; + return (*func)(self, obj, type); + } + static struct wrapperbase tab_descr_get[] = { ! {"__get__", (wrapperfunc)wrap_descr_get, "descr.__get__(obj, type) -> value"}, {0} From effbot@users.sourceforge.net Mon Jul 2 20:54:30 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Mon, 02 Jul 2001 12:54:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _sre.c,2.58,2.59 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv18524/Modules Modified Files: _sre.c Log Message: reapplied darryl gallion's minimizing repeat fix. I'm still not 100% sure about this one, but test #133283 now works even with the fix in place, and so does the test suite. we'll see what comes up... Index: _sre.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_sre.c,v retrieving revision 2.58 retrieving revision 2.59 diff -C2 -r2.58 -r2.59 *** _sre.c 2001/07/02 17:04:48 2.58 --- _sre.c 2001/07/02 19:54:28 2.59 *************** *** 1105,1109 **** state->repeat = rp->prev; /* FIXME: the following fix doesn't always work (#133283) */ ! if (0 && rp->pattern[2] == 65535) { /* unbounded repeat */ for (;;) { --- 1105,1109 ---- state->repeat = rp->prev; /* FIXME: the following fix doesn't always work (#133283) */ ! if (rp->pattern[2] == 65535) { /* unbounded repeat */ for (;;) { From effbot@users.sourceforge.net Mon Jul 2 20:54:30 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Mon, 02 Jul 2001 12:54:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_sre.py,1.24,1.25 re_tests.py,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv18524/Lib/test Modified Files: test_sre.py re_tests.py Log Message: reapplied darryl gallion's minimizing repeat fix. I'm still not 100% sure about this one, but test #133283 now works even with the fix in place, and so does the test suite. we'll see what comes up... Index: test_sre.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sre.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -r1.24 -r1.25 *** test_sre.py 2001/03/22 23:48:28 1.24 --- test_sre.py 2001/07/02 19:54:28 1.25 *************** *** 246,250 **** test("sre.match('(x)*', 50000*'x').span()", (0, 50000), RuntimeError) test("sre.match(r'(x)*y', 50000*'x'+'y').span()", (0, 50001), RuntimeError) ! test("sre.match(r'(x)*?y', 50000*'x'+'y').span()", (0, 50001), RuntimeError) from re_tests import * --- 246,250 ---- test("sre.match('(x)*', 50000*'x').span()", (0, 50000), RuntimeError) test("sre.match(r'(x)*y', 50000*'x'+'y').span()", (0, 50001), RuntimeError) ! test("sre.match(r'(x)*?y', 50000*'x'+'y').span()", (0, 50001)) from re_tests import * Index: re_tests.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/re_tests.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -r1.28 -r1.29 *** re_tests.py 2001/03/22 15:50:10 1.28 --- re_tests.py 2001/07/02 19:54:28 1.29 *************** *** 639,642 **** --- 639,644 ---- # bug 130748: ^* should be an error (nothing to repeat) (r'^*', '', SYNTAX_ERROR), + # bug 133283: minimizing repeat bug + (r'"(?:\\"|[^"])*?"', r'"\""', SUCCEED, 'found', r'"\"'), ] From fdrake@users.sourceforge.net Mon Jul 2 22:22:42 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 02 Jul 2001 14:22:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libprofile.tex,1.34,1.35 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv8424/lib Modified Files: libprofile.tex Log Message: Marked the parameters to Stats.print_*() as optional. This closes SF bug #438032. Index: libprofile.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libprofile.tex,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -r1.34 -r1.35 *** libprofile.tex 2001/06/14 13:57:16 1.34 --- libprofile.tex 2001/07/02 21:22:39 1.35 *************** *** 450,454 **** \end{methoddesc} ! \begin{methoddesc}[Stats]{print_stats}{restriction\optional{, ...}} This method for the \class{Stats} class prints out a report as described in the \function{profile.run()} definition. --- 450,454 ---- \end{methoddesc} ! \begin{methoddesc}[Stats]{print_stats}{\optional{restriction, \moreargs}} This method for the \class{Stats} class prints out a report as described in the \function{profile.run()} definition. *************** *** 485,489 **** ! \begin{methoddesc}[Stats]{print_callers}{restrictions\optional{, ...}} This method for the \class{Stats} class prints a list of all functions that called each function in the profiled database. The ordering is --- 485,489 ---- ! \begin{methoddesc}[Stats]{print_callers}{\optional{restriction, \moreargs}} This method for the \class{Stats} class prints a list of all functions that called each function in the profiled database. The ordering is *************** *** 495,499 **** \end{methoddesc} ! \begin{methoddesc}[Stats]{print_callees}{restrictions\optional{, ...}} This method for the \class{Stats} class prints a list of all function that were called by the indicated function. Aside from this reversal --- 495,499 ---- \end{methoddesc} ! \begin{methoddesc}[Stats]{print_callees}{\optional{restriction, \moreargs}} This method for the \class{Stats} class prints a list of all function that were called by the indicated function. Aside from this reversal From fdrake@users.sourceforge.net Mon Jul 2 22:22:58 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 02 Jul 2001 14:22:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libprofile.tex,1.32.2.1,1.32.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv8507/lib Modified Files: Tag: release21-maint libprofile.tex Log Message: Marked the parameters to Stats.print_*() as optional. This closes SF bug #438032. Index: libprofile.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libprofile.tex,v retrieving revision 1.32.2.1 retrieving revision 1.32.2.2 diff -C2 -r1.32.2.1 -r1.32.2.2 *** libprofile.tex 2001/06/14 13:57:49 1.32.2.1 --- libprofile.tex 2001/07/02 21:22:56 1.32.2.2 *************** *** 450,454 **** \end{methoddesc} ! \begin{methoddesc}[Stats]{print_stats}{restriction\optional{, ...}} This method for the \class{Stats} class prints out a report as described in the \function{profile.run()} definition. --- 450,454 ---- \end{methoddesc} ! \begin{methoddesc}[Stats]{print_stats}{\optional{restriction, \moreargs}} This method for the \class{Stats} class prints out a report as described in the \function{profile.run()} definition. *************** *** 485,489 **** ! \begin{methoddesc}[Stats]{print_callers}{restrictions\optional{, ...}} This method for the \class{Stats} class prints a list of all functions that called each function in the profiled database. The ordering is --- 485,489 ---- ! \begin{methoddesc}[Stats]{print_callers}{\optional{restriction, \moreargs}} This method for the \class{Stats} class prints a list of all functions that called each function in the profiled database. The ordering is *************** *** 495,499 **** \end{methoddesc} ! \begin{methoddesc}[Stats]{print_callees}{restrictions\optional{, ...}} This method for the \class{Stats} class prints a list of all function that were called by the indicated function. Aside from this reversal --- 495,499 ---- \end{methoddesc} ! \begin{methoddesc}[Stats]{print_callees}{\optional{restriction, \moreargs}} This method for the \class{Stats} class prints a list of all function that were called by the indicated function. Aside from this reversal From gvanrossum@users.sourceforge.net Tue Jul 3 01:37:49 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 02 Jul 2001 17:37:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include object.h,2.79.2.21,2.79.2.22 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv15305/Include Modified Files: Tag: descr-branch object.h Log Message: Fix the subtype test (the previous checkins broke test_descr.py because the subtype test was being applied in a multiple-inheritance situation). First, _PyObject_TypeCheck() is renamed to PyType_IsSubtype() and moved from object.c to typeobject.c, where it belings. Next, its implementation is changed to use the MRO tuple if it exists; for bootstrap reasons, it walks the tp_base chain (single inheritance only) as a fallback. Finally, issubtype() is deleted and calls to it are replaced with a call to PyType_IsSubtype(). Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.79.2.21 retrieving revision 2.79.2.22 diff -C2 -r2.79.2.21 -r2.79.2.22 *** object.h 2001/07/02 17:08:33 2.79.2.21 --- object.h 2001/07/03 00:37:47 2.79.2.22 *************** *** 290,296 **** /* Generic type check */ ! extern DL_IMPORT(int) _PyObject_TypeCheck(PyTypeObject *, PyTypeObject *); #define PyObject_TypeCheck(ob, tp) \ ! ((ob)->ob_type == (tp) || _PyObject_TypeCheck((ob)->ob_type, (tp))) extern DL_IMPORT(PyTypeObject) PyType_Type; /* Metatype */ --- 290,296 ---- /* Generic type check */ ! extern DL_IMPORT(int) PyType_IsSubtype(PyTypeObject *, PyTypeObject *); #define PyObject_TypeCheck(ob, tp) \ ! ((ob)->ob_type == (tp) || PyType_IsSubtype((ob)->ob_type, (tp))) extern DL_IMPORT(PyTypeObject) PyType_Type; /* Metatype */ From gvanrossum@users.sourceforge.net Tue Jul 3 01:37:49 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 02 Jul 2001 17:37:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects object.c,2.124.4.20,2.124.4.21 typeobject.c,2.16.8.56,2.16.8.57 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv15305/Objects Modified Files: Tag: descr-branch object.c typeobject.c Log Message: Fix the subtype test (the previous checkins broke test_descr.py because the subtype test was being applied in a multiple-inheritance situation). First, _PyObject_TypeCheck() is renamed to PyType_IsSubtype() and moved from object.c to typeobject.c, where it belings. Next, its implementation is changed to use the MRO tuple if it exists; for bootstrap reasons, it walks the tp_base chain (single inheritance only) as a fallback. Finally, issubtype() is deleted and calls to it are replaced with a call to PyType_IsSubtype(). Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.124.4.20 retrieving revision 2.124.4.21 diff -C2 -r2.124.4.20 -r2.124.4.21 *** object.c 2001/07/02 17:08:33 2.124.4.20 --- object.c 2001/07/03 00:37:47 2.124.4.21 *************** *** 1325,1344 **** - /* type test with subclassing support */ - - int - _PyObject_TypeCheck(PyTypeObject *tp, PyTypeObject *type) - { - do { - if (tp == type) - return 1; - if (!PyType_HasFeature(tp, Py_TPFLAGS_HAVE_CLASS)) - return 0; - tp = tp->tp_base; - } while (tp != NULL); - return 0; - } - - /* NoObject is usable as a non-NULL undefined value, used by the macro None. --- 1325,1328 ---- Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.56 retrieving revision 2.16.8.57 diff -C2 -r2.16.8.56 -r2.16.8.57 *** typeobject.c 2001/07/02 18:06:06 2.16.8.56 --- typeobject.c 2001/07/03 00:37:47 2.16.8.57 *************** *** 184,216 **** } etype; ! static int ! issubtype(PyTypeObject *a, PyTypeObject *b) { ! PyObject *bases; ! PyTypeObject *base; ! int i, n; ! if (b == &PyBaseObject_Type) ! return 1; /* Every type is an implicit subtype of this */ ! while (a != NULL) { ! if (a == b) ! return 1; ! bases = a->tp_bases; ! a = a->tp_base; ! if (bases != NULL && PyTuple_Check(bases)) { ! n = PyTuple_GET_SIZE(bases); ! for (i = 0; i < n; i++) { ! base = (PyTypeObject *) ! PyTuple_GET_ITEM(bases, i); ! if (base == b) ! return 1; ! if (base != a) { ! if (issubtype(base, b)) ! return 1; ! } ! } } } - return 0; } --- 184,216 ---- } etype; ! /* type test with subclassing support */ ! ! int ! PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b) { ! PyObject *mro; ! mro = a->tp_mro; ! if (mro != NULL) { ! /* Deal with multiple inheritance without recursion ! by walking the MRO tuple */ ! int i, n; ! assert(PyTuple_Check(mro)); ! n = PyTuple_GET_SIZE(mro); ! for (i = 0; i < n; i++) { ! if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) ! return 1; } + return 0; + } + else { + /* a is not completely initilized yet; follow tp_base */ + do { + if (a == b) + return 1; + a = a->tp_base; + } while (a != NULL); + return b == &PyBaseObject_Type; } } *************** *** 322,328 **** } candidate = solid_base(base_i); ! if (issubtype(winner, candidate)) ; ! else if (issubtype(candidate, winner)) { winner = candidate; base = base_i; --- 322,328 ---- } candidate = solid_base(base_i); ! if (PyType_IsSubtype(winner, candidate)) ; ! else if (PyType_IsSubtype(candidate, winner)) { winner = candidate; base = base_i; *************** *** 413,419 **** tmp = PyTuple_GET_ITEM(bases, i); tmptype = tmp->ob_type; ! if (issubtype(metatype, tmptype)) continue; ! if (issubtype(tmptype, metatype)) { metatype = tmptype; continue; --- 413,419 ---- tmp = PyTuple_GET_ITEM(bases, i); tmptype = tmp->ob_type; ! if (PyType_IsSubtype(metatype, tmptype)) continue; ! if (PyType_IsSubtype(tmptype, metatype)) { metatype = tmptype; continue; From gvanrossum@users.sourceforge.net Tue Jul 3 01:48:16 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 02 Jul 2001 17:48:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include object.h,2.79.2.22,2.79.2.23 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv16653/Include Modified Files: Tag: descr-branch object.h Log Message: Change the descrgetfunc signature: the thir argument is now an arbitrary object. This is needed so that classmethod() can also be used for classic classes. This is *almost* just a metter of changing casts that don't cause different code to be generated; the exception is wrap_descr_get which also removes a typecheck from the PyArg_ParseTuple() argument list. Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.79.2.22 retrieving revision 2.79.2.23 diff -C2 -r2.79.2.22 -r2.79.2.23 *** object.h 2001/07/03 00:37:47 2.79.2.22 --- object.h 2001/07/03 00:48:14 2.79.2.23 *************** *** 203,208 **** typedef PyObject *(*getiterfunc) (PyObject *); typedef PyObject *(*iternextfunc) (PyObject *); ! typedef PyObject *(*descrgetfunc) (PyObject *, PyObject *, ! struct _typeobject *); typedef int (*descrsetfunc) (PyObject *, PyObject *, PyObject *); typedef int (*initproc)(PyObject *, PyObject *, PyObject *); --- 203,207 ---- typedef PyObject *(*getiterfunc) (PyObject *); typedef PyObject *(*iternextfunc) (PyObject *); ! typedef PyObject *(*descrgetfunc) (PyObject *, PyObject *, PyObject *); typedef int (*descrsetfunc) (PyObject *, PyObject *, PyObject *); typedef int (*initproc)(PyObject *, PyObject *, PyObject *); From gvanrossum@users.sourceforge.net Tue Jul 3 01:48:16 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 02 Jul 2001 17:48:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects funcobject.c,2.37.4.7,2.37.4.8 object.c,2.124.4.21,2.124.4.22 typeobject.c,2.16.8.57,2.16.8.58 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv16653/Objects Modified Files: Tag: descr-branch funcobject.c object.c typeobject.c Log Message: Change the descrgetfunc signature: the thir argument is now an arbitrary object. This is needed so that classmethod() can also be used for classic classes. This is *almost* just a metter of changing casts that don't cause different code to be generated; the exception is wrap_descr_get which also removes a typecheck from the PyArg_ParseTuple() argument list. Index: funcobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/funcobject.c,v retrieving revision 2.37.4.7 retrieving revision 2.37.4.8 diff -C2 -r2.37.4.7 -r2.37.4.8 *** funcobject.c 2001/07/02 18:06:06 2.37.4.7 --- funcobject.c 2001/07/03 00:48:14 2.37.4.8 *************** *** 331,337 **** /* Bind a function to an object */ static PyObject * ! func_descr_get(PyObject *func, PyObject *obj, PyTypeObject *type) { ! return PyMethod_New(func, obj, (PyObject *)type); } --- 331,337 ---- /* Bind a function to an object */ static PyObject * ! func_descr_get(PyObject *func, PyObject *obj, PyObject *type) { ! return PyMethod_New(func, obj, type); } *************** *** 391,395 **** static PyObject * ! cm_descr_get(PyObject *self, PyObject *obj, PyTypeObject *type) { classmethod *cm = (classmethod *)self; --- 391,395 ---- static PyObject * ! cm_descr_get(PyObject *self, PyObject *obj, PyObject *type) { classmethod *cm = (classmethod *)self; *************** *** 401,405 **** } return PyMethod_New(cm->cm_callable, ! (PyObject *)type, (PyObject *)(type->ob_type)); } --- 401,405 ---- } return PyMethod_New(cm->cm_callable, ! type, (PyObject *)(type->ob_type)); } Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.124.4.21 retrieving revision 2.124.4.22 diff -C2 -r2.124.4.21 -r2.124.4.22 *** object.c 2001/07/03 00:37:47 2.124.4.21 --- object.c 2001/07/03 00:48:14 2.124.4.22 *************** *** 1128,1132 **** f = descr->ob_type->tp_descr_get; if (f != NULL && PyDescr_IsData(descr)) ! return f(descr, obj, obj->ob_type); } --- 1128,1132 ---- f = descr->ob_type->tp_descr_get; if (f != NULL && PyDescr_IsData(descr)) ! return f(descr, obj, (PyObject *)obj->ob_type); } *************** *** 1144,1148 **** if (f != NULL) ! return f(descr, obj, obj->ob_type); if (descr != NULL) { --- 1144,1148 ---- if (f != NULL) ! return f(descr, obj, (PyObject *)obj->ob_type); if (descr != NULL) { Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.57 retrieving revision 2.16.8.58 diff -C2 -r2.16.8.57 -r2.16.8.58 *** typeobject.c 2001/07/03 00:37:47 2.16.8.57 --- typeobject.c 2001/07/03 00:48:14 2.16.8.58 *************** *** 633,637 **** f = descr->ob_type->tp_descr_get; if (f != NULL && PyDescr_IsData(descr)) ! return f(descr, (PyObject *)type, metatype); } --- 633,638 ---- f = descr->ob_type->tp_descr_get; if (f != NULL && PyDescr_IsData(descr)) ! return f(descr, ! (PyObject *)type, (PyObject *)metatype); } *************** *** 641,645 **** f = res->ob_type->tp_descr_get; if (f != NULL) ! return f(res, (PyObject *)NULL, type); Py_INCREF(res); return res; --- 642,646 ---- f = res->ob_type->tp_descr_get; if (f != NULL) ! return f(res, (PyObject *)NULL, (PyObject *)type); Py_INCREF(res); return res; *************** *** 648,652 **** /* Use the descriptor from the metatype */ if (f != NULL) { ! res = f(descr, NULL, metatype); return res; } --- 649,653 ---- /* Use the descriptor from the metatype */ if (f != NULL) { ! res = f(descr, (PyObject *)NULL, (PyObject *)metatype); return res; } *************** *** 1643,1652 **** descrgetfunc func = (descrgetfunc)wrapped; PyObject *obj; ! PyTypeObject *type = NULL; ! if (!PyArg_ParseTuple(args, "O|O!", &obj, &PyType_Type, &type)) return NULL; if (type == NULL) ! type = obj->ob_type; return (*func)(self, obj, type); } --- 1644,1653 ---- descrgetfunc func = (descrgetfunc)wrapped; PyObject *obj; ! PyObject *type = NULL; ! if (!PyArg_ParseTuple(args, "O|O", &obj, &type)) return NULL; if (type == NULL) ! type = (PyObject *)obj->ob_type; return (*func)(self, obj, type); } *************** *** 2043,2047 **** } ! SLOT2(tp_descr_get, get, PyObject *, PyTypeObject *, OO); static int --- 2044,2048 ---- } ! SLOT2(tp_descr_get, get, PyObject *, PyObject *, OO); static int From tim_one@users.sourceforge.net Tue Jul 3 02:09:15 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 02 Jul 2001 18:09:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects funcobject.c,2.37.4.8,2.37.4.9 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv22043/python/dist/src/Objects Modified Files: Tag: descr-branch funcobject.c Log Message: Believe it or not, Windows won't compile with a redundant semicolon after PyObject_HEAD. Index: funcobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/funcobject.c,v retrieving revision 2.37.4.8 retrieving revision 2.37.4.9 diff -C2 -r2.37.4.8 -r2.37.4.9 *** funcobject.c 2001/07/03 00:48:14 2.37.4.8 --- funcobject.c 2001/07/03 01:09:13 2.37.4.9 *************** *** 379,383 **** typedef struct { ! PyObject_HEAD; PyObject *cm_callable; } classmethod; --- 379,383 ---- typedef struct { ! PyObject_HEAD PyObject *cm_callable; } classmethod; From gvanrossum@users.sourceforge.net Tue Jul 3 02:14:59 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 02 Jul 2001 18:14:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects classobject.c,2.127.2.6,2.127.2.7 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv23303 Modified Files: Tag: descr-branch classobject.c Log Message: Support class methods for classic classes. This is done by using the tp_descr_get slot in class_getattr() and instance_getattr2() rather than making explicit check for functions. This is an important generalization, apart from the support for class method! Any class attribute that supports the tp_descr_get slot is now allowed to perform its own "bind" operation. This also opens the way to supporting computed attributes using "get/set" descriptors (which requires a only little bit more code I think -- mostly to create a get/set descriptor from a pair of Python functions). Index: classobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v retrieving revision 2.127.2.6 retrieving revision 2.127.2.7 diff -C2 -r2.127.2.6 -r2.127.2.7 *** classobject.c 2001/06/28 16:46:51 2.127.2.6 --- classobject.c 2001/07/03 01:14:57 2.127.2.7 *************** *** 162,165 **** --- 162,167 ---- register char *sname = PyString_AsString(name); PyClassObject *class; + descrgetfunc f; + if (sname[0] == '_' && sname[1] == '_') { if (strcmp(sname, "__dict__") == 0) { *************** *** 191,202 **** PyString_AS_STRING(op->cl_name), sname); return NULL; - } - Py_INCREF(v); - if (PyFunction_Check(v)) { - PyObject *w = PyMethod_New(v, (PyObject *)NULL, - (PyObject *)class); - Py_DECREF(v); - v = w; } return v; } --- 193,202 ---- PyString_AS_STRING(op->cl_name), sname); return NULL; } + f = v->ob_type->tp_descr_get; + if (f == NULL) + Py_INCREF(v); + else + v = f(v, (PyObject *)NULL, (PyObject *)op); return v; } *************** *** 648,651 **** --- 648,653 ---- register PyObject *v; PyClassObject *class; + descrgetfunc f; + class = NULL; v = PyDict_GetItem(inst->in_dict, name); *************** *** 657,663 **** Py_INCREF(v); if (class != NULL) { ! if (PyFunction_Check(v)) { ! PyObject *w = PyMethod_New(v, (PyObject *)inst, ! (PyObject *)class); Py_DECREF(v); v = w; --- 659,666 ---- Py_INCREF(v); if (class != NULL) { ! f = v->ob_type->tp_descr_get; ! if (f != NULL) { ! PyObject *w = f(v, (PyObject *)inst, ! (PyObject *)(inst->in_class)); Py_DECREF(v); v = w; *************** *** 2080,2083 **** --- 2083,2087 ---- sklassname, sfuncname); else { + /* XXX Shouldn't use repr() here! */ PyObject *selfrepr = PyObject_Repr(self); if (selfrepr == NULL) From gvanrossum@users.sourceforge.net Tue Jul 3 02:19:22 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 02 Jul 2001 18:19:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.1.2.23,1.1.2.24 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv24191 Modified Files: Tag: descr-branch test_descr.py Log Message: Add tests for class methods -- both for built-in and classic classes. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_descr.py,v retrieving revision 1.1.2.23 retrieving revision 1.1.2.24 diff -C2 -r1.1.2.23 -r1.1.2.24 *** test_descr.py 2001/06/29 16:38:38 1.1.2.23 --- test_descr.py 2001/07/03 01:19:20 1.1.2.24 *************** *** 616,619 **** --- 616,653 ---- verify(0, "__slots__ = [1] should be illegal") + def classmethods(): + if verbose: print "Testing class methods..." + class C(object): + def foo(*a): return a + goo = classmethod(foo) + verify(C.goo(1) == (C, 1)) + c = C() + verify(c.goo(1) == (C, 1)) + verify(c.foo(1) == (c, 1)) + class D(C): + pass + d = D() + verify(D.goo(1) == (D, 1)) + verify(d.goo(1) == (D, 1)) + verify(d.foo(1) == (d, 1)) + verify(D.foo(d, 1) == (d, 1)) + + def classic(): + if verbose: print "Testing classic classes..." + class C: + def foo(*a): return a + goo = classmethod(foo) + verify(C.goo(1) == (C, 1)) + c = C() + verify(c.goo(1) == (C, 1)) + verify(c.foo(1) == (c, 1)) + class D(C): + pass + d = D() + verify(D.goo(1) == (D, 1)) + verify(d.goo(1) == (D, 1)) + verify(d.foo(1) == (d, 1)) + verify(D.foo(d, 1) == (d, 1)) + def all(): lists() *************** *** 635,638 **** --- 669,674 ---- dynamics() errors() + classmethods() + classic() all() From tim_one@users.sourceforge.net Tue Jul 3 02:26:38 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 02 Jul 2001 18:26:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules spam.c,1.1.2.8,1.1.2.9 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv25111/python/dist/src/Modules Modified Files: Tag: descr-branch spam.c Log Message: Add spam module to Windows build. BUG: The spam PyMethodDef list didn't end with a proper sentinel, causing the Windows Python to run off into outer space (eventually died w/ a memory error). Repeared that. Index: spam.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/Attic/spam.c,v retrieving revision 1.1.2.8 retrieving revision 1.1.2.9 diff -C2 -r1.1.2.8 -r1.1.2.9 *** spam.c 2001/06/29 20:57:12 1.1.2.8 --- spam.c 2001/07/03 01:26:36 1.1.2.9 *************** *** 198,202 **** static PyMethodDef spam_functions[] = { ! {"bench", spam_bench, 1} }; --- 198,203 ---- static PyMethodDef spam_functions[] = { ! {"bench", spam_bench, 1}, ! {NULL, NULL} /* sentinel */ }; From tim_one@users.sourceforge.net Tue Jul 3 02:26:38 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 02 Jul 2001 18:26:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/PC config.c,1.31,1.31.6.1 Message-ID: Update of /cvsroot/python/python/dist/src/PC In directory usw-pr-cvs1:/tmp/cvs-serv25111/python/dist/src/PC Modified Files: Tag: descr-branch config.c Log Message: Add spam module to Windows build. BUG: The spam PyMethodDef list didn't end with a proper sentinel, causing the Windows Python to run off into outer space (eventually died w/ a memory error). Repeared that. Index: config.c =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/config.c,v retrieving revision 1.31 retrieving revision 1.31.6.1 diff -C2 -r1.31 -r1.31.6.1 *** config.c 2001/02/02 00:07:07 1.31 --- config.c 2001/07/03 01:26:36 1.31.6.1 *************** *** 45,48 **** --- 45,49 ---- extern void initxreadlines(void); extern void init_weakref(void); + extern void initspam(void); /* XXX tim: what's the purpose of ADDMODULE MARKER? */ *************** *** 98,101 **** --- 99,104 ---- {"xreadlines", initxreadlines}, {"_weakref", init_weakref}, + + {"spam", initspam}, /* XXX tim: what's the purpose of ADDMODULE MARKER? */ From tim_one@users.sourceforge.net Tue Jul 3 02:26:38 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 02 Jul 2001 18:26:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild pythoncore.dsp,1.15.2.1,1.15.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv25111/python/dist/src/PCbuild Modified Files: Tag: descr-branch pythoncore.dsp Log Message: Add spam module to Windows build. BUG: The spam PyMethodDef list didn't end with a proper sentinel, causing the Windows Python to run off into outer space (eventually died w/ a memory error). Repeared that. Index: pythoncore.dsp =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/pythoncore.dsp,v retrieving revision 1.15.2.1 retrieving revision 1.15.2.2 diff -C2 -r1.15.2.1 -r1.15.2.2 *** pythoncore.dsp 2001/04/24 00:54:17 1.15.2.1 --- pythoncore.dsp 2001/07/03 01:26:36 1.15.2.2 *************** *** 1528,1531 **** --- 1528,1546 ---- # Begin Source File + SOURCE=..\Modules\spam.c + + !IF "$(CFG)" == "pythoncore - Win32 Release" + + !ELSEIF "$(CFG)" == "pythoncore - Win32 Debug" + + !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Debug" + + !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Release" + + !ENDIF + + # End Source File + # Begin Source File + SOURCE=..\Objects\stringobject.c From gvanrossum@users.sourceforge.net Tue Jul 3 10:24:41 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 03 Jul 2001 02:24:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects descrobject.c,1.1.2.12,1.1.2.13 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv12179 Modified Files: Tag: descr-branch descrobject.c Log Message: PyDescr_IsData(): change in specification. If the argument is not a PyDescrObject, this returns true if the argument's type supports the tp_descr_set slot. This allows us to created computed attributes from a pair of get/set functions (see test_descr.py example). This almost works for classic classes too: there, it can be used for read-only computed attributes, but it can't be used to trap setattr unless we change instance setattr to look in the class dict first. Since that's expensive (a chain of dict lookups) we don't do this. Why is it not expensive for new-style classes? Because the class lookup is faster: compare _PyType_Lookup() to class_lookup(). Index: descrobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/Attic/descrobject.c,v retrieving revision 1.1.2.12 retrieving revision 1.1.2.13 diff -C2 -r1.1.2.12 -r1.1.2.13 *** descrobject.c 2001/07/02 17:08:33 1.1.2.12 --- descrobject.c 2001/07/03 09:24:39 1.1.2.13 *************** *** 427,433 **** case DF_GETSET: return 1; } } ! return 0; } --- 427,435 ---- case DF_GETSET: return 1; + default: + return 0; } } ! return d->ob_type->tp_descr_set != NULL; } From gvanrossum@users.sourceforge.net Tue Jul 3 10:24:59 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 03 Jul 2001 02:24:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.1.2.24,1.1.2.25 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv12232 Modified Files: Tag: descr-branch test_descr.py Log Message: PyDescr_IsData(): change in specification. If the argument is not a PyDescrObject, this returns true if the argument's type supports the tp_descr_set slot. This allows us to created computed attributes from a pair of get/set functions (see test_descr.py example). This almost works for classic classes too: there, it can be used for read-only computed attributes, but it can't be used to trap setattr unless we change instance setattr to look in the class dict first. Since that's expensive (a chain of dict lookups) we don't do this. Why is it not expensive for new-style classes? Because the class lookup is faster: compare _PyType_Lookup() to class_lookup(). Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_descr.py,v retrieving revision 1.1.2.24 retrieving revision 1.1.2.25 diff -C2 -r1.1.2.24 -r1.1.2.25 *** test_descr.py 2001/07/03 01:19:20 1.1.2.24 --- test_descr.py 2001/07/03 09:24:56 1.1.2.25 *************** *** 650,653 **** --- 650,680 ---- verify(D.foo(d, 1) == (d, 1)) + def compattr(): + if verbose: print "Testing computed attributes..." + class C(object): + class computed_attribute(object): + def __init__(self, get, set=None): + self.__get = get + self.__set = set + def __get__(self, obj, type=None): + return self.__get(obj) + def __set__(self, obj, value): + return self.__set(obj, value) + def __init__(self): + self.__x = 0 + def __get_x(self): + x = self.__x + self.__x = x+1 + return x + def __set_x(self, x): + self.__x = x + x = computed_attribute(__get_x, __set_x) + a = C() + verify(a.x == 0) + verify(a.x == 1) + a.x = 10 + verify(a.x == 10) + verify(a.x == 11) + def all(): lists() *************** *** 671,674 **** --- 698,702 ---- classmethods() classic() + compattr() all() From gvanrossum@users.sourceforge.net Tue Jul 3 10:56:54 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 03 Jul 2001 02:56:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include classobject.h,2.37,2.37.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv19044/Include Modified Files: Tag: descr-branch classobject.h Log Message: Get rid of PyMethod_{Function,Self,Class}. These were effectively internal APIs, always called after PyMethod_Check(), so it's better to always use the macros PyMethod_GET_{FUNCTION,SELF,SELF}. Index: classobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/classobject.h,v retrieving revision 2.37 retrieving revision 2.37.4.1 diff -C2 -r2.37 -r2.37.4.1 *** classobject.h 2001/03/23 04:17:58 2.37 --- classobject.h 2001/07/03 09:56:52 2.37.4.1 *************** *** 48,55 **** extern DL_IMPORT(PyObject *) PyMethod_New(PyObject *, PyObject *, PyObject *); - extern DL_IMPORT(PyObject *) PyMethod_Function(PyObject *); - extern DL_IMPORT(PyObject *) PyMethod_Self(PyObject *); - extern DL_IMPORT(PyObject *) PyMethod_Class(PyObject *); - /* Macros for direct access to these values. Type checks are *not* done, so use with care. */ --- 48,51 ---- From gvanrossum@users.sourceforge.net Tue Jul 3 10:56:54 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 03 Jul 2001 02:56:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects classobject.c,2.127.2.7,2.127.2.8 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv19044/Objects Modified Files: Tag: descr-branch classobject.c Log Message: Get rid of PyMethod_{Function,Self,Class}. These were effectively internal APIs, always called after PyMethod_Check(), so it's better to always use the macros PyMethod_GET_{FUNCTION,SELF,SELF}. Index: classobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v retrieving revision 2.127.2.7 retrieving revision 2.127.2.8 diff -C2 -r2.127.2.7 -r2.127.2.8 *** classobject.c 2001/07/03 01:14:57 2.127.2.7 --- classobject.c 2001/07/03 09:56:52 2.127.2.8 *************** *** 667,674 **** } else if (PyMethod_Check(v)) { ! PyObject *im_class = PyMethod_Class(v); /* Only if classes are compatible */ if (PyClass_IsSubclass((PyObject *)class, im_class)) { ! PyObject *im_func = PyMethod_Function(v); PyObject *w = PyMethod_New(im_func, (PyObject *)inst, im_class); --- 667,676 ---- } else if (PyMethod_Check(v)) { ! /* XXX This should be a tp_descr_get slot of ! PyMethodObjects */ ! PyObject *im_class = PyMethod_GET_CLASS(v); /* Only if classes are compatible */ if (PyClass_IsSubclass((PyObject *)class, im_class)) { ! PyObject *im_func = PyMethod_GET_FUNCTION(v); PyObject *w = PyMethod_New(im_func, (PyObject *)inst, im_class); *************** *** 1945,1978 **** PyObject_GC_Init(im); return (PyObject *)im; - } - - PyObject * - PyMethod_Function(register PyObject *im) - { - if (!PyMethod_Check(im)) { - PyErr_BadInternalCall(); - return NULL; - } - return ((PyMethodObject *)im)->im_func; - } - - PyObject * - PyMethod_Self(register PyObject *im) - { - if (!PyMethod_Check(im)) { - PyErr_BadInternalCall(); - return NULL; - } - return ((PyMethodObject *)im)->im_self; - } - - PyObject * - PyMethod_Class(register PyObject *im) - { - if (!PyMethod_Check(im)) { - PyErr_BadInternalCall(); - return NULL; - } - return ((PyMethodObject *)im)->im_class; } --- 1947,1950 ---- From tim_one@users.sourceforge.net Tue Jul 3 19:51:23 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 03 Jul 2001 11:51:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.58,2.16.8.59 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv18924/python/dist/src/Objects Modified Files: Tag: descr-branch typeobject.c Log Message: Repair compiler warning (signed/unsigned mismatch across ==). Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.58 retrieving revision 2.16.8.59 diff -C2 -r2.16.8.58 -r2.16.8.59 *** typeobject.c 2001/07/03 00:48:14 2.16.8.58 --- typeobject.c 2001/07/03 18:51:21 2.16.8.59 *************** *** 356,360 **** if (type->tp_dictoffset != 0 && base->tp_dictoffset == 0 && type->tp_dictoffset == b_size && ! t_size == b_size + sizeof(PyObject *)) return 0; /* "Forgive" adding a __dict__ only */ return 1; --- 356,360 ---- if (type->tp_dictoffset != 0 && base->tp_dictoffset == 0 && type->tp_dictoffset == b_size && ! (size_t)t_size == b_size + sizeof(PyObject *)) return 0; /* "Forgive" adding a __dict__ only */ return 1; From effbot@users.sourceforge.net Tue Jul 3 20:27:07 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Tue, 03 Jul 2001 12:27:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules regexpr.c,1.33,1.34 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv27037/modules Modified Files: regexpr.c Log Message: bug #232815 ch is unsigned, so testing for negative values doesn't make sense (as noticed by the OpenVMS compiler) Index: regexpr.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/regexpr.c,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -r1.33 -r1.34 *** regexpr.c 2000/07/21 06:00:07 1.33 --- regexpr.c 2001/07/03 19:27:05 1.34 *************** *** 1384,1388 **** goto bad_match_register; ch = 10 * (a - '0') + ch - '0'; ! if (ch <= 0 || ch >= RE_NREGS) goto bad_match_register; bufp->uses_registers = 1; --- 1384,1388 ---- goto bad_match_register; ch = 10 * (a - '0') + ch - '0'; ! if (ch == 0 || ch >= RE_NREGS) goto bad_match_register; bufp->uses_registers = 1; From effbot@users.sourceforge.net Tue Jul 3 21:32:38 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Tue, 03 Jul 2001 13:32:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _sre.c,2.59,2.60 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv11104/Modules Modified Files: _sre.c Log Message: bug #416670 added copy/deepcopy support to SRE (still not enabled, since it's not covered by the test suite) Index: _sre.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_sre.c,v retrieving revision 2.59 retrieving revision 2.60 diff -C2 -r2.59 -r2.60 *** _sre.c 2001/07/02 19:54:28 2.59 --- _sre.c 2001/07/03 20:32:36 2.60 *************** *** 1698,1717 **** static PyObject* ! call(char* function, PyObject* args) { PyObject* name; ! PyObject* module; PyObject* func; PyObject* result; ! name = PyString_FromString(SRE_MODULE); if (!name) return NULL; ! module = PyImport_Import(name); Py_DECREF(name); ! if (!module) return NULL; ! func = PyObject_GetAttrString(module, function); ! Py_DECREF(module); if (!func) return NULL; --- 1698,1717 ---- static PyObject* ! call(char* module, char* function, PyObject* args) { PyObject* name; ! PyObject* mod; PyObject* func; PyObject* result; ! name = PyString_FromString(module); if (!name) return NULL; ! mod = PyImport_Import(name); Py_DECREF(name); ! if (!mod) return NULL; ! func = PyObject_GetAttrString(mod, function); ! Py_DECREF(mod); if (!func) return NULL; *************** *** 1722,1725 **** --- 1722,1745 ---- } + #ifdef USE_BUILTIN_COPY + static int + deepcopy(PyObject** object, PyObject* memo) + { + PyObject* copy; + + copy = call( + "copy", "deepcopy", + Py_BuildValue("OO", *object, memo) + ); + if (!copy) + return 0; + + Py_DECREF(*object); + *object = copy; + + return 1; /* success */ + } + #endif + static PyObject* pattern_sub(PatternObject* self, PyObject* args, PyObject* kw) *************** *** 1734,1738 **** /* delegate to Python code */ ! return call("_sub", Py_BuildValue("OOOO", self, template, string, count)); } --- 1754,1761 ---- /* delegate to Python code */ ! return call( ! SRE_MODULE, "_sub", ! Py_BuildValue("OOOO", self, template, string, count) ! ); } *************** *** 1749,1753 **** /* delegate to Python code */ ! return call("_subn", Py_BuildValue("OOOO", self, template, string, count)); } --- 1772,1779 ---- /* delegate to Python code */ ! return call( ! SRE_MODULE, "_subn", ! Py_BuildValue("OOOO", self, template, string, count) ! ); } *************** *** 1763,1767 **** /* delegate to Python code */ ! return call("_split", Py_BuildValue("OOO", self, string, maxsplit)); } --- 1789,1796 ---- /* delegate to Python code */ ! return call( ! SRE_MODULE, "_split", ! Py_BuildValue("OOO", self, string, maxsplit) ! ); } *************** *** 1873,1881 **** pattern_copy(PatternObject* self, PyObject* args) { ! #if USE_BUILTIN_COPY PatternObject* copy; int offset; ! /* work in progress */ copy = PyObject_NEW_VAR(PatternObject, &Pattern_Type, self->codesize); --- 1902,1911 ---- pattern_copy(PatternObject* self, PyObject* args) { ! #ifdef USE_BUILTIN_COPY PatternObject* copy; int offset; ! if (args != Py_None && !PyArg_ParseTuple(args, ":__copy__")) ! return NULL; copy = PyObject_NEW_VAR(PatternObject, &Pattern_Type, self->codesize); *************** *** 1902,1907 **** --- 1932,1957 ---- pattern_deepcopy(PatternObject* self, PyObject* args) { + #ifdef USE_BUILTIN_COPY + PatternObject* copy; + + PyObject* memo; + if (!PyArg_ParseTuple(args, "O:__deepcopy__", &memo)) + return NULL; + + copy = (PatternObject*) pattern_copy(self, Py_None); + if (!copy) + return NULL; + + if (!deepcopy(©->groupindex, memo) || + !deepcopy(©->indexgroup, memo) || + !deepcopy(©->pattern, memo)) { + Py_DECREF(copy); + return NULL; + } + + #else PyErr_SetString(PyExc_TypeError, "cannot deepcopy this pattern object"); return NULL; + #endif } *************** *** 2036,2040 **** /* delegate to Python code */ return call( ! "_expand", Py_BuildValue("OOO", self->pattern, self, template) ); --- 2086,2090 ---- /* delegate to Python code */ return call( ! SRE_MODULE, "_expand", Py_BuildValue("OOO", self->pattern, self, template) ); *************** *** 2277,2285 **** match_copy(MatchObject* self, PyObject* args) { ! #if USE_BUILTIN_COPY MatchObject* copy; int slots, offset; ! /* works in progress */ slots = 2 * (self->pattern->groups+1); --- 2327,2336 ---- match_copy(MatchObject* self, PyObject* args) { ! #ifdef USE_BUILTIN_COPY MatchObject* copy; int slots, offset; ! if (args != Py_None && !PyArg_ParseTuple(args, ":__copy__")) ! return NULL; slots = 2 * (self->pattern->groups+1); *************** *** 2302,2306 **** return (PyObject*) copy; #else ! PyErr_SetString(PyExc_TypeError, "cannot deepcopy this match object"); return NULL; #endif --- 2353,2357 ---- return (PyObject*) copy; #else ! PyErr_SetString(PyExc_TypeError, "cannot copy this match object"); return NULL; #endif *************** *** 2310,2315 **** --- 2361,2386 ---- match_deepcopy(MatchObject* self, PyObject* args) { + #ifdef USE_BUILTIN_COPY + MatchObject* copy; + + PyObject* memo; + if (!PyArg_ParseTuple(args, "O:__deepcopy__", &memo)) + return NULL; + + copy = (MatchObject*) match_copy(self, Py_None); + if (!copy) + return NULL; + + if (!deepcopy((PyObject**) ©->pattern, memo) || + !deepcopy(©->string, memo) || + !deepcopy(©->regs, memo)) { + Py_DECREF(copy); + return NULL; + } + + #else PyErr_SetString(PyExc_TypeError, "cannot deepcopy this match object"); return NULL; + #endif } From fdrake@users.sourceforge.net Wed Jul 4 00:39:54 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 03 Jul 2001 16:39:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include pystate.h,2.15,2.16 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv21594/Include Modified Files: pystate.h Log Message: This change adjusts the profiling/tracing support so that the common path (with no profile/trace function) through eval_code2() and eval_frame() avoids several checks. In the common cases of calls, returns, and exception propogation, eval_code2() and eval_frame() used to test two values in the thread-state: the profiling function and the tracing function. With this change, a flag is set in the thread-state if either of these is active, allowing a single check to suffice when both are NULL. This also simplifies the code needed when either function is in use but is already active (to avoid profiling/tracing the profiler/tracer); the flag is set to 0 when the profile/trace code is entered, allowing the same check to suffice for "already in the tracer" for call/return/ exception events. Index: pystate.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pystate.h,v retrieving revision 2.15 retrieving revision 2.16 diff -C2 -r2.15 -r2.16 *** pystate.h 2001/06/27 19:18:03 2.15 --- pystate.h 2001/07/03 23:39:52 2.16 *************** *** 50,53 **** --- 50,54 ---- int ticker; int tracing; + int use_tracing; Py_tracefunc c_profilefunc; From fdrake@users.sourceforge.net Wed Jul 4 00:39:54 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 03 Jul 2001 16:39:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.259,2.260 pystate.c,2.17,2.18 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv21594/Python Modified Files: ceval.c pystate.c Log Message: This change adjusts the profiling/tracing support so that the common path (with no profile/trace function) through eval_code2() and eval_frame() avoids several checks. In the common cases of calls, returns, and exception propogation, eval_code2() and eval_frame() used to test two values in the thread-state: the profiling function and the tracing function. With this change, a flag is set in the thread-state if either of these is active, allowing a single check to suffice when both are NULL. This also simplifies the code needed when either function is in use but is already active (to avoid profiling/tracing the profiler/tracer); the flag is set to 0 when the profile/trace code is entered, allowing the same check to suffice for "already in the tracer" for call/return/ exception events. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.259 retrieving revision 2.260 diff -C2 -r2.259 -r2.260 *** ceval.c 2001/06/27 19:19:46 2.259 --- ceval.c 2001/07/03 23:39:52 2.260 *************** *** 1891,1896 **** --- 1891,1899 ---- /* Inline call_trace() for performance: */ tstate->tracing++; + tstate->use_tracing = 0; err = (tstate->c_tracefunc)(tstate->c_traceobj, f, PyTrace_LINE, Py_None); + tstate->use_tracing = (tstate->c_tracefunc + || tstate->c_profilefunc); tstate->tracing--; break; *************** *** 2143,2152 **** PyTraceBack_Here(f); ! if (tstate->c_tracefunc) ! call_exc_trace(tstate->c_tracefunc, ! tstate->c_traceobj, f); ! if (tstate->c_profilefunc) ! call_exc_trace(tstate->c_profilefunc, ! tstate->c_profileobj, f); } --- 2146,2157 ---- PyTraceBack_Here(f); ! if (tstate->use_tracing) { ! if (tstate->c_tracefunc) ! call_exc_trace(tstate->c_tracefunc, ! tstate->c_traceobj, f); ! if (tstate->c_profilefunc) ! call_exc_trace(tstate->c_profilefunc, ! tstate->c_profileobj,f); ! } } *************** *** 2229,2236 **** retval = NULL; ! if (tstate->c_tracefunc && !tstate->tracing) { ! if (why == WHY_RETURN || why == WHY_YIELD) { ! if (call_trace(tstate->c_tracefunc, tstate->c_traceobj, ! f, PyTrace_RETURN, retval)) { Py_XDECREF(retval); retval = NULL; --- 2234,2243 ---- retval = NULL; ! if (tstate->use_tracing) { ! if (tstate->c_tracefunc ! && (why == WHY_RETURN || why == WHY_YIELD)) { ! if (call_trace(tstate->c_tracefunc, ! tstate->c_traceobj, f, ! PyTrace_RETURN, retval)) { Py_XDECREF(retval); retval = NULL; *************** *** 2238,2250 **** } } ! } ! ! if (tstate->c_profilefunc && !tstate->tracing ! && (why == WHY_RETURN || why == WHY_YIELD)) { ! if (call_trace(tstate->c_profilefunc, tstate->c_profileobj, ! f, PyTrace_RETURN, retval)) { ! Py_XDECREF(retval); ! retval = NULL; ! why = WHY_EXCEPTION; } } --- 2245,2257 ---- } } ! if (tstate->c_profilefunc ! && (why == WHY_RETURN || why == WHY_YIELD)) { ! if (call_trace(tstate->c_profilefunc, ! tstate->c_profileobj, f, ! PyTrace_RETURN, retval)) { ! Py_XDECREF(retval); ! retval = NULL; ! why = WHY_EXCEPTION; ! } } } *************** *** 2472,2504 **** } ! if (tstate->c_tracefunc != NULL && !tstate->tracing) { ! /* tstate->sys_tracefunc, if defined, is a function that ! will be called on *every* entry to a code block. ! Its return value, if not None, is a function that ! will be called at the start of each executed line ! of code. (Actually, the function must return ! itself in order to continue tracing.) ! The trace functions are called with three arguments: ! a pointer to the current frame, a string indicating ! why the function is called, and an argument which ! depends on the situation. The global trace function ! (sys.trace) is also called whenever an exception ! is detected. */ ! if (call_trace(tstate->c_tracefunc, tstate->c_traceobj, ! f, PyTrace_CALL, Py_None)) { ! /* XXX Need way to compute arguments?? */ ! /* Trace function raised an error */ ! goto fail; } ! } ! ! if (tstate->c_profilefunc != NULL) { ! /* Similar for sys_profilefunc, except it needn't return ! itself and isn't called for "line" events */ ! if (call_trace(tstate->c_profilefunc, tstate->c_profileobj, ! f, PyTrace_CALL, Py_None)) { ! /* XXX Need way to compute arguments?? */ ! /* Profile function raised an error */ ! goto fail; } } --- 2479,2514 ---- } ! if (tstate->use_tracing) { ! if (tstate->c_tracefunc != NULL) { ! /* tstate->c_tracefunc, if defined, is a ! function that will be called on *every* entry ! to a code block. Its return value, if not ! None, is a function that will be called at ! the start of each executed line of code. ! (Actually, the function must return itself ! in order to continue tracing.) The trace ! functions are called with three arguments: ! a pointer to the current frame, a string ! indicating why the function is called, and ! an argument which depends on the situation. ! The global trace function is also called ! whenever an exception is detected. */ ! if (call_trace(tstate->c_tracefunc, tstate->c_traceobj, ! f, PyTrace_CALL, Py_None)) { ! /* XXX Need way to compute arguments?? */ ! /* Trace function raised an error */ ! goto fail; ! } } ! if (tstate->c_profilefunc != NULL) { ! /* Similar for c_profilefunc, except it needn't ! return itself and isn't called for "line" events */ ! if (call_trace(tstate->c_profilefunc, ! tstate->c_profileobj, ! f, PyTrace_CALL, Py_None)) { ! /* XXX Need way to compute arguments?? */ ! /* Profile function raised an error */ ! goto fail; ! } } } *************** *** 2804,2808 **** --- 2814,2821 ---- return 0; tstate->tracing++; + tstate->use_tracing = 0; result = func(obj, frame, what, arg); + tstate->use_tracing = ((tstate->c_tracefunc != NULL) + || (tstate->c_profilefunc != NULL)); tstate->tracing--; return result; *************** *** 2817,2823 **** --- 2830,2838 ---- tstate->c_profilefunc = NULL; tstate->c_profileobj = NULL; + tstate->use_tracing = tstate->c_tracefunc != NULL; Py_XDECREF(temp); tstate->c_profilefunc = func; tstate->c_profileobj = arg; + tstate->use_tracing = (func != NULL) || (tstate->c_tracefunc != NULL); } *************** *** 2830,2836 **** --- 2845,2854 ---- tstate->c_tracefunc = NULL; tstate->c_traceobj = NULL; + tstate->use_tracing = tstate->c_profilefunc != NULL; Py_XDECREF(temp); tstate->c_tracefunc = func; tstate->c_traceobj = arg; + tstate->use_tracing = ((func != NULL) + || (tstate->c_profilefunc != NULL)); } Index: pystate.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pystate.c,v retrieving revision 2.17 retrieving revision 2.18 diff -C2 -r2.17 -r2.18 *** pystate.c 2001/06/27 19:19:46 2.17 --- pystate.c 2001/07/03 23:39:52 2.18 *************** *** 110,113 **** --- 110,114 ---- tstate->ticker = 0; tstate->tracing = 0; + tstate->use_tracing = 0; tstate->dict = NULL; From gvanrossum@users.sourceforge.net Wed Jul 4 01:14:00 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 03 Jul 2001 17:14:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects funcobject.c,2.37.4.9,2.37.4.10 typeobject.c,2.16.8.59,2.16.8.60 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv27193/Objects Modified Files: Tag: descr-branch funcobject.c typeobject.c Log Message: Make the tp_new slot overridable by defining a function __new__ in the class statement. This revealed a bug in my original design: class methods can't be used here because there is no way to make an upcall while passing it the most derived type as argument, because the type is *always* implicit for class methods. So I had to add static methods as well. I decided not to throw away class methods, since I'd already done the implementation effort, and one user (Thomas Heller (?)) already mailed me that he wants to check them out. Anyway, it now works, although it's not very useful as long as types like tuple can't be subtyped. A wart: you can now call a type's __new__ method with an argument that is not derived from that type, e.g. list.__new__(dictionary). Because list.__new__() is really just PyType_GenericNew(), this creates a perfectly valid dictionary, but I imagine there are cases where this can do bad things. We can fix this in two ways: either add an explicit typecheck to each _new() that makes assumptions, or change the __new__ wrapper so that it knows the expected type, and does a subtype check. Another wart: currently, the metatype's tp_call() makes the call to the type's tp_init(), after the type's tp_new() succeeds. This code had to be robustified: if tp_new() returned an object from a different type, the wrong type's tp_init() was called. Now it calls the tp_init() of the type of the returned object. But this still feels fishy, because what if tp_new() returned an old object? Then it will be reinitialized! Perhaps the call to tp_init() should be moved back inside tp_new(), so that each type is responsible for calling its own tp_init()? (Problem with that is that it's repeated code -- each tp_new() implementation has to do its own. Index: funcobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/funcobject.c,v retrieving revision 2.37.4.9 retrieving revision 2.37.4.10 diff -C2 -r2.37.4.9 -r2.37.4.10 *** funcobject.c 2001/07/03 01:09:13 2.37.4.9 --- funcobject.c 2001/07/04 00:13:58 2.37.4.10 *************** *** 378,381 **** --- 378,398 ---- /* Class method object */ + /* A class method receives the class as implicit first argument, + just like an instance method receives the instance. + To declare a class method, use this idiom: + + class C: + def f(cls, arg1, arg2, ...): ... + f = classmethod(f) + + It can be called either on the class (e.g. C.f()) or on an instance + (e.g. C().f()); the instance is ignored except for its class. + If a class method is called for a derived class, the derived class + object is passed as the implied first argument. + + Class methods are different than C++ or Java static methods. + If you want those, see static methods below. + */ + typedef struct { PyObject_HEAD *************** *** 458,459 **** --- 475,598 ---- PyType_GenericNew, /* tp_new */ }; + + PyObject * + PyClassMethod_New(PyObject *callable) + { + classmethod *cm = (classmethod *) + PyType_GenericAlloc(&PyClassMethod_Type, 0); + if (cm != NULL) { + Py_INCREF(callable); + cm->cm_callable = callable; + } + return (PyObject *)cm; + } + + + /* Static method object */ + + /* A static method does not receive an implicit first argument. + To declare a static method, use this idiom: + + class C: + def f(arg1, arg2, ...): ... + f = staticmethod(f) + + It can be called either on the class (e.g. C.f()) or on an instance + (e.g. C().f()); the instance is ignored except for its class. + + Static methods in Python are similar to those found in Java or C++. + For a more advanced concept, see class methods above. + */ + + typedef struct { + PyObject_HEAD + PyObject *sm_callable; + } staticmethod; + + static void + sm_dealloc(staticmethod *sm) + { + Py_XDECREF(sm->sm_callable); + PyObject_DEL(sm); + } + + static PyObject * + sm_descr_get(PyObject *self, PyObject *obj, PyObject *type) + { + staticmethod *sm = (staticmethod *)self; + + if (sm->sm_callable == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "uninitialized staticmethod object"); + return NULL; + } + Py_INCREF(sm->sm_callable); + return sm->sm_callable; + } + + static int + sm_init(PyObject *self, PyObject *args, PyObject *kwds) + { + staticmethod *sm = (staticmethod *)self; + PyObject *callable; + + if (!PyArg_ParseTuple(args, "O:callable", &callable)) + return -1; + Py_INCREF(callable); + sm->sm_callable = callable; + return 0; + } + + PyTypeObject PyStaticMethod_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "staticmethod", + sizeof(staticmethod), + 0, + (destructor)sm_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_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + sm_descr_get, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + sm_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + }; + + PyObject * + PyStaticMethod_New(PyObject *callable) + { + staticmethod *sm = (staticmethod *) + PyType_GenericAlloc(&PyStaticMethod_Type, 0); + if (sm != NULL) { + Py_INCREF(callable); + sm->sm_callable = callable; + } + return (PyObject *)sm; + } Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.59 retrieving revision 2.16.8.60 diff -C2 -r2.16.8.59 -r2.16.8.60 *** typeobject.c 2001/07/03 18:51:21 2.16.8.59 --- typeobject.c 2001/07/04 00:13:58 2.16.8.60 *************** *** 96,101 **** obj = type->tp_new(type, args, NULL); ! if (obj != NULL && type->tp_init != NULL) { ! if (type->tp_init(obj, args, kwds) < 0) { Py_DECREF(obj); obj = NULL; --- 96,103 ---- obj = type->tp_new(type, args, NULL); ! if (obj != NULL) { ! type = obj->ob_type; ! if (type->tp_init != NULL && ! type->tp_init(obj, args, kwds) < 0) { Py_DECREF(obj); obj = NULL; *************** *** 535,538 **** --- 537,553 ---- } + /* Special-case __new__: if it's a plain function, + make it a static function */ + tmp = PyDict_GetItemString(dict, "__new__"); + if (tmp != NULL && PyFunction_Check(tmp)) { + tmp = PyStaticMethod_New(tmp); + if (tmp == NULL) { + Py_DECREF(type); + return NULL; + } + PyDict_SetItemString(dict, "__new__", tmp); + Py_DECREF(tmp); + } + /* Add descriptors for custom slots from __slots__, or for __dict__ */ mp = et->members; *************** *** 849,852 **** --- 864,892 ---- static int + add_staticmethodwrappers(PyTypeObject *type, struct wrapperbase *base, + void *wrapped) + { + PyObject *dict = type->tp_defined; + PyObject *sm; + + for (; base->name != NULL; base++) { + PyObject *descr; + if (PyDict_GetItemString(dict, base->name)) + continue; + descr = PyDescr_NewWrapper(type->ob_type, base, wrapped); + if (descr == NULL) + return -1; + sm = PyStaticMethod_New(descr); + Py_DECREF(descr); + if (sm == NULL) + return -1; + if (PyDict_SetItemString(dict, base->name, sm) < 0) + return -1; + Py_DECREF(sm); + } + return 0; + } + + static int add_members(PyTypeObject *type, struct memberlist *memb) { *************** *** 1699,1702 **** --- 1739,1755 ---- }; + static PyObject * + wrap_new(PyObject *type, PyObject *args, void *wrapped) + { + newfunc new = (newfunc)wrapped; + return new((PyTypeObject *)type, args, NULL); + } + + static struct wrapperbase tab_new[] = { + {"__new__", (wrapperfunc)wrap_new, + "T.__new__() -> an object with type T"}, + {0} + }; + static int add_operators(PyTypeObject *type) *************** *** 1788,1791 **** --- 1841,1847 ---- ADD(type->tp_init, tab_init); + if (type->tp_new != NULL) + add_staticmethodwrappers(type, tab_new, type->tp_new); + return 0; } *************** *** 2073,2076 **** --- 2129,2158 ---- } + static PyObject * + slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + PyObject *func = PyObject_GetAttrString((PyObject *)type, "__new__"); + PyObject *newargs, *x; + int i, n; + + if (func == NULL) + return NULL; + assert(PyTuple_Check(args)); + n = PyTuple_GET_SIZE(args); + newargs = PyTuple_New(n+1); + if (newargs == NULL) + return NULL; + Py_INCREF(type); + PyTuple_SET_ITEM(newargs, 0, (PyObject *)type); + for (i = 0; i < n; i++) { + x = PyTuple_GET_ITEM(args, i); + Py_INCREF(x); + PyTuple_SET_ITEM(newargs, i+1, x); + } + x = PyObject_Call(func, newargs, kwds); + Py_DECREF(func); + return x; + } + static void override_slots(PyTypeObject *type, PyObject *dict) *************** *** 2172,2174 **** --- 2254,2257 ---- TPSLOT("__set__", tp_descr_set); TPSLOT("__init__", tp_init); + TPSLOT("__new__", tp_new); } From gvanrossum@users.sourceforge.net Wed Jul 4 01:14:00 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 03 Jul 2001 17:14:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include funcobject.h,2.23.4.1,2.23.4.2 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv27193/Include Modified Files: Tag: descr-branch funcobject.h Log Message: Make the tp_new slot overridable by defining a function __new__ in the class statement. This revealed a bug in my original design: class methods can't be used here because there is no way to make an upcall while passing it the most derived type as argument, because the type is *always* implicit for class methods. So I had to add static methods as well. I decided not to throw away class methods, since I'd already done the implementation effort, and one user (Thomas Heller (?)) already mailed me that he wants to check them out. Anyway, it now works, although it's not very useful as long as types like tuple can't be subtyped. A wart: you can now call a type's __new__ method with an argument that is not derived from that type, e.g. list.__new__(dictionary). Because list.__new__() is really just PyType_GenericNew(), this creates a perfectly valid dictionary, but I imagine there are cases where this can do bad things. We can fix this in two ways: either add an explicit typecheck to each _new() that makes assumptions, or change the __new__ wrapper so that it knows the expected type, and does a subtype check. Another wart: currently, the metatype's tp_call() makes the call to the type's tp_init(), after the type's tp_new() succeeds. This code had to be robustified: if tp_new() returned an object from a different type, the wrong type's tp_init() was called. Now it calls the tp_init() of the type of the returned object. But this still feels fishy, because what if tp_new() returned an old object? Then it will be reinitialized! Perhaps the call to tp_init() should be moved back inside tp_new(), so that each type is responsible for calling its own tp_init()? (Problem with that is that it's repeated code -- each tp_new() implementation has to do its own. Index: funcobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/funcobject.h,v retrieving revision 2.23.4.1 retrieving revision 2.23.4.2 diff -C2 -r2.23.4.1 -r2.23.4.2 *** funcobject.h 2001/07/02 18:06:06 2.23.4.1 --- funcobject.h 2001/07/04 00:13:58 2.23.4.2 *************** *** 43,48 **** (((PyFunctionObject *)func) -> func_closure) ! /* The classmethod type lives here, too */ extern DL_IMPORT(PyTypeObject) PyClassMethod_Type; #ifdef __cplusplus --- 43,52 ---- (((PyFunctionObject *)func) -> func_closure) ! /* The classmethod and staticmethod types lives here, too */ extern DL_IMPORT(PyTypeObject) PyClassMethod_Type; + extern DL_IMPORT(PyTypeObject) PyStaticMethod_Type; + + extern DL_IMPORT(PyObject *) PyClassMethod_New(PyObject *); + extern DL_IMPORT(PyObject *) PyStaticMethod_New(PyObject *); #ifdef __cplusplus From gvanrossum@users.sourceforge.net Wed Jul 4 01:14:00 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 03 Jul 2001 17:14:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.198.2.5,2.198.2.6 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv27193/Python Modified Files: Tag: descr-branch bltinmodule.c Log Message: Make the tp_new slot overridable by defining a function __new__ in the class statement. This revealed a bug in my original design: class methods can't be used here because there is no way to make an upcall while passing it the most derived type as argument, because the type is *always* implicit for class methods. So I had to add static methods as well. I decided not to throw away class methods, since I'd already done the implementation effort, and one user (Thomas Heller (?)) already mailed me that he wants to check them out. Anyway, it now works, although it's not very useful as long as types like tuple can't be subtyped. A wart: you can now call a type's __new__ method with an argument that is not derived from that type, e.g. list.__new__(dictionary). Because list.__new__() is really just PyType_GenericNew(), this creates a perfectly valid dictionary, but I imagine there are cases where this can do bad things. We can fix this in two ways: either add an explicit typecheck to each _new() that makes assumptions, or change the __new__ wrapper so that it knows the expected type, and does a subtype check. Another wart: currently, the metatype's tp_call() makes the call to the type's tp_init(), after the type's tp_new() succeeds. This code had to be robustified: if tp_new() returned an object from a different type, the wrong type's tp_init() was called. Now it calls the tp_init() of the type of the returned object. But this still feels fishy, because what if tp_new() returned an old object? Then it will be reinitialized! Perhaps the call to tp_init() should be moved back inside tp_new(), so that each type is responsible for calling its own tp_init()? (Problem with that is that it's repeated code -- each tp_new() implementation has to do its own. Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.198.2.5 retrieving revision 2.198.2.6 diff -C2 -r2.198.2.5 -r2.198.2.6 *** bltinmodule.c 2001/07/02 18:06:06 2.198.2.5 --- bltinmodule.c 2001/07/04 00:13:58 2.198.2.6 *************** *** 1816,1819 **** --- 1816,1822 ---- (PyObject *) &PyBaseObject_Type) < 0) return NULL; + if (PyDict_SetItemString(dict, "staticmethod", + (PyObject *) &PyStaticMethod_Type) < 0) + return NULL; if (PyDict_SetItemString(dict, "str", (PyObject *) &PyString_Type) < 0) return NULL; From gvanrossum@users.sourceforge.net Wed Jul 4 01:16:04 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 03 Jul 2001 17:16:04 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.1.2.5,1.1.2.6 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv27602 Modified Files: Tag: descr-branch PLAN.txt Log Message: Add commentary to tasks for issubtype() and overriding __new__(). Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Attic/PLAN.txt,v retrieving revision 1.1.2.5 retrieving revision 1.1.2.6 diff -C2 -r1.1.2.5 -r1.1.2.6 *** PLAN.txt 2001/07/01 19:52:44 1.1.2.5 --- PLAN.txt 2001/07/04 00:16:02 1.1.2.6 *************** *** 26,30 **** thing yet. There should be fewer APIs and their implementation should be simpler. The old "abstract subclass" test should probably ! disappear (if we want to root out ExtensionClass). Check for conflicts between base classes. I fear that the rules used --- 26,34 ---- thing yet. There should be fewer APIs and their implementation should be simpler. The old "abstract subclass" test should probably ! disappear (if we want to root out ExtensionClass). *** I think I've ! done 90% of this by creating PyType_IsSubtype() and using it ! appropriately. For now, the old "abstract subclass" test is still ! there, and there may be some places where PyObject_IsSubclass() is ! called where PyType_IsSubtype() would be more appropriate. *** Check for conflicts between base classes. I fear that the rules used *************** *** 75,79 **** Make __new__ overridable through a Python class method (!). Make more ! of the sub-algorithms of type construction available as methods. More -- I'm sure new issues will crop up as we go. --- 79,92 ---- Make __new__ overridable through a Python class method (!). Make more ! of the sub-algorithms of type construction available as methods. *** ! After I implemented class methods, I found that in order to be able ! to make an upcall to Base.__new__() and have it create an instance of ! your class (rather than a Base instance), you can't use class methods ! -- you must use static methods. So I've implemented those too. I've ! hooked up __new__ in the right places, so the first part of this is ! now done (still to do the other construction methods -- unclear that ! we really need any though). I expect that some warts will only be ! really debugged when we try to use this for some, eh, interesting ! types such as tuples. *** More -- I'm sure new issues will crop up as we go. From gvanrossum@users.sourceforge.net Wed Jul 4 01:40:59 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 03 Jul 2001 17:40:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.1.2.25,1.1.2.26 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv32100 Modified Files: Tag: descr-branch test_descr.py Log Message: Rudimentary test for __new__ override. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_descr.py,v retrieving revision 1.1.2.25 retrieving revision 1.1.2.26 diff -C2 -r1.1.2.25 -r1.1.2.26 *** test_descr.py 2001/07/03 09:24:56 1.1.2.25 --- test_descr.py 2001/07/04 00:40:57 1.1.2.26 *************** *** 677,680 **** --- 677,698 ---- verify(a.x == 11) + def newslot(): + if verbose: print "Testing __new__ slot override..." + class C(list): + def __new__(cls): + self = list.__new__(cls) + self.foo = 1 + return self + def __init__(self): + self.foo = self.foo + 2 + a = C() + verify(a.foo == 3) + verify(a.__class__ is C) + class D(C): + pass + b = D() + verify(b.foo == 3) + verify(b.__class__ is D) + def all(): lists() *************** *** 699,702 **** --- 717,721 ---- classic() compattr() + newslot() all() From gvanrossum@users.sourceforge.net Wed Jul 4 01:44:02 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 03 Jul 2001 17:44:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.1.2.26,1.1.2.27 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv32565 Modified Files: Tag: descr-branch test_descr.py Log Message: Add test for static methods (similar to test for class methods). Move a few lines around for consistency. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_descr.py,v retrieving revision 1.1.2.26 retrieving revision 1.1.2.27 diff -C2 -r1.1.2.26 -r1.1.2.27 *** test_descr.py 2001/07/04 00:40:57 1.1.2.26 --- test_descr.py 2001/07/04 00:44:00 1.1.2.27 *************** *** 621,626 **** def foo(*a): return a goo = classmethod(foo) - verify(C.goo(1) == (C, 1)) c = C() verify(c.goo(1) == (C, 1)) verify(c.foo(1) == (c, 1)) --- 621,626 ---- def foo(*a): return a goo = classmethod(foo) c = C() + verify(C.goo(1) == (C, 1)) verify(c.goo(1) == (C, 1)) verify(c.foo(1) == (c, 1)) *************** *** 633,636 **** --- 633,653 ---- verify(D.foo(d, 1) == (d, 1)) + def staticmethods(): + if verbose: print "Testing static methods..." + class C(object): + def foo(*a): return a + goo = staticmethod(foo) + c = C() + verify(C.goo(1) == (1,)) + verify(c.goo(1) == (1,)) + verify(c.foo(1) == (c, 1,)) + class D(C): + pass + d = D() + verify(D.goo(1) == (1,)) + verify(d.goo(1) == (1,)) + verify(d.foo(1) == (d, 1)) + verify(D.foo(d, 1) == (d, 1)) + def classic(): if verbose: print "Testing classic classes..." *************** *** 638,643 **** def foo(*a): return a goo = classmethod(foo) - verify(C.goo(1) == (C, 1)) c = C() verify(c.goo(1) == (C, 1)) verify(c.foo(1) == (c, 1)) --- 655,660 ---- def foo(*a): return a goo = classmethod(foo) c = C() + verify(C.goo(1) == (C, 1)) verify(c.goo(1) == (C, 1)) verify(c.foo(1) == (c, 1)) *************** *** 715,718 **** --- 732,736 ---- errors() classmethods() + staticmethods() classic() compattr() From fdrake@users.sourceforge.net Wed Jul 4 06:18:20 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 03 Jul 2001 22:18:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib urllib2.py,1.13,1.13.2.1 urllib.py,1.126,1.126.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv11349/Lib Modified Files: Tag: release21-maint urllib2.py urllib.py Log Message: Only write out one blank line before the request data. This closes SF patch #419459. Index: urllib2.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/urllib2.py,v retrieving revision 1.13 retrieving revision 1.13.2.1 diff -C2 -r1.13 -r1.13.2.1 *** urllib2.py 2001/04/15 13:08:01 1.13 --- urllib2.py 2001/07/04 05:18:18 1.13.2.1 *************** *** 809,813 **** h.endheaders() if req.has_data(): ! h.send(data + '\r\n') code, msg, hdrs = h.getreply() --- 809,813 ---- h.endheaders() if req.has_data(): ! h.send(data) code, msg, hdrs = h.getreply() Index: urllib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/urllib.py,v retrieving revision 1.126 retrieving revision 1.126.2.1 diff -C2 -r1.126 -r1.126.2.1 *** urllib.py 2001/04/15 20:47:33 1.126 --- urllib.py 2001/07/04 05:18:18 1.126.2.1 *************** *** 287,291 **** h.endheaders() if data is not None: ! h.send(data + '\r\n') errcode, errmsg, headers = h.getreply() fp = h.getfile() --- 287,291 ---- h.endheaders() if data is not None: ! h.send(data) errcode, errmsg, headers = h.getreply() fp = h.getfile() *************** *** 365,369 **** h.endheaders() if data is not None: ! h.send(data + '\r\n') errcode, errmsg, headers = h.getreply() fp = h.getfile() --- 365,369 ---- h.endheaders() if data is not None: ! h.send(data) errcode, errmsg, headers = h.getreply() fp = h.getfile() From fdrake@users.sourceforge.net Wed Jul 4 06:18:31 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 03 Jul 2001 22:18:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib urllib2.py,1.14,1.15 urllib.py,1.126,1.127 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv11373/Lib Modified Files: urllib2.py urllib.py Log Message: Only write out one blank line before the request data. This closes SF patch #419459. Index: urllib2.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/urllib2.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -r1.14 -r1.15 *** urllib2.py 2001/05/09 15:49:24 1.14 --- urllib2.py 2001/07/04 05:18:29 1.15 *************** *** 810,814 **** h.endheaders() if req.has_data(): ! h.send(data + '\r\n') code, msg, hdrs = h.getreply() --- 810,814 ---- h.endheaders() if req.has_data(): ! h.send(data) code, msg, hdrs = h.getreply() Index: urllib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/urllib.py,v retrieving revision 1.126 retrieving revision 1.127 diff -C2 -r1.126 -r1.127 *** urllib.py 2001/04/15 20:47:33 1.126 --- urllib.py 2001/07/04 05:18:29 1.127 *************** *** 287,291 **** h.endheaders() if data is not None: ! h.send(data + '\r\n') errcode, errmsg, headers = h.getreply() fp = h.getfile() --- 287,291 ---- h.endheaders() if data is not None: ! h.send(data) errcode, errmsg, headers = h.getreply() fp = h.getfile() *************** *** 365,369 **** h.endheaders() if data is not None: ! h.send(data + '\r\n') errcode, errmsg, headers = h.getreply() fp = h.getfile() --- 365,369 ---- h.endheaders() if data is not None: ! h.send(data) errcode, errmsg, headers = h.getreply() fp = h.getfile() From fdrake@users.sourceforge.net Wed Jul 4 07:25:56 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 03 Jul 2001 23:25:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/xml/dom minidom.py,1.33,1.34 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/xml/dom In directory usw-pr-cvs1:/tmp/cvs-serv20887 Modified Files: minidom.py Log Message: Make the implementations of getElementsByTagName() and getElementsByTagNameNS() consistent in form as well as functionality (cosmetic). Index: minidom.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xml/dom/minidom.py,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -r1.33 -r1.34 *** minidom.py 2001/06/03 14:06:42 1.33 --- minidom.py 2001/07/04 06:25:53 1.34 *************** *** 552,558 **** def getElementsByTagNameNS(self, namespaceURI, localName): ! rc = [] ! _getElementsByTagNameNSHelper(self, namespaceURI, localName, rc) ! return rc def __repr__(self): --- 552,556 ---- def getElementsByTagNameNS(self, namespaceURI, localName): ! return _getElementsByTagNameNSHelper(self, namespaceURI, localName, []) def __repr__(self): *************** *** 882,894 **** return a - def getElementsByTagNameNS(self, namespaceURI, localName): - rc = [] - _getElementsByTagNameNSHelper(self, namespaceURI, localName, rc) - return rc - def getElementsByTagName(self, name): ! rc = [] ! _getElementsByTagNameHelper(self, name, rc) ! return rc def writexml(self, writer, indent="", addindent="", newl=""): --- 880,888 ---- return a def getElementsByTagName(self, name): ! return _getElementsByTagNameHelper(self, name, []) ! ! def getElementsByTagNameNS(self, namespaceURI, localName): ! return _getElementsByTagNameNSHelper(self, namespaceURI, localName, []) def writexml(self, writer, indent="", addindent="", newl=""): From jack@oratrix.nl Wed Jul 4 09:31:10 2001 From: jack@oratrix.nl (Jack Jansen) Date: Wed, 04 Jul 2001 10:31:10 +0200 Subject: [Python-checkins] CVS: python/dist/src/Include funcobject.h,2.23.4.1,2.23.4.2 In-Reply-To: Message by Guido van Rossum , Tue, 03 Jul 2001 17:14:00 -0700 , Message-ID: <20010704083115.C4454144B75@oratrix.oratrix.nl> Recently, Guido van Rossum said: > So I had to add static methods as well. [...] Je bent wel weer lekker bezig de laatste tijd, he... Ga ik Python nog wel herkennen als ik de descr branch uitcheck? Of krijgen we dan meteen ook begin/end statements? goto? :-) -- Jack Jansen | ++++ stop the execution of Mumia Abu-Jamal ++++ Jack.Jansen@oratrix.com | ++++ if you agree copy these lines to your sig ++++ www.oratrix.nl/~jack | see http://www.xs4all.nl/~tank/spg-l/sigaction.htm From tim_one@users.sourceforge.net Thu Jul 5 04:47:55 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 04 Jul 2001 20:47:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python import.c,2.177,2.178 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv29177/Python Modified Files: import.c Log Message: SF bug #438295: [Windows] __init__.py cause strange behavior Probable fix (the bug report doesn't have enough info to say for sure). find_init_module(): Insist on a case-sensitive match for __init__ files. Given __INIT__.PY instead, find_init_module() thought that was fine, but the later attempt to do find_module("__INIT__.PY") didn't and its caller silently suppressed the resulting ImportError. Now find_init_module() refuses to accept __INIT__.PY to begin with. Bugfix candidate; specific to platforms with case-insensitive filesystems. Index: import.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/import.c,v retrieving revision 2.177 retrieving revision 2.178 diff -C2 -r2.177 -r2.178 *** import.c 2001/04/29 22:21:25 2.177 --- import.c 2001/07/05 03:47:53 2.178 *************** *** 1195,1218 **** find_init_module(char *buf) { ! size_t save_len = strlen(buf); size_t i = save_len; struct stat statbuf; if (save_len + 13 >= MAXPATHLEN) return 0; buf[i++] = SEP; ! strcpy(buf+i, "__init__.py"); if (stat(buf, &statbuf) == 0) { ! buf[save_len] = '\0'; ! return 1; } ! i += strlen(buf+i); ! if (Py_OptimizeFlag) ! strcpy(buf+i, "o"); ! else ! strcpy(buf+i, "c"); if (stat(buf, &statbuf) == 0) { ! buf[save_len] = '\0'; ! return 1; } buf[save_len] = '\0'; --- 1195,1235 ---- find_init_module(char *buf) { ! const size_t save_len = strlen(buf); size_t i = save_len; + char *pname; /* pointer to start of __init__ */ struct stat statbuf; + /* For calling case_ok(buf, len, namelen, name): + * /a/b/c/d/e/f/g/h/i/j/k/some_long_module_name.py\0 + * ^ ^ ^ ^ + * |--------------------- buf ---------------------| + * |------------------- len ------------------| + * |------ name -------| + * |----- namelen -----| + */ if (save_len + 13 >= MAXPATHLEN) return 0; buf[i++] = SEP; ! pname = buf + i; ! strcpy(pname, "__init__.py"); if (stat(buf, &statbuf) == 0) { ! if (case_ok(buf, ! save_len + 9, /* len("/__init__") */ ! 8, /* len("__init__") */ ! pname)) { ! buf[save_len] = '\0'; ! return 1; ! } } ! i += strlen(pname); ! strcpy(buf+i, Py_OptimizeFlag ? "o" : "c"); if (stat(buf, &statbuf) == 0) { ! if (case_ok(buf, ! save_len + 9, /* len("/__init__") */ ! 8, /* len("__init__") */ ! pname)) { ! buf[save_len] = '\0'; ! return 1; ! } } buf[save_len] = '\0'; From jvr@users.sourceforge.net Thu Jul 5 08:03:18 2001 From: jvr@users.sourceforge.net (Just van Rossum) Date: Thu, 05 Jul 2001 00:03:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Tools/IDE MacPrefs.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Tools/IDE In directory usw-pr-cvs1:/tmp/cvs-serv26400 Modified Files: MacPrefs.py Log Message: don't crash when encountering bad marshal data Index: MacPrefs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/MacPrefs.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** MacPrefs.py 2001/03/15 14:33:24 1.2 --- MacPrefs.py 2001/07/05 07:03:16 1.3 *************** *** 51,55 **** try: prefdict = marshal.load(open(self.__path, 'rb')) ! except IOError: pass else: --- 51,56 ---- try: prefdict = marshal.load(open(self.__path, 'rb')) ! except (IOError, ValueError): ! # file not found, or currupt marshal data pass else: From jvr@users.sourceforge.net Thu Jul 5 08:06:28 2001 From: jvr@users.sourceforge.net (Just van Rossum) Date: Thu, 05 Jul 2001 00:06:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Tools/IDE PyEdit.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Tools/IDE In directory usw-pr-cvs1:/tmp/cvs-serv27144 Modified Files: PyEdit.py Log Message: - minor cleanup, removed bogus comments - make method reload handle __private attrs correctly - fixed whole word search Index: PyEdit.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PyEdit.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -r1.19 -r1.20 *** PyEdit.py 2001/06/19 21:37:33 1.19 --- PyEdit.py 2001/07/05 07:06:26 1.20 *************** *** 360,365 **** import EasyDialogs import Qd ! Qd.InitCursor() # XXX should be done by dialog ! save = EasyDialogs.AskYesNoCancel('Save window "%s" before closing?' % self.title, 1) if save > 0: if self.domenu_save(): --- 360,366 ---- import EasyDialogs import Qd ! Qd.InitCursor() ! save = EasyDialogs.AskYesNoCancel('Save window "%s" before closing?' % self.title, ! default=1, no="Don\xd5t save") if save > 0: if self.domenu_save(): *************** *** 367,371 **** elif save < 0: return 1 ! self.globals = None # XXX doesn't help... all globals leak :-( W.Window.close(self) --- 368,372 ---- elif save < 0: return 1 ! self.globals = None W.Window.close(self) *************** *** 565,575 **** raise W.AlertError, "Can't find a class." if globals.has_key(classname): ! locals = globals[classname].__dict__ else: raise W.AlertError, "Can't find class \"%s\"." % classname ! # dedent to top level ! for i in range(len(lines)): ! lines[i] = lines[i][1:] ! pytext = string.join(lines, '\r') elif indent > 0: raise W.AlertError, "Can't run indented code." --- 566,575 ---- raise W.AlertError, "Can't find a class." if globals.has_key(classname): ! klass = globals[classname] else: raise W.AlertError, "Can't find class \"%s\"." % classname ! # add class def ! pytext = ("class %s:\n" % classname) + pytext ! selfirstline = selfirstline - 1 elif indent > 0: raise W.AlertError, "Can't run indented code." *************** *** 579,582 **** --- 579,586 ---- pytext = selfirstline * '\r' + pytext self.execstring(pytext, globals, locals, file, modname) + if indent == 1 and globals[classname] is not klass: + # update the class in place + klass.__dict__.update(globals[classname].__dict__) + globals[classname] = klass def setthreadstate(self, state): *************** *** 787,791 **** def _makewholewordpattern(word): # first, escape special regex chars ! for esc in "\\[].*^+$?": word = _escape(word, esc) notwordcharspat = '[^' + _wordchars + ']' --- 791,795 ---- def _makewholewordpattern(word): # first, escape special regex chars ! for esc in "\\[]().*^+$?": word = _escape(word, esc) notwordcharspat = '[^' + _wordchars + ']' From gvanrossum@users.sourceforge.net Thu Jul 5 14:24:46 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 05 Jul 2001 06:24:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include rangeobject.h,2.16,2.17 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv8011 Modified Files: rangeobject.h Log Message: Rip out the fancy behaviors of xrange that nobody uses: repeat, slice, contains, tolist(), and the start/stop/step attributes. This includes removing the 4th ('repeat') argument to PyRange_New(). Index: rangeobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/rangeobject.h,v retrieving revision 2.16 retrieving revision 2.17 diff -C2 -r2.16 -r2.17 *** rangeobject.h 2001/06/05 05:58:44 2.16 --- rangeobject.h 2001/07/05 13:24:44 2.17 *************** *** 20,24 **** #define PyRange_Check(op) ((op)->ob_type == &PyRange_Type) ! extern DL_IMPORT(PyObject *) PyRange_New(long, long, long, int); #ifdef __cplusplus --- 20,24 ---- #define PyRange_Check(op) ((op)->ob_type == &PyRange_Type) ! extern DL_IMPORT(PyObject *) PyRange_New(long, long, long); #ifdef __cplusplus From gvanrossum@users.sourceforge.net Thu Jul 5 14:24:59 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 05 Jul 2001 06:24:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects rangeobject.c,2.24,2.25 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv8069 Modified Files: rangeobject.c Log Message: *** empty log message *** Index: rangeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/rangeobject.c,v retrieving revision 2.24 retrieving revision 2.25 diff -C2 -r2.24 -r2.25 *** rangeobject.c 2001/01/15 18:58:56 2.24 --- rangeobject.c 2001/07/05 13:24:56 2.25 *************** *** 11,55 **** long step; long len; - int reps; - long totlen; } rangeobject; - static int - long_mul(long i, long j, long *kk) - { - PyObject *a; - PyObject *b; - PyObject *c; - - if ((a = PyInt_FromLong(i)) == NULL) - return 0; - - if ((b = PyInt_FromLong(j)) == NULL) - return 0; - - c = PyNumber_Multiply(a, b); - - Py_DECREF(a); - Py_DECREF(b); - - if (c == NULL) - return 0; - - *kk = PyInt_AS_LONG(c); - Py_DECREF(c); - - if (*kk > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "integer multiplication"); - return 0; - } - else - return 1; - } - PyObject * ! PyRange_New(long start, long len, long step, int reps) { - long totlen = -1; rangeobject *obj = PyObject_NEW(rangeobject, &PyRange_Type); --- 11,19 ---- long step; long len; } rangeobject; PyObject * ! PyRange_New(long start, long len, long step) { rangeobject *obj = PyObject_NEW(rangeobject, &PyRange_Type); *************** *** 57,66 **** return NULL; ! if (len == 0 || reps <= 0) { start = 0; len = 0; step = 1; - reps = 1; - totlen = 0; } else { --- 21,28 ---- return NULL; ! if (len == 0) { start = 0; len = 0; step = 1; } else { *************** *** 72,81 **** "integer addition"); return NULL; - } - if (! long_mul(len, (long) reps, &totlen)) { - if(!PyErr_ExceptionMatches(PyExc_OverflowError)) - return NULL; - PyErr_Clear(); - totlen = -1; } } --- 34,37 ---- *************** *** 84,89 **** obj->len = len; obj->step = step; - obj->reps = reps; - obj->totlen = totlen; return (PyObject *) obj; --- 40,43 ---- *************** *** 99,108 **** range_item(rangeobject *r, int i) { ! if (i < 0 || i >= r->totlen) ! if (r->totlen!=-1) { ! PyErr_SetString(PyExc_IndexError, "xrange object index out of range"); ! return NULL; ! } return PyInt_FromLong(r->start + (i % r->len) * r->step); --- 53,61 ---- range_item(rangeobject *r, int i) { ! if (i < 0 || i >= r->len) { ! PyErr_SetString(PyExc_IndexError, "xrange object index out of range"); ! return NULL; ! } return PyInt_FromLong(r->start + (i % r->len) * r->step); *************** *** 112,119 **** range_length(rangeobject *r) { ! if (r->totlen == -1) ! PyErr_SetString(PyExc_OverflowError, ! "xrange object has too many items"); ! return r->totlen; } --- 65,69 ---- range_length(rangeobject *r) { ! return r->len; } *************** *** 125,129 **** */ char buf1[250]; - char buf2[250]; if (r->start == 0 && r->step == 1) --- 75,78 ---- *************** *** 140,312 **** r->start + r->len * r->step, r->step); - - if (r->reps != 1) - sprintf(buf2, "(%s * %d)", buf1, r->reps); - - return PyString_FromString(r->reps == 1 ? buf1 : buf2); - } - - static PyObject * - range_concat(rangeobject *r, PyObject *obj) - { - PyErr_SetString(PyExc_TypeError, "cannot concatenate xrange objects"); - return NULL; - } - - static PyObject * - range_repeat(rangeobject *r, int n) - { - long lreps = 0; - - if (n <= 0) - return (PyObject *) PyRange_New(0, 0, 1, 1); - - else if (n == 1) { - Py_INCREF(r); - return (PyObject *) r; - } - - else if (! long_mul((long) r->reps, (long) n, &lreps)) - return NULL; - - else - return (PyObject *) PyRange_New( - r->start, - r->len, - r->step, - (int) lreps); - } - - static int - range_compare(rangeobject *r1, rangeobject *r2) - { - if (r1->start != r2->start) - return r1->start - r2->start; - - else if (r1->step != r2->step) - return r1->step - r2->step; - - else if (r1->len != r2->len) - return r1->len - r2->len; - - else - return r1->reps - r2->reps; - } - - static PyObject * - range_slice(rangeobject *r, int low, int high) - { - if (r->reps != 1) { - PyErr_SetString(PyExc_TypeError, - "cannot slice a replicated xrange"); - return NULL; - } - if (low < 0) - low = 0; - else if (low > r->len) - low = r->len; - if (high < 0) - high = 0; - if (high < low) - high = low; - else if (high > r->len) - high = r->len; - - if (low == 0 && high == r->len) { - Py_INCREF(r); - return (PyObject *) r; - } - - return (PyObject *) PyRange_New( - low * r->step + r->start, - high - low, - r->step, - 1); - } - - static PyObject * - range_tolist(rangeobject *self, PyObject *args) - { - PyObject *thelist; - int j; - - if (! PyArg_ParseTuple(args, ":tolist")) - return NULL; - - if (self->totlen == -1) - return PyErr_NoMemory(); - - if ((thelist = PyList_New(self->totlen)) == NULL) - return NULL; ! for (j = 0; j < self->totlen; ++j) ! if ((PyList_SetItem(thelist, j, (PyObject *) PyInt_FromLong( ! self->start + (j % self->len) * self->step))) < 0) ! return NULL; ! ! return thelist; ! } ! ! static PyObject * ! range_getattr(rangeobject *r, char *name) ! { ! PyObject *result; ! ! static PyMethodDef range_methods[] = { ! {"tolist", (PyCFunction)range_tolist, METH_VARARGS, ! "tolist() -> list\n" ! "Return a list object with the same values."}, ! {NULL, NULL} ! }; ! static struct memberlist range_members[] = { ! {"step", T_LONG, offsetof(rangeobject, step), RO}, ! {"start", T_LONG, offsetof(rangeobject, start), RO}, ! {"stop", T_LONG, 0, RO}, ! {NULL, 0, 0, 0} ! }; ! ! result = Py_FindMethod(range_methods, (PyObject *) r, name); ! if (result == NULL) { ! PyErr_Clear(); ! if (strcmp("stop", name) == 0) ! result = PyInt_FromLong(r->start + (r->len * r->step)); ! else ! result = PyMember_Get((char *)r, range_members, name); ! } ! return result; ! } ! ! static int ! range_contains(rangeobject *r, PyObject *obj) ! { ! long num = PyInt_AsLong(obj); ! ! if (num < 0 && PyErr_Occurred()) ! return -1; ! ! if (r->step > 0) { ! if ((num < r->start) || ((num - r->start) % r->step)) ! return 0; ! if (num >= (r->start + (r->len * r->step))) ! return 0; ! } ! else { ! if ((num > r->start) || ((num - r->start) % r->step)) ! return 0; ! if (num <= (r->start + (r->len * r->step))) ! return 0; ! } ! return 1; } static PySequenceMethods range_as_sequence = { (inquiry)range_length, /*sq_length*/ ! (binaryfunc)range_concat, /*sq_concat*/ ! (intargfunc)range_repeat, /*sq_repeat*/ ! (intargfunc)range_item, /*sq_item*/ ! (intintargfunc)range_slice, /*sq_slice*/ 0, /*sq_ass_item*/ 0, /*sq_ass_slice*/ ! (objobjproc)range_contains, /*sq_contains*/ }; --- 89,105 ---- r->start + r->len * r->step, r->step); ! return PyString_FromString(buf1); } static PySequenceMethods range_as_sequence = { (inquiry)range_length, /*sq_length*/ ! 0, /*sq_concat*/ ! 0, /*sq_repeat*/ ! (intargfunc)range_item, /*sq_item*/ ! 0, /*sq_slice*/ 0, /*sq_ass_item*/ 0, /*sq_ass_slice*/ ! 0, /*sq_contains*/ }; *************** *** 319,325 **** (destructor)range_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ ! (getattrfunc)range_getattr, /*tp_getattr*/ 0, /*tp_setattr*/ ! (cmpfunc)range_compare, /*tp_compare*/ (reprfunc)range_repr, /*tp_repr*/ 0, /*tp_as_number*/ --- 112,118 ---- (destructor)range_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ ! 0, /*tp_getattr*/ 0, /*tp_setattr*/ ! 0, /*tp_compare*/ (reprfunc)range_repr, /*tp_repr*/ 0, /*tp_as_number*/ From gvanrossum@users.sourceforge.net Thu Jul 5 14:26:51 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 05 Jul 2001 06:26:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects rangeobject.c,2.24,2.25 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv8615 Modified Files: rangeobject.c Log Message: Rip out the fancy behaviors of xrange that nobody uses: repeat, slice, contains, tolist(), and the start/stop/step attributes. This includes removing the 4th ('repeat') argument to PyRange_New(). Index: rangeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/rangeobject.c,v retrieving revision 2.24 retrieving revision 2.25 diff -C2 -r2.24 -r2.25 *** rangeobject.c 2001/01/15 18:58:56 2.24 --- rangeobject.c 2001/07/05 13:26:49 2.25 *************** *** 11,55 **** long step; long len; - int reps; - long totlen; } rangeobject; - static int - long_mul(long i, long j, long *kk) - { - PyObject *a; - PyObject *b; - PyObject *c; - - if ((a = PyInt_FromLong(i)) == NULL) - return 0; - - if ((b = PyInt_FromLong(j)) == NULL) - return 0; - - c = PyNumber_Multiply(a, b); - - Py_DECREF(a); - Py_DECREF(b); - - if (c == NULL) - return 0; - - *kk = PyInt_AS_LONG(c); - Py_DECREF(c); - - if (*kk > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "integer multiplication"); - return 0; - } - else - return 1; - } - PyObject * ! PyRange_New(long start, long len, long step, int reps) { - long totlen = -1; rangeobject *obj = PyObject_NEW(rangeobject, &PyRange_Type); --- 11,19 ---- long step; long len; } rangeobject; PyObject * ! PyRange_New(long start, long len, long step) { rangeobject *obj = PyObject_NEW(rangeobject, &PyRange_Type); *************** *** 57,66 **** return NULL; ! if (len == 0 || reps <= 0) { start = 0; len = 0; step = 1; - reps = 1; - totlen = 0; } else { --- 21,28 ---- return NULL; ! if (len == 0) { start = 0; len = 0; step = 1; } else { *************** *** 72,81 **** "integer addition"); return NULL; - } - if (! long_mul(len, (long) reps, &totlen)) { - if(!PyErr_ExceptionMatches(PyExc_OverflowError)) - return NULL; - PyErr_Clear(); - totlen = -1; } } --- 34,37 ---- *************** *** 84,89 **** obj->len = len; obj->step = step; - obj->reps = reps; - obj->totlen = totlen; return (PyObject *) obj; --- 40,43 ---- *************** *** 99,108 **** range_item(rangeobject *r, int i) { ! if (i < 0 || i >= r->totlen) ! if (r->totlen!=-1) { ! PyErr_SetString(PyExc_IndexError, "xrange object index out of range"); ! return NULL; ! } return PyInt_FromLong(r->start + (i % r->len) * r->step); --- 53,61 ---- range_item(rangeobject *r, int i) { ! if (i < 0 || i >= r->len) { ! PyErr_SetString(PyExc_IndexError, "xrange object index out of range"); ! return NULL; ! } return PyInt_FromLong(r->start + (i % r->len) * r->step); *************** *** 112,119 **** range_length(rangeobject *r) { ! if (r->totlen == -1) ! PyErr_SetString(PyExc_OverflowError, ! "xrange object has too many items"); ! return r->totlen; } --- 65,69 ---- range_length(rangeobject *r) { ! return r->len; } *************** *** 125,129 **** */ char buf1[250]; - char buf2[250]; if (r->start == 0 && r->step == 1) --- 75,78 ---- *************** *** 140,312 **** r->start + r->len * r->step, r->step); - - if (r->reps != 1) - sprintf(buf2, "(%s * %d)", buf1, r->reps); - - return PyString_FromString(r->reps == 1 ? buf1 : buf2); - } - - static PyObject * - range_concat(rangeobject *r, PyObject *obj) - { - PyErr_SetString(PyExc_TypeError, "cannot concatenate xrange objects"); - return NULL; - } - - static PyObject * - range_repeat(rangeobject *r, int n) - { - long lreps = 0; - - if (n <= 0) - return (PyObject *) PyRange_New(0, 0, 1, 1); - - else if (n == 1) { - Py_INCREF(r); - return (PyObject *) r; - } - - else if (! long_mul((long) r->reps, (long) n, &lreps)) - return NULL; - - else - return (PyObject *) PyRange_New( - r->start, - r->len, - r->step, - (int) lreps); - } - - static int - range_compare(rangeobject *r1, rangeobject *r2) - { - if (r1->start != r2->start) - return r1->start - r2->start; - - else if (r1->step != r2->step) - return r1->step - r2->step; - - else if (r1->len != r2->len) - return r1->len - r2->len; - - else - return r1->reps - r2->reps; - } - - static PyObject * - range_slice(rangeobject *r, int low, int high) - { - if (r->reps != 1) { - PyErr_SetString(PyExc_TypeError, - "cannot slice a replicated xrange"); - return NULL; - } - if (low < 0) - low = 0; - else if (low > r->len) - low = r->len; - if (high < 0) - high = 0; - if (high < low) - high = low; - else if (high > r->len) - high = r->len; - - if (low == 0 && high == r->len) { - Py_INCREF(r); - return (PyObject *) r; - } - - return (PyObject *) PyRange_New( - low * r->step + r->start, - high - low, - r->step, - 1); - } - - static PyObject * - range_tolist(rangeobject *self, PyObject *args) - { - PyObject *thelist; - int j; - - if (! PyArg_ParseTuple(args, ":tolist")) - return NULL; - - if (self->totlen == -1) - return PyErr_NoMemory(); - - if ((thelist = PyList_New(self->totlen)) == NULL) - return NULL; ! for (j = 0; j < self->totlen; ++j) ! if ((PyList_SetItem(thelist, j, (PyObject *) PyInt_FromLong( ! self->start + (j % self->len) * self->step))) < 0) ! return NULL; ! ! return thelist; ! } ! ! static PyObject * ! range_getattr(rangeobject *r, char *name) ! { ! PyObject *result; ! ! static PyMethodDef range_methods[] = { ! {"tolist", (PyCFunction)range_tolist, METH_VARARGS, ! "tolist() -> list\n" ! "Return a list object with the same values."}, ! {NULL, NULL} ! }; ! static struct memberlist range_members[] = { ! {"step", T_LONG, offsetof(rangeobject, step), RO}, ! {"start", T_LONG, offsetof(rangeobject, start), RO}, ! {"stop", T_LONG, 0, RO}, ! {NULL, 0, 0, 0} ! }; ! ! result = Py_FindMethod(range_methods, (PyObject *) r, name); ! if (result == NULL) { ! PyErr_Clear(); ! if (strcmp("stop", name) == 0) ! result = PyInt_FromLong(r->start + (r->len * r->step)); ! else ! result = PyMember_Get((char *)r, range_members, name); ! } ! return result; ! } ! ! static int ! range_contains(rangeobject *r, PyObject *obj) ! { ! long num = PyInt_AsLong(obj); ! ! if (num < 0 && PyErr_Occurred()) ! return -1; ! ! if (r->step > 0) { ! if ((num < r->start) || ((num - r->start) % r->step)) ! return 0; ! if (num >= (r->start + (r->len * r->step))) ! return 0; ! } ! else { ! if ((num > r->start) || ((num - r->start) % r->step)) ! return 0; ! if (num <= (r->start + (r->len * r->step))) ! return 0; ! } ! return 1; } static PySequenceMethods range_as_sequence = { (inquiry)range_length, /*sq_length*/ ! (binaryfunc)range_concat, /*sq_concat*/ ! (intargfunc)range_repeat, /*sq_repeat*/ ! (intargfunc)range_item, /*sq_item*/ ! (intintargfunc)range_slice, /*sq_slice*/ 0, /*sq_ass_item*/ 0, /*sq_ass_slice*/ ! (objobjproc)range_contains, /*sq_contains*/ }; --- 89,105 ---- r->start + r->len * r->step, r->step); ! return PyString_FromString(buf1); } static PySequenceMethods range_as_sequence = { (inquiry)range_length, /*sq_length*/ ! 0, /*sq_concat*/ ! 0, /*sq_repeat*/ ! (intargfunc)range_item, /*sq_item*/ ! 0, /*sq_slice*/ 0, /*sq_ass_item*/ 0, /*sq_ass_slice*/ ! 0, /*sq_contains*/ }; *************** *** 319,325 **** (destructor)range_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ ! (getattrfunc)range_getattr, /*tp_getattr*/ 0, /*tp_setattr*/ ! (cmpfunc)range_compare, /*tp_compare*/ (reprfunc)range_repr, /*tp_repr*/ 0, /*tp_as_number*/ --- 112,118 ---- (destructor)range_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ ! 0, /*tp_getattr*/ 0, /*tp_setattr*/ ! 0, /*tp_compare*/ (reprfunc)range_repr, /*tp_repr*/ 0, /*tp_as_number*/ From gvanrossum@users.sourceforge.net Thu Jul 5 14:27:50 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 05 Jul 2001 06:27:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libstdtypes.tex,1.61,1.62 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv8933 Modified Files: libstdtypes.tex Log Message: Rip out the fancy behaviors of xrange that nobody uses: repeat, slice, contains, tolist(), and the start/stop/step attributes. This includes removing the 4th ('repeat') argument to PyRange_New(). Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.61 retrieving revision 1.62 diff -C2 -r1.61 -r1.62 *** libstdtypes.tex 2001/06/26 20:32:59 1.61 --- libstdtypes.tex 2001/07/05 13:27:48 1.62 *************** *** 776,785 **** advantages. ! XRange objects behave like tuples, and offer a single method: ! ! \begin{methoddesc}[xrange]{tolist}{} ! Return a list object which represents the same values as the xrange ! object. ! \end{methoddesc} --- 776,781 ---- advantages. ! XRange objects have very little behavior: they only support indexing ! and the \function{len()} function. From gvanrossum@users.sourceforge.net Thu Jul 5 15:16:37 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 05 Jul 2001 07:16:37 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0007.txt,NONE,1.1 pep-0000.txt,1.102,1.103 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv20945 Modified Files: pep-0000.txt Added Files: pep-0007.txt Log Message: Style Guide for C Code --- NEW FILE: pep-0007.txt --- PEP: 7 Title: Style Guide for C Code Version: $Revision: 1.1 $ Author: guido@python.org (Guido van Rossum) Status: Active Type: Informational Created: 05-Jul-2001 Post-History: Introduction This document gives coding conventions for the C code comprising the C implementation of Python. Note, rules are there to be broken. Two good reasons to break a particular rule: (1) When applying the rule would make the code less readable, even for someone who is used to reading code that follows the rules. (2) To be consistent with surrounding code that also breaks it (maybe for historic reasons) -- although this is also an opportunity to clean up someone else's mess (in true XP style). C dialect - Use ANSI/ISO standard C (the 1989 version of the standard). - Don't use GCC extensions (e.g. don't write multi-line strings without trailing backslashes). - All function declarations and definitions must use full prototypes (i.e. specify the types of all arguments). - Never use C++ style // one-line comments. - No compiler warnings with major compilers (gcc, VC++, a few others). Code lay-out - Use single-tab indents, where a tab is worth 8 spaces. - No line should be longer than 79 characters. If this and the previous rule together don't give you enough room to code, your code is too complicated -- consider using subroutines. - No line should end in whitespace. If you think you need significant trailing whitespace, think again -- somebody's editor might delete it as a matter of routine. - Function definition style: function name in column 1, outermost curly braces in column 1, blank line after local variable declarations. static int extra_ivars(PyTypeObject *type, PyTypeObject *base) { int t_size = PyType_BASICSIZE(type); int b_size = PyType_BASICSIZE(base); assert(t_size >= b_size); /* type smaller than base! */ ... return 1; } - Code structure: one space between keywords like 'if', 'for' and the following left paren; no spaces inside the paren; braces as shown: if (mro != NULL) { ... } else { ... } - The return statement should *not* get redundant parentheses: return Py_None; /* correct */ return(Py_None); /* incorrect */ - Function and macro call style: foo(a, b, c) -- no space before the open paren, no spaces inside the parens, no spaces before commas, one space after each comma. - Always put spaces around assignment, Boolean and comparison operators. In expressions using a lot of operators, add spaces around the outermost (lowest-priority) operators. - Breaking long lines: if you can, break after commas in the outermost argument list. Always indent continuation lines appropriately, e.g.: PyErr_Format(PyExc_TypeError, "cannot create '%.100s' instances", type->tp_name); - When you break a long expression at a binary operator, the operator goes at the end of the previous line, e.g.: if (type->tp_dictoffset != 0 && base->tp_dictoffset == 0 && type->tp_dictoffset == b_size && (size_t)t_size == b_size + sizeof(PyObject *)) return 0; /* "Forgive" adding a __dict__ only */ - Put blank lines around functions, structure definitions, and major sections inside functions. - Comments go before the code they describe. - All functions and global variables should be declared static unless they are to be part of a published interface - For external functions and variables, we always have a declaration in an appropriate header file in the "Include" directory, which uses the DL_IMPORT() macro, like this: extern DL_IMPORT(PyObject *) PyObject_Repr(PyObject *); Naming conventions - Use a Py prefix for public functions; never for static functions. The Py_ prefix is reserved for global service routines like Py_FatalError; specific groups of routines (e.g. specific object type APIs) use a longer prefix, e.g. PyString_ for string functions. - Public functions and variables use MixedCase with underscores, like this: PyObject_GetAttr, Py_BuildValue, PyExc_TypeError. - Occasionally an "internal" function has to be visible to the loader; we use the _Py prefix for this, e.g.: _PyObject_Dump. - Macros should have a MixedCase prefix and then use upper case, for example: PyString_AS_STRING, Py_PRINT_RAW. Copyright This document has been placed in the public domain. Local Variables: mode: indented-text indent-tabs-mode: nil End: Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.102 retrieving revision 1.103 diff -C2 -r1.102 -r1.103 *** pep-0000.txt 2001/06/27 23:12:54 1.102 --- pep-0000.txt 2001/07/05 14:16:35 1.103 *************** *** 29,32 **** --- 29,33 ---- I 5 pep-0005.txt Guidelines for Language Evolution Prescod I 6 pep-0006.txt Bug Fix Releases Aahz + I 7 pep-0007.txt Style Guide for C Code van Rossum Other Informational PEPs *************** *** 126,129 **** --- 127,131 ---- I 5 pep-0005.txt Guidelines for Language Evolution Prescod I 6 pep-0006.txt Bug Fix Releases Aahz + I 7 pep-0007.txt Style Guide for C Code van Rossum I 42 pep-0042.txt Small Feature Requests Hylton SF 100 pep-0100.txt Python Unicode Integration Lemburg From gvanrossum@users.sourceforge.net Thu Jul 5 15:44:43 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 05 Jul 2001 07:44:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.214,2.215 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv27892 Modified Files: bltinmodule.c Log Message: Complete the xrange-simplification checkins: call PyRange_New() with fewer arguments. Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.214 retrieving revision 2.215 diff -C2 -r2.214 -r2.215 *** bltinmodule.c 2001/06/27 18:59:43 2.214 --- bltinmodule.c 2001/07/05 14:44:41 2.215 *************** *** 1764,1768 **** return NULL; } ! return PyRange_New(ilow, n, istep, 1); } --- 1764,1768 ---- return NULL; } ! return PyRange_New(ilow, n, istep); } From gvanrossum@users.sourceforge.net Thu Jul 5 15:46:27 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 05 Jul 2001 07:46:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.187,1.188 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv28449 Modified Files: NEWS Log Message: News about xrange(). Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.187 retrieving revision 1.188 diff -C2 -r1.187 -r1.188 *** NEWS 2001/06/26 20:12:50 1.187 --- NEWS 2001/07/05 14:46:25 1.188 *************** *** 139,142 **** --- 139,146 ---- Library + - The xrange() object is simplified: it no longer supports slicing, + repetition, comparisons, efficient 'in' checking, the tolist() + method, or the start, stop and step attributes. See PEP 260. + - A new function fnmatch.filter to filter lists of file names was added. From gvanrossum@users.sourceforge.net Thu Jul 5 15:49:23 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 05 Jul 2001 07:49:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_b2.py,1.25,1.26 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv29289 Modified Files: test_b2.py Log Message: Rip out tests for xrange() features no longer supported. Index: test_b2.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_b2.py,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -r1.25 -r1.26 *** test_b2.py 2001/05/06 01:05:01 1.25 --- test_b2.py 2001/07/05 14:49:21 1.26 *************** *** 255,272 **** if tuple(xrange(0,10,2)) != tuple(range(0,10,2)): raise TestFailed, 'xrange(0,10,2)' - # regression tests for SourceForge bug #121695 - def _range_test(r): - verify(r.start != r.stop, 'Test not valid for passed-in xrange object.') - if r.stop in r: - raise TestFailed, 'r.stop in ' + `r` - if r.stop-r.step not in r: - raise TestFailed, 'r.stop-r.step not in ' + `r` - if r.start not in r: - raise TestFailed, 'r.start not in ' + `r` - if r.stop+r.step in r: - raise TestFailed, 'r.stop+r.step in ' + `r` - _range_test(xrange(10)) - _range_test(xrange(9, -1, -1)) - _range_test(xrange(0, 10, 2)) print 'zip' --- 255,258 ---- From gvanrossum@users.sourceforge.net Thu Jul 5 15:50:58 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 05 Jul 2001 07:50:58 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0260.txt,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv29722 Modified Files: pep-0260.txt Log Message: Mention changes to PyRange_New(). Index: pep-0260.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0260.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** pep-0260.txt 2001/06/26 17:57:11 1.1 --- pep-0260.txt 2001/07/05 14:50:56 1.2 *************** *** 44,58 **** x.start, x.stop, x.step attributes By implementing a custom iterator type, we could speed up the common use, but this is optional (the default sequence iterator does just fine). - I expect it will take at most an hour to rip it all out; another - hour to reduce the test suite and documentation. - Scope ! This PEP only affects the xrange() built-in function. --- 44,59 ---- x.start, x.stop, x.step attributes + I also propose to change the signature of the PyRange_New() C API + to remove the 4th argument (the repetition count). + By implementing a custom iterator type, we could speed up the common use, but this is optional (the default sequence iterator does just fine). Scope ! This PEP affects the xrange() built-in function and the ! PyRange_New() C API. From gvanrossum@users.sourceforge.net Thu Jul 5 16:27:22 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 05 Jul 2001 08:27:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libstdtypes.tex,1.62,1.63 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv7893 Modified Files: libstdtypes.tex Log Message: List constraints on xrange() objects. Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.62 retrieving revision 1.63 diff -C2 -r1.62 -r1.63 *** libstdtypes.tex 2001/07/05 13:27:48 1.62 --- libstdtypes.tex 2001/07/05 15:27:19 1.63 *************** *** 380,398 **** or without enclosing parentheses, but an empty tuple must have the enclosing parentheses, e.g., \code{a, b, c} or \code{()}. A single ! item tuple must have a trailing comma, e.g., \code{(d,)}. Buffers are ! not directly supported by Python syntax, but can be created by calling the ! builtin function \function{buffer()}.\bifuncindex{buffer} XRanges ! objects are similar to buffers in that there is no specific syntax to ! create them, but they are created using the \function{xrange()} ! function.\bifuncindex{xrange} \obindex{sequence} \obindex{string} \obindex{Unicode} - \obindex{buffer} \obindex{tuple} \obindex{list} \obindex{xrange} ! Sequence types support the following operations. The \samp{in} and \samp{not in} operations have the same priorities as the comparison operations. The \samp{+} and \samp{*} operations have the same --- 380,404 ---- or without enclosing parentheses, but an empty tuple must have the enclosing parentheses, e.g., \code{a, b, c} or \code{()}. A single ! item tuple must have a trailing comma, e.g., \code{(d,)}. \obindex{sequence} \obindex{string} \obindex{Unicode} \obindex{tuple} \obindex{list} + + Buffer objects are not directly supported by Python syntax, but can be + created by calling the builtin function + \function{buffer()}.\bifuncindex{buffer}. They don't support + concatenation or repetition. + \obindex{buffer} + + Xrange objects are similar to buffers in that there is no specific + syntax to create them, but they are created using the \function{xrange()} + function.\bifuncindex{xrange} They don't support slicing, + concatenation or repetition, and using \code{in}, \code{not in}, + \function{min()} or \function{max()} on them is inefficient. \obindex{xrange} ! Most sequence types support the following operations. The \samp{in} and \samp{not in} operations have the same priorities as the comparison operations. The \samp{+} and \samp{*} operations have the same From gvanrossum@users.sourceforge.net Thu Jul 5 17:25:54 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 05 Jul 2001 09:25:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python pythonrun.c,2.133.4.2,2.133.4.3 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv28656/Python Modified Files: Tag: descr-branch pythonrun.c Log Message: Initialize PyType_Type() early in the game. This fixes the problem Thomas Heller reported on python-dev. Index: pythonrun.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.133.4.2 retrieving revision 2.133.4.3 diff -C2 -r2.133.4.2 -r2.133.4.3 *** pythonrun.c 2001/06/29 14:03:27 2.133.4.2 --- pythonrun.c 2001/07/05 16:25:52 2.133.4.3 *************** *** 115,118 **** --- 115,121 ---- (void) PyThreadState_Swap(tstate); + if (PyType_InitDict(&PyType_Type) < 0) + Py_FatalError("Py_Initialize: can't initialize 'type'"); + interp->modules = PyDict_New(); if (interp->modules == NULL) From fdrake@users.sourceforge.net Thu Jul 5 17:34:39 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 05 Jul 2001 09:34:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libhtmllib.tex,1.22,1.23 libhtmlparser.tex,1.1,1.2 libsgmllib.tex,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv454/lib Modified Files: libhtmllib.tex libhtmlparser.tex libsgmllib.tex Log Message: Added more information on the differences between the htmllib and HTMLParser modules. Index: libhtmllib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libhtmllib.tex,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -r1.22 -r1.23 *** libhtmllib.tex 2000/07/16 19:01:09 1.22 --- libhtmllib.tex 2001/07/05 16:34:36 1.23 *************** *** 71,74 **** --- 71,80 ---- \begin{seealso} + \seemodule{HTMLParser}{Alternate HTML parser that offers a slightly + lower-level view of the input, but is + designed to work with XHTML, and does not + implement some of the SGML syntax not used in + ``HTML as deployed'' and which isn't legal + for XHTML.} \seemodule{htmlentitydefs}{Definition of replacement text for HTML 2.0 entities.} Index: libhtmlparser.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libhtmlparser.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** libhtmlparser.tex 2001/05/30 04:59:00 1.1 --- libhtmlparser.tex 2001/07/05 16:34:36 1.2 *************** *** 7,11 **** This module defines a class \class{HTMLParser} which serves as the basis for parsing text files formatted in HTML\index{HTML} (HyperText ! Mark-up Language) and XHTML.\index{XHTML} --- 7,13 ---- This module defines a class \class{HTMLParser} which serves as the basis for parsing text files formatted in HTML\index{HTML} (HyperText ! Mark-up Language) and XHTML.\index{XHTML} Unlike the parser in ! \refmodule{htmllib}, this parser is not based on the SGML parser in ! \refmodule{sgmllib}. *************** *** 16,19 **** --- 18,25 ---- when tags begin and end. The \class{HTMLParser} class is meant to be overridden by the user to provide a desired behavior. + + Unlike the parser in \refmodule{htmllib}, this parser does not check + that end tags match start tags or call the end-tag handler for + elements which are closed implicitly by closing an outer element. \end{classdesc} Index: libsgmllib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsgmllib.tex,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -r1.21 -r1.22 *** libsgmllib.tex 2001/03/16 20:39:41 1.21 --- libsgmllib.tex 2001/07/05 16:34:36 1.22 *************** *** 11,16 **** Mark-up Language). In fact, it does not provide a full SGML parser --- it only parses SGML insofar as it is used by HTML, and the module ! only exists as a base for the \refmodule{htmllib}\refstmodindex{htmllib} ! module. --- 11,17 ---- Mark-up Language). In fact, it does not provide a full SGML parser --- it only parses SGML insofar as it is used by HTML, and the module ! only exists as a base for the \refmodule{htmllib} module. Another ! HTML parser which supports XHTML and offers a somewhat different ! interface is available in the \refmodule{HTMLParser} module. From fdrake@users.sourceforge.net Thu Jul 5 19:21:59 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 05 Jul 2001 11:21:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib sgmllib.py,1.31,1.32 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv16084 Modified Files: sgmllib.py Log Message: Allow underscores in tag names and quote characters in unquoted attribute values. The change for attribute values matches the way Mozilla and Navigator view the world, at least. This closes SF bug #436621. Index: sgmllib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sgmllib.py,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -r1.31 -r1.32 *** sgmllib.py 2001/05/21 20:17:17 1.31 --- sgmllib.py 2001/07/05 18:21:57 1.32 *************** *** 35,42 **** commentopen = re.compile('', `line` i = 0 while i < len(line): i = Program.search(line, i) if i < 0: break found = Program.group(0) ## if Program is InsideCommentProgram: print '...', ## else: print ' ', ## print found if len(found) == 2: if found == '/*': Program = InsideCommentProgram elif found == '*/': Program = OutsideCommentProgram n = len(found) if Dict.has_key(found): subst = Dict[found] if Program is InsideCommentProgram: if not Docomments: print 'Found in comment:', found i = i + n continue if NotInComment.has_key(found): ## print 'Ignored in comment:', ## print found, '-->', subst ## print 'Line:', line, subst = found ## else: ## print 'Substituting in comment:', ## print found, '-->', subst ## print 'Line:', line, line = line[:i] + subst + line[i+n:] n = len(subst) i = i + n return line Docomments = 0 def setdocomments(): global Docomments Docomments = 1 Reverse = 0 def setreverse(): global Reverse Reverse = (not Reverse) Dict = {} NotInComment = {} def addsubst(substfile): try: fp = open(substfile, 'r') except IOError, msg: err(substfile + ': cannot read substfile: ' + str(msg) + '\n') sys.exit(1) lineno = 0 while 1: line = fp.readline() if not line: break lineno = lineno + 1 try: i = string.index(line, '#') except string.index_error: i = -1 # Happens to delete trailing \n words = string.split(line[:i]) if not words: continue if len(words) == 3 and words[0] == 'struct': words[:2] = [words[0] + ' ' + words[1]] elif len(words) <> 2: err(substfile + ':' + `lineno` + ': warning: bad line: ' + line) continue if Reverse: [value, key] = words else: [key, value] = words if value[0] == '*': value = value[1:] if key[0] == '*': key = key[1:] NotInComment[key] = value if Dict.has_key(key): err(substfile + ':' + `lineno` + ': warning: overriding: ' + key + ' ' + value + '\n') err(substfile + ':' + `lineno` + ': warning: previous: ' + Dict[key] + '\n') Dict[key] = value fp.close() main() --- NEW FILE: fixheader.py --- #! /usr/bin/env python # Add some standard cpp magic to a header file import sys import string def main(): args = sys.argv[1:] for file in args: process(file) def process(file): try: f = open(file, 'r') except IOError, msg: sys.stderr.write('%s: can\'t open: %s\n' % (file, str(msg))) return data = f.read() f.close() if data[:2] <> '/*': sys.stderr.write('%s does not begin with C comment\n' % file) return try: f = open(file, 'w') except IOError, msg: sys.stderr.write('%s: can\'t write: %s\n' % (file, str(msg))) return sys.stderr.write('Processing %s ...\n' % file) magic = 'Py_' for c in file: if c in string.letters + string.digits: magic = magic + string.upper(c) else: magic = magic + '_' sys.stdout = f print '#ifndef', magic print '#define', magic print '#ifdef __cplusplus' print 'extern "C" {' print '#endif' print f.write(data) print print '#ifdef __cplusplus' print '}' print '#endif' print '#endif /*', '!'+magic, '*/' main() --- NEW FILE: fixnotice.py --- #! /usr/bin/env python OLD_NOTICE = """/*********************************************************** Copyright (c) 2000, BeOpen.com. Copyright (c) 1995-2000, Corporation for National Research Initiatives. Copyright (c) 1990-1995, Stichting Mathematisch Centrum. All rights reserved. See the file "Misc/COPYRIGHT" for information on usage and redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. ******************************************************************/ """ NEW_NOTICE = "" # " <-- Help Emacs import os, sys, string def main(): args = sys.argv[1:] if not args: print "No arguments." for arg in args: process(arg) def process(arg): f = open(arg) data = f.read() f.close() i = string.find(data, OLD_NOTICE) if i < 0: ## print "No old notice in", arg return data = data[:i] + NEW_NOTICE + data[i+len(OLD_NOTICE):] new = arg + ".new" backup = arg + ".bak" print "Replacing notice in", arg, "...", sys.stdout.flush() f = open(new, "w") f.write(data) f.close() os.rename(arg, backup) os.rename(new, arg) print "done" if __name__ == '__main__': main() --- NEW FILE: fixps.py --- #!/usr/bin/env python # Fix Python script(s) to reference the interpreter via /usr/bin/env python. # Warning: this overwrites the file without making a backup. import sys import re def main(): for file in sys.argv[1:]: try: f = open(file, 'r') except IOError, msg: print file, ': can\'t open :', msg continue line = f.readline() if not re.match('^#! */usr/local/bin/python', line): print file, ': not a /usr/local/bin/python script' f.close() continue rest = f.read() f.close() line = re.sub('/usr/local/bin/python', '/usr/bin/env python', line) print file, ':', `line` f = open(file, "w") f.write(line) f.write(rest) f.close() main() --- NEW FILE: ftpmirror.py --- #! /usr/bin/env python """Mirror a remote ftp subtree into a local directory tree. usage: ftpmirror [-v] [-q] [-i] [-m] [-n] [-r] [-s pat] [-l username [-p passwd [-a account]]] hostname [remotedir [localdir]] -v: verbose -q: quiet -i: interactive mode -m: macintosh server (NCSA telnet 2.4) (implies -n -s '*.o') -n: don't log in -r: remove local files/directories no longer pertinent -l username [-p passwd [-a account]]: login info (default .netrc or anonymous) -s pat: skip files matching pattern hostname: remote host remotedir: remote directory (default initial) localdir: local directory (default current) """ import os import sys import time import getopt import string import ftplib import netrc from fnmatch import fnmatch # Print usage message and exit def usage(*args): sys.stdout = sys.stderr for msg in args: print msg print __doc__ sys.exit(2) verbose = 1 # 0 for -q, 2 for -v interactive = 0 mac = 0 rmok = 0 nologin = 0 skippats = ['.', '..', '.mirrorinfo'] # Main program: parse command line and start processing def main(): global verbose, interactive, mac, rmok, nologin try: opts, args = getopt.getopt(sys.argv[1:], 'a:bil:mnp:qrs:v') except getopt.error, msg: usage(msg) login = '' passwd = '' account = '' if not args: usage('hostname missing') host = args[0] try: auth = netrc.netrc().authenticators(host) if auth is not None: login, account, passwd = auth except (netrc.NetrcParseError, IOError): pass for o, a in opts: if o == '-l': login = a if o == '-p': passwd = a if o == '-a': account = a if o == '-v': verbose = verbose + 1 if o == '-q': verbose = 0 if o == '-i': interactive = 1 if o == '-m': mac = 1; nologin = 1; skippats.append('*.o') if o == '-n': nologin = 1 if o == '-r': rmok = 1 if o == '-s': skippats.append(a) remotedir = '' localdir = '' if args[1:]: remotedir = args[1] if args[2:]: localdir = args[2] if args[3:]: usage('too many arguments') # f = ftplib.FTP() if verbose: print 'Connecting to %s...' % `host` f.connect(host) if not nologin: if verbose: print 'Logging in as %s...' % `login or 'anonymous'` f.login(login, passwd, account) if verbose: print 'OK.' pwd = f.pwd() if verbose > 1: print 'PWD =', `pwd` if remotedir: if verbose > 1: print 'cwd(%s)' % `remotedir` f.cwd(remotedir) if verbose > 1: print 'OK.' pwd = f.pwd() if verbose > 1: print 'PWD =', `pwd` # mirrorsubdir(f, localdir) # Core logic: mirror one subdirectory (recursively) def mirrorsubdir(f, localdir): pwd = f.pwd() if localdir and not os.path.isdir(localdir): if verbose: print 'Creating local directory', `localdir` try: makedir(localdir) except os.error, msg: print "Failed to establish local directory", `localdir` return infofilename = os.path.join(localdir, '.mirrorinfo') try: text = open(infofilename, 'r').read() except IOError, msg: text = '{}' try: info = eval(text) except (SyntaxError, NameError): print 'Bad mirror info in %s' % `infofilename` info = {} subdirs = [] listing = [] if verbose: print 'Listing remote directory %s...' % `pwd` f.retrlines('LIST', listing.append) filesfound = [] for line in listing: if verbose > 1: print '-->', `line` if mac: # Mac listing has just filenames; # trailing / means subdirectory filename = string.strip(line) mode = '-' if filename[-1:] == '/': filename = filename[:-1] mode = 'd' infostuff = '' else: # Parse, assuming a UNIX listing words = string.split(line, None, 8) if len(words) < 6: if verbose > 1: print 'Skipping short line' continue filename = string.lstrip(words[-1]) i = string.find(filename, " -> ") if i >= 0: # words[0] had better start with 'l'... if verbose > 1: print 'Found symbolic link %s' % `filename` linkto = filename[i+4:] filename = filename[:i] infostuff = words[-5:-1] mode = words[0] skip = 0 for pat in skippats: if fnmatch(filename, pat): if verbose > 1: print 'Skip pattern', `pat`, print 'matches', `filename` skip = 1 break if skip: continue if mode[0] == 'd': if verbose > 1: print 'Remembering subdirectory', `filename` subdirs.append(filename) continue filesfound.append(filename) if info.has_key(filename) and info[filename] == infostuff: if verbose > 1: print 'Already have this version of',`filename` continue fullname = os.path.join(localdir, filename) tempname = os.path.join(localdir, '@'+filename) if interactive: doit = askabout('file', filename, pwd) if not doit: if not info.has_key(filename): info[filename] = 'Not retrieved' continue try: os.unlink(tempname) except os.error: pass if mode[0] == 'l': if verbose: print "Creating symlink %s -> %s" % ( `filename`, `linkto`) try: os.symlink(linkto, tempname) except IOError, msg: print "Can't create %s: %s" % ( `tempname`, str(msg)) continue else: try: fp = open(tempname, 'wb') except IOError, msg: print "Can't create %s: %s" % ( `tempname`, str(msg)) continue if verbose: print 'Retrieving %s from %s as %s...' % \ (`filename`, `pwd`, `fullname`) if verbose: fp1 = LoggingFile(fp, 1024, sys.stdout) else: fp1 = fp t0 = time.time() try: f.retrbinary('RETR ' + filename, fp1.write, 8*1024) except ftplib.error_perm, msg: print msg t1 = time.time() bytes = fp.tell() fp.close() if fp1 != fp: fp1.close() try: os.unlink(fullname) except os.error: pass # Ignore the error try: os.rename(tempname, fullname) except os.error, msg: print "Can't rename %s to %s: %s" % (`tempname`, `fullname`, str(msg)) continue info[filename] = infostuff writedict(info, infofilename) if verbose and mode[0] != 'l': dt = t1 - t0 kbytes = bytes / 1024.0 print int(round(kbytes)), print 'Kbytes in', print int(round(dt)), print 'seconds', if t1 > t0: print '(~%d Kbytes/sec)' % \ int(round(kbytes/dt),) print # # Remove files from info that are no longer remote deletions = 0 for filename in info.keys(): if filename not in filesfound: if verbose: print "Removing obsolete info entry for", print `filename`, "in", `localdir or "."` del info[filename] deletions = deletions + 1 if deletions: writedict(info, infofilename) # # Remove local files that are no longer in the remote directory try: if not localdir: names = os.listdir(os.curdir) else: names = os.listdir(localdir) except os.error: names = [] for name in names: if name[0] == '.' or info.has_key(name) or name in subdirs: continue skip = 0 for pat in skippats: if fnmatch(name, pat): if verbose > 1: print 'Skip pattern', `pat`, print 'matches', `name` skip = 1 break if skip: continue fullname = os.path.join(localdir, name) if not rmok: if verbose: print 'Local file', `fullname`, print 'is no longer pertinent' continue if verbose: print 'Removing local file/dir', `fullname` remove(fullname) # # Recursively mirror subdirectories for subdir in subdirs: if interactive: doit = askabout('subdirectory', subdir, pwd) if not doit: continue if verbose: print 'Processing subdirectory', `subdir` localsubdir = os.path.join(localdir, subdir) pwd = f.pwd() if verbose > 1: print 'Remote directory now:', `pwd` print 'Remote cwd', `subdir` try: f.cwd(subdir) except ftplib.error_perm, msg: print "Can't chdir to", `subdir`, ":", `msg` else: if verbose: print 'Mirroring as', `localsubdir` mirrorsubdir(f, localsubdir) if verbose > 1: print 'Remote cwd ..' f.cwd('..') newpwd = f.pwd() if newpwd != pwd: print 'Ended up in wrong directory after cd + cd ..' print 'Giving up now.' break else: if verbose > 1: print 'OK.' # Helper to remove a file or directory tree def remove(fullname): if os.path.isdir(fullname) and not os.path.islink(fullname): try: names = os.listdir(fullname) except os.error: names = [] ok = 1 for name in names: if not remove(os.path.join(fullname, name)): ok = 0 if not ok: return 0 try: os.rmdir(fullname) except os.error, msg: print "Can't remove local directory %s: %s" % \ (`fullname`, str(msg)) return 0 else: try: os.unlink(fullname) except os.error, msg: print "Can't remove local file %s: %s" % \ (`fullname`, str(msg)) return 0 return 1 # Wrapper around a file for writing to write a hash sign every block. class LoggingFile: def __init__(self, fp, blocksize, outfp): self.fp = fp self.bytes = 0 self.hashes = 0 self.blocksize = blocksize self.outfp = outfp def write(self, data): self.bytes = self.bytes + len(data) hashes = int(self.bytes) / self.blocksize while hashes > self.hashes: self.outfp.write('#') self.outfp.flush() self.hashes = self.hashes + 1 self.fp.write(data) def close(self): self.outfp.write('\n') # Ask permission to download a file. def askabout(filetype, filename, pwd): prompt = 'Retrieve %s %s from %s ? [ny] ' % (filetype, filename, pwd) while 1: reply = string.lower(string.strip(raw_input(prompt))) if reply in ['y', 'ye', 'yes']: return 1 if reply in ['', 'n', 'no', 'nop', 'nope']: return 0 print 'Please answer yes or no.' # Create a directory if it doesn't exist. Recursively create the # parent directory as well if needed. def makedir(pathname): if os.path.isdir(pathname): return dirname = os.path.dirname(pathname) if dirname: makedir(dirname) os.mkdir(pathname, 0777) # Write a dictionary to a file in a way that can be read back using # rval() but is still somewhat readable (i.e. not a single long line). # Also creates a backup file. def writedict(dict, filename): dir, file = os.path.split(filename) tempname = os.path.join(dir, '@' + file) backup = os.path.join(dir, file + '~') try: os.unlink(backup) except os.error: pass fp = open(tempname, 'w') fp.write('{\n') for key, value in dict.items(): fp.write('%s: %s,\n' % (`key`, `value`)) fp.write('}\n') fp.close() try: os.rename(filename, backup) except os.error: pass os.rename(tempname, filename) if __name__ == '__main__': main() --- NEW FILE: gencodec.py --- """ Unicode Mapping Parser and Codec Generator. This script parses Unicode mapping files as available from the Unicode site (ftp://ftp.unicode.org/Public/MAPPINGS/) and creates Python codec modules from them. The codecs use the standard character mapping codec to actually apply the mapping. Synopsis: gencodec.py dir codec_prefix All files in dir are scanned and those producing non-empty mappings will be written to .py with being the first part of the map's filename ('a' in a.b.c.txt) converted to lowercase with hyphens replaced by underscores. The tool also writes marshalled versions of the mapping tables to the same location (with .mapping extension). Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. (c) Copyright Guido van Rossum, 2000. """#" import string,re,os,time,marshal # Create numeric tables or character based ones ? numeric = 1 mapRE = re.compile('((?:0x[0-9a-fA-F]+\+?)+)' '\s+' '((?:(?:0x[0-9a-fA-Z]+|<[A-Za-z]+>)\+?)*)' '\s*' '(#.+)?') def parsecodes(codes, split=string.split,atoi=string.atoi,len=len, filter=filter,range=range): """ Converts code combinations to either a single code integer or a tuple of integers. meta-codes (in angular brackets, e.g. and ) are ignored. Empty codes or illegal ones are returned as None. """ if not codes: return None l = split(codes,'+') if len(l) == 1: return atoi(l[0],16) for i in range(len(l)): try: l[i] = atoi(l[i],16) except ValueError: l[i] = None l = filter(lambda x: x is not None, l) if len(l) == 1: return l[0] else: return tuple(l) def readmap(filename, strip=string.strip): f = open(filename,'r') lines = f.readlines() f.close() enc2uni = {} identity = [] unmapped = range(256) for i in range(256): unmapped[i] = i for line in lines: line = strip(line) if not line or line[0] == '#': continue m = mapRE.match(line) if not m: #print '* not matched: %s' % repr(line) continue enc,uni,comment = m.groups() enc = parsecodes(enc) uni = parsecodes(uni) if not comment: comment = '' else: comment = comment[1:] if enc < 256: unmapped.remove(enc) if enc == uni: identity.append(enc) else: enc2uni[enc] = (uni,comment) else: enc2uni[enc] = (uni,comment) # If there are more identity-mapped entries than unmapped entries, # it pays to generate an identity dictionary first, add add explicit # mappings to None for the rest if len(identity)>=len(unmapped): for enc in unmapped: enc2uni[enc] = (None, "") enc2uni['IDENTITY'] = 256 return enc2uni def hexrepr(t, join=string.join): if t is None: return 'None' try: len(t) except: return '0x%04x' % t return '(' + join(map(lambda t: '0x%04x' % t, t),', ') + ')' def unicoderepr(t, join=string.join): if t is None: return 'None' if numeric: return hexrepr(t) else: try: len(t) except: return repr(unichr(t)) return repr(join(map(unichr, t),'')) def keyrepr(t, join=string.join): if t is None: return 'None' if numeric: return hexrepr(t) else: try: len(t) except: if t < 256: return repr(chr(t)) else: return repr(unichr(t)) return repr(join(map(chr, t),'')) def codegen(name,map,comments=1): """ Returns Python source for the given map. Comments are included in the source, if comments is true (default). """ l = [ '''\ """ Python Character Mapping Codec generated from '%s' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. (c) Copyright 2000 Guido van Rossum. """#" import codecs ### Codec APIs class Codec(codecs.Codec): def encode(self,input,errors='strict'): return codecs.charmap_encode(input,errors,encoding_map) def decode(self,input,errors='strict'): return codecs.charmap_decode(input,errors,decoding_map) class StreamWriter(Codec,codecs.StreamWriter): pass class StreamReader(Codec,codecs.StreamReader): pass ### encodings module API def getregentry(): return (Codec().encode,Codec().decode,StreamReader,StreamWriter) ### Decoding Map ''' % name, ] if map.has_key("IDENTITY"): l.append("decoding_map = codecs.make_identity_dict(range(%d))" % map["IDENTITY"]) l.append("decoding_map.update({") splits = 1 del map["IDENTITY"] else: l.append("decoding_map = {") splits = 0 mappings = map.items() mappings.sort() append = l.append i = 0 for e,value in mappings: try: (u,c) = value except TypeError: u = value c = '' key = keyrepr(e) if c and comments: append('\t%s: %s,\t# %s' % (key,unicoderepr(u),c)) else: append('\t%s: %s,' % (key,unicoderepr(u))) i += 1 if i == 4096: # Split the definition into parts to that the Python # parser doesn't dump core if splits == 0: append('}') else: append('})') append('decoding_map.update({') i = 0 splits = splits + 1 if splits == 0: append('}') else: append('})') append(''' ### Encoding Map encoding_map = codecs.make_encoding_map(decoding_map) ''') return string.join(l,'\n') def pymap(name,map,pyfile,comments=1): code = codegen(name,map,comments) f = open(pyfile,'w') f.write(code) f.close() def marshalmap(name,map,marshalfile): d = {} for e,(u,c) in map.items(): d[e] = (u,c) f = open(marshalfile,'wb') marshal.dump(d,f) f.close() def convertdir(dir,prefix='',comments=1): mapnames = os.listdir(dir) for mapname in mapnames: name = os.path.split(mapname)[1] name = string.replace(name,'-','_') name = string.split(name, '.')[0] name = string.lower(name) codefile = name + '.py' marshalfile = name + '.mapping' print 'converting %s to %s and %s' % (mapname, prefix + codefile, prefix + marshalfile) try: map = readmap(os.path.join(dir,mapname)) if not map: print '* map is empty; skipping' else: pymap(mapname, map, prefix + codefile,comments) marshalmap(mapname, map, prefix + marshalfile) except ValueError: print '* conversion failed' def rewritepythondir(dir,prefix='',comments=1): mapnames = os.listdir(dir) for mapname in mapnames: if not mapname.endswith('.mapping'): continue codefile = mapname[:-len('.mapping')] + '.py' print 'converting %s to %s' % (mapname, prefix + codefile) try: map = marshal.load(open(os.path.join(dir,mapname), 'rb')) if not map: print '* map is empty; skipping' else: pymap(mapname, map, prefix + codefile,comments) except ValueError, why: print '* conversion failed: %s' % why if __name__ == '__main__': import sys if 1: apply(convertdir,tuple(sys.argv[1:])) else: apply(rewritepythondir,tuple(sys.argv[1:])) --- NEW FILE: h2py.py --- #! /usr/bin/env python # Read #define's and translate to Python code. # Handle #include statements. # Handle #define macros with one argument. # Anything that isn't recognized or doesn't translate into valid # Python is ignored. # Without filename arguments, acts as a filter. # If one or more filenames are given, output is written to corresponding # filenames in the local directory, translated to all uppercase, with # the extension replaced by ".py". # By passing one or more options of the form "-i regular_expression" # you can specify additional strings to be ignored. This is useful # e.g. to ignore casts to u_long: simply specify "-i '(u_long)'". # XXX To do: # - turn trailing C comments into Python comments # - turn C Boolean operators "&& || !" into Python "and or not" # - what to do about #if(def)? # - what to do about macros with multiple parameters? import sys, regex, regsub, string, getopt, os p_define = regex.compile('^[\t ]*#[\t ]*define[\t ]+\([a-zA-Z0-9_]+\)[\t ]+') p_macro = regex.compile( '^[\t ]*#[\t ]*define[\t ]+' '\([a-zA-Z0-9_]+\)(\([_a-zA-Z][_a-zA-Z0-9]*\))[\t ]+') p_include = regex.compile('^[\t ]*#[\t ]*include[\t ]+<\([a-zA-Z0-9_/\.]+\)') p_comment = regex.compile('/\*\([^*]+\|\*+[^/]\)*\(\*+/\)?') p_cpp_comment = regex.compile('//.*') ignores = [p_comment, p_cpp_comment] p_char = regex.compile("'\(\\\\.[^\\\\]*\|[^\\\\]\)'") filedict = {} try: searchdirs=string.splitfields(os.environ['include'],';') except KeyError: try: searchdirs=string.splitfields(os.environ['INCLUDE'],';') except KeyError: try: if string.find( sys.platform, "beos" ) == 0: searchdirs=string.splitfields(os.environ['BEINCLUDES'],';') else: raise KeyError except KeyError: searchdirs=['/usr/include'] def main(): global filedict opts, args = getopt.getopt(sys.argv[1:], 'i:') for o, a in opts: if o == '-i': ignores.append(regex.compile(a)) if not args: args = ['-'] for filename in args: if filename == '-': sys.stdout.write('# Generated by h2py from stdin\n') process(sys.stdin, sys.stdout) else: fp = open(filename, 'r') outfile = os.path.basename(filename) i = string.rfind(outfile, '.') if i > 0: outfile = outfile[:i] outfile = string.upper(outfile) outfile = outfile + '.py' outfp = open(outfile, 'w') outfp.write('# Generated by h2py from %s\n' % filename) filedict = {} for dir in searchdirs: if filename[:len(dir)] == dir: filedict[filename[len(dir)+1:]] = None # no '/' trailing break process(fp, outfp) outfp.close() fp.close() def process(fp, outfp, env = {}): lineno = 0 while 1: line = fp.readline() if not line: break lineno = lineno + 1 n = p_define.match(line) if n >= 0: # gobble up continuation lines while line[-2:] == '\\\n': nextline = fp.readline() if not nextline: break lineno = lineno + 1 line = line + nextline name = p_define.group(1) body = line[n:] # replace ignored patterns by spaces for p in ignores: body = regsub.gsub(p, ' ', body) # replace char literals by ord(...) body = regsub.gsub(p_char, 'ord(\\0)', body) stmt = '%s = %s\n' % (name, string.strip(body)) ok = 0 try: exec stmt in env except: sys.stderr.write('Skipping: %s' % stmt) else: outfp.write(stmt) n =p_macro.match(line) if n >= 0: macro, arg = p_macro.group(1, 2) body = line[n:] for p in ignores: body = regsub.gsub(p, ' ', body) body = regsub.gsub(p_char, 'ord(\\0)', body) stmt = 'def %s(%s): return %s\n' % (macro, arg, body) try: exec stmt in env except: sys.stderr.write('Skipping: %s' % stmt) else: outfp.write(stmt) if p_include.match(line) >= 0: regs = p_include.regs a, b = regs[1] filename = line[a:b] if not filedict.has_key(filename): filedict[filename] = None inclfp = None for dir in searchdirs: try: inclfp = open(dir + '/' + filename, 'r') break except IOError: pass if inclfp: outfp.write( '\n# Included from %s\n' % filename) process(inclfp, outfp, env) else: sys.stderr.write('Warning - could not find file %s' % filename) main() --- NEW FILE: ifdef.py --- #! /usr/bin/env python # Selectively preprocess #ifdef / #ifndef statements. # Usage: # ifdef [-Dname] ... [-Uname] ... [file] ... # # This scans the file(s), looking for #ifdef and #ifndef preprocessor # commands that test for one of the names mentioned in the -D and -U # options. On standard output it writes a copy of the input file(s) # minus those code sections that are suppressed by the selected # combination of defined/undefined symbols. The #if(n)def/#else/#else # lines themselfs (if the #if(n)def tests for one of the mentioned # names) are removed as well. # Features: Arbitrary nesting of recognized and unrecognized # preprocesor statements works correctly. Unrecognized #if* commands # are left in place, so it will never remove too much, only too # little. It does accept whitespace around the '#' character. # Restrictions: There should be no comments or other symbols on the # #if(n)def lines. The effect of #define/#undef commands in the input # file or in included files is not taken into account. Tests using # #if and the defined() pseudo function are not recognized. The #elif # command is not recognized. Improperly nesting is not detected. # Lines that look like preprocessor commands but which are actually # part of comments or string literals will be mistaken for # preprocessor commands. import sys import regex import getopt import string defs = [] undefs = [] def main(): opts, args = getopt.getopt(sys.argv[1:], 'D:U:') for o, a in opts: if o == '-D': defs.append(a) if o == '-U': undefs.append(a) if not args: args = ['-'] for file in args: if file == '-': process(sys.stdin, sys.stdout) else: f = open(file, 'r') process(f, sys.stdout) f.close() def process(fpi, fpo): keywords = ('if', 'ifdef', 'ifndef', 'else', 'endif') ok = 1 stack = [] while 1: line = fpi.readline() if not line: break while line[-2:] == '\\\n': nextline = fpi.readline() if not nextline: break line = line + nextline tmp = string.strip(line) if tmp[:1] != '#': if ok: fpo.write(line) continue tmp = string.strip(tmp[1:]) words = string.split(tmp) keyword = words[0] if keyword not in keywords: if ok: fpo.write(line) continue if keyword in ('ifdef', 'ifndef') and len(words) == 2: if keyword == 'ifdef': ko = 1 else: ko = 0 word = words[1] if word in defs: stack.append((ok, ko, word)) if not ko: ok = 0 elif word in undefs: stack.append((ok, not ko, word)) if ko: ok = 0 else: stack.append((ok, -1, word)) if ok: fpo.write(line) elif keyword == 'if': stack.append((ok, -1, '')) if ok: fpo.write(line) elif keyword == 'else' and stack: s_ok, s_ko, s_word = stack[-1] if s_ko < 0: if ok: fpo.write(line) else: s_ko = not s_ko ok = s_ok if not s_ko: ok = 0 stack[-1] = s_ok, s_ko, s_word elif keyword == 'endif' and stack: s_ok, s_ko, s_word = stack[-1] if s_ko < 0: if ok: fpo.write(line) del stack[-1] ok = s_ok else: sys.stderr.write('Unknown keyword %s\n' % keyword) if stack: sys.stderr.write('stack: %s\n' % stack) main() --- NEW FILE: lfcr.py --- #! /usr/bin/env python "Replace LF with CRLF in argument files. Print names of changed files." import sys, re, os for file in sys.argv[1:]: if os.path.isdir(file): print file, "Directory!" continue data = open(file, "rb").read() if '\0' in data: print file, "Binary!" continue newdata = re.sub("\r?\n", "\r\n", data) if newdata != data: print file f = open(file, "wb") f.write(newdata) f.close() --- NEW FILE: linktree.py --- #! /usr/bin/env python # linktree # # Make a copy of a directory tree with symbolic links to all files in the # original tree. # All symbolic links go to a special symbolic link at the top, so you # can easily fix things if the original source tree moves. # See also "mkreal". # # usage: mklinks oldtree newtree import sys, os LINK = '.LINK' # Name of special symlink at the top. debug = 0 def main(): if not 3 <= len(sys.argv) <= 4: print 'usage:', sys.argv[0], 'oldtree newtree [linkto]' return 2 oldtree, newtree = sys.argv[1], sys.argv[2] if len(sys.argv) > 3: link = sys.argv[3] link_may_fail = 1 else: link = LINK link_may_fail = 0 if not os.path.isdir(oldtree): print oldtree + ': not a directory' return 1 try: os.mkdir(newtree, 0777) except os.error, msg: print newtree + ': cannot mkdir:', msg return 1 linkname = os.path.join(newtree, link) try: os.symlink(os.path.join(os.pardir, oldtree), linkname) except os.error, msg: if not link_may_fail: print linkname + ': cannot symlink:', msg return 1 else: print linkname + ': warning: cannot symlink:', msg linknames(oldtree, newtree, link) return 0 def linknames(old, new, link): if debug: print 'linknames', (old, new, link) try: names = os.listdir(old) except os.error, msg: print old + ': warning: cannot listdir:', msg return for name in names: if name not in (os.curdir, os.pardir): oldname = os.path.join(old, name) linkname = os.path.join(link, name) newname = os.path.join(new, name) if debug > 1: print oldname, newname, linkname if os.path.isdir(oldname) and \ not os.path.islink(oldname): try: os.mkdir(newname, 0777) ok = 1 except: print newname + \ ': warning: cannot mkdir:', msg ok = 0 if ok: linkname = os.path.join(os.pardir, linkname) linknames(oldname, newname, linkname) else: os.symlink(linkname, newname) sys.exit(main()) --- NEW FILE: lll.py --- #! /usr/bin/env python # Find symbolic links and show where they point to. # Arguments are directories to search; default is current directory. # No recursion. # (This is a totally different program from "findsymlinks.py"!) import sys, os def lll(dirname): for name in os.listdir(dirname): if name not in (os.curdir, os.pardir): full = os.path.join(dirname, name) if os.path.islink(full): print name, '->', os.readlink(full) args = sys.argv[1:] if not args: args = [os.curdir] first = 1 for arg in args: if len(args) > 1: if not first: print first = 0 print arg + ':' lll(arg) --- NEW FILE: logmerge.py --- #! /usr/bin/env python """Consolidate a bunch of CVS or RCS logs read from stdin. Input should be the output of a CVS or RCS logging command, e.g. cvs log -rrelease14: which dumps all log messages from release1.4 upwards (assuming that release 1.4 was tagged with tag 'release14'). Note the trailing colon! This collects all the revision records and outputs them sorted by date rather than by file, collapsing duplicate revision record, i.e., records with the same message for different files. The -t option causes it to truncate (discard) the last revision log entry; this is useful when using something like the above cvs log command, which shows the revisions including the given tag, while you probably want everything *since* that tag. XXX This code was created by reverse engineering CVS 1.9 and RCS 5.7 from their output. """ import os, sys, getopt, string, re sep1 = '='*77 + '\n' # file separator sep2 = '-'*28 + '\n' # revision separator def main(): """Main program""" truncate_last = 0 reverse = 0 opts, args = getopt.getopt(sys.argv[1:], "tr") for o, a in opts: if o == '-t': truncate_last = 1 elif o == '-r': reverse = 1 database = [] while 1: chunk = read_chunk(sys.stdin) if not chunk: break records = digest_chunk(chunk) if truncate_last: del records[-1] database[len(database):] = records database.sort() if not reverse: database.reverse() format_output(database) def read_chunk(fp): """Read a chunk -- data for one file, ending with sep1. Split the chunk in parts separated by sep2. """ chunk = [] lines = [] while 1: line = fp.readline() if not line: break if line == sep1: if lines: chunk.append(lines) break if line == sep2: if lines: chunk.append(lines) lines = [] else: lines.append(line) return chunk def digest_chunk(chunk): """Digest a chunk -- extrach working file name and revisions""" lines = chunk[0] key = 'Working file:' keylen = len(key) for line in lines: if line[:keylen] == key: working_file = string.strip(line[keylen:]) break else: working_file = None records = [] for lines in chunk[1:]: revline = lines[0] dateline = lines[1] text = lines[2:] words = string.split(dateline) author = None if len(words) >= 3 and words[0] == 'date:': dateword = words[1] timeword = words[2] if timeword[-1:] == ';': timeword = timeword[:-1] date = dateword + ' ' + timeword if len(words) >= 5 and words[3] == 'author:': author = words[4] if author[-1:] == ';': author = author[:-1] else: date = None text.insert(0, revline) words = string.split(revline) if len(words) >= 2 and words[0] == 'revision': rev = words[1] else: rev = None text.insert(0, revline) records.append((date, working_file, rev, author, text)) return records def format_output(database): prevtext = None prev = [] database.append((None, None, None, None, None)) # Sentinel for (date, working_file, rev, author, text) in database: if text != prevtext: if prev: print sep2, for (p_date, p_working_file, p_rev, p_author) in prev: print p_date, p_author, p_working_file, p_rev sys.stdout.writelines(prevtext) prev = [] prev.append((date, working_file, rev, author)) prevtext = text main() --- NEW FILE: mailerdaemon.py --- """mailerdaemon - classes to parse mailer-daemon messages""" import string import rfc822 import calendar import re import os import sys Unparseable = 'mailerdaemon.Unparseable' class ErrorMessage(rfc822.Message): def __init__(self, fp): rfc822.Message.__init__(self, fp) self.sub = '' def is_warning(self): sub = self.getheader('Subject') if not sub: return 0 sub = string.lower(sub) if sub[:12] == 'waiting mail': return 1 if string.find(sub, 'warning') >= 0: return 1 self.sub = sub return 0 def get_errors(self): for p in EMPARSERS: self.rewindbody() try: return p(self.fp, self.sub) except Unparseable: pass raise Unparseable # List of re's or tuples of re's. # If a re, it should contain at least a group (?P...) which # should refer to the email address. The re can also contain a group # (?P...) which should refer to the reason (error message). # If no reason is present, the emparse_list_reason list is used to # find a reason. # If a tuple, the tuple should contain 2 re's. The first re finds a # location, the second re is repeated one or more times to find # multiple email addresses. The second re is matched (not searched) # where the previous match ended. # The re's are compiled using the re module. emparse_list_list = [ 'error: (?Punresolvable): (?P.+)', ('----- The following addresses had permanent fatal errors -----\n', '(?P[^ \n].*)\n( .*\n)?'), 'remote execution.*\n.*rmail (?P.+)', ('The following recipients did not receive your message:\n\n', ' +(?P.*)\n(The following recipients did not receive your message:\n\n)?'), '------- Failure Reasons --------\n\n(?P.*)\n(?P.*)', '^<(?P.*)>:\n(?P.*)', '^(?PUser mailbox exceeds allowed size): (?P.+)', '^5\\d{2} <(?P[^\n>]+)>\\.\\.\\. (?P.+)', '^Original-Recipient: rfc822;(?P.*)', '^did not reach the following recipient\\(s\\):\n\n(?P.*) on .*\n +(?P.*)', '^ <(?P[^\n>]+)> \\.\\.\\. (?P.*)', '^Report on your message to: (?P.*)\nReason: (?P.*)', '^Your message was not delivered to +(?P.*)\n +for the following reason:\n +(?P.*)', '^ was not +(?P[^ \n].*?) *\n.*\n.*\n.*\n because:.*\n +(?P[^ \n].*?) *\n', ] # compile the re's in the list and store them in-place. for i in range(len(emparse_list_list)): x = emparse_list_list[i] if type(x) is type(''): x = re.compile(x, re.MULTILINE) else: xl = [] for x in x: xl.append(re.compile(x, re.MULTILINE)) x = tuple(xl) del xl emparse_list_list[i] = x del x del i # list of re's used to find reasons (error messages). # if a string, "<>" is replaced by a copy of the email address. # The expressions are searched for in order. After the first match, # no more expressions are searched for. So, order is important. emparse_list_reason = [ r'^5\d{2} <>\.\.\. (?P.*)', '<>\.\.\. (?P.*)', re.compile(r'^<<< 5\d{2} (?P.*)', re.MULTILINE), re.compile('===== stderr was =====\nrmail: (?P.*)'), re.compile('^Diagnostic-Code: (?P.*)', re.MULTILINE), ] emparse_list_from = re.compile('^From:', re.IGNORECASE|re.MULTILINE) def emparse_list(fp, sub): data = fp.read() res = emparse_list_from.search(data) if res is None: from_index = len(data) else: from_index = res.start(0) errors = [] emails = [] reason = None for regexp in emparse_list_list: if type(regexp) is type(()): res = regexp[0].search(data, 0, from_index) if res is not None: try: reason = res.group('reason') except IndexError: pass while 1: res = regexp[1].match(data, res.end(0), from_index) if res is None: break emails.append(res.group('email')) break else: res = regexp.search(data, 0, from_index) if res is not None: emails.append(res.group('email')) try: reason = res.group('reason') except IndexError: pass break if not emails: raise Unparseable if not reason: reason = sub if reason[:15] == 'returned mail: ': reason = reason[15:] for regexp in emparse_list_reason: if type(regexp) is type(''): for i in range(len(emails)-1,-1,-1): email = emails[i] exp = re.compile(string.join(string.split(regexp, '<>'), re.escape(email)), re.MULTILINE) res = exp.search(data) if res is not None: errors.append(string.join(string.split(string.strip(email)+': '+res.group('reason')))) del emails[i] continue res = regexp.search(data) if res is not None: reason = res.group('reason') break for email in emails: errors.append(string.join(string.split(string.strip(email)+': '+reason))) return errors EMPARSERS = [emparse_list, ] def sort_numeric(a, b): a = string.atoi(a) b = string.atoi(b) if a < b: return -1 elif a > b: return 1 else: return 0 def parsedir(dir, modify): os.chdir(dir) pat = re.compile('^[0-9]*$') errordict = {} errorfirst = {} errorlast = {} nok = nwarn = nbad = 0 # find all numeric file names and sort them files = filter(lambda fn, pat=pat: pat.match(fn) is not None, os.listdir('.')) files.sort(sort_numeric) for fn in files: # Lets try to parse the file. fp = open(fn) m = ErrorMessage(fp) sender = m.getaddr('From') print '%s\t%-40s\t'%(fn, sender[1]), if m.is_warning(): fp.close() print 'warning only' nwarn = nwarn + 1 if modify: os.rename(fn, ','+fn) ## os.unlink(fn) continue try: errors = m.get_errors() except Unparseable: print '** Not parseable' nbad = nbad + 1 fp.close() continue print len(errors), 'errors' # Remember them for e in errors: try: mm, dd = m.getdate('date')[1:1+2] date = '%s %02d' % (calendar.month_abbr[mm], dd) except: date = '??????' if not errordict.has_key(e): errordict[e] = 1 errorfirst[e] = '%s (%s)' % (fn, date) else: errordict[e] = errordict[e] + 1 errorlast[e] = '%s (%s)' % (fn, date) fp.close() nok = nok + 1 if modify: os.rename(fn, ','+fn) ## os.unlink(fn) print '--------------' print nok, 'files parsed,',nwarn,'files warning-only,', print nbad,'files unparseable' print '--------------' list = [] for e in errordict.keys(): list.append((errordict[e], errorfirst[e], errorlast[e], e)) list.sort() for num, first, last, e in list: print '%d %s - %s\t%s' % (num, first, last, e) def main(): modify = 0 if len(sys.argv) > 1 and sys.argv[1] == '-d': modify = 1 del sys.argv[1] if len(sys.argv) > 1: for folder in sys.argv[1:]: parsedir(folder, modify) else: parsedir('/ufs/jack/Mail/errorsinbox', modify) if __name__ == '__main__' or sys.argv[0] == __name__: main() --- NEW FILE: md5sum.py --- #! /usr/bin/env python """Python utility to print MD5 checksums of argument files. Works with Python 1.5.2 and later. """ import sys, md5 BLOCKSIZE = 1024*1024 def hexify(s): return ("%02x"*len(s)) % tuple(map(ord, s)) def main(): args = sys.argv[1:] if not args: sys.stderr.write("usage: %s file ...\n" % sys.argv[0]) sys.exit(2) for file in sys.argv[1:]: f = open(file, "rb") sum = md5.new() while 1: block = f.read(BLOCKSIZE) if not block: break sum.update(block) f.close() print hexify(sum.digest()), file if __name__ == "__main__": main() --- NEW FILE: methfix.py --- #! /usr/bin/env python # Fix Python source files to avoid using # def method(self, (arg1, ..., argn)): # instead of the more rational # def method(self, arg1, ..., argn): # # Command line arguments are files or directories to be processed. # Directories are searched recursively for files whose name looks # like a python module. # Symbolic links are always ignored (except as explicit directory # arguments). Of course, the original file is kept as a back-up # (with a "~" attached to its name). # It complains about binaries (files containing null bytes) # and about files that are ostensibly not Python files: if the first # line starts with '#!' and does not contain the string 'python'. # # Changes made are reported to stdout in a diff-like format. # # Undoubtedly you can do this using find and sed or perl, but this is # a nice example of Python code that recurses down a directory tree # and uses regular expressions. Also note several subtleties like # preserving the file's mode and avoiding to even write a temp file # when no changes are needed for a file. # # NB: by changing only the function fixline() you can turn this # into a program for a different change to Python programs... import sys import regex import os from stat import * import string err = sys.stderr.write dbg = err rep = sys.stdout.write def main(): bad = 0 if not sys.argv[1:]: # No arguments err('usage: ' + sys.argv[0] + ' file-or-directory ...\n') sys.exit(2) for arg in sys.argv[1:]: if os.path.isdir(arg): if recursedown(arg): bad = 1 elif os.path.islink(arg): err(arg + ': will not process symbolic links\n') bad = 1 else: if fix(arg): bad = 1 sys.exit(bad) ispythonprog = regex.compile('^[a-zA-Z0-9_]+\.py$') def ispython(name): return ispythonprog.match(name) >= 0 def recursedown(dirname): dbg('recursedown(' + `dirname` + ')\n') bad = 0 try: names = os.listdir(dirname) except os.error, msg: err(dirname + ': cannot list directory: ' + `msg` + '\n') return 1 names.sort() subdirs = [] for name in names: if name in (os.curdir, os.pardir): continue fullname = os.path.join(dirname, name) if os.path.islink(fullname): pass elif os.path.isdir(fullname): subdirs.append(fullname) elif ispython(name): if fix(fullname): bad = 1 for fullname in subdirs: if recursedown(fullname): bad = 1 return bad def fix(filename): ## dbg('fix(' + `filename` + ')\n') try: f = open(filename, 'r') except IOError, msg: err(filename + ': cannot open: ' + `msg` + '\n') return 1 head, tail = os.path.split(filename) tempname = os.path.join(head, '@' + tail) g = None # If we find a match, we rewind the file and start over but # now copy everything to a temp file. lineno = 0 while 1: line = f.readline() if not line: break lineno = lineno + 1 if g is None and '\0' in line: # Check for binary files err(filename + ': contains null bytes; not fixed\n') f.close() return 1 if lineno == 1 and g is None and line[:2] == '#!': # Check for non-Python scripts words = string.split(line[2:]) if words and regex.search('[pP]ython', words[0]) < 0: msg = filename + ': ' + words[0] msg = msg + ' script; not fixed\n' err(msg) f.close() return 1 while line[-2:] == '\\\n': nextline = f.readline() if not nextline: break line = line + nextline lineno = lineno + 1 newline = fixline(line) if newline != line: if g is None: try: g = open(tempname, 'w') except IOError, msg: f.close() err(tempname+': cannot create: '+\ `msg`+'\n') return 1 f.seek(0) lineno = 0 rep(filename + ':\n') continue # restart from the beginning rep(`lineno` + '\n') rep('< ' + line) rep('> ' + newline) if g is not None: g.write(newline) # End of file f.close() if not g: return 0 # No changes # Finishing touch -- move files # First copy the file's mode to the temp file try: statbuf = os.stat(filename) os.chmod(tempname, statbuf[ST_MODE] & 07777) except os.error, msg: err(tempname + ': warning: chmod failed (' + `msg` + ')\n') # Then make a backup of the original file as filename~ try: os.rename(filename, filename + '~') except os.error, msg: err(filename + ': warning: backup failed (' + `msg` + ')\n') # Now move the temp file to the original file try: os.rename(tempname, filename) except os.error, msg: err(filename + ': rename failed (' + `msg` + ')\n') return 1 # Return succes return 0 fixpat = '^[ \t]+def +[a-zA-Z0-9_]+ *( *self *, *\(( *\(.*\) *)\) *) *:' fixprog = regex.compile(fixpat) def fixline(line): if fixprog.match(line) >= 0: (a, b), (c, d) = fixprog.regs[1:3] line = line[:a] + line[c:d] + line[b:] return line main() --- NEW FILE: mkreal.py --- #! /usr/bin/env python # mkreal # # turn a symlink to a directory into a real directory import sys import os from stat import * join = os.path.join error = 'mkreal error' BUFSIZE = 32*1024 def mkrealfile(name): st = os.stat(name) # Get the mode mode = S_IMODE(st[ST_MODE]) linkto = os.readlink(name) # Make sure again it's a symlink f_in = open(name, 'r') # This ensures it's a file os.unlink(name) f_out = open(name, 'w') while 1: buf = f_in.read(BUFSIZE) if not buf: break f_out.write(buf) del f_out # Flush data to disk before changing mode os.chmod(name, mode) def mkrealdir(name): st = os.stat(name) # Get the mode mode = S_IMODE(st[ST_MODE]) linkto = os.readlink(name) files = os.listdir(name) os.unlink(name) os.mkdir(name, mode) os.chmod(name, mode) linkto = join(os.pardir, linkto) # for file in files: if file not in (os.curdir, os.pardir): os.symlink(join(linkto, file), join(name, file)) def main(): sys.stdout = sys.stderr progname = os.path.basename(sys.argv[0]) if progname == '-c': progname = 'mkreal' args = sys.argv[1:] if not args: print 'usage:', progname, 'path ...' sys.exit(2) status = 0 for name in args: if not os.path.islink(name): print progname+':', name+':', 'not a symlink' status = 1 else: if os.path.isdir(name): mkrealdir(name) else: mkrealfile(name) sys.exit(status) main() --- NEW FILE: ndiff.py --- #! /usr/bin/env python # Module ndiff version 1.6.0 # Released to the public domain 08-Dec-2000, # by Tim Peters (tim.one@home.com). # Provided as-is; use at your own risk; no warranty; no promises; enjoy! """ndiff [-q] file1 file2 or ndiff (-r1 | -r2) < ndiff_output > file1_or_file2 Print a human-friendly file difference report to stdout. Both inter- and intra-line differences are noted. In the second form, recreate file1 (-r1) or file2 (-r2) on stdout, from an ndiff report on stdin. In the first form, if -q ("quiet") is not specified, the first two lines of output are -: file1 +: file2 Each remaining line begins with a two-letter code: "- " line unique to file1 "+ " line unique to file2 " " line common to both files "? " line not present in either input file Lines beginning with "? " attempt to guide the eye to intraline differences, and were not present in either input file. These lines can be confusing if the source files contain tab characters. The first file can be recovered by retaining only lines that begin with " " or "- ", and deleting those 2-character prefixes; use ndiff with -r1. The second file can be recovered similarly, but by retaining only " " and "+ " lines; use ndiff with -r2; or, on Unix, the second file can be recovered by piping the output through sed -n '/^[+ ] /s/^..//p' See module comments for details and programmatic interface. """ __version__ = 1, 5, 0 # SequenceMatcher tries to compute a "human-friendly diff" between # two sequences (chiefly picturing a file as a sequence of lines, # and a line as a sequence of characters, here). Unlike e.g. UNIX(tm) # diff, the fundamental notion is the longest *contiguous* & junk-free # matching subsequence. That's what catches peoples' eyes. The # Windows(tm) windiff has another interesting notion, pairing up elements # that appear uniquely in each sequence. That, and the method here, # appear to yield more intuitive difference reports than does diff. This # method appears to be the least vulnerable to synching up on blocks # of "junk lines", though (like blank lines in ordinary text files, # or maybe "

" lines in HTML files). That may be because this is # the only method of the 3 that has a *concept* of "junk" . # # Note that ndiff makes no claim to produce a *minimal* diff. To the # contrary, minimal diffs are often counter-intuitive, because they # synch up anywhere possible, sometimes accidental matches 100 pages # apart. Restricting synch points to contiguous matches preserves some # notion of locality, at the occasional cost of producing a longer diff. # # With respect to junk, an earlier version of ndiff simply refused to # *start* a match with a junk element. The result was cases like this: # before: private Thread currentThread; # after: private volatile Thread currentThread; # If you consider whitespace to be junk, the longest contiguous match # not starting with junk is "e Thread currentThread". So ndiff reported # that "e volatil" was inserted between the 't' and the 'e' in "private". # While an accurate view, to people that's absurd. The current version # looks for matching blocks that are entirely junk-free, then extends the # longest one of those as far as possible but only with matching junk. # So now "currentThread" is matched, then extended to suck up the # preceding blank; then "private" is matched, and extended to suck up the # following blank; then "Thread" is matched; and finally ndiff reports # that "volatile " was inserted before "Thread". The only quibble # remaining is that perhaps it was really the case that " volatile" # was inserted after "private". I can live with that . # # NOTE on junk: the module-level names # IS_LINE_JUNK # IS_CHARACTER_JUNK # can be set to any functions you like. The first one should accept # a single string argument, and return true iff the string is junk. # The default is whether the regexp r"\s*#?\s*$" matches (i.e., a # line without visible characters, except for at most one splat). # The second should accept a string of length 1 etc. The default is # whether the character is a blank or tab (note: bad idea to include # newline in this!). # # After setting those, you can call fcompare(f1name, f2name) with the # names of the files you want to compare. The difference report # is sent to stdout. Or you can call main(args), passing what would # have been in sys.argv[1:] had the cmd-line form been used. from difflib import SequenceMatcher import string TRACE = 0 # define what "junk" means import re def IS_LINE_JUNK(line, pat=re.compile(r"\s*#?\s*$").match): return pat(line) is not None def IS_CHARACTER_JUNK(ch, ws=" \t"): return ch in ws del re # meant for dumping lines def dump(tag, x, lo, hi): for i in xrange(lo, hi): print tag, x[i], def plain_replace(a, alo, ahi, b, blo, bhi): assert alo < ahi and blo < bhi # dump the shorter block first -- reduces the burden on short-term # memory if the blocks are of very different sizes if bhi - blo < ahi - alo: dump('+', b, blo, bhi) dump('-', a, alo, ahi) else: dump('-', a, alo, ahi) dump('+', b, blo, bhi) # When replacing one block of lines with another, this guy searches # the blocks for *similar* lines; the best-matching pair (if any) is # used as a synch point, and intraline difference marking is done on # the similar pair. Lots of work, but often worth it. def fancy_replace(a, alo, ahi, b, blo, bhi): if TRACE: print '*** fancy_replace', alo, ahi, blo, bhi dump('>', a, alo, ahi) dump('<', b, blo, bhi) # don't synch up unless the lines have a similarity score of at # least cutoff; best_ratio tracks the best score seen so far best_ratio, cutoff = 0.74, 0.75 cruncher = SequenceMatcher(IS_CHARACTER_JUNK) eqi, eqj = None, None # 1st indices of equal lines (if any) # search for the pair that matches best without being identical # (identical lines must be junk lines, & we don't want to synch up # on junk -- unless we have to) for j in xrange(blo, bhi): bj = b[j] cruncher.set_seq2(bj) for i in xrange(alo, ahi): ai = a[i] if ai == bj: if eqi is None: eqi, eqj = i, j continue cruncher.set_seq1(ai) # computing similarity is expensive, so use the quick # upper bounds first -- have seen this speed up messy # compares by a factor of 3. # note that ratio() is only expensive to compute the first # time it's called on a sequence pair; the expensive part # of the computation is cached by cruncher if cruncher.real_quick_ratio() > best_ratio and \ cruncher.quick_ratio() > best_ratio and \ cruncher.ratio() > best_ratio: best_ratio, best_i, best_j = cruncher.ratio(), i, j if best_ratio < cutoff: # no non-identical "pretty close" pair if eqi is None: # no identical pair either -- treat it as a straight replace plain_replace(a, alo, ahi, b, blo, bhi) return # no close pair, but an identical pair -- synch up on that best_i, best_j, best_ratio = eqi, eqj, 1.0 else: # there's a close pair, so forget the identical pair (if any) eqi = None # a[best_i] very similar to b[best_j]; eqi is None iff they're not # identical if TRACE: print '*** best_ratio', best_ratio, best_i, best_j dump('>', a, best_i, best_i+1) dump('<', b, best_j, best_j+1) # pump out diffs from before the synch point fancy_helper(a, alo, best_i, b, blo, best_j) # do intraline marking on the synch pair aelt, belt = a[best_i], b[best_j] if eqi is None: # pump out a '-', '?', '+', '?' quad for the synched lines atags = btags = "" cruncher.set_seqs(aelt, belt) for tag, ai1, ai2, bj1, bj2 in cruncher.get_opcodes(): la, lb = ai2 - ai1, bj2 - bj1 if tag == 'replace': atags += '^' * la btags += '^' * lb elif tag == 'delete': atags += '-' * la elif tag == 'insert': btags += '+' * lb elif tag == 'equal': atags += ' ' * la btags += ' ' * lb else: raise ValueError, 'unknown tag ' + `tag` printq(aelt, belt, atags, btags) else: # the synch pair is identical print ' ', aelt, # pump out diffs from after the synch point fancy_helper(a, best_i+1, ahi, b, best_j+1, bhi) def fancy_helper(a, alo, ahi, b, blo, bhi): if alo < ahi: if blo < bhi: fancy_replace(a, alo, ahi, b, blo, bhi) else: dump('-', a, alo, ahi) elif blo < bhi: dump('+', b, blo, bhi) # Crap to deal with leading tabs in "?" output. Can hurt, but will # probably help most of the time. def printq(aline, bline, atags, btags): common = min(count_leading(aline, "\t"), count_leading(bline, "\t")) common = min(common, count_leading(atags[:common], " ")) print "-", aline, if count_leading(atags, " ") < len(atags): print "?", "\t" * common + atags[common:] print "+", bline, if count_leading(btags, " ") < len(btags): print "?", "\t" * common + btags[common:] def count_leading(line, ch): i, n = 0, len(line) while i < n and line[i] == ch: i += 1 return i def fail(msg): import sys out = sys.stderr.write out(msg + "\n\n") out(__doc__) return 0 # open a file & return the file object; gripe and return 0 if it # couldn't be opened def fopen(fname): try: return open(fname, 'r') except IOError, detail: return fail("couldn't open " + fname + ": " + str(detail)) # open two files & spray the diff to stdout; return false iff a problem def fcompare(f1name, f2name): f1 = fopen(f1name) f2 = fopen(f2name) if not f1 or not f2: return 0 a = f1.readlines(); f1.close() b = f2.readlines(); f2.close() cruncher = SequenceMatcher(IS_LINE_JUNK, a, b) for tag, alo, ahi, blo, bhi in cruncher.get_opcodes(): if tag == 'replace': fancy_replace(a, alo, ahi, b, blo, bhi) elif tag == 'delete': dump('-', a, alo, ahi) elif tag == 'insert': dump('+', b, blo, bhi) elif tag == 'equal': dump(' ', a, alo, ahi) else: raise ValueError, 'unknown tag ' + `tag` return 1 # crack args (sys.argv[1:] is normal) & compare; # return false iff a problem def main(args): import getopt try: opts, args = getopt.getopt(args, "qr:") except getopt.error, detail: return fail(str(detail)) noisy = 1 qseen = rseen = 0 for opt, val in opts: if opt == "-q": qseen = 1 noisy = 0 elif opt == "-r": rseen = 1 whichfile = val if qseen and rseen: return fail("can't specify both -q and -r") if rseen: if args: return fail("no args allowed with -r option") if whichfile in "12": restore(whichfile) return 1 return fail("-r value must be 1 or 2") if len(args) != 2: return fail("need 2 filename args") f1name, f2name = args if noisy: print '-:', f1name print '+:', f2name return fcompare(f1name, f2name) def restore(which): import sys tag = {"1": "- ", "2": "+ "}[which] prefixes = (" ", tag) for line in sys.stdin.readlines(): if line[:2] in prefixes: print line[2:], if __name__ == '__main__': import sys args = sys.argv[1:] if "-profile" in args: import profile, pstats args.remove("-profile") statf = "ndiff.pro" profile.run("main(args)", statf) stats = pstats.Stats(statf) stats.strip_dirs().sort_stats('time').print_stats() else: main(args) --- NEW FILE: nm2def.py --- #! /usr/bin/env python """nm2def.py Helpers to extract symbols from Unix libs and auto-generate Windows definition files from them. Depends on nm(1). Tested on Linux and Solaris only (-p option to nm is for Solaris only). By Marc-Andre Lemburg, Aug 1998. Additional notes: the output of nm is supposed to look like this: acceler.o: 000001fd T PyGrammar_AddAccelerators U PyGrammar_FindDFA 00000237 T PyGrammar_RemoveAccelerators U _IO_stderr_ U exit U fprintf U free U malloc U printf grammar1.o: 00000000 T PyGrammar_FindDFA 00000034 T PyGrammar_LabelRepr U _PyParser_TokenNames U abort U printf U sprintf ... Even if this isn't the default output of your nm, there is generally an option to produce this format (since it is the original v7 Unix format). """ import os,re,string,sys PYTHONLIB = 'libpython'+sys.version[:3]+'.a' PC_PYTHONLIB = 'Python'+sys.version[0]+sys.version[2]+'.dll' NM = 'nm -p -g %s' # For Linux, use "nm -g %s" def symbols(lib=PYTHONLIB,types=('T','C','D')): lines = os.popen(NM % lib).readlines() lines = map(string.strip,lines) symbols = {} for line in lines: if len(line) == 0 or ':' in line: continue items = string.split(line) if len(items) != 3: continue address, type, name = items if type not in types: continue symbols[name] = address,type return symbols def export_list(symbols): data = [] code = [] for name,(addr,type) in symbols.items(): if type in ('C','D'): data.append('\t'+name) else: code.append('\t'+name) data.sort() data.append('') code.sort() return string.join(data,' DATA\n')+'\n'+string.join(code,'\n') # Definition file template DEF_TEMPLATE = """\ EXPORTS %s """ # Special symbols that have to be included even though they don't # pass the filter SPECIALS = ( ) def filter_Python(symbols,specials=SPECIALS): for name in symbols.keys(): if name[:2] == 'Py' or name[:3] == '_Py': pass elif name not in specials: del symbols[name] def main(): s = symbols(PYTHONLIB) filter_Python(s) exports = export_list(s) f = sys.stdout # open('PC/python_nt.def','w') f.write(DEF_TEMPLATE % (exports)) f.close() if __name__ == '__main__': main() --- NEW FILE: objgraph.py --- #! /usr/bin/env python # objgraph # # Read "nm -o" input (on IRIX: "nm -Bo") of a set of libraries or modules # and print various interesting listings, such as: # # - which names are used but not defined in the set (and used where), # - which names are defined in the set (and where), # - which modules use which other modules, # - which modules are used by which other modules. # # Usage: objgraph [-cdu] [file] ... # -c: print callers per objectfile # -d: print callees per objectfile # -u: print usage of undefined symbols # If none of -cdu is specified, all are assumed. # Use "nm -o" to generate the input (on IRIX: "nm -Bo"), # e.g.: nm -o /lib/libc.a | objgraph import sys import string import os import getopt import regex # Types of symbols. # definitions = 'TRGDSBAEC' externals = 'UV' ignore = 'Nntrgdsbavuc' # Regular expression to parse "nm -o" output. # matcher = regex.compile('\(.*\):\t?........ \(.\) \(.*\)$') # Store "item" in "dict" under "key". # The dictionary maps keys to lists of items. # If there is no list for the key yet, it is created. # def store(dict, key, item): if dict.has_key(key): dict[key].append(item) else: dict[key] = [item] # Return a flattened version of a list of strings: the concatenation # of its elements with intervening spaces. # def flat(list): s = '' for item in list: s = s + ' ' + item return s[1:] # Global variables mapping defined/undefined names to files and back. # file2undef = {} def2file = {} file2def = {} undef2file = {} # Read one input file and merge the data into the tables. # Argument is an open file. # def readinput(file): while 1: s = file.readline() if not s: break # If you get any output from this line, # it is probably caused by an unexpected input line: if matcher.search(s) < 0: s; continue # Shouldn't happen (ra, rb), (r1a, r1b), (r2a, r2b), (r3a, r3b) = matcher.regs[:4] fn, name, type = s[r1a:r1b], s[r3a:r3b], s[r2a:r2b] if type in definitions: store(def2file, name, fn) store(file2def, fn, name) elif type in externals: store(file2undef, fn, name) store(undef2file, name, fn) elif not type in ignore: print fn + ':' + name + ': unknown type ' + type # Print all names that were undefined in some module and where they are # defined. # def printcallee(): flist = file2undef.keys() flist.sort() for file in flist: print file + ':' elist = file2undef[file] elist.sort() for ext in elist: if len(ext) >= 8: tabs = '\t' else: tabs = '\t\t' if not def2file.has_key(ext): print '\t' + ext + tabs + ' *undefined' else: print '\t' + ext + tabs + flat(def2file[ext]) # Print for each module the names of the other modules that use it. # def printcaller(): files = file2def.keys() files.sort() for file in files: callers = [] for label in file2def[file]: if undef2file.has_key(label): callers = callers + undef2file[label] if callers: callers.sort() print file + ':' lastfn = '' for fn in callers: if fn <> lastfn: print '\t' + fn lastfn = fn else: print file + ': unused' # Print undefine names and where they are used. # def printundef(): undefs = {} for file in file2undef.keys(): for ext in file2undef[file]: if not def2file.has_key(ext): store(undefs, ext, file) elist = undefs.keys() elist.sort() for ext in elist: print ext + ':' flist = undefs[ext] flist.sort() for file in flist: print '\t' + file # Print warning messages about names defined in more than one file. # def warndups(): savestdout = sys.stdout sys.stdout = sys.stderr names = def2file.keys() names.sort() for name in names: if len(def2file[name]) > 1: print 'warning:', name, 'multiply defined:', print flat(def2file[name]) sys.stdout = savestdout # Main program # def main(): try: optlist, args = getopt.getopt(sys.argv[1:], 'cdu') except getopt.error: sys.stdout = sys.stderr print 'Usage:', os.path.basename(sys.argv[0]), print '[-cdu] [file] ...' print '-c: print callers per objectfile' print '-d: print callees per objectfile' print '-u: print usage of undefined symbols' print 'If none of -cdu is specified, all are assumed.' print 'Use "nm -o" to generate the input (on IRIX: "nm -Bo"),' print 'e.g.: nm -o /lib/libc.a | objgraph' return 1 optu = optc = optd = 0 for opt, void in optlist: if opt == '-u': optu = 1 elif opt == '-c': optc = 1 elif opt == '-d': optd = 1 if optu == optc == optd == 0: optu = optc = optd = 1 if not args: args = ['-'] for file in args: if file == '-': readinput(sys.stdin) else: readinput(open(file, 'r')) # warndups() # more = (optu + optc + optd > 1) if optd: if more: print '---------------All callees------------------' printcallee() if optu: if more: print '---------------Undefined callees------------' printundef() if optc: if more: print '---------------All Callers------------------' printcaller() return 0 # Call the main program. # Use its return value as exit status. # Catch interrupts to avoid stack trace. # try: sys.exit(main()) except KeyboardInterrupt: sys.exit(1) --- NEW FILE: parseentities.py --- #!/usr/local/bin/python """ Utility for parsing HTML entity definitions available from: http://www.w3.org/ as e.g. http://www.w3.org/TR/REC-html40/HTMLlat1.ent Input is read from stdin, output is written to stdout in form of a Python snippet defining a dictionary "entitydefs" mapping literal entity name to character or numeric entity. Marc-Andre Lemburg, mal@lemburg.com, 1999. Use as you like. NO WARRANTIES. """ import re,sys import TextTools entityRE = re.compile('') def parse(text,pos=0,endpos=None): pos = 0 if endpos is None: endpos = len(text) d = {} while 1: m = entityRE.search(text,pos,endpos) if not m: break name,charcode,comment = m.groups() d[name] = charcode,comment pos = m.end() return d def writefile(f,defs): f.write("entitydefs = {\n") items = defs.items() items.sort() for name,(charcode,comment) in items: if charcode[:2] == '&#': code = int(charcode[2:-1]) if code < 256: charcode = "'\%o'" % code else: charcode = repr(charcode) else: charcode = repr(charcode) comment = TextTools.collapse(comment) f.write(" '%s':\t%s, \t# %s\n" % (name,charcode,comment)) f.write('\n}\n') if __name__ == '__main__': if len(sys.argv) > 1: infile = open(sys.argv[1]) else: infile = sys.stdin if len(sys.argv) > 2: outfile = open(sys.argv[2],'w') else: outfile = sys.stdout text = infile.read() defs = parse(text) writefile(outfile,defs) --- NEW FILE: pathfix.py --- #! /usr/bin/env python # Change the #! line occurring in Python scripts. The new interpreter # pathname must be given with a -i option. # # Command line arguments are files or directories to be processed. # Directories are searched recursively for files whose name looks # like a python module. # Symbolic links are always ignored (except as explicit directory # arguments). Of course, the original file is kept as a back-up # (with a "~" attached to its name). # # Undoubtedly you can do this using find and sed or perl, but this is # a nice example of Python code that recurses down a directory tree # and uses regular expressions. Also note several subtleties like # preserving the file's mode and avoiding to even write a temp file # when no changes are needed for a file. # # NB: by changing only the function fixfile() you can turn this # into a program for a different change to Python programs... import sys import regex import os from stat import * import string import getopt err = sys.stderr.write dbg = err rep = sys.stdout.write new_interpreter = None def main(): global new_interpreter usage = ('usage: %s -i /interpreter file-or-directory ...\n' % sys.argv[0]) try: opts, args = getopt.getopt(sys.argv[1:], 'i:') except getopt.error, msg: err(msg + '\n') err(usage) sys.exit(2) for o, a in opts: if o == '-i': new_interpreter = a if not new_interpreter or new_interpreter[0] != '/' or not args: err('-i option or file-or-directory missing\n') err(usage) sys.exit(2) bad = 0 for arg in args: if os.path.isdir(arg): if recursedown(arg): bad = 1 elif os.path.islink(arg): err(arg + ': will not process symbolic links\n') bad = 1 else: if fix(arg): bad = 1 sys.exit(bad) ispythonprog = regex.compile('^[a-zA-Z0-9_]+\.py$') def ispython(name): return ispythonprog.match(name) >= 0 def recursedown(dirname): dbg('recursedown(' + `dirname` + ')\n') bad = 0 try: names = os.listdir(dirname) except os.error, msg: err(dirname + ': cannot list directory: ' + `msg` + '\n') return 1 names.sort() subdirs = [] for name in names: if name in (os.curdir, os.pardir): continue fullname = os.path.join(dirname, name) if os.path.islink(fullname): pass elif os.path.isdir(fullname): subdirs.append(fullname) elif ispython(name): if fix(fullname): bad = 1 for fullname in subdirs: if recursedown(fullname): bad = 1 return bad def fix(filename): ## dbg('fix(' + `filename` + ')\n') try: f = open(filename, 'r') except IOError, msg: err(filename + ': cannot open: ' + `msg` + '\n') return 1 line = f.readline() fixed = fixline(line) if line == fixed: rep(filename+': no change\n') f.close() return head, tail = os.path.split(filename) tempname = os.path.join(head, '@' + tail) try: g = open(tempname, 'w') except IOError, msg: f.close() err(tempname+': cannot create: '+`msg`+'\n') return 1 rep(filename + ': updating\n') g.write(fixed) BUFSIZE = 8*1024 while 1: buf = f.read(BUFSIZE) if not buf: break g.write(buf) g.close() f.close() # Finishing touch -- move files # First copy the file's mode to the temp file try: statbuf = os.stat(filename) os.chmod(tempname, statbuf[ST_MODE] & 07777) except os.error, msg: err(tempname + ': warning: chmod failed (' + `msg` + ')\n') # Then make a backup of the original file as filename~ try: os.rename(filename, filename + '~') except os.error, msg: err(filename + ': warning: backup failed (' + `msg` + ')\n') # Now move the temp file to the original file try: os.rename(tempname, filename) except os.error, msg: err(filename + ': rename failed (' + `msg` + ')\n') return 1 # Return succes return 0 def fixline(line): if line[:2] != '#!': return line if string.find(line, "python") < 0: return line return '#! %s\n' % new_interpreter main() --- NEW FILE: pdeps.py --- #! /usr/bin/env python # pdeps # # Find dependencies between a bunch of Python modules. # # Usage: # pdeps file1.py file2.py ... # # Output: # Four tables separated by lines like '--- Closure ---': # 1) Direct dependencies, listing which module imports which other modules # 2) The inverse of (1) # 3) Indirect dependencies, or the closure of the above # 4) The inverse of (3) # # To do: # - command line options to select output type # - option to automatically scan the Python library for referenced modules # - option to limit output to particular modules import sys import regex import os import string # Main program # def main(): args = sys.argv[1:] if not args: print 'usage: pdeps file.py file.py ...' return 2 # table = {} for arg in args: process(arg, table) # print '--- Uses ---' printresults(table) # print '--- Used By ---' inv = inverse(table) printresults(inv) # print '--- Closure of Uses ---' reach = closure(table) printresults(reach) # print '--- Closure of Used By ---' invreach = inverse(reach) printresults(invreach) # return 0 # Compiled regular expressions to search for import statements # m_import = regex.compile('^[ \t]*from[ \t]+\([^ \t]+\)[ \t]+') m_from = regex.compile('^[ \t]*import[ \t]+\([^#]+\)') # Collect data from one file # def process(filename, table): fp = open(filename, 'r') mod = os.path.basename(filename) if mod[-3:] == '.py': mod = mod[:-3] table[mod] = list = [] while 1: line = fp.readline() if not line: break while line[-1:] == '\\': nextline = fp.readline() if not nextline: break line = line[:-1] + nextline if m_import.match(line) >= 0: (a, b), (a1, b1) = m_import.regs[:2] elif m_from.match(line) >= 0: (a, b), (a1, b1) = m_from.regs[:2] else: continue words = string.splitfields(line[a1:b1], ',') # print '#', line, words for word in words: word = string.strip(word) if word not in list: list.append(word) # Compute closure (this is in fact totally general) # def closure(table): modules = table.keys() # # Initialize reach with a copy of table # reach = {} for mod in modules: reach[mod] = table[mod][:] # # Iterate until no more change # change = 1 while change: change = 0 for mod in modules: for mo in reach[mod]: if mo in modules: for m in reach[mo]: if m not in reach[mod]: reach[mod].append(m) change = 1 # return reach # Invert a table (this is again totally general). # All keys of the original table are made keys of the inverse, # so there may be empty lists in the inverse. # def inverse(table): inv = {} for key in table.keys(): if not inv.has_key(key): inv[key] = [] for item in table[key]: store(inv, item, key) return inv # Store "item" in "dict" under "key". # The dictionary maps keys to lists of items. # If there is no list for the key yet, it is created. # def store(dict, key, item): if dict.has_key(key): dict[key].append(item) else: dict[key] = [item] # Tabulate results neatly # def printresults(table): modules = table.keys() maxlen = 0 for mod in modules: maxlen = max(maxlen, len(mod)) modules.sort() for mod in modules: list = table[mod] list.sort() print string.ljust(mod, maxlen), ':', if mod in list: print '(*)', for ref in list: print ref, print # Call main and honor exit status try: sys.exit(main()) except KeyboardInterrupt: sys.exit(1) --- NEW FILE: pindent.py --- #! /usr/bin/env python # This file contains a class and a main program that perform three # related (though complimentary) formatting operations on Python # programs. When called as "pindent -c", it takes a valid Python # program as input and outputs a version augmented with block-closing # comments. When called as "pindent -d", it assumes its input is a # Python program with block-closing comments and outputs a commentless # version. When called as "pindent -r" it assumes its input is a # Python program with block-closing comments but with its indentation # messed up, and outputs a properly indented version. # A "block-closing comment" is a comment of the form '# end ' # where is the keyword that opened the block. If the # opening keyword is 'def' or 'class', the function or class name may # be repeated in the block-closing comment as well. Here is an # example of a program fully augmented with block-closing comments: # def foobar(a, b): # if a == b: # a = a+1 # elif a < b: # b = b-1 # if b > a: a = a-1 # # end if # else: # print 'oops!' # # end if # # end def foobar # Note that only the last part of an if...elif...else... block needs a # block-closing comment; the same is true for other compound # statements (e.g. try...except). Also note that "short-form" blocks # like the second 'if' in the example must be closed as well; # otherwise the 'else' in the example would be ambiguous (remember # that indentation is not significant when interpreting block-closing # comments). # The operations are idempotent (i.e. applied to their own output # they yield an identical result). Running first "pindent -c" and # then "pindent -r" on a valid Python program produces a program that # is semantically identical to the input (though its indentation may # be different). Running "pindent -e" on that output produces a # program that only differs from the original in indentation. # Other options: # -s stepsize: set the indentation step size (default 8) # -t tabsize : set the number of spaces a tab character is worth (default 8) # -e : expand TABs into spaces # file ... : input file(s) (default standard input) # The results always go to standard output # Caveats: # - comments ending in a backslash will be mistaken for continued lines # - continuations using backslash are always left unchanged # - continuations inside parentheses are not extra indented by -r # but must be indented for -c to work correctly (this breaks # idempotency!) # - continued lines inside triple-quoted strings are totally garbled # Secret feature: # - On input, a block may also be closed with an "end statement" -- # this is a block-closing comment without the '#' sign. # Possible improvements: # - check syntax based on transitions in 'next' table # - better error reporting # - better error recovery # - check identifier after class/def # The following wishes need a more complete tokenization of the source: # - Don't get fooled by comments ending in backslash # - reindent continuation lines indicated by backslash # - handle continuation lines inside parentheses/braces/brackets # - handle triple quoted strings spanning lines # - realign comments # - optionally do much more thorough reformatting, a la C indent # Defaults STEPSIZE = 8 TABSIZE = 8 EXPANDTABS = 0 import os import re import string import sys next = {} next['if'] = next['elif'] = 'elif', 'else', 'end' next['while'] = next['for'] = 'else', 'end' next['try'] = 'except', 'finally' next['except'] = 'except', 'else', 'end' next['else'] = next['finally'] = next['def'] = next['class'] = 'end' next['end'] = () start = 'if', 'while', 'for', 'try', 'def', 'class' class PythonIndenter: def __init__(self, fpi = sys.stdin, fpo = sys.stdout, indentsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): self.fpi = fpi self.fpo = fpo self.indentsize = indentsize self.tabsize = tabsize self.lineno = 0 self.expandtabs = expandtabs self._write = fpo.write self.kwprog = re.compile( r'^\s*(?P[a-z]+)' r'(\s+(?P[a-zA-Z_]\w*))?' r'[^\w]') self.endprog = re.compile( r'^\s*#?\s*end\s+(?P[a-z]+)' r'(\s+(?P[a-zA-Z_]\w*))?' r'[^\w]') self.wsprog = re.compile(r'^[ \t]*') # end def __init__ def write(self, line): if self.expandtabs: self._write(string.expandtabs(line, self.tabsize)) else: self._write(line) # end if # end def write def readline(self): line = self.fpi.readline() if line: self.lineno = self.lineno + 1 # end if return line # end def readline def error(self, fmt, *args): if args: fmt = fmt % args # end if sys.stderr.write('Error at line %d: %s\n' % (self.lineno, fmt)) self.write('### %s ###\n' % fmt) # end def error def getline(self): line = self.readline() while line[-2:] == '\\\n': line2 = self.readline() if not line2: break # end if line = line + line2 # end while return line # end def getline def putline(self, line, indent = None): if indent is None: self.write(line) return # end if tabs, spaces = divmod(indent*self.indentsize, self.tabsize) i = 0 m = self.wsprog.match(line) if m: i = m.end() # end if self.write('\t'*tabs + ' '*spaces + line[i:]) # end def putline def reformat(self): stack = [] while 1: line = self.getline() if not line: break # EOF # end if m = self.endprog.match(line) if m: kw = 'end' kw2 = m.group('kw') if not stack: self.error('unexpected end') elif stack[-1][0] != kw2: self.error('unmatched end') # end if del stack[-1:] self.putline(line, len(stack)) continue # end if m = self.kwprog.match(line) if m: kw = m.group('kw') if kw in start: self.putline(line, len(stack)) stack.append((kw, kw)) continue # end if if next.has_key(kw) and stack: self.putline(line, len(stack)-1) kwa, kwb = stack[-1] stack[-1] = kwa, kw continue # end if # end if self.putline(line, len(stack)) # end while if stack: self.error('unterminated keywords') for kwa, kwb in stack: self.write('\t%s\n' % kwa) # end for # end if # end def reformat def delete(self): begin_counter = 0 end_counter = 0 while 1: line = self.getline() if not line: break # EOF # end if m = self.endprog.match(line) if m: end_counter = end_counter + 1 continue # end if m = self.kwprog.match(line) if m: kw = m.group('kw') if kw in start: begin_counter = begin_counter + 1 # end if # end if self.putline(line) # end while if begin_counter - end_counter < 0: sys.stderr.write('Warning: input contained more end tags than expected\n') elif begin_counter - end_counter > 0: sys.stderr.write('Warning: input contained less end tags than expected\n') # end if # end def delete def complete(self): self.indentsize = 1 stack = [] todo = [] current, firstkw, lastkw, topid = 0, '', '', '' while 1: line = self.getline() i = 0 m = self.wsprog.match(line) if m: i = m.end() # end if m = self.endprog.match(line) if m: thiskw = 'end' endkw = m.group('kw') thisid = m.group('id') else: m = self.kwprog.match(line) if m: thiskw = m.group('kw') if not next.has_key(thiskw): thiskw = '' # end if if thiskw in ('def', 'class'): thisid = m.group('id') else: thisid = '' # end if elif line[i:i+1] in ('\n', '#'): todo.append(line) continue else: thiskw = '' # end if # end if indent = len(string.expandtabs(line[:i], self.tabsize)) while indent < current: if firstkw: if topid: s = '# end %s %s\n' % ( firstkw, topid) else: s = '# end %s\n' % firstkw # end if self.putline(s, current) firstkw = lastkw = '' # end if current, firstkw, lastkw, topid = stack[-1] del stack[-1] # end while if indent == current and firstkw: if thiskw == 'end': if endkw != firstkw: self.error('mismatched end') # end if firstkw = lastkw = '' elif not thiskw or thiskw in start: if topid: s = '# end %s %s\n' % ( firstkw, topid) else: s = '# end %s\n' % firstkw # end if self.putline(s, current) firstkw = lastkw = topid = '' # end if # end if if indent > current: stack.append((current, firstkw, lastkw, topid)) if thiskw and thiskw not in start: # error thiskw = '' # end if current, firstkw, lastkw, topid = \ indent, thiskw, thiskw, thisid # end if if thiskw: if thiskw in start: firstkw = lastkw = thiskw topid = thisid else: lastkw = thiskw # end if # end if for l in todo: self.write(l) # end for todo = [] if not line: break # end if self.write(line) # end while # end def complete # end class PythonIndenter # Simplified user interface # - xxx_filter(input, output): read and write file objects # - xxx_string(s): take and return string object # - xxx_file(filename): process file in place, return true iff changed def complete_filter(input = sys.stdin, output = sys.stdout, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): pi = PythonIndenter(input, output, stepsize, tabsize, expandtabs) pi.complete() # end def complete_filter def delete_filter(input= sys.stdin, output = sys.stdout, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): pi = PythonIndenter(input, output, stepsize, tabsize, expandtabs) pi.delete() # end def delete_filter def reformat_filter(input = sys.stdin, output = sys.stdout, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): pi = PythonIndenter(input, output, stepsize, tabsize, expandtabs) pi.reformat() # end def reformat_filter class StringReader: def __init__(self, buf): self.buf = buf self.pos = 0 self.len = len(self.buf) # end def __init__ def read(self, n = 0): if n <= 0: n = self.len - self.pos else: n = min(n, self.len - self.pos) # end if r = self.buf[self.pos : self.pos + n] self.pos = self.pos + n return r # end def read def readline(self): i = string.find(self.buf, '\n', self.pos) return self.read(i + 1 - self.pos) # end def readline def readlines(self): lines = [] line = self.readline() while line: lines.append(line) line = self.readline() # end while return lines # end def readlines # seek/tell etc. are left as an exercise for the reader # end class StringReader class StringWriter: def __init__(self): self.buf = '' # end def __init__ def write(self, s): self.buf = self.buf + s # end def write def getvalue(self): return self.buf # end def getvalue # end class StringWriter def complete_string(source, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): input = StringReader(source) output = StringWriter() pi = PythonIndenter(input, output, stepsize, tabsize, expandtabs) pi.complete() return output.getvalue() # end def complete_string def delete_string(source, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): input = StringReader(source) output = StringWriter() pi = PythonIndenter(input, output, stepsize, tabsize, expandtabs) pi.delete() return output.getvalue() # end def delete_string def reformat_string(source, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): input = StringReader(source) output = StringWriter() pi = PythonIndenter(input, output, stepsize, tabsize, expandtabs) pi.reformat() return output.getvalue() # end def reformat_string def complete_file(filename, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): source = open(filename, 'r').read() result = complete_string(source, stepsize, tabsize, expandtabs) if source == result: return 0 # end if import os try: os.rename(filename, filename + '~') except os.error: pass # end try f = open(filename, 'w') f.write(result) f.close() return 1 # end def complete_file def delete_file(filename, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): source = open(filename, 'r').read() result = delete_string(source, stepsize, tabsize, expandtabs) if source == result: return 0 # end if import os try: os.rename(filename, filename + '~') except os.error: pass # end try f = open(filename, 'w') f.write(result) f.close() return 1 # end def delete_file def reformat_file(filename, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): source = open(filename, 'r').read() result = reformat_string(source, stepsize, tabsize, expandtabs) if source == result: return 0 # end if import os try: os.rename(filename, filename + '~') except os.error: pass # end try f = open(filename, 'w') f.write(result) f.close() return 1 # end def reformat_file # Test program when called as a script usage = """ usage: pindent (-c|-d|-r) [-s stepsize] [-t tabsize] [-e] [file] ... -c : complete a correctly indented program (add #end directives) -d : delete #end directives -r : reformat a completed program (use #end directives) -s stepsize: indentation step (default %(STEPSIZE)d) -t tabsize : the worth in spaces of a tab (default %(TABSIZE)d) -e : expand TABs into spaces (defailt OFF) [file] ... : files are changed in place, with backups in file~ If no files are specified or a single - is given, the program acts as a filter (reads stdin, writes stdout). """ % vars() def error_both(op1, op2): sys.stderr.write('Error: You can not specify both '+op1+' and -'+op2[0]+' at the same time\n') sys.stderr.write(usage) sys.exit(2) # end def error_both def test(): import getopt try: opts, args = getopt.getopt(sys.argv[1:], 'cdrs:t:e') except getopt.error, msg: sys.stderr.write('Error: %s\n' % msg) sys.stderr.write(usage) sys.exit(2) # end try action = None stepsize = STEPSIZE tabsize = TABSIZE expandtabs = EXPANDTABS for o, a in opts: if o == '-c': if action: error_both(o, action) # end if action = 'complete' elif o == '-d': if action: error_both(o, action) # end if action = 'delete' elif o == '-r': if action: error_both(o, action) # end if action = 'reformat' elif o == '-s': stepsize = string.atoi(a) elif o == '-t': tabsize = string.atoi(a) elif o == '-e': expandtabs = 1 # end if # end for if not action: sys.stderr.write( 'You must specify -c(omplete), -d(elete) or -r(eformat)\n') sys.stderr.write(usage) sys.exit(2) # end if if not args or args == ['-']: action = eval(action + '_filter') action(sys.stdin, sys.stdout, stepsize, tabsize, expandtabs) else: action = eval(action + '_file') for file in args: action(file, stepsize, tabsize, expandtabs) # end for # end if # end def test if __name__ == '__main__': test() # end if --- NEW FILE: ptags.py --- #! /usr/bin/env python # ptags # # Create a tags file for Python programs, usable with vi. # Tagged are: # - functions (even inside other defs or classes) # - classes # - filenames # Warns about files it cannot open. # No warnings about duplicate tags. import sys, re, os tags = [] # Modified global variable! def main(): args = sys.argv[1:] for file in args: treat_file(file) if tags: fp = open('tags', 'w') tags.sort() for s in tags: fp.write(s) expr = '^[ \t]*(def|class)[ \t]+([a-zA-Z0-9_]+)[ \t]*[:\(]' matcher = re.compile(expr) def treat_file(file): try: fp = open(file, 'r') except: sys.stderr.write('Cannot open %s\n' % file) return base = os.path.basename(file) if base[-3:] == '.py': base = base[:-3] s = base + '\t' + file + '\t' + '1\n' tags.append(s) while 1: line = fp.readline() if not line: break m = matcher.match(line) if m: content = m.group(0) name = m.group(2) s = name + '\t' + file + '\t/^' + content + '/\n' tags.append(s) main() --- NEW FILE: pydoc.pyw --- import pydoc pydoc.gui() --- NEW FILE: redemo.py --- """Basic regular expression demostration facility (Perl style syntax).""" from Tkinter import * import re class ReDemo: def __init__(self, master): self.master = master self.promptdisplay = Label(self.master, anchor=W, text="Enter a Perl-style regular expression:") self.promptdisplay.pack(side=TOP, fill=X) self.regexdisplay = Entry(self.master) self.regexdisplay.pack(fill=X) self.regexdisplay.focus_set() self.addoptions() self.statusdisplay = Label(self.master, text="", anchor=W) self.statusdisplay.pack(side=TOP, fill=X) self.labeldisplay = Label(self.master, anchor=W, text="Enter a string to search:") self.labeldisplay.pack(fill=X) self.labeldisplay.pack(fill=X) self.showframe = Frame(master) self.showframe.pack(fill=X, anchor=W) self.showvar = StringVar(master) self.showvar.set("first") self.showfirstradio = Radiobutton(self.showframe, text="Highlight first match", variable=self.showvar, value="first", command=self.recompile) self.showfirstradio.pack(side=LEFT) self.showallradio = Radiobutton(self.showframe, text="Highlight all matches", variable=self.showvar, value="all", command=self.recompile) self.showallradio.pack(side=LEFT) self.stringdisplay = Text(self.master, width=60, height=4) self.stringdisplay.pack(fill=BOTH, expand=1) self.stringdisplay.tag_configure("hit", background="yellow") self.grouplabel = Label(self.master, text="Groups:", anchor=W) self.grouplabel.pack(fill=X) self.grouplist = Listbox(self.master) self.grouplist.pack(expand=1, fill=BOTH) self.regexdisplay.bind('', self.recompile) self.stringdisplay.bind('', self.reevaluate) self.compiled = None self.recompile() btags = self.regexdisplay.bindtags() self.regexdisplay.bindtags(btags[1:] + btags[:1]) btags = self.stringdisplay.bindtags() self.stringdisplay.bindtags(btags[1:] + btags[:1]) def addoptions(self): self.frames = [] self.boxes = [] self.vars = [] for name in ('IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL', 'VERBOSE'): if len(self.boxes) % 3 == 0: frame = Frame(self.master) frame.pack(fill=X) self.frames.append(frame) val = getattr(re, name) var = IntVar() box = Checkbutton(frame, variable=var, text=name, offvalue=0, onvalue=val, command=self.recompile) box.pack(side=LEFT) self.boxes.append(box) self.vars.append(var) def getflags(self): flags = 0 for var in self.vars: flags = flags | var.get() flags = flags return flags def recompile(self, event=None): try: self.compiled = re.compile(self.regexdisplay.get(), self.getflags()) bg = self.promptdisplay['background'] self.statusdisplay.config(text="", background=bg) except re.error, msg: self.compiled = None self.statusdisplay.config( text="re.error: %s" % str(msg), background="red") self.reevaluate() def reevaluate(self, event=None): try: self.stringdisplay.tag_remove("hit", "1.0", END) except TclError: pass try: self.stringdisplay.tag_remove("hit0", "1.0", END) except TclError: pass self.grouplist.delete(0, END) if not self.compiled: return self.stringdisplay.tag_configure("hit", background="yellow") self.stringdisplay.tag_configure("hit0", background="orange") text = self.stringdisplay.get("1.0", END) last = 0 nmatches = 0 while last <= len(text): m = self.compiled.search(text, last) if m is None: break first, last = m.span() if last == first: last = first+1 tag = "hit0" else: tag = "hit" pfirst = "1.0 + %d chars" % first plast = "1.0 + %d chars" % last self.stringdisplay.tag_add(tag, pfirst, plast) if nmatches == 0: self.stringdisplay.yview_pickplace(pfirst) groups = list(m.groups()) groups.insert(0, m.group()) for i in range(len(groups)): g = "%2d: %s" % (i, `groups[i]`) self.grouplist.insert(END, g) nmatches = nmatches + 1 if self.showvar.get() == "first": break if nmatches == 0: self.statusdisplay.config(text="(no match)", background="yellow") else: self.statusdisplay.config(text="") # Main function, run when invoked as a stand-alone Python program. def main(): root = Tk() demo = ReDemo(root) root.protocol('WM_DELETE_WINDOW', root.quit) root.mainloop() if __name__ == '__main__': main() --- NEW FILE: reindent.py --- #! /usr/bin/env python # Released to the public domain, by Tim Peters, 03 October 2000. """reindent [-d][-r][-v] path ... -d Dry run. Analyze, but don't make any changes to, files. -r Recurse. Search for all .py files in subdirectories too. -v Verbose. Print informative msgs; else no output. Change Python (.py) files to use 4-space indents and no hard tab characters. Also trim excess whitespace from ends of lines, and empty lines at the ends of files. Ensure the last line ends with a newline. Pass one or more file and/or directory paths. When a directory path, all .py files within the directory will be examined, and, if the -r option is given, likewise recursively for subdirectories. Overwrites files in place, renaming the originals with a .bak extension. If reindent finds nothing to change, the file is left alone. If reindent does change a file, the changed file is a fixed-point for reindent (i.e., running reindent on the resulting .py file won't change it again). The hard part of reindenting is figuring out what to do with comment lines. So long as the input files get a clean bill of health from tabnanny.py, reindent should do a good job. """ __version__ = "1" import tokenize import os import sys verbose = 0 recurse = 0 dryrun = 0 def errprint(*args): sep = "" for arg in args: sys.stderr.write(sep + str(arg)) sep = " " sys.stderr.write("\n") def main(): import getopt global verbose, recurse, dryrun try: opts, args = getopt.getopt(sys.argv[1:], "drv") except getopt.error, msg: errprint(msg) return for o, a in opts: if o == '-d': dryrun += 1 elif o == '-r': recurse += 1 elif o == '-v': verbose += 1 if not args: errprint("Usage:", __doc__) return for arg in args: check(arg) def check(file): if os.path.isdir(file) and not os.path.islink(file): if verbose: print "listing directory", file names = os.listdir(file) for name in names: fullname = os.path.join(file, name) if ((recurse and os.path.isdir(fullname) and not os.path.islink(fullname)) or name.lower().endswith(".py")): check(fullname) return if verbose: print "checking", file, "...", try: f = open(file) except IOError, msg: errprint("%s: I/O Error: %s" % (file, str(msg))) return r = Reindenter(f) f.close() if r.run(): if verbose: print "changed." if dryrun: print "But this is a dry run, so leaving it alone." if not dryrun: bak = file + ".bak" if os.path.exists(bak): os.remove(bak) os.rename(file, bak) if verbose: print "renamed", file, "to", bak f = open(file, "w") r.write(f) f.close() if verbose: print "wrote new", file else: if verbose: print "unchanged." class Reindenter: def __init__(self, f): self.find_stmt = 1 # next token begins a fresh stmt? self.level = 0 # current indent level # Raw file lines. self.raw = f.readlines() # File lines, rstripped & tab-expanded. Dummy at start is so # that we can use tokenize's 1-based line numbering easily. # Note that a line is all-blank iff it's "\n". self.lines = [line.rstrip().expandtabs() + "\n" for line in self.raw] self.lines.insert(0, None) self.index = 1 # index into self.lines of next line # List of (lineno, indentlevel) pairs, one for each stmt and # comment line. indentlevel is -1 for comment lines, as a # signal that tokenize doesn't know what to do about them; # indeed, they're our headache! self.stats = [] def run(self): tokenize.tokenize(self.getline, self.tokeneater) # Remove trailing empty lines. lines = self.lines while lines and lines[-1] == "\n": lines.pop() # Sentinel. stats = self.stats stats.append((len(lines), 0)) # Map count of leading spaces to # we want. have2want = {} # Program after transformation. after = self.after = [] for i in range(len(stats)-1): thisstmt, thislevel = stats[i] nextstmt = stats[i+1][0] have = getlspace(lines[thisstmt]) want = thislevel * 4 if want < 0: # A comment line. if have: # An indented comment line. If we saw the same # indentation before, reuse what it most recently # mapped to. want = have2want.get(have, -1) if want < 0: # Then it probably belongs to the next real stmt. for j in xrange(i+1, len(stats)-1): jline, jlevel = stats[j] if jlevel >= 0: if have == getlspace(lines[jline]): want = jlevel * 4 break if want < 0: # Maybe it's a hanging # comment like this one, # in which case we should shift it like its base # line got shifted. for j in xrange(i-1, -1, -1): jline, jlevel = stats[j] if jlevel >= 0: want = have + getlspace(after[jline-1]) - \ getlspace(lines[jline]) break if want < 0: # Still no luck -- leave it alone. want = have else: want = 0 assert want >= 0 have2want[have] = want diff = want - have if diff == 0 or have == 0: after.extend(lines[thisstmt:nextstmt]) else: for line in lines[thisstmt:nextstmt]: if diff > 0: if line == "\n": after.append(line) else: after.append(" " * diff + line) else: remove = min(getlspace(line), -diff) after.append(line[remove:]) return self.raw != self.after def write(self, f): f.writelines(self.after) # Line-getter for tokenize. def getline(self): if self.index >= len(self.lines): line = "" else: line = self.lines[self.index] self.index += 1 return line # Line-eater for tokenize. def tokeneater(self, type, token, (sline, scol), end, line, INDENT=tokenize.INDENT, DEDENT=tokenize.DEDENT, NEWLINE=tokenize.NEWLINE, COMMENT=tokenize.COMMENT, NL=tokenize.NL): if type == NEWLINE: # A program statement, or ENDMARKER, will eventually follow, # after some (possibly empty) run of tokens of the form # (NL | COMMENT)* (INDENT | DEDENT+)? self.find_stmt = 1 elif type == INDENT: self.find_stmt = 1 self.level += 1 elif type == DEDENT: self.find_stmt = 1 self.level -= 1 elif type == COMMENT: if self.find_stmt: self.stats.append((sline, -1)) # but we're still looking for a new stmt, so leave # find_stmt alone elif type == NL: pass elif self.find_stmt: # This is the first "real token" following a NEWLINE, so it # must be the first token of the next program statement, or an # ENDMARKER. self.find_stmt = 0 if line: # not endmarker self.stats.append((sline, self.level)) # Count number of leading blanks. def getlspace(line): i, n = 0, len(line) while i < n and line[i] == " ": i += 1 return i if __name__ == '__main__': main() --- NEW FILE: rgrep.py --- #! /usr/bin/env python """Reverse grep. Usage: rgrep [-i] pattern file """ import sys import re import string import getopt def main(): bufsize = 64*1024 reflags = 0 opts, args = getopt.getopt(sys.argv[1:], "i") for o, a in opts: if o == '-i': reflags = reflags | re.IGNORECASE if len(args) < 2: usage("not enough arguments") if len(args) > 2: usage("exactly one file argument required") pattern, filename = args try: prog = re.compile(pattern, reflags) except re.error, msg: usage("error in regular expression: %s" % str(msg)) try: f = open(filename) except IOError, msg: usage("can't open %s: %s" % (repr(filename), str(msg)), 1) f.seek(0, 2) pos = f.tell() leftover = None while pos > 0: size = min(pos, bufsize) pos = pos - size f.seek(pos) buffer = f.read(size) lines = string.split(buffer, "\n") del buffer if leftover is None: if not lines[-1]: del lines[-1] else: lines[-1] = lines[-1] + leftover if pos > 0: leftover = lines[0] del lines[0] else: leftover = None lines.reverse() for line in lines: if prog.search(line): print line def usage(msg, code=2): sys.stdout = sys.stderr print msg print __doc__ sys.exit(code) if __name__ == '__main__': main() --- NEW FILE: suff.py --- #! /usr/bin/env python # suff # # show different suffixes amongst arguments import sys def main(): files = sys.argv[1:] suffixes = {} for file in files: suff = getsuffix(file) if not suffixes.has_key(suff): suffixes[suff] = [] suffixes[suff].append(file) keys = suffixes.keys() keys.sort() for suff in keys: print `suff`, len(suffixes[suff]) def getsuffix(file): suff = '' for i in range(len(file)): if file[i] == '.': suff = file[i:] return suff main() --- NEW FILE: sum5.py --- #! /usr/bin/env python # print md5 checksum for files bufsize = 8096 fnfilter = None rmode = 'r' usage = """ usage: sum5 [-b] [-t] [-l] [-s bufsize] [file ...] -b : read files in binary mode -t : read files in text mode (default) -l : print last pathname component only -s bufsize: read buffer size (default %d) file ... : files to sum; '-' or no files means stdin """ % bufsize import sys import string import os import md5 import regsub StringType = type('') FileType = type(sys.stdin) def sum(*files): sts = 0 if files and type(files[-1]) == FileType: out, files = files[-1], files[:-1] else: out = sys.stdout if len(files) == 1 and type(files[0]) != StringType: files = files[0] for f in files: if type(f) == StringType: if f == '-': sts = printsumfp(sys.stdin, '', out) or sts else: sts = printsum(f, out) or sts else: sts = sum(f, out) or sts return sts def printsum(file, out = sys.stdout): try: fp = open(file, rmode) except IOError, msg: sys.stderr.write('%s: Can\'t open: %s\n' % (file, msg)) return 1 if fnfilter: file = fnfilter(file) sts = printsumfp(fp, file, out) fp.close() return sts def printsumfp(fp, file, out = sys.stdout): m = md5.md5() try: while 1: data = fp.read(bufsize) if not data: break m.update(data) except IOError, msg: sys.stderr.write('%s: I/O error: %s\n' % (file, msg)) return 1 out.write('%s %s\n' % (hexify(m.digest()), file)) return 0 def hexify(s): res = '' for c in s: res = res + '%02x' % ord(c) return res def main(args = sys.argv[1:], out = sys.stdout): global fnfilter, rmode, bufsize import getopt try: opts, args = getopt.getopt(args, 'blts:') except getopt.error, msg: sys.stderr.write('%s: %s\n%s' % (sys.argv[0], msg, usage)) return 2 for o, a in opts: if o == '-l': fnfilter = os.path.basename if o == '-b': rmode = 'rb' if o == '-t': rmode = 'r' if o == '-s': bufsize = string.atoi(a) if not args: args = ['-'] return sum(args, out) if __name__ == '__main__' or __name__ == sys.argv[0]: sys.exit(main(sys.argv[1:], sys.stdout)) --- NEW FILE: texi2html.py --- #! /usr/bin/env python # Convert GNU texinfo files into HTML, one file per node. # Based on Texinfo 2.14. # Usage: texi2html [-d] [-d] [-c] inputfile outputdirectory # The input file must be a complete texinfo file, e.g. emacs.texi. # This creates many files (one per info node) in the output directory, # overwriting existing files of the same name. All files created have # ".html" as their extension. # XXX To do: # - handle @comment*** correctly # - handle @xref {some words} correctly # - handle @ftable correctly (items aren't indexed?) # - handle @itemx properly # - handle @exdent properly # - add links directly to the proper line from indices # - check against the definitive list of @-cmds; we still miss (among others): [...1574 lines suppressed...] parser.print_headers = print_headers file = sys.argv[1] parser.setdirname(sys.argv[2]) if file == '-': fp = sys.stdin else: parser.setincludedir(os.path.dirname(file)) try: fp = open(file, 'r') except IOError, msg: print file, ':', msg sys.exit(1) parser.parse(fp) fp.close() parser.report() if __name__ == "__main__": test() --- NEW FILE: trace.py --- #!/usr/bin/env python # Copyright 2000, Mojam Media, Inc., all rights reserved. # Author: Skip Montanaro # # Copyright 1999, Bioreason, Inc., all rights reserved. # Author: Andrew Dalke # # Copyright 1995-1997, Automatrix, Inc., all rights reserved. # Author: Skip Montanaro # # Copyright 1991-1995, Stichting Mathematisch Centrum, all rights reserved. # # # Permission to use, copy, modify, and distribute this Python software and # its associated documentation for any purpose without fee is hereby # granted, provided that the above copyright notice appears in all copies, # and that both that copyright notice and this permission notice appear in # supporting documentation, and that the name of neither Automatrix, # Bioreason or Mojam Media be used in advertising or publicity pertaining to # distribution of the software without specific, written prior permission. # # # Summary of recent changes: # Support for files with the same basename (submodules in packages) # Expanded the idea of how to ignore files or modules # Split tracing and counting into different classes # Extracted count information and reporting from the count class # Added some ability to detect which missing lines could be executed # Added pseudo-pragma to prohibit complaining about unexecuted lines # Rewrote the main program # Summary of older changes: # Added run-time display of statements being executed # Incorporated portability and performance fixes from Greg Stein # Incorporated main program from Michael Scharf """ program/module to trace Python program or function execution Sample use, command line: trace.py -c -f counts --ignore-dir '$prefix' spam.py eggs trace.py -t --ignore-dir '$prefix' spam.py eggs Sample use, programmatically (still more complicated than it should be) # create an Ignore option, telling it what you want to ignore ignore = trace.Ignore(dirs = [sys.prefix, sys.exec_prefix]) # create a Coverage object, telling it what to ignore coverage = trace.Coverage(ignore) # run the new command using the given trace trace.run(coverage.trace, 'main()') # make a report, telling it where you want output t = trace.create_results_log(coverage.results(), '/usr/local/Automatrix/concerts/coverage') show_missing = 1) The Trace class can be instantited instead of the Coverage class if runtime display of executable lines is desired instead of statement converage measurement. """ import sys, os, string, marshal, tempfile, copy, operator def usage(outfile): outfile.write("""Usage: %s [OPTIONS] [ARGS] Execution: --help Display this help then exit. --version Output version information then exit. -t,--trace Print the line to be executed to sys.stdout. -c,--count Count the number of times a line is executed. Results are written in the results file, if given. -r,--report Generate a report from a results file; do not execute any code. (One of `-t', `-c' or `-r' must be specified) -s,--summary Generate a brief summary for each file. (Can only be used with -c or -r.) I/O: -f,--file= File name for accumulating results over several runs. (No file name means do not archive results) -d,--logdir= Directory to use when writing annotated log files. Log files are the module __name__ with `.` replaced by os.sep and with '.pyl' added. -m,--missing Annotate all executable lines which were not executed with a '>>>>>> '. -R,--no-report Do not generate the annotated reports. Useful if you want to accumulate several over tests. -C,--coverdir= Generate .cover files in this directory Selection: Do not trace or log lines from ... --ignore-module=[string] modules with the given __name__, and submodules of that module --ignore-dir=[string] files in the stated directory (multiple directories can be joined by os.pathsep) The selection options can be listed multiple times to ignore different modules. """ % sys.argv[0]) class Ignore: def __init__(self, modules = None, dirs = None): self._mods = modules or [] self._dirs = dirs or [] self._ignore = { '': 1 } def names(self, filename, modulename): if self._ignore.has_key(modulename): return self._ignore[modulename] # haven't seen this one before, so see if the module name is # on the ignore list. Need to take some care since ignoring # "cmp" musn't mean ignoring "cmpcache" but ignoring # "Spam" must also mean ignoring "Spam.Eggs". for mod in self._mods: if mod == modulename: # Identical names, so ignore self._ignore[modulename] = 1 return 1 # check if the module is a proper submodule of something on # the ignore list n = len(mod) # (will not overflow since if the first n characters are the # same and the name has not already occured, then the size # of "name" is greater than that of "mod") if mod == modulename[:n] and modulename[n] == '.': self._ignore[modulename] = 1 return 1 # Now check that __file__ isn't in one of the directories if filename is None: # must be a built-in, so we must ignore self._ignore[modulename] = 1 return 1 # Ignore a file when it contains one of the ignorable paths for d in self._dirs: # The '+ os.sep' is to ensure that d is a parent directory, # as compared to cases like: # d = "/usr/local" # filename = "/usr/local.py" # or # d = "/usr/local.py" # filename = "/usr/local.py" if string.find(filename, d + os.sep) == 0: self._ignore[modulename] = 1 return 1 # Tried the different ways, so we don't ignore this module self._ignore[modulename] = 0 return 0 def run(trace, cmd): import __main__ dict = __main__.__dict__ sys.settrace(trace) try: exec cmd in dict, dict finally: sys.settrace(None) def runctx(trace, cmd, globals=None, locals=None): if globals is None: globals = {} if locals is None: locals = {} sys.settrace(trace) try: exec cmd in dict, dict finally: sys.settrace(None) def runfunc(trace, func, *args, **kw): result = None sys.settrace(trace) try: result = apply(func, args, kw) finally: sys.settrace(None) return result class CoverageResults: def __init__(self, counts = {}, modules = {}): self.counts = counts.copy() # map (filename, lineno) to count self.modules = modules.copy() # map filenames to modules def update(self, other): """Merge in the data from another CoverageResults""" counts = self.counts other_counts = other.counts modules = self.modules other_modules = other.modules for key in other_counts.keys(): counts[key] = counts.get(key, 0) + other_counts[key] for key in other_modules.keys(): if modules.has_key(key): # make sure they point to the same file assert modules[key] == other_modules[key], \ "Strange! filename %s has two different module " \ "names: %s and %s" % \ (key, modules[key], other_modules[key]) else: modules[key] = other_modules[key] # Given a code string, return the SET_LINENO information def _find_LINENO_from_string(co_code): """return all of the SET_LINENO information from a code string""" import dis linenos = {} # This code was filched from the `dis' module then modified n = len(co_code) i = 0 prev_op = None prev_lineno = 0 while i < n: c = co_code[i] op = ord(c) if op == dis.SET_LINENO: if prev_op == op: # two SET_LINENO in a row, so the previous didn't # indicate anything. This occurs with triple # quoted strings (?). Remove the old one. del linenos[prev_lineno] prev_lineno = ord(co_code[i+1]) + ord(co_code[i+2])*256 linenos[prev_lineno] = 1 if op >= dis.HAVE_ARGUMENT: i = i + 3 else: i = i + 1 prev_op = op return linenos def _find_LINENO(code): """return all of the SET_LINENO information from a code object""" import types # get all of the lineno information from the code of this scope level linenos = _find_LINENO_from_string(code.co_code) # and check the constants for references to other code objects for c in code.co_consts: if type(c) == types.CodeType: # find another code object, so recurse into it linenos.update(_find_LINENO(c)) return linenos def find_executable_linenos(filename): """return a dict of the line numbers from executable statements in a file Works by finding all of the code-like objects in the module then searching the byte code for 'SET_LINENO' terms (so this won't work one -O files). """ import parser assert filename.endswith('.py') prog = open(filename).read() ast = parser.suite(prog) code = parser.compileast(ast, filename) # The only way I know to find line numbers is to look for the # SET_LINENO instructions. Isn't there some way to get it from # the AST? return _find_LINENO(code) ### XXX because os.path.commonprefix seems broken by my way of thinking... def commonprefix(dirs): "Given a list of pathnames, returns the longest common leading component" if not dirs: return '' n = copy.copy(dirs) for i in range(len(n)): n[i] = n[i].split(os.sep) prefix = n[0] for item in n: for i in range(len(prefix)): if prefix[:i+1] <> item[:i+1]: prefix = prefix[:i] if i == 0: return '' break return os.sep.join(prefix) def create_results_log(results, dirname = ".", show_missing = 1, save_counts = 0, summary = 0, coverdir = None): import re # turn the counts data ("(filename, lineno) = count") into something # accessible on a per-file basis per_file = {} for filename, lineno in results.counts.keys(): lines_hit = per_file[filename] = per_file.get(filename, {}) lines_hit[lineno] = results.counts[(filename, lineno)] # try and merge existing counts and modules file from dirname try: counts = marshal.load(open(os.path.join(dirname, "counts"))) modules = marshal.load(open(os.path.join(dirname, "modules"))) results.update(results.__class__(counts, modules)) except IOError: pass # there are many places where this is insufficient, like a blank # line embedded in a multiline string. blank = re.compile(r'^\s*(#.*)?$') # accumulate summary info, if needed sums = {} # generate file paths for the coverage files we are going to write... fnlist = [] tfdir = tempfile.gettempdir() for key in per_file.keys(): filename = key # skip some "files" we don't care about... if filename == "": continue # are these caused by code compiled using exec or something? if filename.startswith(tfdir): continue modulename = os.path.split(results.modules[key])[1] if filename.endswith(".pyc") or filename.endswith(".pyo"): filename = filename[:-1] if coverdir: listfilename = os.path.join(coverdir, modulename + ".cover") else: # XXX this is almost certainly not portable!!! fndir = os.path.dirname(filename) if os.path.isabs(filename): coverpath = fndir else: coverpath = os.path.join(dirname, fndir) # build list file name by appending a ".cover" to the module name # and sticking it into the specified directory if "." in modulename: # A module in a package finalname = modulename.split(".")[-1] listfilename = os.path.join(coverpath, finalname + ".cover") else: listfilename = os.path.join(coverpath, modulename + ".cover") # Get the original lines from the .py file try: lines = open(filename, 'r').readlines() except IOError, err: print >> sys.stderr, "trace: Could not open %s for reading " \ "because: %s - skipping" % (`filename`, err.strerror) continue try: outfile = open(listfilename, 'w') except IOError, err: sys.stderr.write( '%s: Could not open %s for writing because: %s" \ "- skipping\n' % ("trace", `listfilename`, err.strerror)) continue # If desired, get a list of the line numbers which represent # executable content (returned as a dict for better lookup speed) if show_missing: executable_linenos = find_executable_linenos(filename) else: executable_linenos = {} n_lines = 0 n_hits = 0 lines_hit = per_file[key] for i in range(len(lines)): line = lines[i] # do the blank/comment match to try to mark more lines # (help the reader find stuff that hasn't been covered) if lines_hit.has_key(i+1): # count precedes the lines that we captured outfile.write('%5d: ' % lines_hit[i+1]) n_hits = n_hits + 1 n_lines = n_lines + 1 elif blank.match(line): # blank lines and comments are preceded by dots outfile.write(' . ') else: # lines preceded by no marks weren't hit # Highlight them if so indicated, unless the line contains # '#pragma: NO COVER' (it is possible to embed this into # the text as a non-comment; no easy fix) if executable_linenos.has_key(i+1) and \ string.find(lines[i], string.join(['#pragma', 'NO COVER'])) == -1: outfile.write('>>>>>> ') else: outfile.write(' '*7) n_lines = n_lines + 1 outfile.write(string.expandtabs(lines[i], 8)) outfile.close() if summary and n_lines: percent = int(100 * n_hits / n_lines) sums[modulename] = n_lines, percent, modulename, filename if save_counts: # try and store counts and module info into dirname try: marshal.dump(results.counts, open(os.path.join(dirname, "counts"), "w")) marshal.dump(results.modules, open(os.path.join(dirname, "modules"), "w")) except IOError, err: sys.stderr.write("cannot save counts/modules " \ "files because %s" % err.strerror) if summary and sums: mods = sums.keys() mods.sort() print "lines cov% module (path)" for m in mods: n_lines, percent, modulename, filename = sums[m] print "%5d %3d%% %s (%s)" % sums[m] # There is a lot of code shared between these two classes even though # it is straightforward to make a super class to share code. However, # for performance reasons (remember, this is called at every step) I # wanted to keep everything to a single function call. Also, by # staying within a single scope, I don't have to temporarily nullify # sys.settrace, which would slow things down even more. class Coverage: def __init__(self, ignore = Ignore()): self.ignore = ignore self.ignore_names = ignore._ignore # access ignore's cache (speed hack) self.counts = {} # keys are (filename, linenumber) self.modules = {} # maps filename -> module name def trace(self, frame, why, arg): if why == 'line': # something is fishy about getting the file name filename = frame.f_globals.get("__file__", None) if filename is None: filename = frame.f_code.co_filename try: modulename = frame.f_globals["__name__"] except KeyError: # PyRun_String() for example # XXX what to do? modulename = None # We do this next block to keep from having to make methods # calls, which also requires resetting the trace ignore_it = self.ignore_names.get(modulename, -1) if ignore_it == -1: # unknown filename sys.settrace(None) ignore_it = self.ignore.names(filename, modulename) sys.settrace(self.trace) # record the module name for every file self.modules[filename] = modulename if not ignore_it: lineno = frame.f_lineno # record the file name and line number of every trace key = (filename, lineno) self.counts[key] = self.counts.get(key, 0) + 1 return self.trace def results(self): return CoverageResults(self.counts, self.modules) class Trace: def __init__(self, ignore = Ignore()): self.ignore = ignore self.ignore_names = ignore._ignore # access ignore's cache (speed hack) self.files = {'': None} # stores lines from the .py file, # or None def trace(self, frame, why, arg): if why == 'line': filename = frame.f_code.co_filename try: modulename = frame.f_globals["__name__"] except KeyError: # PyRun_String() for example # XXX what to do? modulename = None # We do this next block to keep from having to make methods # calls, which also requires resetting the trace ignore_it = self.ignore_names.get(modulename, -1) if ignore_it == -1: # unknown filename sys.settrace(None) ignore_it = self.ignore.names(filename, modulename) sys.settrace(self.trace) if not ignore_it: lineno = frame.f_lineno files = self.files if filename != '' and not files.has_key(filename): files[filename] = map(string.rstrip, open(filename).readlines()) # If you want to see filenames (the original behaviour), try: # modulename = filename # or, prettier but confusing when several files have the # same name # modulename = os.path.basename(filename) if files[filename] != None: print '%s(%d): %s' % (os.path.basename(filename), lineno, files[filename][lineno-1]) else: print '%s(%d): ??' % (modulename, lineno) return self.trace def _err_exit(msg): print >> sys.stderr, "%s: %s" % (sys.argv[0], msg) sys.exit(1) def main(argv = None): import getopt if argv is None: argv = sys.argv try: opts, prog_argv = getopt.getopt(argv[1:], "tcrRf:d:msC:", ["help", "version", "trace", "count", "report", "no-report", "file=", "logdir=", "missing", "ignore-module=", "ignore-dir=", "coverdir="]) except getopt.error, msg: print >> sys.stderr, "%s: %s" % (sys.argv[0], msg) print >> sys.stderr, "Try `%s --help' for more information" \ % sys.argv[0] sys.exit(1) trace = 0 count = 0 report = 0 no_report = 0 counts_file = None logdir = "." missing = 0 ignore_modules = [] ignore_dirs = [] coverdir = None summary = 0 for opt, val in opts: if opt == "--help": usage(sys.stdout) sys.exit(0) if opt == "--version": sys.stdout.write("trace 2.0\n") sys.exit(0) if opt == "-t" or opt == "--trace": trace = 1 continue if opt == "-c" or opt == "--count": count = 1 continue if opt == "-r" or opt == "--report": report = 1 continue if opt == "-R" or opt == "--no-report": no_report = 1 continue if opt == "-f" or opt == "--file": counts_file = val continue if opt == "-d" or opt == "--logdir": logdir = val continue if opt == "-m" or opt == "--missing": missing = 1 continue if opt == "-C" or opt == "--coverdir": coverdir = val continue if opt == "-s" or opt == "--summary": summary = 1 continue if opt == "--ignore-module": ignore_modules.append(val) continue if opt == "--ignore-dir": for s in string.split(val, os.pathsep): s = os.path.expandvars(s) # should I also call expanduser? (after all, could use $HOME) s = string.replace(s, "$prefix", os.path.join(sys.prefix, "lib", "python" + sys.version[:3])) s = string.replace(s, "$exec_prefix", os.path.join(sys.exec_prefix, "lib", "python" + sys.version[:3])) s = os.path.normpath(s) ignore_dirs.append(s) continue assert 0, "Should never get here" if len(prog_argv) == 0: _err_exit("missing name of file to run") if count + trace + report > 1: _err_exit("can only specify one of --trace, --count or --report") if count + trace + report == 0: _err_exit("must specify one of --trace, --count or --report") if report and counts_file is None: _err_exit("--report requires a --file") if report and no_report: _err_exit("cannot specify both --report and --no-report") if logdir is not None: # warn if the directory doesn't exist, but keep on going # (is this the correct behaviour?) if not os.path.isdir(logdir): sys.stderr.write( "trace: WARNING, --logdir directory %s is not available\n" % `logdir`) sys.argv = prog_argv progname = prog_argv[0] if eval(sys.version[:3])>1.3: sys.path[0] = os.path.split(progname)[0] # ??? # everything is ready ignore = Ignore(ignore_modules, ignore_dirs) if trace: t = Trace(ignore) try: run(t.trace, 'execfile(' + `progname` + ')') except IOError, err: _err_exit("Cannot run file %s because: %s" % \ (`sys.argv[0]`, err.strerror)) elif count: t = Coverage(ignore) try: run(t.trace, 'execfile(' + `progname` + ')') except IOError, err: _err_exit("Cannot run file %s because: %s" % \ (`sys.argv[0]`, err.strerror)) except SystemExit: pass results = t.results() # Add another lookup from the program's file name to its import name # This give the right results, but I'm not sure why ... results.modules[progname] = os.path.splitext(progname)[0] if counts_file: # add in archived data, if available try: old_counts, old_modules = marshal.load(open(counts_file, 'rb')) except IOError: pass else: results.update(CoverageResults(old_counts, old_modules)) if not no_report: create_results_log(results, logdir, missing, summary=summary, coverdir=coverdir) if counts_file: try: marshal.dump( (results.counts, results.modules), open(counts_file, 'wb')) except IOError, err: _err_exit("Cannot save counts file %s because: %s" % \ (`counts_file`, err.strerror)) elif report: old_counts, old_modules = marshal.load(open(counts_file, 'rb')) results = CoverageResults(old_counts, old_modules) create_results_log(results, logdir, missing, summary=summary, coverdir=coverdir) else: assert 0, "Should never get here" if __name__=='__main__': main() --- NEW FILE: treesync.py --- #! /usr/bin/env python """Script to synchronize two source trees. Invoke with two arguments: python treesync.py slave master The assumption is that "master" contains CVS administration while slave doesn't. All files in the slave tree that have a CVS/Entries entry in the master tree are synchronized. This means: If the files differ: if the slave file is newer: normalize the slave file if the files still differ: copy the slave to the master else (the master is newer): copy the master to the slave normalizing the slave means replacing CRLF with LF when the master doesn't use CRLF """ import os, sys, stat, string, getopt # Interactivity options default_answer = "ask" create_files = "yes" create_directories = "no" write_slave = "ask" write_master = "ask" def main(): global always_no, always_yes global create_directories, write_master, write_slave opts, args = getopt.getopt(sys.argv[1:], "nym:s:d:f:a:") for o, a in opts: if o == '-y': default_answer = "yes" if o == '-n': default_answer = "no" if o == '-s': write_slave = a if o == '-m': write_master = a if o == '-d': create_directories = a if o == '-f': create_files = a if o == '-a': create_files = create_directories = write_slave = write_master = a try: [slave, master] = args except ValueError: print "usage: python", sys.argv[0] or "treesync.py", print "[-n] [-y] [-m y|n|a] [-s y|n|a] [-d y|n|a] [-f n|y|a]", print "slavedir masterdir" return process(slave, master) def process(slave, master): cvsdir = os.path.join(master, "CVS") if not os.path.isdir(cvsdir): print "skipping master subdirectory", master print "-- not under CVS" return print "-"*40 print "slave ", slave print "master", master if not os.path.isdir(slave): if not okay("create slave directory %s?" % slave, answer=create_directories): print "skipping master subdirectory", master print "-- no corresponding slave", slave return print "creating slave directory", slave try: os.mkdir(slave) except os.error, msg: print "can't make slave directory", slave, ":", msg return else: print "made slave directory", slave cvsdir = None subdirs = [] names = os.listdir(master) for name in names: mastername = os.path.join(master, name) slavename = os.path.join(slave, name) if name == "CVS": cvsdir = mastername else: if os.path.isdir(mastername) and not os.path.islink(mastername): subdirs.append((slavename, mastername)) if cvsdir: entries = os.path.join(cvsdir, "Entries") for e in open(entries).readlines(): words = string.split(e, '/') if words[0] == '' and words[1:]: name = words[1] s = os.path.join(slave, name) m = os.path.join(master, name) compare(s, m) for (s, m) in subdirs: process(s, m) def compare(slave, master): try: sf = open(slave, 'r') except IOError: sf = None try: mf = open(master, 'rb') except IOError: mf = None if not sf: if not mf: print "Neither master nor slave exists", master return print "Creating missing slave", slave copy(master, slave, answer=create_files) return if not mf: print "Not updating missing master", master return if sf and mf: if identical(sf, mf): return sft = mtime(sf) mft = mtime(mf) if mft > sft: # Master is newer -- copy master to slave sf.close() mf.close() print "Master ", master print "is newer than slave", slave copy(master, slave, answer=write_slave) return # Slave is newer -- copy slave to master print "Slave is", sft-mft, "seconds newer than master" # But first check what to do about CRLF mf.seek(0) fun = funnychars(mf) mf.close() sf.close() if fun: print "***UPDATING MASTER (BINARY COPY)***" copy(slave, master, "rb", answer=write_master) else: print "***UPDATING MASTER***" copy(slave, master, "r", answer=write_master) BUFSIZE = 16*1024 def identical(sf, mf): while 1: sd = sf.read(BUFSIZE) md = mf.read(BUFSIZE) if sd != md: return 0 if not sd: break return 1 def mtime(f): st = os.fstat(f.fileno()) return st[stat.ST_MTIME] def funnychars(f): while 1: buf = f.read(BUFSIZE) if not buf: break if '\r' in buf or '\0' in buf: return 1 return 0 def copy(src, dst, rmode="rb", wmode="wb", answer='ask'): print "copying", src print " to", dst if not okay("okay to copy? ", answer): return f = open(src, rmode) g = open(dst, wmode) while 1: buf = f.read(BUFSIZE) if not buf: break g.write(buf) f.close() g.close() def okay(prompt, answer='ask'): answer = string.lower(string.strip(answer)) if not answer or answer[0] not in 'ny': answer = raw_input(prompt) answer = string.lower(string.strip(answer)) if not answer: answer = default_answer if answer[:1] == 'y': return 1 if answer[:1] == 'n': return 0 print "Yes or No please -- try again:" return okay(prompt) main() --- NEW FILE: untabify.py --- #! /usr/bin/env python "Replace tabs with spaces in argument files. Print names of changed files." import os import sys import string import getopt def main(): tabsize = 8 try: opts, args = getopt.getopt(sys.argv[1:], "t:") if not args: raise getopt.error, "At least one file argument required" except getopt.error, msg: print msg print "usage:", sys.argv[0], "[-t tabwidth] file ..." return for optname, optvalue in opts: if optname == '-t': tabsize = int(optvalue) for file in args: process(file, tabsize) def process(file, tabsize): try: f = open(file) text = f.read() f.close() except IOError, msg: print "%s: I/O error: %s" % (`file`, str(msg)) return newtext = string.expandtabs(text, tabsize) if newtext == text: return backup = file + "~" try: os.unlink(backup) except os.error: pass try: os.rename(file, backup) except os.error: pass f = open(file, "w") f.write(newtext) f.close() print file if __name__ == '__main__': main() --- NEW FILE: which.py --- #! /usr/bin/env python # Variant of "which". # On stderr, near and total misses are reported. # '-l' argument adds ls -l of each file found. import sys if sys.path[0] in (".", ""): del sys.path[0] import sys, os, string from stat import * def msg(str): sys.stderr.write(str + '\n') pathlist = string.splitfields(os.environ['PATH'], ':') sts = 0 longlist = '' if sys.argv[1:] and sys.argv[1][:2] == '-l': longlist = sys.argv[1] del sys.argv[1] for prog in sys.argv[1:]: ident = () for dir in pathlist: file = os.path.join(dir, prog) try: st = os.stat(file) except os.error: continue if not S_ISREG(st[ST_MODE]): msg(file + ': not a disk file') else: mode = S_IMODE(st[ST_MODE]) if mode & 0111: if not ident: print file ident = st[:3] else: if st[:3] == ident: s = 'same as: ' else: s = 'also: ' msg(s + file) else: msg(file + ': not executable') if longlist: sts = os.system('ls ' + longlist + ' ' + file) if sts: msg('"ls -l" exit status: ' + `sts`) if not ident: msg(prog + ': not found') sts = 1 sys.exit(sts) --- NEW FILE: xxci.py --- #! /usr/bin/env python # xxci # # check in files for which rcsdiff returns nonzero exit status import sys import os from stat import * import commands import fnmatch import string EXECMAGIC = '\001\140\000\010' MAXSIZE = 200*1024 # Files this big must be binaries and are skipped. def getargs(): args = sys.argv[1:] if args: return args print 'No arguments, checking almost *, in "ls -t" order' list = [] for file in os.listdir(os.curdir): if not skipfile(file): list.append((getmtime(file), file)) list.sort() if not list: print 'Nothing to do -- exit 1' sys.exit(1) list.sort() list.reverse() for mtime, file in list: args.append(file) return args def getmtime(file): try: st = os.stat(file) return st[ST_MTIME] except os.error: return -1 badnames = ['tags', 'TAGS', 'xyzzy', 'nohup.out', 'core'] badprefixes = ['.', ',', '@', '#', 'o.'] badsuffixes = \ ['~', '.a', '.o', '.old', '.bak', '.orig', '.new', '.prev', '.not', \ '.pyc', '.fdc', '.rgb', '.elc', ',v'] ignore = [] def setup(): ignore[:] = badnames for p in badprefixes: ignore.append(p + '*') for p in badsuffixes: ignore.append('*' + p) try: f = open('.xxcign', 'r') except IOError: return ignore[:] = ignore + string.split(f.read()) def skipfile(file): for p in ignore: if fnmatch.fnmatch(file, p): return 1 try: st = os.lstat(file) except os.error: return 1 # Doesn't exist -- skip it # Skip non-plain files. if not S_ISREG(st[ST_MODE]): return 1 # Skip huge files -- probably binaries. if st[ST_SIZE] >= MAXSIZE: return 1 # Skip executables try: data = open(file, 'r').read(len(EXECMAGIC)) if data == EXECMAGIC: return 1 except: pass return 0 def badprefix(file): for bad in badprefixes: if file[:len(bad)] == bad: return 1 return 0 def badsuffix(file): for bad in badsuffixes: if file[-len(bad):] == bad: return 1 return 0 def go(args): for file in args: print file + ':' if differing(file): showdiffs(file) if askyesno('Check in ' + file + ' ? '): sts = os.system('rcs -l ' + file) # ignored sts = os.system('ci -l ' + file) def differing(file): cmd = 'co -p ' + file + ' 2>/dev/null | cmp -s - ' + file sts = os.system(cmd) return sts != 0 def showdiffs(file): cmd = 'rcsdiff ' + file + ' 2>&1 | ${PAGER-more}' sts = os.system(cmd) def askyesno(prompt): s = raw_input(prompt) return s in ['y', 'yes'] try: setup() go(getargs()) except KeyboardInterrupt: print '[Intr]' From fdrake@users.sourceforge.net Fri Jul 6 18:17:14 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 06 Jul 2001 10:17:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libpopen2.tex,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv5638/lib Modified Files: libpopen2.tex Log Message: Explain the exit code for the wait() method, including a reference to the os.W*() functions used to interpret the return value. This fixes SF bug #429361. Index: libpopen2.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libpopen2.tex,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -r1.13 -r1.14 *** libpopen2.tex 2000/09/28 20:27:51 1.13 --- libpopen2.tex 2001/07/06 17:17:12 1.14 *************** *** 78,82 **** \begin{methoddesc}{wait}{} ! Waits for and returns the return code of the child process. \end{methoddesc} --- 78,87 ---- \begin{methoddesc}{wait}{} ! Waits for and returns the status code of the child process. The ! status code encodes both the return code of the process and ! information about whether it exited using the \cfunction{exit()} ! system call or died due to a signal. Functions to help interpret the ! status code are defined in the \refmodule{os} module; see section ! \ref{os-process} for the \function{W\var{*}()} family of functions. \end{methoddesc} From fdrake@users.sourceforge.net Fri Jul 6 18:18:07 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 06 Jul 2001 10:18:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libpopen2.tex,1.13,1.13.6.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv5879/lib Modified Files: Tag: release21-maint libpopen2.tex Log Message: Explain the exit code for the wait() method, including a reference to the os.W*() functions used to interpret the return value. This fixes SF bug #429361. Index: libpopen2.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libpopen2.tex,v retrieving revision 1.13 retrieving revision 1.13.6.1 diff -C2 -r1.13 -r1.13.6.1 *** libpopen2.tex 2000/09/28 20:27:51 1.13 --- libpopen2.tex 2001/07/06 17:18:05 1.13.6.1 *************** *** 78,82 **** \begin{methoddesc}{wait}{} ! Waits for and returns the return code of the child process. \end{methoddesc} --- 78,87 ---- \begin{methoddesc}{wait}{} ! Waits for and returns the status code of the child process. The ! status code encodes both the return code of the process and ! information about whether it exited using the \cfunction{exit()} ! system call or died due to a signal. Functions to help interpret the ! status code are defined in the \refmodule{os} module; see section ! \ref{os-process} for the \function{W\var{*}()} family of functions. \end{methoddesc} From fdrake@users.sourceforge.net Fri Jul 6 18:22:50 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 06 Jul 2001 10:22:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib ConfigParser.py,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv7578/Lib Modified Files: ConfigParser.py Log Message: When reading a continuation line, make sure we still use the transformed name when filling in the internal data structures, otherwise we incorrectly raise a KeyError. This fixes SF bug #432369. Index: ConfigParser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/ConfigParser.py,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -r1.32 -r1.33 *** ConfigParser.py 2001/02/26 21:55:34 1.32 --- ConfigParser.py 2001/07/06 17:22:48 1.33 *************** *** 432,436 **** value = line.strip() if value: ! cursect[optname] = cursect[optname] + '\n ' + value # a section header or option header? else: --- 432,437 ---- value = line.strip() if value: ! k = self.optionxform(optname) ! cursect[k] = "%s\n%s" % (cursect[k], value) # a section header or option header? else: From fdrake@users.sourceforge.net Fri Jul 6 18:22:50 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 06 Jul 2001 10:22:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_cfgparser.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv7578/Lib/test Modified Files: test_cfgparser.py Log Message: When reading a continuation line, make sure we still use the transformed name when filling in the internal data structures, otherwise we incorrectly raise a KeyError. This fixes SF bug #432369. Index: test_cfgparser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_cfgparser.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** test_cfgparser.py 2001/02/26 21:55:34 1.7 --- test_cfgparser.py 2001/07/06 17:22:48 1.8 *************** *** 71,74 **** --- 71,81 ---- verify(cf.options("a") == []) + # SF bug #432369: + cf = ConfigParser.ConfigParser() + sio = StringIO.StringIO("[MySection]\nOption: first line\n\tsecond line\n") + cf.readfp(sio) + verify(cf.options("MySection") == ["option"]) + verify(cf.get("MySection", "Option") == "first line\nsecond line") + def interpolation(src): From fdrake@users.sourceforge.net Fri Jul 6 18:23:24 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 06 Jul 2001 10:23:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib ConfigParser.py,1.32,1.32.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv7784/Lib Modified Files: Tag: release21-maint ConfigParser.py Log Message: When reading a continuation line, make sure we still use the transformed name when filling in the internal data structures, otherwise we incorrectly raise a KeyError. This fixes SF bug #432369. Index: ConfigParser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/ConfigParser.py,v retrieving revision 1.32 retrieving revision 1.32.4.1 diff -C2 -r1.32 -r1.32.4.1 *** ConfigParser.py 2001/02/26 21:55:34 1.32 --- ConfigParser.py 2001/07/06 17:23:22 1.32.4.1 *************** *** 432,436 **** value = line.strip() if value: ! cursect[optname] = cursect[optname] + '\n ' + value # a section header or option header? else: --- 432,437 ---- value = line.strip() if value: ! k = self.optionxform(optname) ! cursect[k] = "%s\n%s" % (cursect[k], value) # a section header or option header? else: From fdrake@users.sourceforge.net Fri Jul 6 18:23:24 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 06 Jul 2001 10:23:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_cfgparser.py,1.7,1.7.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv7784/Lib/test Modified Files: Tag: release21-maint test_cfgparser.py Log Message: When reading a continuation line, make sure we still use the transformed name when filling in the internal data structures, otherwise we incorrectly raise a KeyError. This fixes SF bug #432369. Index: test_cfgparser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_cfgparser.py,v retrieving revision 1.7 retrieving revision 1.7.4.1 diff -C2 -r1.7 -r1.7.4.1 *** test_cfgparser.py 2001/02/26 21:55:34 1.7 --- test_cfgparser.py 2001/07/06 17:23:22 1.7.4.1 *************** *** 71,74 **** --- 71,81 ---- verify(cf.options("a") == []) + # SF bug #432369: + cf = ConfigParser.ConfigParser() + sio = StringIO.StringIO("[MySection]\nOption: first line\n\tsecond line\n") + cf.readfp(sio) + verify(cf.options("MySection") == ["option"]) + verify(cf.get("MySection", "Option") == "first line\nsecond line") + def interpolation(src): From fdrake@users.sourceforge.net Fri Jul 6 18:28:41 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 06 Jul 2001 10:28:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tut tut.tex,1.142,1.143 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tut In directory usw-pr-cvs1:/tmp/cvs-serv9280/tut Modified Files: tut.tex Log Message: Fix up a few style nits -- avoid "e.g." and "i.e." -- these make translation more difficult, as well as reading the English more difficult for non-native speakers. Index: tut.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tut/tut.tex,v retrieving revision 1.142 retrieving revision 1.143 diff -C2 -r1.142 -r1.143 *** tut.tex 2001/06/29 17:50:57 1.142 --- tut.tex 2001/07/06 17:28:39 1.143 *************** *** 243,247 **** \emph{secondary prompt}, by default three dots (\samp{...~}). The interpreter prints a welcome message stating its version number ! and a copyright notice before printing the first prompt, e.g.: \begin{verbatim} --- 243,247 ---- \emph{secondary prompt}, by default three dots (\samp{...~}). The interpreter prints a welcome message stating its version number ! and a copyright notice before printing the first prompt: \begin{verbatim} *************** *** 326,331 **** If you want to read an additional start-up file from the current ! directory, you can program this in the global start-up file, ! e.g.\ \samp{if os.path.isfile('.pythonrc.py'): execfile('.pythonrc.py')}. If you want to use the startup file in a script, you must do this explicitly in the script: --- 326,331 ---- If you want to read an additional start-up file from the current ! directory, you can program this in the global start-up file using code ! like \samp{if os.path.isfile('.pythonrc.py'): execfile('.pythonrc.py')}. If you want to use the startup file in a script, you must do this explicitly in the script: *************** *** 528,532 **** String literals can span multiple lines in several ways. Newlines can ! be escaped with backslashes, e.g.: \begin{verbatim} --- 528,532 ---- String literals can span multiple lines in several ways. Newlines can ! be escaped with backslashes: \begin{verbatim} *************** *** 729,733 **** For non-negative indices, the length of a slice is the difference of ! the indices, if both are within bounds, e.g., the length of \code{word[1:3]} is 2. --- 729,733 ---- For non-negative indices, the length of a slice is the difference of ! the indices, if both are within bounds. For example, the length of \code{word[1:3]} is 2. *************** *** 800,805 **** \end{verbatim} ! The raw mode is most useful when you have to enter lots of backslashes ! e.g. in regular expressions. Apart from these standard encodings, Python provides a whole set of --- 800,805 ---- \end{verbatim} ! The raw mode is most useful when you have to enter lots of ! backslashes, as can be necessary in regular expressions. Apart from these standard encodings, Python provides a whole set of *************** *** 1074,1078 **** halting condition (as C), Python's \keyword{for}\stindex{for} statement iterates over the items of any ! sequence (e.g., a list or a string), in the order that they appear in the sequence. For example (no pun intended): % One suggestion was to give a real C example here, but that may only --- 1074,1078 ---- halting condition (as C), Python's \keyword{for}\stindex{for} statement iterates over the items of any ! sequence (a list or a string), in the order that they appear in the sequence. For example (no pun intended): % One suggestion was to give a real C example here, but that may only *************** *** 1091,1098 **** It is not safe to modify the sequence being iterated over in the loop ! (this can only happen for mutable sequence types, i.e., lists). If ! you need to modify the list you are iterating over, e.g., duplicate ! selected items, you must iterate over a copy. The slice notation ! makes this particularly convenient: \begin{verbatim} --- 1091,1098 ---- It is not safe to modify the sequence being iterated over in the loop ! (this can only happen for mutable sequence types, such as lists). If ! you need to modify the list you are iterating over (for example, to ! duplicate selected items) you must iterate over a copy. The slice ! notation makes this particularly convenient: \begin{verbatim} *************** *** 1109,1113 **** If you do need to iterate over a sequence of numbers, the built-in function \function{range()} comes in handy. It generates lists ! containing arithmetic progressions, e.g.: \begin{verbatim} --- 1109,1113 ---- If you do need to iterate over a sequence of numbers, the built-in function \function{range()} comes in handy. It generates lists ! containing arithmetic progressions: \begin{verbatim} *************** *** 1246,1250 **** Actually, \emph{call by object reference} would be a better description, since if a mutable object is passed, the caller ! will see any changes the callee makes to it (e.g., items inserted into a list). } When a function calls another function, a new local symbol table is --- 1246,1250 ---- Actually, \emph{call by object reference} would be a better description, since if a mutable object is passed, the caller ! will see any changes the callee makes to it (items inserted into a list). } When a function calls another function, a new local symbol table is *************** *** 1332,1336 **** The most useful form is to specify a default value for one or more arguments. This creates a function that can be called with fewer ! arguments than it is defined, e.g. \begin{verbatim} --- 1332,1336 ---- The most useful form is to specify a default value for one or more arguments. This creates a function that can be called with fewer ! arguments than it is defined \begin{verbatim} *************** *** 1350,1354 **** The default values are evaluated at the point of function definition ! in the \emph{defining} scope, so that e.g. \begin{verbatim} --- 1350,1354 ---- The default values are evaluated at the point of function definition ! in the \emph{defining} scope, so that \begin{verbatim} *************** *** 1510,1514 **** function definition. Like nested function definitions, lambda forms cannot reference variables from the containing scope, but this can be ! overcome through the judicious use of default argument values, e.g. \begin{verbatim} --- 1510,1514 ---- function definition. Like nested function definitions, lambda forms cannot reference variables from the containing scope, but this can be ! overcome through the judicious use of default argument values: \begin{verbatim} *************** *** 1854,1858 **** \section{Tuples and Sequences \label{tuples}} ! We saw that lists and strings have many common properties, e.g., indexing and slicing operations. They are two examples of \emph{sequence} data types. Since Python is an evolving language, --- 1854,1858 ---- \section{Tuples and Sequences \label{tuples}} ! We saw that lists and strings have many common properties, such as indexing and slicing operations. They are two examples of \emph{sequence} data types. Since Python is an evolving language, *************** *** 1880,1886 **** necessary anyway (if the tuple is part of a larger expression). ! Tuples have many uses, e.g., (x, y) coordinate pairs, employee records ! from a database, etc. Tuples, like strings, are immutable: it is not ! possible to assign to the individual items of a tuple (you can simulate much of the same effect with slicing and concatenation, though). It is also possible to create tuples which contain mutable --- 1880,1886 ---- necessary anyway (if the tuple is part of a larger expression). ! Tuples have many uses. For example: (x, y) coordinate pairs, employee ! records from a database, etc. Tuples, like strings, are immutable: it ! is not possible to assign to the individual items of a tuple (you can simulate much of the same effect with slicing and concatenation, though). It is also possible to create tuples which contain mutable *************** *** 1908,1912 **** \emph{tuple packing}: the values \code{12345}, \code{54321} and \code{'hello!'} are packed together in a tuple. The reverse operation ! is also possible, e.g.: \begin{verbatim} --- 1908,1912 ---- \emph{tuple packing}: the values \code{12345}, \code{54321} and \code{'hello!'} are packed together in a tuple. The reverse operation ! is also possible: \begin{verbatim} *************** *** 1993,1998 **** operators. ! Comparisons can be chained: e.g., \code{a < b == c} tests whether ! \code{a} is less than \code{b} and moreover \code{b} equals \code{c}. Comparisons may be combined by the Boolean operators \code{and} and --- 1993,1999 ---- operators. ! Comparisons can be chained. For example, \code{a < b == c} tests ! whether \code{a} is less than \code{b} and moreover \code{b} equals ! \code{c}. Comparisons may be combined by the Boolean operators \code{and} and *************** *** 2199,2203 **** and then in the list of directories specified by the environment variable \envvar{PYTHONPATH}. This has the same syntax as ! the shell variable \envvar{PATH}, i.e., a list of directory names. When \envvar{PYTHONPATH} is not set, or when the file is not found there, the search continues in an installation-dependent --- 2200,2204 ---- and then in the list of directories specified by the environment variable \envvar{PYTHONPATH}. This has the same syntax as ! the shell variable \envvar{PATH}, that is, a list of directory names. When \envvar{PYTHONPATH} is not set, or when the file is not found there, the search continues in an installation-dependent *************** *** 2290,2294 **** the core of the language but are nevertheless built in, either for efficiency or to provide access to operating system primitives such as ! system calls. The set of such modules is a configuration option; e.g., the \module{amoeba} module is only provided on systems that somehow support Amoeba primitives. One particular module deserves some --- 2291,2296 ---- the core of the language but are nevertheless built in, either for efficiency or to provide access to operating system primitives such as ! system calls. The set of such modules is a configuration option which ! also dependson the underlying platform For example, the \module{amoeba} module is only provided on systems that somehow support Amoeba primitives. One particular module deserves some *************** *** 2317,2321 **** path taken from the environment variable \envvar{PYTHONPATH}, or from a built-in default if \envvar{PYTHONPATH} is not set. You can modify ! it using standard list operations, e.g.: \begin{verbatim} --- 2319,2323 ---- path taken from the environment variable \envvar{PYTHONPATH}, or from a built-in default if \envvar{PYTHONPATH} is not set. You can modify ! it using standard list operations: \begin{verbatim} *************** *** 2385,2397 **** the uniform handling of sound files and sound data. There are many different sound file formats (usually recognized by their extension, ! e.g. \file{.wav}, \file{.aiff}, \file{.au}), so you may need to create ! and maintain a growing collection of modules for the conversion ! between the various file formats. There are also many different ! operations you might want to perform on sound data (e.g. mixing, ! adding echo, applying an equalizer function, creating an artificial ! stereo effect), so in addition you will be writing a never-ending ! stream of modules to perform these operations. Here's a possible ! structure for your package (expressed in terms of a hierarchical ! filesystem): \begin{verbatim} --- 2387,2399 ---- the uniform handling of sound files and sound data. There are many different sound file formats (usually recognized by their extension, ! for example: \file{.wav}, \file{.aiff}, \file{.au}), so you may need ! to create and maintain a growing collection of modules for the ! conversion between the various file formats. There are also many ! different operations you might want to perform on sound data (such as ! mixing, adding echo, applying an equalizer function, creating an ! artificial stereo effect), so in addition you will be writing a ! never-ending stream of modules to perform these operations. Here's a ! possible structure for your package (expressed in terms of a ! hierarchical filesystem): \begin{verbatim} *************** *** 2437,2441 **** This loads the submodule \module{Sound.Effects.echo}. It must be referenced ! with its full name, e.g. \begin{verbatim} --- 2439,2443 ---- This loads the submodule \module{Sound.Effects.echo}. It must be referenced ! with its full name. \begin{verbatim} *************** *** 2524,2528 **** submodules explicitly loaded) by \file{__init__.py}. It also includes any submodules of the package that were explicitly loaded by previous ! import statements, e.g. \begin{verbatim} --- 2526,2530 ---- submodules explicitly loaded) by \file{__init__.py}. It also includes any submodules of the package that were explicitly loaded by previous ! import statements. Consider this code: \begin{verbatim} *************** *** 2704,2709 **** \end{verbatim} ! If there is more than one format in the string you pass a tuple as ! right operand, e.g. \begin{verbatim} --- 2706,2711 ---- \end{verbatim} ! If there is more than one format in the string, you need to pass a ! tuple as right operand, as in this example: \begin{verbatim} *************** *** 2728,2732 **** up, it would be nice if you could reference the variables to be formatted by name instead of by position. This can be done by using ! an extension of C formats using the form \code{\%(name)format}, e.g. \begin{verbatim} --- 2730,2734 ---- up, it would be nice if you could reference the variables to be formatted by name instead of by position. This can be done by using ! form \code{\%(name)format}, as shown here: \begin{verbatim} *************** *** 3043,3048 **** be executed. Handlers only handle exceptions that occur in the corresponding try clause, not in other handlers of the same ! \keyword{try} statement. An except clause may name multiple exceptions ! as a parenthesized list, e.g.: \begin{verbatim} --- 3045,3050 ---- be executed. Handlers only handle exceptions that occur in the corresponding try clause, not in other handlers of the same ! \keyword{try} statement. An except clause may name multiple exceptions ! as a parenthesized list, for example: \begin{verbatim} *************** *** 3311,3316 **** assignment to attributes is possible. Module attributes are writable: you can write \samp{modname.the_answer = 42}. Writable attributes may ! also be deleted with the \keyword{del} statement, e.g. ! \samp{del modname.the_answer}. Name spaces are created at different moments and have different --- 3313,3319 ---- assignment to attributes is possible. Module attributes are writable: you can write \samp{modname.the_answer = 42}. Writable attributes may ! also be deleted with the \keyword{del} statement. For example, ! \samp{del modname.the_answer} will remove the attribute ! \member{the_answer} from the object named by \code{modname}. Name spaces are created at different moments and have different *************** *** 3339,3343 **** Although scopes are determined statically, they are used dynamically. At any time during execution, exactly three nested scopes are in use ! (i.e., exactly three namespaces are directly accessible): the innermost scope, which is searched first, contains the local names, the middle scope, searched next, contains the current module's global --- 3342,3346 ---- Although scopes are determined statically, they are used dynamically. At any time during execution, exactly three nested scopes are in use ! (exactly three namespaces are directly accessible): the innermost scope, which is searched first, contains the local names, the middle scope, searched next, contains the current module's global *************** *** 3513,3517 **** are \emph{methods}. A method is a function that ``belongs to'' an object. (In Python, the term method is not unique to class instances: ! other object types can have methods as well, e.g., list objects have methods called append, insert, remove, sort, and so on. However, below, we'll use the term method exclusively to mean methods of class --- 3516,3520 ---- are \emph{methods}. A method is a function that ``belongs to'' an object. (In Python, the term method is not unique to class instances: ! other object types can have methods as well. For example, list objects have methods called append, insert, remove, sort, and so on. However, below, we'll use the term method exclusively to mean methods of class *************** *** 3530,3534 **** \subsection{Method Objects \label{methodObjects}} ! Usually, a method is called immediately, e.g.: \begin{verbatim} --- 3533,3537 ---- \subsection{Method Objects \label{methodObjects}} ! Usually, a method is called immediately: \begin{verbatim} *************** *** 3584,3590 **** avoid accidental name conflicts, which may cause hard-to-find bugs in large programs, it is wise to use some kind of convention that ! minimizes the chance of conflicts, e.g., capitalize method names, ! prefix data attribute names with a small unique string (perhaps just ! an underscore), or use verbs for methods and nouns for data attributes. --- 3587,3594 ---- avoid accidental name conflicts, which may cause hard-to-find bugs in large programs, it is wise to use some kind of convention that ! minimizes the chance of conflicts. Possible conventions include ! capitalizing method names, prefixing data attribute names with a small ! unique string (perhaps just an underscore), or using verbs for methods ! and nouns for data attributes. *************** *** 3648,3652 **** Methods may call other methods by using method attributes of the ! \code{self} argument, e.g.: \begin{verbatim} --- 3652,3656 ---- Methods may call other methods by using method attributes of the ! \code{self} argument: \begin{verbatim} *************** *** 3691,3695 **** the derived class definition. Instead of a base class name, an expression is also allowed. This is useful when the base class is ! defined in another module, e.g., \begin{verbatim} --- 3695,3699 ---- the derived class definition. Instead of a base class name, an expression is also allowed. This is useful when the base class is ! defined in another module, \begin{verbatim} *************** *** 3786,3793 **** rules are designed mostly to avoid accidents; it still is possible for a determined soul to access or modify a variable that is considered ! private. This can even be useful, e.g. for the debugger, and that's ! one reason why this loophole is not closed. (Buglet: derivation of a ! class with the same name as the base class makes use of private ! variables of the base class possible.) Notice that code passed to \code{exec}, \code{eval()} or --- 3790,3797 ---- rules are designed mostly to avoid accidents; it still is possible for a determined soul to access or modify a variable that is considered ! private. This can even be useful in special circumstances, such as in ! the debugger, and that's one reason why this loophole is not closed. ! (Buglet: derivation of a class with the same name as the base class ! makes use of private variables of the base class possible.) Notice that code passed to \code{exec}, \code{eval()} or *************** *** 3825,3829 **** Sometimes it is useful to have a data type similar to the Pascal ``record'' or C ``struct'', bundling together a couple of named data ! items. An empty class definition will do nicely, e.g.: \begin{verbatim} --- 3829,3833 ---- Sometimes it is useful to have a data type similar to the Pascal ``record'' or C ``struct'', bundling together a couple of named data ! items. An empty class definition will do nicely: \begin{verbatim} From tim_one@users.sourceforge.net Fri Jul 6 18:45:45 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 06 Jul 2001 10:45:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects listobject.c,2.96,2.97 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv13211 Modified Files: listobject.c Log Message: SF bug #439104: Tuple richcompares has code-typo. Symptom: (1, 2, 3) <= (1, 2) returned 1. This was already fixed in CVS for tuples, but an isomorphic error was in the list richcompare code. Index: listobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v retrieving revision 2.96 retrieving revision 2.97 diff -C2 -r2.96 -r2.97 *** listobject.c 2001/06/16 05:11:17 2.96 --- listobject.c 2001/07/06 17:45:43 2.97 *************** *** 1513,1517 **** switch (op) { case Py_LT: cmp = vs < ws; break; ! case Py_LE: cmp = ws <= ws; break; case Py_EQ: cmp = vs == ws; break; case Py_NE: cmp = vs != ws; break; --- 1513,1517 ---- switch (op) { case Py_LT: cmp = vs < ws; break; ! case Py_LE: cmp = vs <= ws; break; case Py_EQ: cmp = vs == ws; break; case Py_NE: cmp = vs != ws; break; From tim_one@users.sourceforge.net Fri Jul 6 18:48:49 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 06 Jul 2001 10:48:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects listobject.c,2.92,2.92.4.1 tupleobject.c,2.48.4.2,2.48.4.3 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv14270/python-release21-maint/dist/src/Objects Modified Files: Tag: release21-maint listobject.c tupleobject.c Log Message: SF bug #439104: Tuple richcompares has code-typo. Symptom: (1, 2, 3) <= (1, 2) returned 1. Also an isomorphic error was in the list richcompare code. Index: listobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v retrieving revision 2.92 retrieving revision 2.92.4.1 diff -C2 -r2.92 -r2.92.4.1 *** listobject.c 2001/02/12 22:06:02 2.92 --- listobject.c 2001/07/06 17:48:47 2.92.4.1 *************** *** 1462,1466 **** switch (op) { case Py_LT: cmp = vs < ws; break; ! case Py_LE: cmp = ws <= ws; break; case Py_EQ: cmp = vs == ws; break; case Py_NE: cmp = vs != ws; break; --- 1462,1466 ---- switch (op) { case Py_LT: cmp = vs < ws; break; ! case Py_LE: cmp = vs <= ws; break; case Py_EQ: cmp = vs == ws; break; case Py_NE: cmp = vs != ws; break; Index: tupleobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/tupleobject.c,v retrieving revision 2.48.4.2 retrieving revision 2.48.4.3 diff -C2 -r2.48.4.2 -r2.48.4.3 *** tupleobject.c 2001/05/29 08:05:01 2.48.4.2 --- tupleobject.c 2001/07/06 17:48:47 2.48.4.3 *************** *** 415,419 **** switch (op) { case Py_LT: cmp = vs < ws; break; ! case Py_LE: cmp = ws <= ws; break; case Py_EQ: cmp = vs == ws; break; case Py_NE: cmp = vs != ws; break; --- 415,419 ---- switch (op) { case Py_LT: cmp = vs < ws; break; ! case Py_LE: cmp = vs <= ws; break; case Py_EQ: cmp = vs == ws; break; case Py_NE: cmp = vs != ws; break; From tim_one@users.sourceforge.net Fri Jul 6 19:53:49 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 06 Jul 2001 11:53:49 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.1.2.9,1.1.2.10 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv30306/descr/dist/src Modified Files: Tag: descr-branch PLAN.txt Log Message: Rename spam.c to xxsubtype.c, to serve as a permanent subtyping example we can merge back into the trunk later. TODO: This works on Windows but I don't know what's needed on Unix. Leaving that part to Guido. Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Attic/PLAN.txt,v retrieving revision 1.1.2.9 retrieving revision 1.1.2.10 diff -C2 -r1.1.2.9 -r1.1.2.10 *** PLAN.txt 2001/07/06 05:23:35 1.1.2.9 --- PLAN.txt 2001/07/06 18:53:47 1.1.2.10 *************** *** 188,192 **** way into the branch Unix and Windows builds (pythoncore.dsp and PC/config.c); also imported by test_descr.py. How about renaming to ! xxsubtype.c (whatever) now? --- 188,194 ---- way into the branch Unix and Windows builds (pythoncore.dsp and PC/config.c); also imported by test_descr.py. How about renaming to ! xxsubtype.c (whatever) now? *** Partly done: renamed on Windows and ! changes checked in. I assume Guido can fiddle the Unix build accordingly ! 50x faster than I can! *** From tim_one@users.sourceforge.net Fri Jul 6 19:53:50 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 06 Jul 2001 11:53:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/PC config.c,1.31.6.1,1.31.6.2 Message-ID: Update of /cvsroot/python/python/dist/src/PC In directory usw-pr-cvs1:/tmp/cvs-serv30306/descr/dist/src/PC Modified Files: Tag: descr-branch config.c Log Message: Rename spam.c to xxsubtype.c, to serve as a permanent subtyping example we can merge back into the trunk later. TODO: This works on Windows but I don't know what's needed on Unix. Leaving that part to Guido. Index: config.c =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/config.c,v retrieving revision 1.31.6.1 retrieving revision 1.31.6.2 diff -C2 -r1.31.6.1 -r1.31.6.2 *** config.c 2001/07/03 01:26:36 1.31.6.1 --- config.c 2001/07/06 18:53:47 1.31.6.2 *************** *** 45,49 **** extern void initxreadlines(void); extern void init_weakref(void); ! extern void initspam(void); /* XXX tim: what's the purpose of ADDMODULE MARKER? */ --- 45,49 ---- extern void initxreadlines(void); extern void init_weakref(void); ! extern void initxxsubtype(void); /* XXX tim: what's the purpose of ADDMODULE MARKER? */ *************** *** 100,104 **** {"_weakref", init_weakref}, ! {"spam", initspam}, /* XXX tim: what's the purpose of ADDMODULE MARKER? */ --- 100,104 ---- {"_weakref", init_weakref}, ! {"xxsubtype", initxxsubtype}, /* XXX tim: what's the purpose of ADDMODULE MARKER? */ From tim_one@users.sourceforge.net Fri Jul 6 19:53:50 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 06 Jul 2001 11:53:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild pythoncore.dsp,1.15.2.3,1.15.2.4 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv30306/descr/dist/src/PCbuild Modified Files: Tag: descr-branch pythoncore.dsp Log Message: Rename spam.c to xxsubtype.c, to serve as a permanent subtyping example we can merge back into the trunk later. TODO: This works on Windows but I don't know what's needed on Unix. Leaving that part to Guido. Index: pythoncore.dsp =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/pythoncore.dsp,v retrieving revision 1.15.2.3 retrieving revision 1.15.2.4 diff -C2 -r1.15.2.3 -r1.15.2.4 *** pythoncore.dsp 2001/07/05 21:32:21 1.15.2.3 --- pythoncore.dsp 2001/07/06 18:53:48 1.15.2.4 *************** *** 1498,1516 **** # Begin Source File - SOURCE=..\Modules\spam.c - - !IF "$(CFG)" == "pythoncore - Win32 Release" - - !ELSEIF "$(CFG)" == "pythoncore - Win32 Debug" - - !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Debug" - - !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Release" - - !ENDIF - - # End Source File - # Begin Source File - SOURCE=..\Objects\stringobject.c --- 1498,1501 ---- *************** *** 1739,1742 **** --- 1724,1742 ---- SOURCE=..\Modules\xreadlinesmodule.c + + !IF "$(CFG)" == "pythoncore - Win32 Release" + + !ELSEIF "$(CFG)" == "pythoncore - Win32 Debug" + + !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Debug" + + !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Release" + + !ENDIF + + # End Source File + # Begin Source File + + SOURCE=..\Modules\xxsubtype.c !IF "$(CFG)" == "pythoncore - Win32 Release" From tim_one@users.sourceforge.net Fri Jul 6 19:53:49 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 06 Jul 2001 11:53:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules xxsubtype.c,NONE,1.1.2.1 spam.c,1.1.2.9,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv30306/descr/dist/src/Modules Added Files: Tag: descr-branch xxsubtype.c Removed Files: Tag: descr-branch spam.c Log Message: Rename spam.c to xxsubtype.c, to serve as a permanent subtyping example we can merge back into the trunk later. TODO: This works on Windows but I don't know what's needed on Unix. Leaving that part to Guido. --- NEW FILE: xxsubtype.c --- #include "Python.h" /* Examples showing how to subtype the builtin list and dict types from C. */ /* spamlist -- a list subtype */ typedef struct { PyListObject list; int state; } spamlistobject; static PyObject * spamlist_getstate(spamlistobject *self, PyObject *args) { if (!PyArg_ParseTuple(args, ":getstate")) return NULL; return PyInt_FromLong(self->state); } static PyObject * spamlist_setstate(spamlistobject *self, PyObject *args) { int state; if (!PyArg_ParseTuple(args, "i:setstate", &state)) return NULL; self->state = state; Py_INCREF(Py_None); return Py_None; } static PyMethodDef spamlist_methods[] = { {"getstate", (PyCFunction)spamlist_getstate, METH_VARARGS, "getstate() -> state"}, {"setstate", (PyCFunction)spamlist_setstate, METH_VARARGS, "setstate(state)"}, {NULL, NULL}, }; staticforward PyTypeObject spamlist_type; static int spamlist_init(spamlistobject *self, PyObject *args, PyObject *kwds) { if (PyList_Type.tp_init((PyObject *)self, args, kwds) < 0) return -1; self->state = 0; return 0; } static PyTypeObject spamlist_type = { PyObject_HEAD_INIT(&PyType_Type) 0, "spamlist", sizeof(spamlistobject), 0, 0, /* 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_BASETYPE, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ spamlist_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ &PyList_Type, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)spamlist_init, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ }; /* spamdict -- a dict subtype */ typedef struct { PyDictObject dict; int state; } spamdictobject; static PyObject * spamdict_getstate(spamdictobject *self, PyObject *args) { if (!PyArg_ParseTuple(args, ":getstate")) return NULL; return PyInt_FromLong(self->state); } static PyObject * spamdict_setstate(spamdictobject *self, PyObject *args) { int state; if (!PyArg_ParseTuple(args, "i:setstate", &state)) return NULL; self->state = state; Py_INCREF(Py_None); return Py_None; } static PyMethodDef spamdict_methods[] = { {"getstate", (PyCFunction)spamdict_getstate, METH_VARARGS, "getstate() -> state"}, {"setstate", (PyCFunction)spamdict_setstate, METH_VARARGS, "setstate(state)"}, {NULL, NULL}, }; staticforward PyTypeObject spamdict_type; static int spamdict_init(spamdictobject *self, PyObject *args, PyObject *kwds) { if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0) return -1; self->state = 0; return 0; } static PyTypeObject spamdict_type = { PyObject_HEAD_INIT(&PyType_Type) 0, "spamdict", sizeof(spamdictobject), 0, 0, /* 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_BASETYPE, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ spamdict_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ &PyDict_Type, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)spamdict_init, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ }; PyObject * spam_bench(PyObject *self, PyObject *args) { PyObject *obj, *name, *res; int n = 1000; time_t t0, t1; if (!PyArg_ParseTuple(args, "OS|i", &obj, &name, &n)) return NULL; t0 = clock(); while (--n >= 0) { res = PyObject_GetAttr(obj, name); if (res == NULL) return NULL; Py_DECREF(res); } t1 = clock(); return PyFloat_FromDouble((double)(t1-t0) / CLOCKS_PER_SEC); } static PyMethodDef xxsubtype_functions[] = { {"bench", spam_bench, METH_VARARGS}, {NULL, NULL} /* sentinel */ }; DL_EXPORT(void) initxxsubtype(void) { PyObject *m, *d; m = Py_InitModule("xxsubtype", xxsubtype_functions); if (m == NULL) return; if (PyType_InitDict(&spamlist_type) < 0) return; if (PyType_InitDict(&spamdict_type) < 0) return; d = PyModule_GetDict(m); if (d == NULL) return; Py_INCREF(&spamlist_type); if (PyDict_SetItemString(d, "spamlist", (PyObject *) &spamlist_type) < 0) return; Py_INCREF(&spamdict_type); if (PyDict_SetItemString(d, "spamdict", (PyObject *) &spamdict_type) < 0) return; } --- spam.c DELETED --- From tim_one@users.sourceforge.net Fri Jul 6 19:53:49 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 06 Jul 2001 11:53:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.1.2.29,1.1.2.30 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv30306/descr/dist/src/Lib/test Modified Files: Tag: descr-branch test_descr.py Log Message: Rename spam.c to xxsubtype.c, to serve as a permanent subtyping example we can merge back into the trunk later. TODO: This works on Windows but I don't know what's needed on Unix. Leaving that part to Guido. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_descr.py,v retrieving revision 1.1.2.29 retrieving revision 1.1.2.30 diff -C2 -r1.1.2.29 -r1.1.2.30 *** test_descr.py 2001/07/05 21:42:37 1.1.2.29 --- test_descr.py 2001/07/06 18:53:47 1.1.2.30 *************** *** 218,224 **** def spamlists(): if verbose: print "Testing spamlist operations..." ! import copy, spam def spamlist(l, memo=None): ! import spam return spam.spamlist(l) # This is an ugly hack: --- 218,224 ---- def spamlists(): if verbose: print "Testing spamlist operations..." ! import copy, xxsubtype as spam def spamlist(l, memo=None): ! import xxsubtype as spam return spam.spamlist(l) # This is an ugly hack: *************** *** 255,261 **** def spamdicts(): if verbose: print "Testing spamdict operations..." ! import copy, spam def spamdict(d, memo=None): ! import spam sd = spam.spamdict() for k, v in d.items(): sd[k] = v --- 255,261 ---- def spamdicts(): if verbose: print "Testing spamdict operations..." ! import copy, xxsubtype as spam def spamdict(d, memo=None): ! import xxsubtype as spam sd = spam.spamdict() for k, v in d.items(): sd[k] = v From gvanrossum@users.sourceforge.net Fri Jul 6 20:04:33 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 06 Jul 2001 12:04:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules Setup.dist,1.21.4.1,1.21.4.2 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv938 Modified Files: Tag: descr-branch Setup.dist Log Message: Rename spam.c to xxsetup.c, finishing Tim's work. (Note to current users: you must copy your Setup.dist file to your Setup file before this takes effect!) Index: Setup.dist =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/Setup.dist,v retrieving revision 1.21.4.1 retrieving revision 1.21.4.2 diff -C2 -r1.21.4.1 -r1.21.4.2 *** Setup.dist 2001/05/05 15:55:47 1.21.4.1 --- Setup.dist 2001/07/06 19:04:31 1.21.4.2 *************** *** 465,468 **** # xx xxmodule.c ! # Another example -- the 'spam' module shows C-level subtyping in action ! spam spam.c --- 465,468 ---- # xx xxmodule.c ! # Another example -- the 'xxsubtype' module shows C-level subtyping in action ! xxsubtype xxsubtype.c From gvanrossum@users.sourceforge.net Fri Jul 6 20:08:19 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 06 Jul 2001 12:08:19 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.1.2.10,1.1.2.11 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv1751 Modified Files: Tag: descr-branch PLAN.txt Log Message: Mark more stuff done. Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Attic/PLAN.txt,v retrieving revision 1.1.2.10 retrieving revision 1.1.2.11 diff -C2 -r1.1.2.10 -r1.1.2.11 *** PLAN.txt 2001/07/06 18:53:47 1.1.2.10 --- PLAN.txt 2001/07/06 19:08:17 1.1.2.11 *************** *** 76,80 **** defaults? *** Done, really. *** ! Add error checking to the MRO calculation. Make __new__ overridable through a Python class method (!). Make more --- 76,80 ---- defaults? *** Done, really. *** ! Add error checking to the MRO calculation. *** Done. *** Make __new__ overridable through a Python class method (!). Make more *************** *** 85,92 **** -- you must use static methods. So I've implemented those too. I've hooked up __new__ in the right places, so the first part of this is ! now done (still to do the other construction methods -- unclear that ! we really need any though). I expect that some warts will only be ! really debugged when we try to use this for some, eh, interesting ! types such as tuples. *** More -- I'm sure new issues will crop up as we go. --- 85,92 ---- -- you must use static methods. So I've implemented those too. I've hooked up __new__ in the right places, so the first part of this is ! now done. I've also exported the MRO calculation and made it ! overridable, as metamethod mro(). I believe that closes this topic ! for now. I expect that some warts will only be really debugged when ! we try to use this for some, eh, interesting types such as tuples. *** More -- I'm sure new issues will crop up as we go. From fdrake@users.sourceforge.net Fri Jul 6 20:28:50 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 06 Jul 2001 12:28:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libaifc.tex,1.14,1.15 libarray.tex,1.28,1.29 libbisect.tex,1.9,1.10 libcgi.tex,1.29,1.30 libcurses.tex,1.32,1.33 libftplib.tex,1.31,1.32 libfuncs.tex,1.78,1.79 libgettext.tex,1.7,1.8 libimp.tex,1.28,1.29 libmd5.tex,1.19,1.20 libmimify.tex,1.10,1.11 libnis.tex,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv8338 Modified Files: libaifc.tex libarray.tex libbisect.tex libcgi.tex libcurses.tex libftplib.tex libfuncs.tex libgettext.tex libimp.tex libmd5.tex libmimify.tex libnis.tex Log Message: Fix up a few style nits -- avoid "e.g." and "i.e." -- these make translation more difficult, as well as reading the English more difficult for non-native speakers. Index: libaifc.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libaifc.tex,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -r1.14 -r1.15 *** libaifc.tex 1999/12/21 18:31:29 1.14 --- libaifc.tex 2001/07/06 19:28:48 1.15 *************** *** 30,34 **** bits), uses two channels (stereo) and has a frame rate of 44,100 frames/second. This gives a frame size of 4 bytes (2*2), and a ! second's worth occupies 2*2*44100 bytes, i.e.\ 176,400 bytes. Module \module{aifc} defines the following function: --- 30,34 ---- bits), uses two channels (stereo) and has a frame rate of 44,100 frames/second. This gives a frame size of 4 bytes (2*2), and a ! second's worth occupies 2*2*44100 bytes (176,400 bytes). Module \module{aifc} defines the following function: Index: libarray.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libarray.tex,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -r1.28 -r1.29 *** libarray.tex 2000/12/11 20:57:13 1.28 --- libarray.tex 2001/07/06 19:28:48 1.29 *************** *** 109,113 **** \begin{methoddesc}[array]{fromstring}{s} Appends items from the string, interpreting the string as an ! array of machine values (i.e. as if it had been read from a file using the \method{fromfile()} method). \end{methoddesc} --- 109,113 ---- \begin{methoddesc}[array]{fromstring}{s} Appends items from the string, interpreting the string as an ! array of machine values (as if it had been read from a file using the \method{fromfile()} method). \end{methoddesc} Index: libbisect.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libbisect.tex,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -r1.9 -r1.10 *** libbisect.tex 2001/01/04 14:18:55 1.9 --- libbisect.tex 2001/07/06 19:28:48 1.10 *************** *** 16,20 **** \module{bisect} because it uses a basic bisection algorithm to do its work. The source code may be most useful as a working example of the ! algorithm (i.e., the boundary conditions are already right!). The following functions are provided: --- 16,20 ---- \module{bisect} because it uses a basic bisection algorithm to do its work. The source code may be most useful as a working example of the ! algorithm (the boundary conditions are already right!). The following functions are provided: Index: libcgi.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcgi.tex,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -r1.29 -r1.30 *** libcgi.tex 2001/06/29 14:59:01 1.29 --- libcgi.tex 2001/07/06 19:28:48 1.30 *************** *** 113,117 **** \samp{form.getvalue(\var{key})} would return a list of strings. If you expect this possibility ! (i.e., when your HTML form contains multiple fields with the same name), use the \function{type()} function to determine whether you have a single instance or a list of instances. For example, here's --- 113,117 ---- \samp{form.getvalue(\var{key})} would return a list of strings. If you expect this possibility ! (when your HTML form contains multiple fields with the same name), use the \function{type()} function to determine whether you have a single instance or a list of instances. For example, here's *************** *** 284,288 **** contain such characters in HTML. If the optional flag \var{quote} is true, the double quote character (\character{"}) is also translated; ! this helps for inclusion in an HTML attribute value, e.g. in \code{}. \end{funcdesc} --- 284,288 ---- contain such characters in HTML. If the optional flag \var{quote} is true, the double quote character (\character{"}) is also translated; ! this helps for inclusion in an HTML attribute value, as in \code{}. \end{funcdesc} *************** *** 291,302 **** \subsection{Caring about security} ! There's one important rule: if you invoke an external program (e.g. ! via the \function{os.system()} or \function{os.popen()} functions), ! make very sure you don't pass arbitrary strings received from the ! client to the shell. This is a well-known security hole whereby ! clever hackers anywhere on the web can exploit a gullible CGI script ! to invoke arbitrary shell commands. Even parts of the URL or field ! names cannot be trusted, since the request doesn't have to come from ! your form! To be on the safe side, if you must pass a string gotten from a form --- 291,302 ---- \subsection{Caring about security} ! There's one important rule: if you invoke an external program (via the ! \function{os.system()} or \function{os.popen()} functions. or others ! with similar functionality), make very sure you don't pass arbitrary ! strings received from the client to the shell. This is a well-known ! security hole whereby clever hackers anywhere on the web can exploit a ! gullible CGI script to invoke arbitrary shell commands. Even parts of ! the URL or field names cannot be trusted, since the request doesn't ! have to come from your form! To be on the safe side, if you must pass a string gotten from a form *************** *** 338,342 **** If you need to load modules from a directory which is not on Python's default module search path, you can change the path in your script, ! before importing other modules, e.g.: \begin{verbatim} --- 338,342 ---- If you need to load modules from a directory which is not on Python's default module search path, you can change the path in your script, ! before importing other modules. For example: \begin{verbatim} *************** *** 384,388 **** If this gives an error of type 404, the server cannot find the script -- perhaps you need to install it in a different directory. If it ! gives another error (e.g. 500), there's an installation problem that you should fix before trying to go any further. If you get a nicely formatted listing of the environment and form content (in this --- 384,388 ---- If this gives an error of type 404, the server cannot find the script -- perhaps you need to install it in a different directory. If it ! gives another error, there's an installation problem that you should fix before trying to go any further. If you get a nicely formatted listing of the environment and form content (in this *************** *** 403,412 **** the \file{cgi.py} file itself. ! When an ordinary Python script raises an unhandled exception ! (e.g. because of a typo in a module name, a file that can't be opened, ! etc.), the Python interpreter prints a nice traceback and exits. ! While the Python interpreter will still do this when your CGI script ! raises an exception, most likely the traceback will end up in one of ! the HTTP server's log file, or be discarded altogether. Fortunately, once you have managed to get your script to execute --- 403,412 ---- the \file{cgi.py} file itself. ! When an ordinary Python script raises an unhandled exception (for ! whatever reason: of a typo in a module name, a file that can't be ! opened, etc.), the Python interpreter prints a nice traceback and ! exits. While the Python interpreter will still do this when your CGI ! script raises an exception, most likely the traceback will end up in ! one of the HTTP server's log file, or be discarded altogether. Fortunately, once you have managed to get your script to execute Index: libcurses.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcurses.tex,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -r1.32 -r1.33 *** libcurses.tex 2001/04/21 05:56:06 1.32 --- libcurses.tex 2001/07/06 19:28:48 1.33 *************** *** 332,336 **** screen. Pads can be used when a large window is needed, and only a part of the window will be on the screen at one time. Automatic ! refreshes of pads (e.g., from scrolling or echoing of input) do not occur. The \method{refresh()} and \method{noutrefresh()} methods of a pad require 6 arguments to specify the part of the pad to be --- 332,336 ---- screen. Pads can be used when a large window is needed, and only a part of the window will be on the screen at one time. Automatic ! refreshes of pads (such as from scrolling or echoing of input) do not occur. The \method{refresh()} and \method{noutrefresh()} methods of a pad require 6 arguments to specify the part of the pad to be *************** *** 543,547 **** \begin{methoddesc}{addch}{\optional{y, x,} ch\optional{, attr}} ! \strong{Note:} A \emph{character} means a C character (i.e., an \ASCII{} code), rather then a Python character (a string of length 1). (This note is true whenever the documentation mentions a character.) --- 543,547 ---- \begin{methoddesc}{addch}{\optional{y, x,} ch\optional{, attr}} ! \strong{Note:} A \emph{character} means a C character (an \ASCII{} code), rather then a Python character (a string of length 1). (This note is true whenever the documentation mentions a character.) Index: libftplib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libftplib.tex,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -r1.31 -r1.32 *** libftplib.tex 2001/02/15 13:53:40 1.31 --- libftplib.tex 2001/07/06 19:28:48 1.32 *************** *** 149,153 **** callback\optional{, maxblocksize\optional{, rest}}} Retrieve a file in binary transfer mode. \var{command} should be an ! appropriate \samp{RETR} command, i.e.\ \code{'RETR \var{filename}'}. The \var{callback} function is called for each block of data received, with a single string argument giving the data block. --- 149,153 ---- callback\optional{, maxblocksize\optional{, rest}}} Retrieve a file in binary transfer mode. \var{command} should be an ! appropriate \samp{RETR} command: \code{'RETR \var{filename}'}. The \var{callback} function is called for each block of data received, with a single string argument giving the data block. *************** *** 176,180 **** \begin{methoddesc}{storbinary}{command, file\optional{, blocksize}} Store a file in binary transfer mode. \var{command} should be an ! appropriate \samp{STOR} command, i.e.\ \code{"STOR \var{filename}"}. \var{file} is an open file object which is read until \EOF{} using its \method{read()} method in blocks of size \var{blocksize} to provide the --- 176,180 ---- \begin{methoddesc}{storbinary}{command, file\optional{, blocksize}} Store a file in binary transfer mode. \var{command} should be an ! appropriate \samp{STOR} command: \code{"STOR \var{filename}"}. \var{file} is an open file object which is read until \EOF{} using its \method{read()} method in blocks of size \var{blocksize} to provide the *************** *** 282,288 **** \begin{methoddesc}{close}{} Close the connection unilaterally. This should not be applied to an ! already closed connection (e.g.\ after a successful call to \method{quit()}. After this call the \class{FTP} instance should not ! be used any more (i.e., after a call to \method{close()} or \method{quit()} you cannot reopen the connection by issuing another \method{login()} method). --- 282,288 ---- \begin{methoddesc}{close}{} Close the connection unilaterally. This should not be applied to an ! already closed connection (such as after a successful call to \method{quit()}. After this call the \class{FTP} instance should not ! be used any more (after a call to \method{close()} or \method{quit()} you cannot reopen the connection by issuing another \method{login()} method). Index: libfuncs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfuncs.tex,v retrieving revision 1.78 retrieving revision 1.79 diff -C2 -r1.78 -r1.79 *** libfuncs.tex 2001/05/15 15:27:53 1.78 --- libfuncs.tex 2001/07/06 19:28:48 1.79 *************** *** 100,107 **** \begin{funcdesc}{chr}{i} Return a string of one character whose \ASCII{} code is the integer ! \var{i}, e.g., \code{chr(97)} returns the string \code{'a'}. This is the ! inverse of \function{ord()}. The argument must be in the range [0..255], ! inclusive; \exception{ValueError} will be raised if \var{i} is ! outside that range. \end{funcdesc} --- 100,107 ---- \begin{funcdesc}{chr}{i} Return a string of one character whose \ASCII{} code is the integer ! \var{i}. For example, \code{chr(97)} returns the string \code{'a'}. ! This is the inverse of \function{ord()}. The argument must be in ! the range [0..255], inclusive; \exception{ValueError} will be raised ! if \var{i} is outside that range. \end{funcdesc} *************** *** 123,134 **** executed by an \keyword{exec} statement or evaluated by a call to \function{eval()}. The \var{filename} argument should ! give the file from which the code was read; pass e.g. \code{''} ! if it wasn't read from a file. The \var{kind} argument specifies ! what kind of code must be compiled; it can be \code{'exec'} if ! \var{string} consists of a sequence of statements, \code{'eval'} ! if it consists of a single expression, or \code{'single'} if ! it consists of a single interactive statement (in the latter case, ! expression statements that evaluate to something else than ! \code{None} will printed). \end{funcdesc} --- 123,134 ---- executed by an \keyword{exec} statement or evaluated by a call to \function{eval()}. The \var{filename} argument should ! give the file from which the code was read; pass same recognizable value ! if it wasn't read from a file (\code{''} is commonly used). ! The \var{kind} argument specifies what kind of code must be ! compiled; it can be \code{'exec'} if \var{string} consists of a ! sequence of statements, \code{'eval'} if it consists of a single ! expression, or \code{'single'} if it consists of a single ! interactive statement (in the latter case, expression statements ! that evaluate to something else than \code{None} will printed). \end{funcdesc} *************** *** 157,163 **** attribute for that object. This information is gleaned from the object's \member{__dict__}, \member{__methods__} and \member{__members__} ! attributes, if defined. The list is not necessarily complete; e.g., ! for classes, attributes defined in base classes are not included, ! and for class instances, methods are not included. The resulting list is sorted alphabetically. For example: --- 157,163 ---- attribute for that object. This information is gleaned from the object's \member{__dict__}, \member{__methods__} and \member{__members__} ! attributes, if defined. The list is not necessarily complete. For ! example, for classes, attributes defined in base classes are not ! included, and for class instances, methods are not included. The resulting list is sorted alphabetically. For example: *************** *** 203,209 **** This function can also be used to execute arbitrary code objects ! (e.g.\ created by \function{compile()}). In this case pass a code ! object instead of a string. The code object must have been compiled ! passing \code{'eval'} to the \var{kind} argument. Hints: dynamic execution of statements is supported by the --- 203,209 ---- This function can also be used to execute arbitrary code objects ! (such as those created by \function{compile()}). In this case pass ! a code object instead of a string. The code object must have been ! compiled passing \code{'eval'} as the \var{kind} argument. Hints: dynamic execution of statements is supported by the *************** *** 240,244 **** is a string or a tuple, the result also has that type; otherwise it is always a list. If \var{function} is \code{None}, the identity ! function is assumed, i.e.\ all elements of \var{list} that are false (zero or empty) are removed. \end{funcdesc} --- 240,244 ---- is a string or a tuple, the result also has that type; otherwise it is always a list. If \var{function} is \code{None}, the identity ! function is assumed, that is, all elements of \var{list} that are false (zero or empty) are removed. \end{funcdesc} *************** *** 287,292 **** are integers. They are used to quickly compare dictionary keys during a dictionary lookup. Numeric values that compare equal ! have the same hash value (even if they are of different types, e.g. ! 1 and 1.0). \end{funcdesc} --- 287,292 ---- are integers. They are used to quickly compare dictionary keys during a dictionary lookup. Numeric values that compare equal ! have the same hash value (even if they are of different types, as is ! the case for 1 and 1.0). \end{funcdesc} *************** *** 294,302 **** Convert an integer number (of any size) to a hexadecimal string. The result is a valid Python expression. Note: this always yields ! an unsigned literal, e.g. on a 32-bit machine, \code{hex(-1)} yields ! \code{'0xffffffff'}. When evaluated on a machine with the same ! word size, this literal is evaluated as -1; at a different word ! size, it may turn up as a large positive number or raise an ! \exception{OverflowError} exception. \end{funcdesc} --- 294,302 ---- Convert an integer number (of any size) to a hexadecimal string. The result is a valid Python expression. Note: this always yields ! an unsigned literal. For example, on a 32-bit machine, ! \code{hex(-1)} yields \code{'0xffffffff'}. When evaluated on a ! machine with the same word size, this literal is evaluated as -1; at ! a different word size, it may turn up as a large positive number or ! raise an \exception{OverflowError} exception. \end{funcdesc} *************** *** 353,357 **** the names used in Python programs are automatically interned, and the dictionaries used to hold module, class or instance attributes ! have interned keys. Interned strings are immortal (i.e. never get garbage collected). \end{funcdesc} --- 353,357 ---- the names used in Python programs are automatically interned, and the dictionaries used to hold module, class or instance attributes ! have interned keys. Interned strings are immortal (never get garbage collected). \end{funcdesc} *************** *** 411,444 **** \begin{funcdesc}{map}{function, list, ...} ! Apply \var{function} to every item of \var{list} and return a list ! of the results. If additional \var{list} arguments are passed, ! \var{function} must take that many arguments and is applied to ! the items of all lists in parallel; if a list is shorter than another ! it is assumed to be extended with \code{None} items. If ! \var{function} is \code{None}, the identity function is assumed; if ! there are multiple list arguments, \function{map()} returns a list ! consisting of tuples containing the corresponding items from all lists ! (i.e. a kind of transpose operation). The \var{list} arguments may be ! any kind of sequence; the result is always a list. \end{funcdesc} \begin{funcdesc}{max}{s\optional{, args...}} ! With a single argument \var{s}, return the largest item of a ! non-empty sequence (e.g., a string, tuple or list). With more than ! one argument, return the largest of the arguments. \end{funcdesc} \begin{funcdesc}{min}{s\optional{, args...}} ! With a single argument \var{s}, return the smallest item of a ! non-empty sequence (e.g., a string, tuple or list). With more than ! one argument, return the smallest of the arguments. \end{funcdesc} \begin{funcdesc}{oct}{x} Convert an integer number (of any size) to an octal string. The ! result is a valid Python expression. Note: this always yields ! an unsigned literal, e.g. on a 32-bit machine, \code{oct(-1)} yields ! \code{'037777777777'}. When evaluated on a machine with the same ! word size, this literal is evaluated as -1; at a different word size, it may turn up as a large positive number or raise an \exception{OverflowError} exception. --- 411,444 ---- \begin{funcdesc}{map}{function, list, ...} ! Apply \var{function} to every item of \var{list} and return a list ! of the results. If additional \var{list} arguments are passed, ! \var{function} must take that many arguments and is applied to the ! items of all lists in parallel; if a list is shorter than another it ! is assumed to be extended with \code{None} items. If \var{function} ! is \code{None}, the identity function is assumed; if there are ! multiple list arguments, \function{map()} returns a list consisting ! of tuples containing the corresponding items from all lists (a kind ! of transpose operation). The \var{list} arguments may be any kind ! of sequence; the result is always a list. \end{funcdesc} \begin{funcdesc}{max}{s\optional{, args...}} ! With a single argument \var{s}, return the largest item of a ! non-empty sequence (such as a string, tuple or list). With more ! than one argument, return the largest of the arguments. \end{funcdesc} \begin{funcdesc}{min}{s\optional{, args...}} ! With a single argument \var{s}, return the smallest item of a ! non-empty sequence (such as a string, tuple or list). With more ! than one argument, return the smallest of the arguments. \end{funcdesc} \begin{funcdesc}{oct}{x} Convert an integer number (of any size) to an octal string. The ! result is a valid Python expression. Note: this always yields an ! unsigned literal. For example, on a 32-bit machine, \code{oct(-1)} ! yields \code{'037777777777'}. When evaluated on a machine with the ! same word size, this literal is evaluated as -1; at a different word size, it may turn up as a large positive number or raise an \exception{OverflowError} exception. *************** *** 500,505 **** arithmetic operators apply. The effective operand type is also the type of the result; if the result is not expressible in this type, the ! function raises an exception; e.g., \code{pow(2, -1)} or \code{pow(2, ! 35000)} is not allowed. \end{funcdesc} --- 500,505 ---- arithmetic operators apply. The effective operand type is also the type of the result; if the result is not expressible in this type, the ! function raises an exception; for example, \code{pow(2, -1)} or ! \code{pow(2, 35000)} is not allowed. \end{funcdesc} *************** *** 571,575 **** file using an external editor and want to try out the new version without leaving the Python interpreter. The return value is the ! module object (i.e.\ the same as the \var{module} argument). There are a number of caveats: --- 571,575 ---- file using an external editor and want to try out the new version without leaving the Python interpreter. The return value is the ! module object (the same as the \var{module} argument). There are a number of caveats: *************** *** 624,628 **** The result is a floating point number. Values are rounded to the closest multiple of 10 to the power minus \var{n}; if two multiples ! are equally close, rounding is done away from 0 (so e.g. \code{round(0.5)} is \code{1.0} and \code{round(-0.5)} is \code{-1.0}). \end{funcdesc} --- 624,628 ---- The result is a floating point number. Values are rounded to the closest multiple of 10 to the power minus \var{n}; if two multiples ! are equally close, rounding is done away from 0 (so. for example, \code{round(0.5)} is \code{1.0} and \code{round(-0.5)} is \code{-1.0}). \end{funcdesc} *************** *** 646,650 **** Python\index{Numerical Python} and other third party extensions. Slice objects are also generated when extended indexing syntax is ! used, e.g. for \samp{a[start:stop:step]} or \samp{a[start:stop, i]}. \end{funcdesc} --- 646,650 ---- Python\index{Numerical Python} and other third party extensions. Slice objects are also generated when extended indexing syntax is ! used. For example: \samp{a[start:stop:step]} or \samp{a[start:stop, i]}. \end{funcdesc} *************** *** 681,685 **** \begin{funcdesc}{unichr}{i} Return the Unicode string of one character whose Unicode code is the ! integer \var{i}, e.g., \code{unichr(97)} returns the string \code{u'a'}. This is the inverse of \function{ord()} for Unicode strings. The argument must be in the range [0..65535], inclusive. --- 681,685 ---- \begin{funcdesc}{unichr}{i} Return the Unicode string of one character whose Unicode code is the ! integer \var{i}. For example, \code{unichr(97)} returns the string \code{u'a'}. This is the inverse of \function{ord()} for Unicode strings. The argument must be in the range [0..65535], inclusive. *************** *** 713,717 **** In the current implementation, local variable bindings cannot normally be affected this way, but variables retrieved from ! other scopes (e.g. modules) can be. This may change.} \end{funcdesc} --- 713,717 ---- In the current implementation, local variable bindings cannot normally be affected this way, but variables retrieved from ! other scopes (such as modules) can be. This may change.} \end{funcdesc} *************** *** 724,729 **** \function{xrange()} still has to create the values when asked for them) except when a very large range is used on a memory-starved ! machine (e.g. MS-DOS) or when all of the range's elements are never ! used (e.g. when the loop is usually terminated with \keyword{break}). \end{funcdesc} --- 724,729 ---- \function{xrange()} still has to create the values when asked for them) except when a very large range is used on a memory-starved ! machine or when all of the range's elements are never used (such as ! when the loop is usually terminated with \keyword{break}). \end{funcdesc} Index: libgettext.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libgettext.tex,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** libgettext.tex 2001/01/31 21:21:45 1.7 --- libgettext.tex 2001/07/06 19:28:48 1.8 *************** *** 42,51 **** If \var{localedir} is omitted or \code{None}, then the current binding for \var{domain} is returned.\footnote{ ! The default locale directory is system dependent; e.g.\ on ! RedHat Linux it is \file{/usr/share/locale}, but on Solaris it ! is \file{/usr/lib/locale}. The \module{gettext} module does ! not try to support these system dependent defaults; instead ! its default is \file{\code{sys.prefix}/share/locale}. For ! this reason, it is always best to call \function{bindtextdomain()} with an explicit absolute path at the start of your application.} --- 42,51 ---- If \var{localedir} is omitted or \code{None}, then the current binding for \var{domain} is returned.\footnote{ ! The default locale directory is system dependent; for example, ! on RedHat Linux it is \file{/usr/share/locale}, but on Solaris ! it is \file{/usr/lib/locale}. The \module{gettext} module ! does not try to support these system dependent defaults; ! instead its default is \file{\code{sys.prefix}/share/locale}. ! For this reason, it is always best to call \function{bindtextdomain()} with an explicit absolute path at the start of your application.} *************** *** 142,147 **** As seen below, you usually mark the strings in your application that are ! candidates for translation, by wrapping them in a call to the function ! \function{_()}, e.g. \begin{verbatim} --- 142,147 ---- As seen below, you usually mark the strings in your application that are ! candidates for translation, by wrapping them in a call to the ! \function{_()} function, like this: \begin{verbatim} *************** *** 288,293 **** In order to prepare your code for I18N, you need to look at all the strings in your files. Any string that needs to be translated ! should be marked by wrapping it in \code{_('...')} -- i.e. a call to ! the function \function{_()}. For example: \begin{verbatim} --- 288,293 ---- In order to prepare your code for I18N, you need to look at all the strings in your files. Any string that needs to be translated ! should be marked by wrapping it in \code{_('...')} --- that is, a call ! to the function \function{_()}. For example: \begin{verbatim} *************** *** 318,322 **** intricacies of Python source code, but knows nothing about C or C++ source code. You don't need GNU \code{gettext} unless you're also ! going to be translating C code (e.g. C extension modules). \program{pygettext} generates textual Uniforum-style human readable --- 318,322 ---- intricacies of Python source code, but knows nothing about C or C++ source code. You don't need GNU \code{gettext} unless you're also ! going to be translating C code (such as C extension modules). \program{pygettext} generates textual Uniforum-style human readable Index: libimp.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libimp.tex,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -r1.28 -r1.29 *** libimp.tex 2001/01/17 05:12:13 1.28 --- libimp.tex 2001/07/06 19:28:48 1.29 *************** *** 58,62 **** This function does not handle hierarchical module names (names ! containing dots). In order to find \var{P}.\var{M}, i.e., submodule \var{M} of package \var{P}, use \function{find_module()} and \function{load_module()} to find and load package \var{P}, and then use --- 58,62 ---- This function does not handle hierarchical module names (names ! containing dots). In order to find \var{P}.\var{M}, that is, submodule \var{M} of package \var{P}, use \function{find_module()} and \function{load_module()} to find and load package \var{P}, and then use *************** *** 212,216 **** The following function emulates what was the standard import statement ! up to Python 1.4 (i.e., no hierarchical module names). (This \emph{implementation} wouldn't work in that version, since \function{find_module()} has been extended and --- 212,216 ---- The following function emulates what was the standard import statement ! up to Python 1.4 (no hierarchical module names). (This \emph{implementation} wouldn't work in that version, since \function{find_module()} has been extended and Index: libmd5.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libmd5.tex,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -r1.19 -r1.20 *** libmd5.tex 2001/01/24 17:19:06 1.19 --- libmd5.tex 2001/07/06 19:28:48 1.20 *************** *** 51,55 **** Update the md5 object with the string \var{arg}. Repeated calls are equivalent to a single call with the concatenation of all the ! arguments, i.e.\ \code{m.update(a); m.update(b)} is equivalent to \code{m.update(a+b)}. \end{methoddesc} --- 51,55 ---- Update the md5 object with the string \var{arg}. Repeated calls are equivalent to a single call with the concatenation of all the ! arguments: \code{m.update(a); m.update(b)} is equivalent to \code{m.update(a+b)}. \end{methoddesc} Index: libmimify.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libmimify.tex,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -r1.10 -r1.11 *** libmimify.tex 2000/04/04 20:42:38 1.10 --- libmimify.tex 2001/07/06 19:28:48 1.11 *************** *** 57,61 **** \begin{datadesc}{MAXLEN} By default, a part will be encoded as quoted-printable when it ! contains any non-\ASCII{} characters (i.e., characters with the 8th bit set), or if there are any lines longer than \constant{MAXLEN} characters (default value 200). --- 57,61 ---- \begin{datadesc}{MAXLEN} By default, a part will be encoded as quoted-printable when it ! contains any non-\ASCII{} characters (characters with the 8th bit set), or if there are any lines longer than \constant{MAXLEN} characters (default value 200). Index: libnis.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libnis.tex,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** libnis.tex 2000/12/01 15:25:23 1.5 --- libnis.tex 2001/07/06 19:28:48 1.6 *************** *** 6,10 **** \moduleauthor{Fred Gansevles}{Fred.Gansevles@cs.utwente.nl} \sectionauthor{Moshe Zadka}{moshez@zadka.site.co.il} ! \modulesynopsis{Interface to Sun's NIS (a.k.a. Yellow Pages) library.} The \module{nis} module gives a thin wrapper around the NIS library, useful --- 6,10 ---- \moduleauthor{Fred Gansevles}{Fred.Gansevles@cs.utwente.nl} \sectionauthor{Moshe Zadka}{moshez@zadka.site.co.il} ! \modulesynopsis{Interface to Sun's NIS (Yellow Pages) library.} The \module{nis} module gives a thin wrapper around the NIS library, useful *************** *** 12,16 **** Because NIS exists only on \UNIX{} systems, this module is ! only available for \UNIX{}. The \module{nis} module defines the following functions: --- 12,16 ---- Because NIS exists only on \UNIX{} systems, this module is ! only available for \UNIX. The \module{nis} module defines the following functions: *************** *** 20,27 **** error (\exception{nis.error}) if there is none. Both should be strings, \var{key} is 8-bit clean. ! Return value is an arbitrary array of bytes (i.e., may contain \code{NULL} and other joys). ! Note that \var{mapname} is first checked if it is an alias to another name. \end{funcdesc} --- 20,28 ---- error (\exception{nis.error}) if there is none. Both should be strings, \var{key} is 8-bit clean. ! Return value is an arbitrary array of bytes (may contain \code{NULL} and other joys). ! Note that \var{mapname} is first checked if it is an alias to another ! name. \end{funcdesc} *************** *** 32,36 **** arrays of bytes. ! Note that \var{mapname} is first checked if it is an alias to another name. \end{funcdesc} --- 33,38 ---- arrays of bytes. ! Note that \var{mapname} is first checked if it is an alias to another ! name. \end{funcdesc} From tim_one@users.sourceforge.net Fri Jul 6 21:04:01 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 06 Jul 2001 13:04:01 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.1.2.11,1.1.2.12 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv19156/descr/dist/src Modified Files: Tag: descr-branch PLAN.txt Log Message: Record that spam->xxsubtype rename is finished. Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Attic/PLAN.txt,v retrieving revision 1.1.2.11 retrieving revision 1.1.2.12 diff -C2 -r1.1.2.11 -r1.1.2.12 *** PLAN.txt 2001/07/06 19:08:17 1.1.2.11 --- PLAN.txt 2001/07/06 20:03:59 1.1.2.12 *************** *** 185,194 **** later. To undo or rename before final merge: Modules/spam.c has worked its way into the branch Unix and Windows builds (pythoncore.dsp and PC/config.c); also imported by test_descr.py. How about renaming to ! xxsubtype.c (whatever) now? *** Partly done: renamed on Windows and ! changes checked in. I assume Guido can fiddle the Unix build accordingly ! 50x faster than I can! *** --- 185,193 ---- later. + Done: To undo or rename before final merge: Modules/spam.c has worked its way into the branch Unix and Windows builds (pythoncore.dsp and PC/config.c); also imported by test_descr.py. How about renaming to ! xxsubtype.c (whatever) now? From bwarsaw@users.sourceforge.net Fri Jul 6 21:07:15 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Fri, 06 Jul 2001 13:07:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc python-mode.el,4.3,4.4 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv20111 Modified Files: python-mode.el Log Message: (py-continuation-offset): Update docstring to describe that this additional offset is only applied to continuation lines for block opening statements. (py-compute-indentation): Only add py-continuation-offset if py-statement-opens-block-p is true. Index: python-mode.el =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/python-mode.el,v retrieving revision 4.3 retrieving revision 4.4 diff -C2 -r4.3 -r4.4 *** python-mode.el 2001/06/19 18:24:42 4.3 --- python-mode.el 2001/07/06 20:07:13 4.4 *************** *** 9,13 **** ;; Keywords: python languages oop ! (defconst py-version "$Revision$" "`python-mode' version number.") --- 9,13 ---- ;; Keywords: python languages oop ! (defconst py-version "4.3" "`python-mode' version number.") *************** *** 125,131 **** (defcustom py-continuation-offset 4 ! "*Additional amount of offset to give for continuation lines. Continuation lines are those that immediately follow a backslash ! terminated line." :type 'integer :group 'python) --- 125,132 ---- (defcustom py-continuation-offset 4 ! "*Additional amount of offset to give for some continuation lines. Continuation lines are those that immediately follow a backslash ! terminated line. Only those continuation lines for a block opening ! statement are given this extra offset." :type 'integer :group 'python) *************** *** 1834,1838 **** (goto-char startpos) (skip-chars-forward "^ \t\n"))) ! (+ (current-column) py-continuation-offset 1) )))) --- 1835,1843 ---- (goto-char startpos) (skip-chars-forward "^ \t\n"))) ! ;; if this is a continuation for a block opening ! ;; statement, add some extra offset. ! (+ (current-column) (if (py-statement-opens-block-p) ! py-continuation-offset 0) ! 1) )))) From fdrake@users.sourceforge.net Fri Jul 6 21:23:04 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 06 Jul 2001 13:23:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libtelnetlib.tex,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv24408 Modified Files: libtelnetlib.tex Log Message: Fix up a few style nits -- avoid "e.g." and "i.e." -- these make translation more difficult, as well as reading the English more difficult for non-native speakers. Add an index entry for the Telnet protocol. Always refer to the protocol as Telnet instead of telnet. Index: libtelnetlib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libtelnetlib.tex,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -r1.6 -r1.7 *** libtelnetlib.tex 2000/07/16 19:01:10 1.6 --- libtelnetlib.tex 2001/07/06 20:23:02 1.7 *************** *** 6,9 **** --- 6,11 ---- \sectionauthor{Skip Montanaro}{skip@mojam.com} + \index{protocol!Telnet} + The \module{telnetlib} module provides a \class{Telnet} class that implements the Telnet protocol. See \rfc{854} for details about the *************** *** 12,16 **** \begin{classdesc}{Telnet}{\optional{host\optional{, port}}} ! \class{Telnet} represents a connection to a telnet server. The instance is initially not connected by default; the \method{open()} method must be used to establish a connection. Alternatively, the --- 14,18 ---- \begin{classdesc}{Telnet}{\optional{host\optional{, port}}} ! \class{Telnet} represents a connection to a Telnet server. The instance is initially not connected by default; the \method{open()} method must be used to establish a connection. Alternatively, the *************** *** 93,97 **** Connect to a host. The optional second argument is the port number, which ! defaults to the standard telnet port (23). Do not try to reopen an already connected instance. --- 95,99 ---- Connect to a host. The optional second argument is the port number, which ! defaults to the standard Telnet port (23). Do not try to reopen an already connected instance. *************** *** 128,132 **** \begin{methoddesc}{interact}{} ! Interaction function, emulates a very dumb telnet client. \end{methoddesc} --- 130,134 ---- \begin{methoddesc}{interact}{} ! Interaction function, emulates a very dumb Telnet client. \end{methoddesc} *************** *** 152,156 **** far (may be the empty string if a timeout happened). ! If a regular expression ends with a greedy match (e.g. \regexp{.*}) or if more than one expression can match the same input, the results are indeterministic, and may depend on the I/O timing. --- 154,158 ---- far (may be the empty string if a timeout happened). ! If a regular expression ends with a greedy match (such as \regexp{.*}) or if more than one expression can match the same input, the results are indeterministic, and may depend on the I/O timing. From gvanrossum@users.sourceforge.net Fri Jul 6 21:26:33 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 06 Jul 2001 13:26:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/idle PyShell.py,1.33,1.34 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/idle In directory usw-pr-cvs1:/tmp/cvs-serv25376 Modified Files: PyShell.py Log Message: Amazing. A very subtle change in policy in descr-branch actually found a bug here. Here's the deal: Class PyShell derives from class OutputWindow. Method PyShell.close() wants to invoke its parent method, but because PyShell long ago was inherited from class PyShellEditorWindow, it invokes PyShelEditorWindow.close(self). Now, class PyShellEditorWindow itself derives from class OutputWindow, and inherits the close() method from there without overriding it. Under the old rules, PyShellEditorWindow.close would return an unbound method restricted to the class that defined the implementation of close(), which was OutputWindow.close. Under the new rules, the unbound method is restricted to the class whose method was requested, that is PyShellEditorWindow, and this was correctly trapped as an error. Index: PyShell.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/idle/PyShell.py,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -r1.33 -r1.34 *** PyShell.py 2001/03/29 03:34:43 1.33 --- PyShell.py 2001/07/06 20:26:31 1.34 *************** *** 419,423 **** self.top.quit() return "cancel" ! return PyShellEditorWindow.close(self) def _close(self): --- 419,423 ---- self.top.quit() return "cancel" ! return OutputWindow.close(self) def _close(self): From bwarsaw@users.sourceforge.net Fri Jul 6 21:27:31 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Fri, 06 Jul 2001 13:27:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc python-mode.el,4.4,4.5 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv25634 Modified Files: python-mode.el Log Message: (py-version): Hopefully fixed my XEmacs settings so this doesn't get clobbered on checkin. Index: python-mode.el =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/python-mode.el,v retrieving revision 4.4 retrieving revision 4.5 diff -C2 -r4.4 -r4.5 *** python-mode.el 2001/07/06 20:07:13 4.4 --- python-mode.el 2001/07/06 20:27:29 4.5 *************** *** 9,13 **** ;; Keywords: python languages oop ! (defconst py-version "4.3" "`python-mode' version number.") --- 9,13 ---- ;; Keywords: python languages oop ! (defconst py-version "$Revision$" "`python-mode' version number.") From fdrake@users.sourceforge.net Fri Jul 6 21:30:13 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 06 Jul 2001 13:30:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libos.tex,1.58,1.59 libprofile.tex,1.35,1.36 libre.tex,1.61,1.62 librexec.tex,1.15,1.16 librlcompleter.tex,1.5,1.6 libsha.tex,1.6,1.7 libsignal.tex,1.20,1.21 libstdtypes.tex,1.63,1.64 libstringio.tex,1.5,1.6 libstruct.tex,1.29,1.30 libthreading.tex,1.8,1.9 libtime.tex,1.39,1.40 libuser.tex,1.16,1.17 libwinreg.tex,1.6,1.7 libxmllib.tex,1.30,1.31 libzipfile.tex,1.11,1.12 xmlsaxreader.tex,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv26370 Modified Files: libos.tex libprofile.tex libre.tex librexec.tex librlcompleter.tex libsha.tex libsignal.tex libstdtypes.tex libstringio.tex libstruct.tex libthreading.tex libtime.tex libuser.tex libwinreg.tex libxmllib.tex libzipfile.tex xmlsaxreader.tex Log Message: Fix up a few style nits -- avoid "e.g." and "i.e." -- these make translation more difficult, as well as reading the English more difficult for non-native speakers. Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.58 retrieving revision 1.59 diff -C2 -r1.58 -r1.59 *** libos.tex 2001/06/11 18:25:34 1.58 --- libos.tex 2001/07/06 20:30:11 1.59 *************** *** 14,18 **** as found there. The design of all Python's built-in OS dependent modules is such that as long as the same functionality is available, ! it uses the same interface; e.g., the function \code{os.stat(\var{path})} returns stat information about \var{path} in the same format (which happens to have originated with the --- 14,18 ---- as found there. The design of all Python's built-in OS dependent modules is such that as long as the same functionality is available, ! it uses the same interface; for example, the function \code{os.stat(\var{path})} returns stat information about \var{path} in the same format (which happens to have originated with the *************** *** 43,49 **** \begin{excdesc}{error} ! This exception is raised when a function returns a ! system-related error (e.g., not for illegal argument types). This is ! also known as the built-in exception \exception{OSError}. The accompanying value is a pair containing the numeric error code from \cdata{errno} and the corresponding string, as would be printed by the --- 43,49 ---- \begin{excdesc}{error} ! This exception is raised when a function returns a system-related ! error (not for illegal argument types or other incidental errors). ! This is also known as the built-in exception \exception{OSError}. The accompanying value is a pair containing the numeric error code from \cdata{errno} and the corresponding string, as would be printed by the *************** *** 56,60 **** the C \cdata{errno} variable, and the latter holds the corresponding error message from \cfunction{strerror()}. For exceptions that ! involve a file system path (e.g. \function{chdir()} or \function{unlink()}), the exception instance will contain a third attribute, \member{filename}, which is the file name passed to the --- 56,60 ---- the C \cdata{errno} variable, and the latter holds the corresponding error message from \cfunction{strerror()}. For exceptions that ! involve a file system path (such as \function{chdir()} or \function{unlink()}), the exception instance will contain a third attribute, \member{filename}, which is the file name passed to the *************** *** 73,80 **** \begin{datadesc}{path} The corresponding OS dependent standard module for pathname ! operations, e.g., \module{posixpath} or \module{macpath}. Thus, given ! the proper imports, \code{os.path.split(\var{file})} is equivalent to but ! more portable than \code{posixpath.split(\var{file})}. Note that this ! is also a valid module: it may be imported directly as \refmodule{os.path}. \end{datadesc} --- 73,81 ---- \begin{datadesc}{path} The corresponding OS dependent standard module for pathname ! operations, such as \module{posixpath} or \module{macpath}. Thus, ! given the proper imports, \code{os.path.split(\var{file})} is ! equivalent to but more portable than ! \code{posixpath.split(\var{file})}. Note that this is also an ! importable module: it may be imported directly as \refmodule{os.path}. \end{datadesc} *************** *** 859,863 **** \begin{funcdesc}{execv}{path, args} Execute the executable \var{path} with argument list \var{args}, ! replacing the current process (i.e., the Python interpreter). The argument list may be a tuple or list of strings. Availability: \UNIX{}, Windows. --- 860,864 ---- \begin{funcdesc}{execv}{path, args} Execute the executable \var{path} with argument list \var{args}, ! replacing the current process (the Python interpreter). The argument list may be a tuple or list of strings. Availability: \UNIX{}, Windows. *************** *** 866,871 **** \begin{funcdesc}{execve}{path, args, env} Execute the executable \var{path} with argument list \var{args}, ! and environment \var{env}, ! replacing the current process (i.e., the Python interpreter). The argument list may be a tuple or list of strings. The environment must be a dictionary mapping strings to strings. --- 867,872 ---- \begin{funcdesc}{execve}{path, args, env} Execute the executable \var{path} with argument list \var{args}, ! and environment \var{env}, replacing the current process (the Python ! interpreter). The argument list may be a tuple or list of strings. The environment must be a dictionary mapping strings to strings. *************** *** 1151,1168 **** \begin{datadesc}{curdir} ! The constant string used by the OS to refer to the current directory, ! e.g.\ \code{'.'} for \POSIX{} or \code{':'} for the Macintosh. \end{datadesc} \begin{datadesc}{pardir} ! The constant string used by the OS to refer to the parent directory, ! e.g.\ \code{'..'} for \POSIX{} or \code{'::'} for the Macintosh. \end{datadesc} \begin{datadesc}{sep} The character used by the OS to separate pathname components, ! e.g.\ \character{/} for \POSIX{} or \character{:} for the Macintosh. ! Note that knowing this is not sufficient to be able to parse or ! concatenate pathnames --- use \function{os.path.split()} and \function{os.path.join()} --- but it is occasionally useful. \end{datadesc} --- 1152,1169 ---- \begin{datadesc}{curdir} ! The constant string used by the OS to refer to the current directory. ! For example: \code{'.'} for \POSIX{} or \code{':'} for the Macintosh. \end{datadesc} \begin{datadesc}{pardir} ! The constant string used by the OS to refer to the parent directory. ! For example: \code{'..'} for \POSIX{} or \code{'::'} for the Macintosh. \end{datadesc} \begin{datadesc}{sep} The character used by the OS to separate pathname components, ! for example, \character{/} for \POSIX{} or \character{:} for the ! Macintosh. Note that knowing this is not sufficient to be able to ! parse or concatenate pathnames --- use \function{os.path.split()} and \function{os.path.join()} --- but it is occasionally useful. \end{datadesc} *************** *** 1176,1180 **** \begin{datadesc}{pathsep} The character conventionally used by the OS to separate search patch ! components (as in \envvar{PATH}), e.g.\ \character{:} for \POSIX{} or \character{;} for DOS and Windows. \end{datadesc} --- 1177,1181 ---- \begin{datadesc}{pathsep} The character conventionally used by the OS to separate search patch ! components (as in \envvar{PATH}), such as \character{:} for \POSIX{} or \character{;} for DOS and Windows. \end{datadesc} *************** *** 1187,1192 **** \begin{datadesc}{linesep} The string used to separate (or, rather, terminate) lines on the ! current platform. This may be a single character, ! e.g.\ \code{'\e n'} for \POSIX{} or \code{'\e r'} for MacOS, or multiple ! characters, e.g.\ \code{'\e r\e n'} for MS-DOS and MS Windows. \end{datadesc} --- 1188,1193 ---- \begin{datadesc}{linesep} The string used to separate (or, rather, terminate) lines on the ! current platform. This may be a single character, such as \code{'\e ! n'} for \POSIX{} or \code{'\e r'} for MacOS, or multiple characters, ! for example, \code{'\e r\e n'} for MS-DOS and MS Windows. \end{datadesc} Index: libprofile.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libprofile.tex,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -r1.35 -r1.36 *** libprofile.tex 2001/07/02 21:22:39 1.35 --- libprofile.tex 2001/07/06 20:30:11 1.36 *************** *** 320,325 **** \item[cumtime ] ! is the total time spent in this and all subfunctions (i.e., from ! invocation till exit). This figure is accurate \emph{even} for recursive functions. --- 320,325 ---- \item[cumtime ] ! is the total time spent in this and all subfunctions (from invocation ! till exit). This figure is accurate \emph{even} for recursive functions. *************** *** 332,340 **** \end{description} ! When there are two numbers in the first column (e.g.: \samp{43/3}), ! then the latter is the number of primitive calls, and the former is ! the actual number of calls. Note that when the function does not ! recurse, these two values are the same, and only the single figure is ! printed. \end{funcdesc} --- 332,340 ---- \end{description} ! When there are two numbers in the first column (for example, ! \samp{43/3}), then the latter is the number of primitive calls, and ! the former is the actual number of calls. Note that when the function ! does not recurse, these two values are the same, and only the single ! figure is printed. \end{funcdesc} *************** *** 356,360 **** \emph{no} file compatibility guaranteed with future versions of this profiler, and there is no compatibility with files produced by other ! profilers (e.g., the old system profiler). If several files are provided, all the statistics for identical --- 356,360 ---- \emph{no} file compatibility guaranteed with future versions of this profiler, and there is no compatibility with files produced by other ! profilers (such as the old system profiler). If several files are provided, all the statistics for identical *************** *** 378,382 **** entries in a ``random'' order, as it was just after object initialization and loading. If \method{strip_dirs()} causes two ! function names to be indistinguishable (i.e., they are on the same line of the same filename, and have the same function name), then the statistics for these two entries are accumulated into a single entry. --- 378,382 ---- entries in a ``random'' order, as it was just after object initialization and loading. If \method{strip_dirs()} causes two ! function names to be indistinguishable (they are on the same line of the same filename, and have the same function name), then the statistics for these two entries are accumulated into a single entry. *************** *** 424,428 **** Note that all sorts on statistics are in descending order (placing most time consuming items first), where as name, file, and line number ! searches are in ascending order (i.e., alphabetical). The subtle distinction between \code{'nfl'} and \code{'stdname'} is that the standard name is a sort of the name as printed, which means that the --- 424,428 ---- Note that all sorts on statistics are in descending order (placing most time consuming items first), where as name, file, and line number ! searches are in ascending order (alphabetical). The subtle distinction between \code{'nfl'} and \code{'stdname'} is that the standard name is a sort of the name as printed, which means that the *************** *** 539,546 **** times, or call many functions, will typically accumulate this error. The error that accumulates in this fashion is typically less than the ! accuracy of the clock (i.e., less than one clock tick), but it \emph{can} accumulate and become very significant. This profiler provides a means of calibrating itself for a given platform so that ! this error can be probabilistically (i.e., on the average) removed. After the profiler is calibrated, it will be more accurate (in a least square sense), but it will sometimes produce negative numbers (when --- 539,546 ---- times, or call many functions, will typically accumulate this error. The error that accumulates in this fashion is typically less than the ! accuracy of the clock (less than one clock tick), but it \emph{can} accumulate and become very significant. This profiler provides a means of calibrating itself for a given platform so that ! this error can be probabilistically (on the average) removed. After the profiler is calibrated, it will be more accurate (in a least square sense), but it will sometimes produce negative numbers (when *************** *** 696,701 **** The following derived profiler simulates the old style profiler, providing errant results on recursive functions. The reason for the ! usefulness of this profiler is that it runs faster (i.e., less ! overhead) than the old profiler. It still creates all the caller stats, and is quite useful when there is \emph{no} recursion in the user's code. It is also a lot more accurate than the old profiler, as --- 696,701 ---- The following derived profiler simulates the old style profiler, providing errant results on recursive functions. The reason for the ! usefulness of this profiler is that it runs faster (less ! overhead) than the new profiler. It still creates all the caller stats, and is quite useful when there is \emph{no} recursion in the user's code. It is also a lot more accurate than the old profiler, as Index: libre.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libre.tex,v retrieving revision 1.61 retrieving revision 1.62 diff -C2 -r1.61 -r1.62 *** libre.tex 2001/04/18 17:26:20 1.61 --- libre.tex 2001/07/06 20:30:11 1.62 *************** *** 230,236 **** For example, if the pattern is \regexp{(?P[a-zA-Z_]\e w*)}, the group can be referenced by its ! name in arguments to methods of match objects, such as \code{m.group('id')} ! or \code{m.end('id')}, and also by name in pattern text ! (e.g. \regexp{(?P=id)}) and replacement text (e.g. \code{\e g}). \item[\code{(?P=\var{name})}] Matches whatever text was matched by the --- 230,237 ---- For example, if the pattern is \regexp{(?P[a-zA-Z_]\e w*)}, the group can be referenced by its ! name in arguments to methods of match objects, such as ! \code{m.group('id')} or \code{m.end('id')}, and also by name in ! pattern text (for example, \regexp{(?P=id)}) and replacement text ! (such as \code{\e g}). \item[\code{(?P=\var{name})}] Matches whatever text was matched by the *************** *** 517,521 **** The pattern may be a string or an RE object; if you need to specify regular expression flags, you must use a RE object, or use ! embedded modifiers in a pattern; e.g. \samp{sub("(?i)b+", "x", "bbbb BBBB")} returns \code{'x x'}. --- 518,522 ---- The pattern may be a string or an RE object; if you need to specify regular expression flags, you must use a RE object, or use ! embedded modifiers in a pattern; for example, \samp{sub("(?i)b+", "x", "bbbb BBBB")} returns \code{'x x'}. *************** *** 556,562 **** \begin{excdesc}{error} Exception raised when a string passed to one of the functions here ! is not a valid regular expression (e.g., unmatched parentheses) or ! when some other error occurs during compilation or matching. It is ! never an error if a string contains no match for a pattern. \end{excdesc} --- 557,564 ---- \begin{excdesc}{error} Exception raised when a string passed to one of the functions here ! is not a valid regular expression (for example, it might contain ! unmatched parentheses) or when some other error occurs during ! compilation or matching. It is never an error if a string contains ! no match for a pattern. \end{excdesc} *************** *** 655,659 **** argument, the result is a single string; if there are multiple arguments, the result is a tuple with one item per argument. ! Without arguments, \var{group1} defaults to zero (i.e. the whole match is returned). If a \var{groupN} argument is zero, the corresponding return value is the --- 657,661 ---- argument, the result is a single string; if there are multiple arguments, the result is a tuple with one item per argument. ! Without arguments, \var{group1} defaults to zero (the whole match is returned). If a \var{groupN} argument is zero, the corresponding return value is the Index: librexec.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/librexec.tex,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -r1.15 -r1.16 *** librexec.tex 2001/06/22 18:21:53 1.15 --- librexec.tex 2001/07/06 20:30:11 1.16 *************** *** 33,37 **** the \class{RExec} object doesn't make these calls --- they are made by a module loader object that's part of the \class{RExec} object. This ! allows another level of flexibility, e.g. using packages.) By providing an alternate \class{RHooks} object, we can control the --- 33,38 ---- the \class{RExec} object doesn't make these calls --- they are made by a module loader object that's part of the \class{RExec} object. This ! allows another level of flexibility, which can be useful when changing ! the mechanics of \keyword{import} within the restricted environment.) By providing an alternate \class{RHooks} object, we can control the *************** *** 136,140 **** \begin{methoddesc}{r_unload}{module} ! Unload the module object \var{module} (i.e., remove it from the restricted environment's \code{sys.modules} dictionary). \end{methoddesc} --- 137,141 ---- \begin{methoddesc}{r_unload}{module} ! Unload the module object \var{module} (remove it from the restricted environment's \code{sys.modules} dictionary). \end{methoddesc} Index: librlcompleter.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/librlcompleter.tex,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** librlcompleter.tex 2000/12/01 15:25:23 1.5 --- librlcompleter.tex 2001/07/06 20:30:11 1.6 *************** *** 58,62 **** If called for a dotted name, it will try to evaluate anything without ! obvious side-effects (i.e., functions will not be evaluated, but it can generate calls to \method{__getattr__()}) upto the last part, and find matches for the rest via the \function{dir()} function. --- 58,62 ---- If called for a dotted name, it will try to evaluate anything without ! obvious side-effects (functions will not be evaluated, but it can generate calls to \method{__getattr__()}) upto the last part, and find matches for the rest via the \function{dir()} function. Index: libsha.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsha.tex,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -r1.6 -r1.7 *** libsha.tex 2000/09/18 15:34:57 1.6 --- libsha.tex 2001/07/06 20:30:11 1.7 *************** *** 43,47 **** Update the sha object with the string \var{arg}. Repeated calls are equivalent to a single call with the concatenation of all the ! arguments, i.e.\ \code{m.update(a); m.update(b)} is equivalent to \code{m.update(a+b)}. \end{methoddesc} --- 43,47 ---- Update the sha object with the string \var{arg}. Repeated calls are equivalent to a single call with the concatenation of all the ! arguments: \code{m.update(a); m.update(b)} is equivalent to \code{m.update(a+b)}. \end{methoddesc} Index: libsignal.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsignal.tex,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -r1.20 -r1.21 *** libsignal.tex 2001/05/10 15:57:17 1.20 --- libsignal.tex 2001/07/06 20:30:11 1.21 *************** *** 13,17 **** \item A handler for a particular signal, once set, remains installed until ! it is explicitly reset (i.e. Python emulates the BSD style interface regardless of the underlying implementation), with the exception of the handler for \constant{SIGCHLD}, which follows the underlying --- 13,17 ---- \item A handler for a particular signal, once set, remains installed until ! it is explicitly reset (Python emulates the BSD style interface regardless of the underlying implementation), with the exception of the handler for \constant{SIGCHLD}, which follows the underlying *************** *** 26,31 **** the Python user is concerned, they can only occur between the ``atomic'' instructions of the Python interpreter. This means that ! signals arriving during long calculations implemented purely in \C{} ! (e.g.\ regular expression matches on large bodies of text) may be delayed for an arbitrary amount of time. --- 26,31 ---- the Python user is concerned, they can only occur between the ``atomic'' instructions of the Python interpreter. This means that ! signals arriving during long calculations implemented purely in C ! (such as regular expression matches on large bodies of text) may be delayed for an arbitrary amount of time. *************** *** 98,102 **** If \var{time} is non-zero, this function requests that a \constant{SIGALRM} signal be sent to the process in \var{time} seconds. ! Any previously scheduled alarm is canceled (i.e.\ only one alarm can be scheduled at any time). The returned value is then the number of seconds before any previously set alarm was to have been delivered. --- 98,102 ---- If \var{time} is non-zero, this function requests that a \constant{SIGALRM} signal be sent to the process in \var{time} seconds. ! Any previously scheduled alarm is canceled (only one alarm can be scheduled at any time). The returned value is then the number of seconds before any previously set alarm was to have been delivered. Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.63 retrieving revision 1.64 diff -C2 -r1.63 -r1.64 *** libstdtypes.tex 2001/07/05 15:27:19 1.63 --- libstdtypes.tex 2001/07/06 20:30:11 1.64 *************** *** 446,450 **** \item[(2)] If \var{i} or \var{j} is negative, the index is relative to ! the end of the string, i.e., \code{len(\var{s}) + \var{i}} or \code{len(\var{s}) + \var{j}} is substituted. But note that \code{-0} is still \code{0}. --- 446,450 ---- \item[(2)] If \var{i} or \var{j} is negative, the index is relative to ! the end of the string: \code{len(\var{s}) + \var{i}} or \code{len(\var{s}) + \var{j}} is substituted. But note that \code{-0} is still \code{0}. *************** *** 539,543 **** \begin{methoddesc}[string]{istitle}{} ! Return true if the string is a titlecased string, i.e.\ uppercase characters may only follow uncased characters and lowercase characters only cased ones. Return false otherwise. --- 539,543 ---- \begin{methoddesc}[string]{istitle}{} ! Return true if the string is a titlecased string: uppercase characters may only follow uncased characters and lowercase characters only cased ones. Return false otherwise. *************** *** 629,633 **** \begin{methoddesc}[string]{title}{} ! Return a titlecased version of, i.e.\ words start with uppercase characters, all remaining cased characters are lowercase. \end{methoddesc} --- 629,633 ---- \begin{methoddesc}[string]{title}{} ! Return a titlecased version of the string: words start with uppercase characters, all remaining cased characters are lowercase. \end{methoddesc} *************** *** 1009,1013 **** Modifying this dictionary will actually change the module's symbol table, but direct assignment to the \member{__dict__} attribute is not ! possible (i.e., you can write \code{\var{m}.__dict__['a'] = 1}, which defines \code{\var{m}.a} to be \code{1}, but you can't write \code{\var{m}.__dict__ = \{\}}. --- 1009,1013 ---- Modifying this dictionary will actually change the module's symbol table, but direct assignment to the \member{__dict__} attribute is not ! possible (you can write \code{\var{m}.__dict__['a'] = 1}, which defines \code{\var{m}.a} to be \code{1}, but you can't write \code{\var{m}.__dict__ = \{\}}. *************** *** 1088,1092 **** Like function objects, methods objects support getting arbitrary attributes. However, since method attributes are actually ! stored on the underlying function object (i.e. \code{meth.im_func}), setting method attributes on either bound or unbound methods is disallowed. Attempting to set a method attribute results in a --- 1088,1092 ---- Like function objects, methods objects support getting arbitrary attributes. However, since method attributes are actually ! stored on the underlying function object (\code{meth.im_func}), setting method attributes on either bound or unbound methods is disallowed. Attempting to set a method attribute results in a *************** *** 1168,1172 **** \function{open()}\bifuncindex{open} described in section \ref{built-in-funcs}, ``Built-in Functions.'' They are also returned ! by some other built-in functions and methods, e.g., \function{os.popen()} and \function{os.fdopen()} and the \method{makefile()} method of socket objects. --- 1168,1172 ---- \function{open()}\bifuncindex{open} described in section \ref{built-in-funcs}, ``Built-in Functions.'' They are also returned ! by some other built-in functions and methods, such as \function{os.popen()} and \function{os.fdopen()} and the \method{makefile()} method of socket objects. *************** *** 1207,1214 **** underlying implementation to request I/O operations from the operating system. This can be useful for other, lower level ! interfaces that use file descriptors, e.g.\ module ! \refmodule{fcntl}\refbimodindex{fcntl} or \function{os.read()} and ! friends. \strong{Note:} File-like objects which do not have a real ! file descriptor should \emph{not} provide this method! \end{methoddesc} --- 1207,1215 ---- underlying implementation to request I/O operations from the operating system. This can be useful for other, lower level ! interfaces that use file descriptors, such as the ! \refmodule{fcntl}\refbimodindex{fcntl} module or ! \function{os.read()} and friends. \strong{Note:} File-like objects ! which do not have a real file descriptor should \emph{not} provide ! this method! \end{methoddesc} *************** *** 1230,1234 **** The advantage of leaving the newline on is that an empty string can be returned to mean \EOF{} without being ambiguous. Another ! advantage is that (in cases where it might matter, e.g. if you want to make an exact copy of a file while scanning its lines) you can tell whether the last line of a file ended in a newline --- 1231,1235 ---- The advantage of leaving the newline on is that an empty string can be returned to mean \EOF{} without being ambiguous. Another ! advantage is that (in cases where it might matter, for example. if you want to make an exact copy of a file while scanning its lines) you can tell whether the last line of a file ended in a newline *************** *** 1357,1370 **** \begin{memberdesc}[object]{__methods__} ! List of the methods of many built-in object types, ! e.g., \code{[].__methods__} yields ! \code{['append', 'count', 'index', 'insert', 'pop', 'remove', ! 'reverse', 'sort']}. This usually does not need to be explicitly ! provided by the object. \end{memberdesc} \begin{memberdesc}[object]{__members__} Similar to \member{__methods__}, but lists data attributes. This ! usually does not need to be explicitly provided by the object. \end{memberdesc} --- 1358,1371 ---- \begin{memberdesc}[object]{__methods__} ! List of the methods of many built-in object types. For example, ! \code{[].__methods__} yields \code{['append', 'count', 'index', ! 'insert', 'pop', 'remove', 'reverse', 'sort']}. This usually does not ! need to be explicitly provided by the object. \end{memberdesc} \begin{memberdesc}[object]{__members__} Similar to \member{__methods__}, but lists data attributes. This ! usually does not need to be explicitly provided by the object, and ! need not include the names of the attributes defined in this section. \end{memberdesc} *************** *** 1374,1377 **** \begin{memberdesc}[class]{__bases__} ! The tuple of base classes of a class object. \end{memberdesc} --- 1375,1379 ---- \begin{memberdesc}[class]{__bases__} ! The tuple of base classes of a class object. If there are no base ! classes, this will be an empty tuple. \end{memberdesc} Index: libstringio.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstringio.tex,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** libstringio.tex 2000/11/28 16:24:28 1.5 --- libstringio.tex 2001/07/06 20:30:11 1.6 *************** *** 18,22 **** The \class{StringIO} object can accept either Unicode or 8-bit strings, but mixing the two may take some care. If both are used, ! 8-bit strings that cannot be interpreted as 7-bit \ASCII{} (i.e., that use the 8th bit) will cause a \exception{UnicodeError} to be raised when \method{getvalue()} is called. --- 18,22 ---- The \class{StringIO} object can accept either Unicode or 8-bit strings, but mixing the two may take some care. If both are used, ! 8-bit strings that cannot be interpreted as 7-bit \ASCII{} (that use the 8th bit) will cause a \exception{UnicodeError} to be raised when \method{getvalue()} is called. Index: libstruct.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstruct.tex,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -r1.29 -r1.30 *** libstruct.tex 2001/06/15 14:13:07 1.29 --- libstruct.tex 2001/07/06 20:30:11 1.30 *************** *** 34,39 **** \textrm{\ldots})}) according to the given format. The result is a tuple even if it contains exactly one item. The string must contain ! exactly the amount of data required by the format (i.e. ! \code{len(\var{string})} must equal \code{calcsize(\var{fmt})}). \end{funcdesc} --- 34,39 ---- \textrm{\ldots})}) according to the given format. The result is a tuple even if it contains exactly one item. The string must contain ! exactly the amount of data required by the format ! (\code{len(\var{string})} must equal \code{calcsize(\var{fmt})}). \end{funcdesc} *************** *** 79,84 **** ! A format character may be preceded by an integral repeat count; ! e.g.\ the format string \code{'4h'} means exactly the same as \code{'hhhh'}. --- 79,84 ---- ! A format character may be preceded by an integral repeat count. For ! example, the format string \code{'4h'} means exactly the same as \code{'hhhh'}. *************** *** 88,92 **** For the \character{s} format character, the count is interpreted as the size of the string, not a repeat count like for the other format ! characters; e.g. \code{'10s'} means a single 10-byte string, while \code{'10c'} means 10 characters. For packing, the string is truncated or padded with null bytes as appropriate to make it fit. --- 88,92 ---- For the \character{s} format character, the count is interpreted as the size of the string, not a repeat count like for the other format ! characters; for example, \code{'10s'} means a single 10-byte string, while \code{'10c'} means 10 characters. For packing, the string is truncated or padded with null bytes as appropriate to make it fit. *************** *** 134,139 **** Native byte order is big-endian or little-endian, depending on the ! host system (e.g. Motorola and Sun are big-endian; Intel and DEC are ! little-endian). Native size and alignment are determined using the C compiler's --- 134,139 ---- Native byte order is big-endian or little-endian, depending on the ! host system. For example, Motorola and Sun processors are big-endian; ! Intel and DEC processors are little-endian. Native size and alignment are determined using the C compiler's *************** *** 157,161 **** little-endian. ! There is no way to indicate non-native byte order (i.e. force byte-swapping); use the appropriate choice of \character{<} or \character{>}. --- 157,161 ---- little-endian. ! There is no way to indicate non-native byte order (force byte-swapping); use the appropriate choice of \character{<} or \character{>}. *************** *** 183,190 **** Hint: to align the end of a structure to the alignment requirement of a particular type, end the format with the code for that type with a ! repeat count of zero, e.g.\ the format \code{'llh0l'} specifies two ! pad bytes at the end, assuming longs are aligned on 4-byte boundaries. ! This only works when native size and alignment are in effect; ! standard size and alignment does not enforce any alignment. \begin{seealso} --- 183,190 ---- Hint: to align the end of a structure to the alignment requirement of a particular type, end the format with the code for that type with a ! repeat count of zero. For example, the format \code{'llh0l'} ! specifies two pad bytes at the end, assuming longs are aligned on ! 4-byte boundaries. This only works when native size and alignment are ! in effect; standard size and alignment does not enforce any alignment. \begin{seealso} Index: libthreading.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libthreading.tex,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** libthreading.tex 2001/05/31 20:24:07 1.8 --- libthreading.tex 2001/07/06 20:30:11 1.9 *************** *** 151,158 **** To lock the lock, a thread calls its \method{acquire()} method; this returns once the thread owns the lock. To unlock the lock, a ! thread calls its \method{release()} method. \method{acquire()}/\method{release()} call pairs ! may be nested; only the final \method{release()} (i.e. the \method{release()} of the ! outermost pair) resets the lock to unlocked and allows another ! thread blocked in \method{acquire()} to proceed. \begin{methoddesc}{acquire}{\optional{blocking\code{ = 1}}} --- 151,159 ---- To lock the lock, a thread calls its \method{acquire()} method; this returns once the thread owns the lock. To unlock the lock, a ! thread calls its \method{release()} method. ! \method{acquire()}/\method{release()} call pairs may be nested; only ! the final \method{release()} (the \method{release()} of the outermost ! pair) resets the lock to unlocked and allows another thread blocked in ! \method{acquire()} to proceed. \begin{methoddesc}{acquire}{\optional{blocking\code{ = 1}}} *************** *** 454,458 **** created. These are thread objects corresponding to ``alien threads''. These are threads of control started outside the ! threading module, e.g. directly from C code. Dummy thread objects have limited functionality; they are always considered alive, active, and daemonic, and cannot be \method{join()}ed. They are never --- 455,459 ---- created. These are thread objects corresponding to ``alien threads''. These are threads of control started outside the ! threading module, such as directly from C code. Dummy thread objects have limited functionality; they are always considered alive, active, and daemonic, and cannot be \method{join()}ed. They are never Index: libtime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libtime.tex,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -r1.39 -r1.40 *** libtime.tex 2001/06/29 15:39:53 1.39 --- libtime.tex 2001/07/06 20:30:11 1.40 *************** *** 81,85 **** \begin{tableiii}{r|l|l}{textrm}{Index}{Field}{Values} ! \lineiii{0}{year}{(e.g.\ 1993)} \lineiii{1}{month}{range [1,12]} \lineiii{2}{day}{range [1,31]} --- 81,85 ---- \begin{tableiii}{r|l|l}{textrm}{Index}{Field}{Values} ! \lineiii{0}{year}{(for example, 1993)} \lineiii{1}{month}{range [1,12]} \lineiii{2}{day}{range [1,31]} *************** *** 286,291 **** \begin{datadesc}{timezone} The offset of the local (non-DST) timezone, in seconds west of UTC ! (i.e. negative in most of Western Europe, positive in the US, zero in ! the UK). \end{datadesc} --- 286,291 ---- \begin{datadesc}{timezone} The offset of the local (non-DST) timezone, in seconds west of UTC ! (negative in most of Western Europe, positive in the US, zero in the ! UK). \end{datadesc} Index: libuser.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libuser.tex,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -r1.16 -r1.17 *** libuser.tex 2000/10/18 17:43:06 1.16 --- libuser.tex 2001/07/06 20:30:11 1.17 *************** *** 25,29 **** The \module{user} module looks for a file \file{.pythonrc.py} in the user's home directory and if it can be opened, executes it (using ! \function{execfile()}\bifuncindex{execfile}) in its own (i.e. the module \module{user}'s) global namespace. Errors during this phase are not caught; that's up to the program that imports the --- 25,29 ---- The \module{user} module looks for a file \file{.pythonrc.py} in the user's home directory and if it can be opened, executes it (using ! \function{execfile()}\bifuncindex{execfile}) in its own (the module \module{user}'s) global namespace. Errors during this phase are not caught; that's up to the program that imports the Index: libwinreg.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libwinreg.tex,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -r1.6 -r1.7 *** libwinreg.tex 2000/11/30 07:12:54 1.6 --- libwinreg.tex 2001/07/06 20:30:11 1.7 *************** *** 381,386 **** print "Yes" \end{verbatim} ! will print \code{Yes} if the handle is currently valid (i.e., ! has not been closed or detached). The object also support comparison semantics, so handle --- 381,386 ---- print "Yes" \end{verbatim} ! will print \code{Yes} if the handle is currently valid (has not been ! closed or detached). The object also support comparison semantics, so handle Index: libxmllib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libxmllib.tex,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -r1.30 -r1.31 *** libxmllib.tex 2000/11/28 06:39:28 1.30 --- libxmllib.tex 2001/07/06 20:30:11 1.31 *************** *** 268,272 **** Tag and attribute names that are defined in an XML namespace are handled as if the name of the tag or element consisted of the ! namespace (i.e. the URL that defines the namespace) followed by a space and the name of the tag or attribute. For instance, the tag \code{} is treated as if --- 268,272 ---- Tag and attribute names that are defined in an XML namespace are handled as if the name of the tag or element consisted of the ! namespace (the URL that defines the namespace) followed by a space and the name of the tag or attribute. For instance, the tag \code{} is treated as if Index: libzipfile.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libzipfile.tex,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -r1.11 -r1.12 *** libzipfile.tex 2001/05/11 15:49:19 1.11 --- libzipfile.tex 2001/07/06 20:30:11 1.12 *************** *** 80,84 **** \begin{classdesc}{ZipFile}{file\optional{, mode\optional{, compression}}} Open a ZIP file, where \var{file} can be either a path to a file ! (i.e. a string) or a file-like object. The \var{mode} parameter should be \code{'r'} to read an existing file, \code{'w'} to truncate and write a new file, or \code{'a'} to append to an --- 80,84 ---- \begin{classdesc}{ZipFile}{file\optional{, mode\optional{, compression}}} Open a ZIP file, where \var{file} can be either a path to a file ! (a string) or a file-like object. The \var{mode} parameter should be \code{'r'} to read an existing file, \code{'w'} to truncate and write a new file, or \code{'a'} to append to an Index: xmlsaxreader.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/xmlsaxreader.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** xmlsaxreader.tex 2000/10/12 20:05:09 1.1 --- xmlsaxreader.tex 2001/07/06 20:30:11 1.2 *************** *** 93,97 **** \begin{methoddesc}[XMLReader]{parse}{source} Process an input source, producing SAX events. The \var{source} ! object can be a system identifier (i.e. a string identifying the input source -- typically a file name or an URL), a file-like object, or an \class{InputSource} object. When \method{parse()} --- 93,97 ---- \begin{methoddesc}[XMLReader]{parse}{source} Process an input source, producing SAX events. The \var{source} ! object can be a system identifier (a string identifying the input source -- typically a file name or an URL), a file-like object, or an \class{InputSource} object. When \method{parse()} From bwarsaw@users.sourceforge.net Fri Jul 6 21:38:13 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Fri, 06 Jul 2001 13:38:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc python-mode.el,4.5,4.6 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv29380 Modified Files: python-mode.el Log Message: Once again, attempt to preserve $Revision$ Index: python-mode.el =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/python-mode.el,v retrieving revision 4.5 retrieving revision 4.6 diff -C2 -r4.5 -r4.6 From effbot@users.sourceforge.net Fri Jul 6 21:56:12 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Fri, 06 Jul 2001 13:56:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib sre.py,1.31,1.32 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv1289/Lib Modified Files: sre.py Log Message: bug #436596 re.findall doesn't take a maxsplit argument Index: sre.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre.py,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -r1.31 -r1.32 *** sre.py 2001/03/22 15:50:10 1.31 --- sre.py 2001/07/06 20:56:10 1.32 *************** *** 76,80 **** return _compile(pattern, 0).split(string, maxsplit) ! def findall(pattern, string, maxsplit=0): """Return a list of all non-overlapping matches in the string. --- 76,80 ---- return _compile(pattern, 0).split(string, maxsplit) ! def findall(pattern, string): """Return a list of all non-overlapping matches in the string. *************** *** 84,88 **** Empty matches are included in the result.""" ! return _compile(pattern, 0).findall(string, maxsplit) def compile(pattern, flags=0): --- 84,88 ---- Empty matches are included in the result.""" ! return _compile(pattern, 0).findall(string) def compile(pattern, flags=0): From fdrake@users.sourceforge.net Fri Jul 6 22:01:21 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 06 Jul 2001 14:01:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools/sgmlconv latex2esis.py,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools/sgmlconv In directory usw-pr-cvs1:/tmp/cvs-serv3089 Modified Files: latex2esis.py Log Message: Allow optional arguments to LaTeX macros to span lines. This is legal in LaTeX and we have at least one occurance of that in the content, so this script needs to support it as well. Index: latex2esis.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/sgmlconv/latex2esis.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -r1.23 -r1.24 *** latex2esis.py 2001/03/23 16:53:34 1.23 --- latex2esis.py 2001/07/06 21:01:19 1.24 *************** *** 57,61 **** _comment_rx = re.compile("%+ ?(.*)\n[ \t]*") _text_rx = re.compile(r"[^]~%\\{}]+") ! _optional_rx = re.compile(r"\s*[[]([^]]*)[]]") # _parameter_rx is this complicated to allow {...} inside a parameter; # this is useful to match tabular layout specifications like {c|p{24pt}} --- 57,61 ---- _comment_rx = re.compile("%+ ?(.*)\n[ \t]*") _text_rx = re.compile(r"[^]~%\\{}]+") ! _optional_rx = re.compile(r"\s*[[]([^]]*)[]]", re.MULTILINE) # _parameter_rx is this complicated to allow {...} inside a parameter; # this is useful to match tabular layout specifications like {c|p{24pt}} From fdrake@users.sourceforge.net Fri Jul 6 22:03:32 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 06 Jul 2001 14:03:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools/sgmlconv docfixer.py,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools/sgmlconv In directory usw-pr-cvs1:/tmp/cvs-serv3469 Modified Files: docfixer.py Log Message: Simplification to mirror a better conversion specification and more powerful latex2esis.py. Index: docfixer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/sgmlconv/docfixer.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -r1.28 -r1.29 *** docfixer.py 2001/03/29 23:31:22 1.28 --- docfixer.py 2001/07/06 21:03:30 1.29 *************** *** 191,200 **** # 1. descname = descriptor.tagName ! index = 1 ! if descname[-2:] == "ni": ! descname = descname[:-2] ! descriptor.setAttribute("index", "no") ! set_tagName(descriptor, descname) ! index = 0 desctype = descname[:-4] # remove 'desc' linename = desctype + "line" --- 191,195 ---- # 1. descname = descriptor.tagName ! index = descriptor.getAttribute("name") != "no" desctype = descname[:-4] # remove 'desc' linename = desctype + "line" From tim_one@users.sourceforge.net Fri Jul 6 22:06:56 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 06 Jul 2001 14:06:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib FCNTL.py,NONE,1.1.4.1 HTMLParser.py,NONE,1.3.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv3927 Added Files: Tag: descr-branch FCNTL.py HTMLParser.py Log Message: More new additions for descr-branch. --- NEW FILE: FCNTL.py --- """Backward-compatibility version of FCNTL; export constants exported by fcntl, and issue a deprecation warning. """ import warnings warnings.warn("the FCNTL module is deprecated; please use fcntl", DeprecationWarning) # Export the constants known to the fcntl module: from fcntl import * # and *only* the constants: __all__ = [s for s in dir() if s[0] in "ABCDEFGHIJKLMNOPQRSTUVWXYZ"] --- NEW FILE: HTMLParser.py --- """A parser for HTML.""" # This file is based on sgmllib.py, but the API is slightly different. # XXX There should be a way to distinguish between PCDATA (parsed # character data -- the normal case), RCDATA (replaceable character # data -- only char and entity references and end tags are special) # and CDATA (character data -- only end tags are special). import re import string # Regular expressions used for parsing interesting_normal = re.compile('[&<]') interesting_cdata = re.compile(r'<(/|\Z)') incomplete = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*|#[0-9]*)?') entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]') charref = re.compile('&#([0-9]+)[^0-9]') starttagopen = re.compile('<[a-zA-Z]') piopen = re.compile(r'<\?') piclose = re.compile('>') endtagopen = re.compile(']*>') commentopen = re.compile(' --- 53,64 ---- + *************** *** 696,699 **** --- 696,707 ---- + + + + + From gvanrossum@users.sourceforge.net Sat Jul 7 19:35:12 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 07 Jul 2001 11:35:12 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0000.txt,1.104,1.105 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv9736 Modified Files: pep-0000.txt Log Message: If we're going to group them by hundreds, the blank line belongs *before* PEP 100, not after it. Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.104 retrieving revision 1.105 diff -C2 -r1.104 -r1.105 *** pep-0000.txt 2001/07/05 18:48:30 1.104 --- pep-0000.txt 2001/07/07 18:35:10 1.105 *************** *** 131,136 **** I 8 pep-0008.txt Style Guide for Python Code van Rossum, Warsaw I 42 pep-0042.txt Small Feature Requests Hylton - SF 100 pep-0100.txt Python Unicode Integration Lemburg IF 160 pep-0160.txt Python 1.6 Release Schedule Drake --- 131,136 ---- I 8 pep-0008.txt Style Guide for Python Code van Rossum, Warsaw I 42 pep-0042.txt Small Feature Requests Hylton + SF 100 pep-0100.txt Python Unicode Integration Lemburg IF 160 pep-0160.txt Python 1.6 Release Schedule Drake From tim_one@users.sourceforge.net Sat Jul 7 23:45:46 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 15:45:46 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.1.2.15,1.1.2.16 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv20562/descr/dist/src Modified Files: Tag: descr-branch PLAN.txt Log Message: ************ IMPORTANT ************ I'm about to make a giant checkin, merging the trunk into descr-branch. See the PLAN.txt changes for open issues with this merge. There are a couple known problems, but that's all, and I figure Guido can sort them out faster than I can (and even if I weren't burned out ). Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Attic/PLAN.txt,v retrieving revision 1.1.2.15 retrieving revision 1.1.2.16 diff -C2 -r1.1.2.15 -r1.1.2.16 *** PLAN.txt 2001/07/06 22:02:35 1.1.2.15 --- PLAN.txt 2001/07/07 22:45:44 1.1.2.16 *************** *** 252,274 **** ------------------------------------------------------------------ ! Merge glitches: ! + test_unicode.py fails, but due to this oddity (cause unknown, but more ! Unicode changes still need to be merged): ! >>> "%*s" % (5, u"abc") ! Traceback (most recent call last): ! File "", line 1, in ? ! TypeError: * wants int ! >>> ! + test___all__.py yields: ! c:\code\descr\dist\src\lib\FCNTL.py:7: DeprecationWarning: the FCNTL ! module is deprecated; please use fcntl ! ! Assuming this will go away when newer test___all__ gets merged (but it ! can't now, because it imports other new stuff that can't yet be merged ! until its implementation code is merged, etc). ------------------------------------------------------------------ 2001-07-06 --- 252,269 ---- ------------------------------------------------------------------ ! Merge of trunk tag date2001-07-06 into descr-branch was committed on ! 2001-07-07. ! Merge issues: ! + Tried only on Windows; Unix build may not even compile. ! + New std test failures (again on Windows): ! test_descr.py ! test_generators.py ! + If some non-Windows test has an expected-output file in descr-branch ! that has been removed on the trunk since descr-fork, it will probably ! fail. The cure is to remove the expected-output file in descr-branch too. ------------------------------------------------------------------ 2001-07-06 *************** *** 322,333 **** retrieving revision 2.15 Merging differences between 2.14 and 2.15 into cStringIO.h - RCS file: /cvsroot/python/python/dist/src/Include/ceval.h,v - retrieving revision 2.41 - retrieving revision 2.42 - Merging differences between 2.41 and 2.42 into ceval.h - RCS file: /cvsroot/python/python/dist/src/Include/compile.h,v - retrieving revision 2.29 - retrieving revision 2.30 - Merging differences between 2.29 and 2.30 into compile.h RCS file: /cvsroot/python/python/dist/src/Include/fileobject.h,v retrieving revision 2.22 --- 317,320 ---- *************** *** 338,377 **** retrieving revision 2.18 Merging differences between 2.17 and 2.18 into floatobject.h - RCS file: /cvsroot/python/python/dist/src/Include/frameobject.h,v - retrieving revision 2.31 - retrieving revision 2.33 - Merging differences between 2.31 and 2.33 into frameobject.h - RCS file: /cvsroot/python/python/dist/src/Include/graminit.h,v - retrieving revision 2.16 - retrieving revision 2.17 - Merging differences between 2.16 and 2.17 into graminit.h RCS file: /cvsroot/python/python/dist/src/Include/longobject.h,v retrieving revision 2.19 retrieving revision 2.20 Merging differences between 2.19 and 2.20 into longobject.h - RCS file: /cvsroot/python/python/dist/src/Include/opcode.h,v - retrieving revision 2.35 - retrieving revision 2.36 - Merging differences between 2.35 and 2.36 into opcode.h RCS file: /cvsroot/python/python/dist/src/Include/pyport.h,v retrieving revision 2.26 retrieving revision 2.27 Merging differences between 2.26 and 2.27 into pyport.h - RCS file: /cvsroot/python/python/dist/src/Include/pystate.h,v - retrieving revision 2.14 - retrieving revision 2.16 - Merging differences between 2.14 and 2.16 into pystate.h RCS file: /cvsroot/python/python/dist/src/Include/rangeobject.h,v retrieving revision 2.15 retrieving revision 2.17 Merging differences between 2.15 and 2.17 into rangeobject.h - RCS file: /cvsroot/python/python/dist/src/Include/stringobject.h,v - retrieving revision 2.25 - retrieving revision 2.28 - Merging differences between 2.25 and 2.28 into stringobject.h - RCS file: /cvsroot/python/python/dist/src/Include/symtable.h,v - retrieving revision 2.7 - retrieving revision 2.8 - Merging differences between 2.7 and 2.8 into symtable.h RCS file: /cvsroot/python/python/dist/src/Include/tupleobject.h,v retrieving revision 2.24 --- 325,340 ---- *************** *** 382,389 **** retrieving revision 2.27 Merging differences between 2.20 and 2.27 into unicodeobject.h - RCS file: /cvsroot/python/python/dist/src/Lib/Cookie.py,v - retrieving revision 1.8 - retrieving revision 1.9 - Merging differences between 1.8 and 1.9 into Cookie.py RCS file: /cvsroot/python/python/dist/src/Lib/UserDict.py,v retrieving revision 1.12 --- 345,348 ---- *************** *** 653,660 **** retrieving revision 1.7 Merging differences between 1.6 and 1.7 into test_contains.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_cookie.py,v - retrieving revision 1.9 - retrieving revision 1.10 - Merging differences between 1.9 and 1.10 into test_cookie.py RCS file: /cvsroot/python/python/dist/src/Lib/test/test_copy_reg.py,v retrieving revision 1.1 --- 612,615 ---- *************** *** 673,680 **** retrieving revision 1.4 Merging differences between 1.3 and 1.4 into test_dospath.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_extcall.py,v - retrieving revision 1.14 - retrieving revision 1.16 - Merging differences between 1.14 and 1.16 into test_extcall.py RCS file: /cvsroot/python/python/dist/src/Lib/test/test_fcntl.py,v retrieving revision 1.17 --- 628,631 ---- *************** *** 730,742 **** Merging differences between 1.6 and 1.7 into test_parser.py U mergedescr/dist/src/Lib/test/test_pprint.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pyexpat.py,v - retrieving revision 1.7 - retrieving revision 1.9 - Merging differences between 1.7 and 1.9 into test_pyexpat.py U mergedescr/dist/src/Lib/test/test_quopri.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_regex.py,v - retrieving revision 1.9 - retrieving revision 1.10 - Merging differences between 1.9 and 1.10 into test_regex.py RCS file: /cvsroot/python/python/dist/src/Lib/test/test_rfc822.py,v retrieving revision 1.9 --- 681,685 ---- *************** *** 789,808 **** retrieving revision 1.4 Merging differences between 1.3 and 1.4 into test_coercion - RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_cookie,v - retrieving revision 1.6 - retrieving revision 1.7 - Merging differences between 1.6 and 1.7 into test_cookie - RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_extcall,v - retrieving revision 1.8 - retrieving revision 1.9 - Merging differences between 1.8 and 1.9 into test_extcall RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_minidom,v retrieving revision 1.12 retrieving revision 1.13 Merging differences between 1.12 and 1.13 into test_minidom - RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_pyexpat,v - retrieving revision 1.6 - retrieving revision 1.7 - Merging differences between 1.6 and 1.7 into test_pyexpat RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_scope,v retrieving revision 1.6 --- 732,739 ---- *************** *** 889,896 **** retrieving revision 2.190 Merging differences between 2.187 and 2.190 into posixmodule.c - RCS file: /cvsroot/python/python/dist/src/Modules/pyexpat.c,v - retrieving revision 2.45 - retrieving revision 2.46 - Merging differences between 2.45 and 2.46 into pyexpat.c RCS file: /cvsroot/python/python/dist/src/Modules/regexpr.c,v retrieving revision 1.33 --- 820,823 ---- *************** *** 944,952 **** Merging differences between 2.127 and 2.132 into classobject.c rcsmerge: warning: conflicts during merge - RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v - retrieving revision 2.80 - retrieving revision 2.106 - Merging differences between 2.80 and 2.106 into dictobject.c - rcsmerge: warning: conflicts during merge RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.112 --- 871,874 ---- *************** *** 957,964 **** retrieving revision 2.82 Merging differences between 2.81 and 2.82 into floatobject.c - RCS file: /cvsroot/python/python/dist/src/Objects/frameobject.c,v - retrieving revision 2.49 - retrieving revision 2.52 - Merging differences between 2.49 and 2.52 into frameobject.c RCS file: /cvsroot/python/python/dist/src/Objects/funcobject.c,v retrieving revision 2.37 --- 879,882 ---- *************** *** 998,1006 **** Merging differences between 2.24 and 2.25 into rangeobject.c rcsmerge: warning: conflicts during merge - RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v - retrieving revision 2.103 - retrieving revision 2.120 - Merging differences between 2.103 and 2.120 into stringobject.c - rcsmerge: warning: conflicts during merge RCS file: /cvsroot/python/python/dist/src/Objects/tupleobject.c,v retrieving revision 2.48 --- 916,919 ---- *************** *** 1042,1054 **** Merging differences between 2.198 and 2.215 into bltinmodule.c rcsmerge: warning: conflicts during merge - RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v - retrieving revision 2.241 - retrieving revision 2.260 - Merging differences between 2.241 and 2.260 into ceval.c - rcsmerge: warning: conflicts during merge - RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v - retrieving revision 2.197 - retrieving revision 2.206 - Merging differences between 2.197 and 2.206 into compile.c RCS file: /cvsroot/python/python/dist/src/Python/dynload_win.c,v retrieving revision 2.7 --- 955,958 ---- *************** *** 1064,1071 **** Merging differences between 2.54 and 2.60 into getargs.c rcsmerge: warning: conflicts during merge - RCS file: /cvsroot/python/python/dist/src/Python/graminit.c,v - retrieving revision 2.28 - retrieving revision 2.29 - Merging differences between 2.28 and 2.29 into graminit.c RCS file: /cvsroot/python/python/dist/src/Python/import.c,v retrieving revision 2.176 --- 968,971 ---- *************** *** 1076,1091 **** retrieving revision 1.64 Merging differences between 1.62 and 1.64 into marshal.c - RCS file: /cvsroot/python/python/dist/src/Python/pystate.c,v - retrieving revision 2.16 - retrieving revision 2.18 - Merging differences between 2.16 and 2.18 into pystate.c RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.133 retrieving revision 2.134 Merging differences between 2.133 and 2.134 into pythonrun.c - RCS file: /cvsroot/python/python/dist/src/Python/symtable.c,v - retrieving revision 2.4 - retrieving revision 2.5 - Merging differences between 2.4 and 2.5 into symtable.c RCS file: /cvsroot/python/python/dist/src/Python/sysmodule.c,v retrieving revision 2.85 --- 976,983 ---- From tim_one@users.sourceforge.net Sat Jul 7 23:55:31 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 15:55:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/xml/dom minidom.py,1.32,1.32.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/xml/dom In directory usw-pr-cvs1:/tmp/cvs-serv24450/mergedescr/dist/src/Lib/xml/dom Modified Files: Tag: descr-branch minidom.py Log Message: Merge of trunk tag date2001-07-06 into descr-branch. Index: minidom.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xml/dom/minidom.py,v retrieving revision 1.32 retrieving revision 1.32.4.1 diff -C2 -r1.32 -r1.32.4.1 *** minidom.py 2001/04/05 14:41:30 1.32 --- minidom.py 2001/07/07 22:55:29 1.32.4.1 *************** *** 280,284 **** for node in parent.childNodes: if node.nodeType == Node.ELEMENT_NODE: ! if ((localName == "*" or node.tagName == localName) and (nsURI == "*" or node.namespaceURI == nsURI)): rc.append(node) --- 280,284 ---- for node in parent.childNodes: if node.nodeType == Node.ELEMENT_NODE: ! if ((localName == "*" or node.localName == localName) and (nsURI == "*" or node.namespaceURI == nsURI)): rc.append(node) *************** *** 552,556 **** def getElementsByTagNameNS(self, namespaceURI, localName): ! _getElementsByTagNameNSHelper(self, namespaceURI, localName, []) def __repr__(self): --- 552,556 ---- def getElementsByTagNameNS(self, namespaceURI, localName): ! return _getElementsByTagNameNSHelper(self, namespaceURI, localName, []) def __repr__(self): *************** *** 880,890 **** return a - def getElementsByTagNameNS(self, namespaceURI, localName): - _getElementsByTagNameNSHelper(self, namespaceURI, localName) - def getElementsByTagName(self, name): ! rc = [] ! _getElementsByTagNameHelper(self, name, rc) ! return rc def writexml(self, writer, indent="", addindent="", newl=""): --- 880,888 ---- return a def getElementsByTagName(self, name): ! return _getElementsByTagNameHelper(self, name, []) ! ! def getElementsByTagNameNS(self, namespaceURI, localName): ! return _getElementsByTagNameNSHelper(self, namespaceURI, localName, []) def writexml(self, writer, indent="", addindent="", newl=""): From tim_one@users.sourceforge.net Sat Jul 7 23:55:31 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 15:55:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/xml/sax expatreader.py,1.22,1.22.6.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/xml/sax In directory usw-pr-cvs1:/tmp/cvs-serv24450/mergedescr/dist/src/Lib/xml/sax Modified Files: Tag: descr-branch expatreader.py Log Message: Merge of trunk tag date2001-07-06 into descr-branch. Index: expatreader.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xml/sax/expatreader.py,v retrieving revision 1.22 retrieving revision 1.22.6.1 diff -C2 -r1.22 -r1.22.6.1 *** expatreader.py 2001/01/27 09:01:20 1.22 --- expatreader.py 2001/07/07 22:55:29 1.22.6.1 *************** *** 7,10 **** --- 7,17 ---- from xml.sax._exceptions import * + + # xml.parsers.expat does not raise ImportError in Jython + import sys + if sys.platform[ : 4] == "java": + raise SAXReaderNotAvailable("expat not available in Java", None) + del sys + try: from xml.parsers import expat *************** *** 47,50 **** --- 54,64 ---- self._parser.SetBase(source.getSystemId()) + # Redefined setContentHandle to allow changing handlers during parsing + + def setContentHandler(self, handler): + xmlreader.IncrementalParser.setContentHandler(self, handler) + if self._parsing: + self._reset_cont_handler() + def getFeature(self, name): if name == handler.feature_namespaces: *************** *** 69,72 **** --- 83,88 ---- if name == handler.property_lexical_handler: self._lex_handler_prop = value + if self._parsing: + self._reset_lex_handler_prop() else: raise SAXNotRecognizedException("Property '%s' not recognized" % name) *************** *** 102,105 **** --- 118,131 ---- self._parser = None + def _reset_cont_handler(self): + self._parser.ProcessingInstructionHandler = \ + self._cont_handler.processingInstruction + self._parser.CharacterDataHandler = self._cont_handler.characters + + 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: *************** *** 112,118 **** self._parser.EndElementHandler = self.end_element ! self._parser.ProcessingInstructionHandler = \ ! self._cont_handler.processingInstruction ! self._parser.CharacterDataHandler = self._cont_handler.characters self._parser.UnparsedEntityDeclHandler = self.unparsed_entity_decl self._parser.NotationDeclHandler = self.notation_decl --- 138,142 ---- self._parser.EndElementHandler = self.end_element ! self._reset_cont_handler() self._parser.UnparsedEntityDeclHandler = self.unparsed_entity_decl self._parser.NotationDeclHandler = self.notation_decl *************** *** 122,128 **** self._decl_handler_prop = None if self._lex_handler_prop: ! self._parser.CommentHandler = self._lex_handler_prop.comment ! self._parser.StartCdataSectionHandler = self._lex_handler_prop.startCDATA ! self._parser.EndCdataSectionHandler = self._lex_handler_prop.endCDATA # self._parser.DefaultHandler = # self._parser.DefaultHandlerExpand = --- 146,150 ---- self._decl_handler_prop = None if self._lex_handler_prop: ! self._reset_lex_handler_prop() # self._parser.DefaultHandler = # self._parser.DefaultHandlerExpand = From tim_one@users.sourceforge.net Sat Jul 7 23:55:31 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 15:55:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_unicode_file,NONE,1.1.4.1 test_coercion,1.3,1.3.6.1 test_cookie,1.6,1.6.4.1 test_extcall,1.8,1.8.4.1 test_minidom,1.12,1.12.6.1 test_pyexpat,1.6,1.6.6.1 test_scope,1.6,1.6.4.1 test_copy_reg,1.1,NONE test_descr,1.1.2.1,NONE test_difflib,1.2,NONE test_doctest,1.5,NONE test_dospath,1.1,NONE test_mailbox,1.1,NONE test_parser,1.4,NONE test_sha,1.1,NONE test_strop,1.2,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv24450/mergedescr/dist/src/Lib/test/output Modified Files: Tag: descr-branch test_coercion test_cookie test_extcall test_minidom test_pyexpat test_scope Added Files: Tag: descr-branch test_unicode_file Removed Files: Tag: descr-branch test_copy_reg test_descr test_difflib test_doctest test_dospath test_mailbox test_parser test_sha test_strop Log Message: Merge of trunk tag date2001-07-06 into descr-branch. --- NEW FILE: test_unicode_file --- test_unicode_file All the Unicode tests appeared to work Index: test_coercion =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_coercion,v retrieving revision 1.3 retrieving revision 1.3.6.1 diff -C2 -r1.3 -r1.3.6.1 *** test_coercion 2001/01/04 01:36:25 1.3 --- test_coercion 2001/07/07 22:55:29 1.3.6.1 *************** *** 517,521 **** [1] %= None ... exceptions.TypeError [1] + ... exceptions.TypeError ! [1] += ... exceptions.AttributeError [1] - ... exceptions.TypeError [1] -= ... exceptions.TypeError --- 517,521 ---- [1] %= None ... exceptions.TypeError [1] + ... exceptions.TypeError ! [1] += ... exceptions.TypeError [1] - ... exceptions.TypeError [1] -= ... exceptions.TypeError *************** *** 529,533 **** [1] %= ... exceptions.TypeError [1] + ... exceptions.TypeError ! [1] += ... exceptions.AttributeError [1] - ... exceptions.TypeError [1] -= ... exceptions.TypeError --- 529,533 ---- [1] %= ... exceptions.TypeError [1] + ... exceptions.TypeError ! [1] += ... exceptions.TypeError [1] - ... exceptions.TypeError [1] -= ... exceptions.TypeError Index: test_cookie =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_cookie,v retrieving revision 1.6 retrieving revision 1.6.4.1 diff -C2 -r1.6 -r1.6.4.1 *** test_cookie 2001/04/06 21:20:58 1.6 --- test_cookie 2001/07/07 22:55:29 1.6.4.1 *************** *** 1,10 **** test_cookie ! ! Set-Cookie: vienna=finger; Set-Cookie: chips=ahoy; - vienna 'finger' 'finger' Set-Cookie: vienna=finger; chips 'ahoy' 'ahoy' Set-Cookie: chips=ahoy; Set-Cookie: keebler="E=mc2; L=\"Loves\"; fudge=\012;"; --- 1,10 ---- test_cookie ! Set-Cookie: chips=ahoy; Set-Cookie: vienna=finger; chips 'ahoy' 'ahoy' Set-Cookie: chips=ahoy; + vienna 'finger' 'finger' + Set-Cookie: vienna=finger; Set-Cookie: keebler="E=mc2; L=\"Loves\"; fudge=\012;"; Index: test_extcall =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_extcall,v retrieving revision 1.8 retrieving revision 1.8.4.1 diff -C2 -r1.8 -r1.8.4.1 *** test_extcall 2001/04/11 13:53:35 1.8 --- test_extcall 2001/07/07 22:55:29 1.8.4.1 *************** *** 41,45 **** za () {'d': 'dd'} -> za() got an unexpected keyword argument 'd' za () {'a': 'aa', 'd': 'dd'} -> za() got an unexpected keyword argument 'd' ! za () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> za() got an unexpected keyword argument 'd' za (1, 2) {} -> za() takes exactly 1 argument (2 given) za (1, 2) {'a': 'aa'} -> za() takes exactly 1 non-keyword argument (2 given) --- 41,45 ---- za () {'d': 'dd'} -> za() got an unexpected keyword argument 'd' za () {'a': 'aa', 'd': 'dd'} -> za() got an unexpected keyword argument 'd' ! za () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> za() got an unexpected keyword argument 'b' za (1, 2) {} -> za() takes exactly 1 argument (2 given) za (1, 2) {'a': 'aa'} -> za() takes exactly 1 non-keyword argument (2 given) *************** *** 60,65 **** zade (1, 2) {'a': 'aa'} -> zade() got multiple values for keyword argument 'a' zade (1, 2) {'d': 'dd'} -> zade() got multiple values for keyword argument 'd' ! zade (1, 2) {'a': 'aa', 'd': 'dd'} -> zade() got multiple values for keyword argument 'd' ! zade (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zade() got multiple values for keyword argument 'd' zade (1, 2, 3, 4, 5) {} -> zade() takes at most 3 arguments (5 given) zade (1, 2, 3, 4, 5) {'a': 'aa'} -> zade() takes at most 3 non-keyword arguments (5 given) --- 60,65 ---- zade (1, 2) {'a': 'aa'} -> zade() got multiple values for keyword argument 'a' zade (1, 2) {'d': 'dd'} -> zade() got multiple values for keyword argument 'd' ! zade (1, 2) {'a': 'aa', 'd': 'dd'} -> zade() got multiple values for keyword argument 'a' ! zade (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zade() got multiple values for keyword argument 'a' zade (1, 2, 3, 4, 5) {} -> zade() takes at most 3 arguments (5 given) zade (1, 2, 3, 4, 5) {'a': 'aa'} -> zade() takes at most 3 non-keyword arguments (5 given) *************** *** 76,80 **** zabk (1, 2) {'d': 'dd'} -> ok zabk 1 2 D E V {'d': 'dd'} zabk (1, 2) {'a': 'aa', 'd': 'dd'} -> zabk() got multiple values for keyword argument 'a' ! zabk (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabk() got multiple values for keyword argument 'b' zabk (1, 2, 3, 4, 5) {} -> zabk() takes exactly 2 arguments (5 given) zabk (1, 2, 3, 4, 5) {'a': 'aa'} -> zabk() takes exactly 2 non-keyword arguments (5 given) --- 76,80 ---- zabk (1, 2) {'d': 'dd'} -> ok zabk 1 2 D E V {'d': 'dd'} zabk (1, 2) {'a': 'aa', 'd': 'dd'} -> zabk() got multiple values for keyword argument 'a' ! zabk (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabk() got multiple values for keyword argument 'a' zabk (1, 2, 3, 4, 5) {} -> zabk() takes exactly 2 arguments (5 given) zabk (1, 2, 3, 4, 5) {'a': 'aa'} -> zabk() takes exactly 2 non-keyword arguments (5 given) *************** *** 91,100 **** zabdv (1, 2) {'d': 'dd'} -> ok zabdv 1 2 dd E () d zabdv (1, 2) {'a': 'aa', 'd': 'dd'} -> zabdv() got multiple values for keyword argument 'a' ! zabdv (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdv() got an unexpected keyword argument 'e' zabdv (1, 2, 3, 4, 5) {} -> ok zabdv 1 2 3 E (4, 5) e zabdv (1, 2, 3, 4, 5) {'a': 'aa'} -> zabdv() got multiple values for keyword argument 'a' zabdv (1, 2, 3, 4, 5) {'d': 'dd'} -> zabdv() got multiple values for keyword argument 'd' ! zabdv (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zabdv() got multiple values for keyword argument 'd' ! zabdv (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdv() got multiple values for keyword argument 'd' zabdevk () {} -> zabdevk() takes at least 2 arguments (0 given) zabdevk () {'a': 'aa'} -> zabdevk() takes at least 2 non-keyword arguments (1 given) --- 91,100 ---- zabdv (1, 2) {'d': 'dd'} -> ok zabdv 1 2 dd E () d zabdv (1, 2) {'a': 'aa', 'd': 'dd'} -> zabdv() got multiple values for keyword argument 'a' ! zabdv (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdv() got multiple values for keyword argument 'a' zabdv (1, 2, 3, 4, 5) {} -> ok zabdv 1 2 3 E (4, 5) e zabdv (1, 2, 3, 4, 5) {'a': 'aa'} -> zabdv() got multiple values for keyword argument 'a' zabdv (1, 2, 3, 4, 5) {'d': 'dd'} -> zabdv() got multiple values for keyword argument 'd' ! zabdv (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zabdv() got multiple values for keyword argument 'a' ! zabdv (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdv() got multiple values for keyword argument 'a' zabdevk () {} -> zabdevk() takes at least 2 arguments (0 given) zabdevk () {'a': 'aa'} -> zabdevk() takes at least 2 non-keyword arguments (1 given) *************** *** 106,113 **** zabdevk (1, 2) {'d': 'dd'} -> ok zabdevk 1 2 dd e () {} zabdevk (1, 2) {'a': 'aa', 'd': 'dd'} -> zabdevk() got multiple values for keyword argument 'a' ! zabdevk (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdevk() got multiple values for keyword argument 'b' zabdevk (1, 2, 3, 4, 5) {} -> ok zabdevk 1 2 3 4 (5,) {} zabdevk (1, 2, 3, 4, 5) {'a': 'aa'} -> zabdevk() got multiple values for keyword argument 'a' zabdevk (1, 2, 3, 4, 5) {'d': 'dd'} -> zabdevk() got multiple values for keyword argument 'd' ! zabdevk (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zabdevk() got multiple values for keyword argument 'd' ! zabdevk (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdevk() got multiple values for keyword argument 'd' --- 106,113 ---- zabdevk (1, 2) {'d': 'dd'} -> ok zabdevk 1 2 dd e () {} zabdevk (1, 2) {'a': 'aa', 'd': 'dd'} -> zabdevk() got multiple values for keyword argument 'a' ! zabdevk (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdevk() got multiple values for keyword argument 'a' zabdevk (1, 2, 3, 4, 5) {} -> ok zabdevk 1 2 3 4 (5,) {} zabdevk (1, 2, 3, 4, 5) {'a': 'aa'} -> zabdevk() got multiple values for keyword argument 'a' zabdevk (1, 2, 3, 4, 5) {'d': 'dd'} -> zabdevk() got multiple values for keyword argument 'd' ! zabdevk (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zabdevk() got multiple values for keyword argument 'a' ! zabdevk (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdevk() got multiple values for keyword argument 'a' Index: test_minidom =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_minidom,v retrieving revision 1.12 retrieving revision 1.12.6.1 diff -C2 -r1.12 -r1.12.6.1 *** test_minidom 2000/12/31 04:03:27 1.12 --- test_minidom 2001/07/07 22:55:29 1.12.6.1 *************** *** 111,114 **** --- 111,115 ---- Test Succeeded testGetElementsByTagName Passed assertion: len(Node.allnodes) == 0 + Passed Test Test Succeeded testGetElementsByTagNameNS Passed assertion: len(Node.allnodes) == 0 Index: test_pyexpat =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_pyexpat,v retrieving revision 1.6 retrieving revision 1.6.6.1 diff -C2 -r1.6 -r1.6.6.1 *** test_pyexpat 2001/01/24 21:46:18 1.6 --- test_pyexpat 2001/07/07 22:55:29 1.6.6.1 *************** *** 4,7 **** --- 4,15 ---- OK. OK. + OK. + OK. + OK. + OK. + OK. + OK. + OK. + OK. PI: 'xml-stylesheet' 'href="stylesheet.css"' *************** *** 100,104 **** ParserCreate() argument 2 must be string or None, not int Caught expected ValueError: ! namespace_separator must be one character, omitted, or None ! Caught expected ValueError: ! namespace_separator must be one character, omitted, or None --- 108,110 ---- ParserCreate() argument 2 must be string or None, not int Caught expected ValueError: ! namespace_separator must be at most one character, omitted, or None Index: test_scope =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_scope,v retrieving revision 1.6 retrieving revision 1.6.4.1 diff -C2 -r1.6 -r1.6.4.1 *** test_scope 2001/03/21 16:44:39 1.6 --- test_scope 2001/07/07 22:55:29 1.6.4.1 *************** *** 18,19 **** --- 18,21 ---- 17. class and global 18. verify that locals() works + 19. var is bound and free in class + 20. interaction with trace function --- test_copy_reg DELETED --- --- test_descr DELETED --- --- test_difflib DELETED --- --- test_doctest DELETED --- --- test_dospath DELETED --- --- test_mailbox DELETED --- --- test_parser DELETED --- --- test_sha DELETED --- --- test_strop DELETED --- From tim_one@users.sourceforge.net Sat Jul 7 23:55:32 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 15:55:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild BUILDno.txt,1.12,1.12.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv24450/mergedescr/dist/src/PCbuild Modified Files: Tag: descr-branch BUILDno.txt Log Message: Merge of trunk tag date2001-07-06 into descr-branch. Index: BUILDno.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/BUILDno.txt,v retrieving revision 1.12 retrieving revision 1.12.2.1 diff -C2 -r1.12 -r1.12.2.1 *** BUILDno.txt 2001/04/18 21:12:25 1.12 --- BUILDno.txt 2001/07/07 22:55:30 1.12.2.1 *************** *** 34,37 **** --- 34,45 ---- Windows Python BUILD numbers ---------------------------- + 20 2.1.1 TENTATIVE + 20-Jul-2001 + 19 2.1.1c1 TENTATIVE + 13-Jul-2001 + 18 2.0.1 + 22-Jun-2001 + 17 2.0.1c1 + 13-Jun-2001 16 CVS development 18-Apr-2001 From tim_one@users.sourceforge.net Sat Jul 7 23:55:32 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 15:55:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/PC WinMain.c,1.6,1.6.8.1 config.h,1.51,1.51.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/PC In directory usw-pr-cvs1:/tmp/cvs-serv24450/mergedescr/dist/src/PC Modified Files: Tag: descr-branch WinMain.c config.h Log Message: Merge of trunk tag date2001-07-06 into descr-branch. Index: WinMain.c =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/WinMain.c,v retrieving revision 1.6 retrieving revision 1.6.8.1 diff -C2 -r1.6 -r1.6.8.1 *** WinMain.c 2000/07/22 23:59:33 1.6 --- WinMain.c 2001/07/07 22:55:30 1.6.8.1 *************** *** 1,5 **** /* Minimal main program -- everything is loaded from the library. */ ! #define WINDOWS_LEAN_AND_MEAN #include --- 1,5 ---- /* Minimal main program -- everything is loaded from the library. */ ! #define WIN32_LEAN_AND_MEAN #include Index: config.h =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/config.h,v retrieving revision 1.51 retrieving revision 1.51.2.1 diff -C2 -r1.51 -r1.51.2.1 *** config.h 2001/04/21 03:20:47 1.51 --- config.h 2001/07/07 22:55:30 1.51.2.1 *************** *** 37,40 **** --- 37,41 ---- #include #define HAVE_LIMITS_H + #define HAVE_SYS_UTIME_H #define HAVE_HYPOT #define DONT_HAVE_SIG_ALARM *************** *** 178,181 **** --- 179,186 ---- #undef HAVE_HYPOT + #undef HAVE_SYS_UTIME_H + #define HAVE_UTIME_H + #define HAVE_DIRENT_H + #define HAVE_CLOCK #else /* !_WIN32 */ *************** *** 340,343 **** --- 345,349 ---- #endif + #define SIZEOF_SHORT 2 #define SIZEOF_INT 4 #define SIZEOF_LONG 4 *************** *** 479,482 **** --- 485,504 ---- /* #define WITH_READLINE 1 */ + /* Define if you want to have a Unicode type. */ + #define Py_USING_UNICODE + + /* Define as the integral type used for Unicode representation. */ + #define PY_UNICODE_TYPE unsigned short + + /* Define as the size of the unicode type. */ + #define Py_UNICODE_SIZE SIZEOF_SHORT + + /* Define if you have a useable wchar_t type defined in wchar.h; useable + means wchar_t must be 16-bit unsigned type. (see + Include/unicodeobject.h). */ + #if Py_UNICODE_SIZE == 2 + #define HAVE_USABLE_WCHAR_T + #endif + /* Define if you want cycle garbage collection */ #define WITH_CYCLE_GC 1 *************** *** 594,598 **** /* Define if you have the header file. */ ! #define HAVE_SYS_UTIME_H 1 /* Define if you have the header file. */ --- 616,620 ---- /* Define if you have the header file. */ ! /* #define HAVE_SYS_UTIME_H 1 */ /* Define if you have the header file. */ From tim_one@users.sourceforge.net Sat Jul 7 23:55:32 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 15:55:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules addrinfo.h,NONE,1.1.2.1 getaddrinfo.c,NONE,1.1.2.1 getnameinfo.c,NONE,1.2.2.1 testcapi_long.h,NONE,1.2.2.1 _codecsmodule.c,2.6,2.6.8.1 _cursesmodule.c,2.51,2.51.4.1 _sre.c,2.55,2.55.4.1 _testcapimodule.c,1.3,1.3.4.1 _tkinter.c,1.115,1.115.6.1 _weakref.c,1.10,1.10.4.1 arraymodule.c,2.62,2.62.6.1 binascii.c,2.28,2.28.6.1 fcntlmodule.c,2.28,2.28.6.1 main.c,1.52,1.52.4.1 makesetup,1.35,1.35.6.1 mathmodule.c,2.58,2.58.8.1 mmapmodule.c,2.28,2.28.2.1 parsermodule.c,2.60,2.60.6.1 pcremodule.c,2.25,2.25.8.1 posixmodule.c,2.187,2.187.4.1 pyexpat.c,2.45,2.45.4.1 regexpr.c,1.33,1.33.8.1 selectmodule.c,2.50,2.50.6.1 socketmodule.c,1.141,1.141.4.1 sre.h,2.18,2.18.10.1 sre_constants.h,2.12,2.12.4.1 stropmodule.c,2.75,2.75.8.1 structmodule.c,2.42,2.42.4.1 termios.c,2.24,2.24.4.1 timemodule.c,2.110,2.110.4.1 xreadlinesmodule.c,1.5,1.5.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv24450/mergedescr/dist/src/Modules Modified Files: Tag: descr-branch _codecsmodule.c _cursesmodule.c _sre.c _testcapimodule.c _tkinter.c _weakref.c arraymodule.c binascii.c fcntlmodule.c main.c makesetup mathmodule.c mmapmodule.c parsermodule.c pcremodule.c posixmodule.c pyexpat.c regexpr.c selectmodule.c socketmodule.c sre.h sre_constants.h stropmodule.c structmodule.c termios.c timemodule.c xreadlinesmodule.c Added Files: Tag: descr-branch addrinfo.h getaddrinfo.c getnameinfo.c testcapi_long.h Log Message: Merge of trunk tag date2001-07-06 into descr-branch. --- NEW FILE: addrinfo.h --- /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef HAVE_GETADDRINFO /* * Error return codes from getaddrinfo() */ #ifndef EAI_ADDRFAMILY #define EAI_ADDRFAMILY 1 /* address family for hostname not supported */ #define EAI_AGAIN 2 /* temporary failure in name resolution */ #define EAI_BADFLAGS 3 /* invalid value for ai_flags */ #define EAI_FAIL 4 /* non-recoverable failure in name resolution */ #define EAI_FAMILY 5 /* ai_family not supported */ #define EAI_MEMORY 6 /* memory allocation failure */ #define EAI_NODATA 7 /* no address associated with hostname */ #define EAI_NONAME 8 /* hostname nor servname provided, or not known */ #define EAI_SERVICE 9 /* servname not supported for ai_socktype */ #define EAI_SOCKTYPE 10 /* ai_socktype not supported */ #define EAI_SYSTEM 11 /* system error returned in errno */ #define EAI_BADHINTS 12 #define EAI_PROTOCOL 13 #define EAI_MAX 14 #endif /* * Flag values for getaddrinfo() */ #ifndef AI_PASSIVE #define AI_PASSIVE 0x00000001 /* get address to use bind() */ #define AI_CANONNAME 0x00000002 /* fill ai_canonname */ #define AI_NUMERICHOST 0x00000004 /* prevent name resolution */ /* valid flags for addrinfo */ #define AI_MASK (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST) #define AI_ALL 0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */ #define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */ #define AI_ADDRCONFIG 0x00000400 /* only if any address is assigned */ #define AI_V4MAPPED 0x00000800 /* accept IPv4-mapped IPv6 address */ /* special recommended flags for getipnodebyname */ #define AI_DEFAULT (AI_V4MAPPED_CFG | AI_ADDRCONFIG) #endif /* * Constants for getnameinfo() */ #ifndef NI_MAXHOST #define NI_MAXHOST 1025 #define NI_MAXSERV 32 #endif /* * Flag values for getnameinfo() */ #ifndef NI_NOFQDN #define NI_NOFQDN 0x00000001 #define NI_NUMERICHOST 0x00000002 #define NI_NAMEREQD 0x00000004 #define NI_NUMERICSERV 0x00000008 #define NI_DGRAM 0x00000010 #endif #ifndef HAVE_ADDRINFO struct addrinfo { int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ int ai_family; /* PF_xxx */ int ai_socktype; /* SOCK_xxx */ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ size_t ai_addrlen; /* length of ai_addr */ char *ai_canonname; /* canonical name for hostname */ struct sockaddr *ai_addr; /* binary address */ struct addrinfo *ai_next; /* next structure in linked list */ }; #endif #ifndef HAVE_SOCKADDR_STORAGE /* * RFC 2553: protocol-independent placeholder for socket addresses */ #define _SS_MAXSIZE 128 #ifdef HAVE_LONG_LONG #define _SS_ALIGNSIZE (sizeof(long long)) #else #define _SS_ALIGNSIZE (sizeof(double)) #endif #define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(u_char) * 2) #define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(u_char) * 2 - \ _SS_PAD1SIZE - _SS_ALIGNSIZE) struct sockaddr_storage { #ifdef HAVE_SOCKADDR_SA_LEN unsigned char ss_len; /* address length */ unsigned char ss_family; /* address family */ #else unsigned short ss_family; /* address family */ #endif char __ss_pad1[_SS_PAD1SIZE]; #ifdef HAVE_LONG_LONG long long __ss_align; /* force desired structure storage alignment */ #else double __ss_align; /* force desired structure storage alignment */ #endif char __ss_pad2[_SS_PAD2SIZE]; }; #endif #ifdef __cplusplus extern "C" { #endif extern void freehostent Py_PROTO((struct hostent *)); #ifdef __cplusplus } #endif #endif --- NEW FILE: getaddrinfo.c --- /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * GAI_ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR GAI_ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON GAI_ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN GAI_ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator. * * Issues to be discussed: * - Thread safe-ness must be checked. * - Return values. There are nonstandard return values defined and used * in the source code. This is because RFC2133 is silent about which error * code must be returned for which situation. * - PF_UNSPEC case would be handled in getipnodebyname() with the AI_ALL flag. */ #if 0 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "addrinfo.h" #endif #if defined(__KAME__) && defined(INET6) # define FAITH #endif #define SUCCESS 0 #define GAI_ANY 0 #define YES 1 #define NO 0 #ifdef FAITH static int translate = NO; static struct in6_addr faith_prefix = IN6ADDR_GAI_ANY_INIT; #endif static const char in_addrany[] = { 0, 0, 0, 0 }; static const char in6_addrany[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static const char in_loopback[] = { 127, 0, 0, 1 }; static const char in6_loopback[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; struct sockinet { u_char si_len; u_char si_family; u_short si_port; }; static struct gai_afd { int a_af; int a_addrlen; int a_socklen; int a_off; const char *a_addrany; const char *a_loopback; } gai_afdl [] = { #ifdef INET6 #define N_INET6 0 {PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6), offsetof(struct sockaddr_in6, sin6_addr), in6_addrany, in6_loopback}, #define N_INET 1 #else #define N_INET 0 #endif {PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in), offsetof(struct sockaddr_in, sin_addr), in_addrany, in_loopback}, {0, 0, 0, 0, NULL, NULL}, }; #ifdef INET6 #define PTON_MAX 16 #else #define PTON_MAX 4 #endif static int get_name Py_PROTO((const char *, struct gai_afd *, struct addrinfo **, char *, struct addrinfo *, int)); static int get_addr Py_PROTO((const char *, int, struct addrinfo **, struct addrinfo *, int)); static int str_isnumber Py_PROTO((const char *)); static char *ai_errlist[] = { "success.", "address family for hostname not supported.", /* EAI_ADDRFAMILY */ "temporary failure in name resolution.", /* EAI_AGAIN */ "invalid value for ai_flags.", /* EAI_BADFLAGS */ "non-recoverable failure in name resolution.", /* EAI_FAIL */ "ai_family not supported.", /* EAI_FAMILY */ "memory allocation failure.", /* EAI_MEMORY */ "no address associated with hostname.", /* EAI_NODATA */ "hostname nor servname provided, or not known.",/* EAI_NONAME */ "servname not supported for ai_socktype.", /* EAI_SERVICE */ "ai_socktype not supported.", /* EAI_SOCKTYPE */ "system error returned in errno.", /* EAI_SYSTEM */ "invalid value for hints.", /* EAI_BADHINTS */ "resolved protocol is unknown.", /* EAI_PROTOCOL */ "unknown error.", /* EAI_MAX */ }; #define GET_CANONNAME(ai, str) \ if (pai->ai_flags & AI_CANONNAME) {\ if (((ai)->ai_canonname = (char *)malloc(strlen(str) + 1)) != NULL) {\ strcpy((ai)->ai_canonname, (str));\ } else {\ error = EAI_MEMORY;\ goto free;\ }\ } #ifdef HAVE_SOCKADDR_SA_LEN #define GET_AI(ai, gai_afd, addr, port) {\ char *p;\ if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\ ((gai_afd)->a_socklen)))\ == NULL) goto free;\ memcpy(ai, pai, sizeof(struct addrinfo));\ (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\ memset((ai)->ai_addr, 0, (gai_afd)->a_socklen);\ (ai)->ai_addr->sa_len = (ai)->ai_addrlen = (gai_afd)->a_socklen;\ (ai)->ai_addr->sa_family = (ai)->ai_family = (gai_afd)->a_af;\ ((struct sockinet *)(ai)->ai_addr)->si_port = port;\ p = (char *)((ai)->ai_addr);\ memcpy(p + (gai_afd)->a_off, (addr), (gai_afd)->a_addrlen);\ } #else #define GET_AI(ai, gai_afd, addr, port) {\ char *p;\ if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\ ((gai_afd)->a_socklen)))\ == NULL) goto free;\ memcpy(ai, pai, sizeof(struct addrinfo));\ (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\ memset((ai)->ai_addr, 0, (gai_afd)->a_socklen);\ (ai)->ai_addr->sa_family = (ai)->ai_family = (gai_afd)->a_af;\ ((struct sockinet *)(ai)->ai_addr)->si_port = port;\ p = (char *)((ai)->ai_addr);\ memcpy(p + (gai_afd)->a_off, (addr), (gai_afd)->a_addrlen);\ } #endif #define ERR(err) { error = (err); goto bad; } char * gai_strerror(ecode) int ecode; { if (ecode < 0 || ecode > EAI_MAX) ecode = EAI_MAX; return ai_errlist[ecode]; } void freeaddrinfo(ai) struct addrinfo *ai; { struct addrinfo *next; do { next = ai->ai_next; if (ai->ai_canonname) free(ai->ai_canonname); /* no need to free(ai->ai_addr) */ free(ai); } while ((ai = next) != NULL); } static int str_isnumber(p) const char *p; { char *q = (char *)p; while (*q) { if (! isdigit(*q)) return NO; q++; } return YES; } int getaddrinfo(hostname, servname, hints, res) const char *hostname, *servname; const struct addrinfo *hints; struct addrinfo **res; { struct addrinfo sentinel; struct addrinfo *top = NULL; struct addrinfo *cur; int i, error = 0; char pton[PTON_MAX]; struct addrinfo ai; struct addrinfo *pai; u_short port; #ifdef FAITH static int firsttime = 1; if (firsttime) { /* translator hack */ { char *q = getenv("GAI"); if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1) translate = YES; } firsttime = 0; } #endif /* initialize file static vars */ sentinel.ai_next = NULL; cur = &sentinel; pai = &ai; pai->ai_flags = 0; pai->ai_family = PF_UNSPEC; pai->ai_socktype = GAI_ANY; pai->ai_protocol = GAI_ANY; pai->ai_addrlen = 0; pai->ai_canonname = NULL; pai->ai_addr = NULL; pai->ai_next = NULL; port = GAI_ANY; if (hostname == NULL && servname == NULL) return EAI_NONAME; if (hints) { /* error check for hints */ if (hints->ai_addrlen || hints->ai_canonname || hints->ai_addr || hints->ai_next) ERR(EAI_BADHINTS); /* xxx */ if (hints->ai_flags & ~AI_MASK) ERR(EAI_BADFLAGS); switch (hints->ai_family) { case PF_UNSPEC: case PF_INET: #ifdef INET6 case PF_INET6: #endif break; default: ERR(EAI_FAMILY); } memcpy(pai, hints, sizeof(*pai)); switch (pai->ai_socktype) { case GAI_ANY: switch (pai->ai_protocol) { case GAI_ANY: break; case IPPROTO_UDP: pai->ai_socktype = SOCK_DGRAM; break; case IPPROTO_TCP: pai->ai_socktype = SOCK_STREAM; break; default: pai->ai_socktype = SOCK_RAW; break; } break; case SOCK_RAW: break; case SOCK_DGRAM: if (pai->ai_protocol != IPPROTO_UDP && pai->ai_protocol != GAI_ANY) ERR(EAI_BADHINTS); /*xxx*/ pai->ai_protocol = IPPROTO_UDP; break; case SOCK_STREAM: if (pai->ai_protocol != IPPROTO_TCP && pai->ai_protocol != GAI_ANY) ERR(EAI_BADHINTS); /*xxx*/ pai->ai_protocol = IPPROTO_TCP; break; default: ERR(EAI_SOCKTYPE); break; } } /* * service port */ if (servname) { if (str_isnumber(servname)) { if (pai->ai_socktype == GAI_ANY) { /* caller accept *GAI_ANY* socktype */ pai->ai_socktype = SOCK_DGRAM; pai->ai_protocol = IPPROTO_UDP; } port = htons(atoi(servname)); } else { struct servent *sp; char *proto; proto = NULL; switch (pai->ai_socktype) { case GAI_ANY: proto = NULL; break; case SOCK_DGRAM: proto = "udp"; break; case SOCK_STREAM: proto = "tcp"; break; default: fprintf(stderr, "panic!\n"); break; } if ((sp = getservbyname(servname, proto)) == NULL) ERR(EAI_SERVICE); port = sp->s_port; if (pai->ai_socktype == GAI_ANY) if (strcmp(sp->s_proto, "udp") == 0) { pai->ai_socktype = SOCK_DGRAM; pai->ai_protocol = IPPROTO_UDP; } else if (strcmp(sp->s_proto, "tcp") == 0) { pai->ai_socktype = SOCK_STREAM; pai->ai_protocol = IPPROTO_TCP; } else ERR(EAI_PROTOCOL); /*xxx*/ } } /* * hostname == NULL. * passive socket -> anyaddr (0.0.0.0 or ::) * non-passive socket -> localhost (127.0.0.1 or ::1) */ if (hostname == NULL) { struct gai_afd *gai_afd; for (gai_afd = &gai_afdl[0]; gai_afd->a_af; gai_afd++) { if (!(pai->ai_family == PF_UNSPEC || pai->ai_family == gai_afd->a_af)) { continue; } if (pai->ai_flags & AI_PASSIVE) { GET_AI(cur->ai_next, gai_afd, gai_afd->a_addrany, port); /* xxx meaningless? * GET_CANONNAME(cur->ai_next, "anyaddr"); */ } else { GET_AI(cur->ai_next, gai_afd, gai_afd->a_loopback, port); /* xxx meaningless? * GET_CANONNAME(cur->ai_next, "localhost"); */ } cur = cur->ai_next; } top = sentinel.ai_next; if (top) goto good; else ERR(EAI_FAMILY); } /* hostname as numeric name */ for (i = 0; gai_afdl[i].a_af; i++) { if (inet_pton(gai_afdl[i].a_af, hostname, pton)) { u_long v4a; u_char pfx; switch (gai_afdl[i].a_af) { case AF_INET: v4a = ((struct in_addr *)pton)->s_addr; if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) pai->ai_flags &= ~AI_CANONNAME; v4a >>= IN_CLASSA_NSHIFT; if (v4a == 0 || v4a == IN_LOOPBACKNET) pai->ai_flags &= ~AI_CANONNAME; break; #ifdef INET6 case AF_INET6: pfx = ((struct in6_addr *)pton)->s6_addr8[0]; if (pfx == 0 || pfx == 0xfe || pfx == 0xff) pai->ai_flags &= ~AI_CANONNAME; break; #endif } if (pai->ai_family == gai_afdl[i].a_af || pai->ai_family == PF_UNSPEC) { if (! (pai->ai_flags & AI_CANONNAME)) { GET_AI(top, &gai_afdl[i], pton, port); goto good; } /* * if AI_CANONNAME and if reverse lookup * fail, return ai anyway to pacify * calling application. * * XXX getaddrinfo() is a name->address * translation function, and it looks strange * that we do addr->name translation here. */ get_name(pton, &gai_afdl[i], &top, pton, pai, port); goto good; } else ERR(EAI_FAMILY); /*xxx*/ } } if (pai->ai_flags & AI_NUMERICHOST) ERR(EAI_NONAME); /* hostname as alphabetical name */ error = get_addr(hostname, pai->ai_family, &top, pai, port); if (error == 0) { if (top) { good: *res = top; return SUCCESS; } else error = EAI_FAIL; } free: if (top) freeaddrinfo(top); bad: *res = NULL; return error; } static int get_name(addr, gai_afd, res, numaddr, pai, port0) const char *addr; struct gai_afd *gai_afd; struct addrinfo **res; char *numaddr; struct addrinfo *pai; int port0; { u_short port = port0 & 0xffff; struct hostent *hp; struct addrinfo *cur; int error = 0, h_error; #ifdef INET6 hp = getipnodebyaddr(addr, gai_afd->a_addrlen, gai_afd->a_af, &h_error); #else hp = gethostbyaddr(addr, gai_afd->a_addrlen, AF_INET); #endif if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { GET_AI(cur, gai_afd, hp->h_addr_list[0], port); GET_CANONNAME(cur, hp->h_name); } else GET_AI(cur, gai_afd, numaddr, port); #ifdef INET6 if (hp) freehostent(hp); #endif *res = cur; return SUCCESS; free: if (cur) freeaddrinfo(cur); #ifdef INET6 if (hp) freehostent(hp); #endif /* bad: */ *res = NULL; return error; } static int get_addr(hostname, af, res, pai, port0) const char *hostname; int af; struct addrinfo **res; struct addrinfo *pai; int port0; { u_short port = port0 & 0xffff; struct addrinfo sentinel; struct hostent *hp; struct addrinfo *top, *cur; struct gai_afd *gai_afd; int i, error = 0, h_error; char *ap; #ifndef INET6 extern int h_errno; #endif top = NULL; sentinel.ai_next = NULL; cur = &sentinel; #ifdef INET6 if (af == AF_UNSPEC) { hp = getipnodebyname(hostname, AF_INET6, AI_ADDRCONFIG|AI_ALL|AI_V4MAPPED, &h_error); } else hp = getipnodebyname(hostname, af, AI_ADDRCONFIG, &h_error); #else hp = gethostbyname(hostname); h_error = h_errno; #endif if (hp == NULL) { switch (h_error) { case HOST_NOT_FOUND: case NO_DATA: error = EAI_NODATA; break; case TRY_AGAIN: error = EAI_AGAIN; break; case NO_RECOVERY: default: error = EAI_FAIL; break; } goto bad; } if ((hp->h_name == NULL) || (hp->h_name[0] == 0) || (hp->h_addr_list[0] == NULL)) ERR(EAI_FAIL); for (i = 0; (ap = hp->h_addr_list[i]) != NULL; i++) { switch (af) { #ifdef INET6 case AF_INET6: gai_afd = &gai_afdl[N_INET6]; break; #endif #ifndef INET6 default: /* AF_UNSPEC */ #endif case AF_INET: gai_afd = &gai_afdl[N_INET]; break; #ifdef INET6 default: /* AF_UNSPEC */ if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) { ap += sizeof(struct in6_addr) - sizeof(struct in_addr); gai_afd = &gai_afdl[N_INET]; } else gai_afd = &gai_afdl[N_INET6]; break; #endif } #ifdef FAITH if (translate && gai_afd->a_af == AF_INET) { struct in6_addr *in6; GET_AI(cur->ai_next, &gai_afdl[N_INET6], ap, port); in6 = &((struct sockaddr_in6 *)cur->ai_next->ai_addr)->sin6_addr; memcpy(&in6->s6_addr32[0], &faith_prefix, sizeof(struct in6_addr) - sizeof(struct in_addr)); memcpy(&in6->s6_addr32[3], ap, sizeof(struct in_addr)); } else #endif /* FAITH */ GET_AI(cur->ai_next, gai_afd, ap, port); if (cur == &sentinel) { top = cur->ai_next; GET_CANONNAME(top, hp->h_name); } cur = cur->ai_next; } #ifdef INET6 freehostent(hp); #endif *res = top; return SUCCESS; free: if (top) freeaddrinfo(top); #ifdef INET6 if (hp) freehostent(hp); #endif bad: *res = NULL; return error; } --- NEW FILE: getnameinfo.c --- /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Issues to be discussed: * - Thread safe-ness must be checked * - Return values. There seems to be no standard for return value (RFC2133) * but INRIA implementation returns EAI_xxx defined for getaddrinfo(). */ #if 0 #include #include #include #include #include #include #include #include #include #include "addrinfo.h" #endif #define SUCCESS 0 #define YES 1 #define NO 0 static struct gni_afd { int a_af; int a_addrlen; int a_socklen; int a_off; } gni_afdl [] = { #ifdef INET6 {PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6), offsetof(struct sockaddr_in6, sin6_addr)}, #endif {PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in), offsetof(struct sockaddr_in, sin_addr)}, {0, 0, 0}, }; struct gni_sockinet { u_char si_len; u_char si_family; u_short si_port; }; #define ENI_NOSOCKET 0 #define ENI_NOSERVNAME 1 #define ENI_NOHOSTNAME 2 #define ENI_MEMORY 3 #define ENI_SYSTEM 4 #define ENI_FAMILY 5 #define ENI_SALEN 6 int getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) const struct sockaddr *sa; size_t salen; char *host; size_t hostlen; char *serv; size_t servlen; int flags; { struct gni_afd *gni_afd; struct servent *sp; struct hostent *hp; u_short port; int family, len, i; char *addr, *p; u_long v4a; u_char pfx; int h_error; char numserv[512]; char numaddr[512]; if (sa == NULL) return ENI_NOSOCKET; #ifdef HAVE_SOCKADDR_SA_LEN len = sa->sa_len; if (len != salen) return ENI_SALEN; #else len = salen; #endif family = sa->sa_family; for (i = 0; gni_afdl[i].a_af; i++) if (gni_afdl[i].a_af == family) { gni_afd = &gni_afdl[i]; goto found; } return ENI_FAMILY; found: if (len != gni_afd->a_socklen) return ENI_SALEN; port = ((struct gni_sockinet *)sa)->si_port; /* network byte order */ addr = (char *)sa + gni_afd->a_off; if (serv == NULL || servlen == 0) { /* what we should do? */ } else if (flags & NI_NUMERICSERV) { sprintf(numserv, "%d", ntohs(port)); if (strlen(numserv) > servlen) return ENI_MEMORY; strcpy(serv, numserv); } else { sp = getservbyport(port, (flags & NI_DGRAM) ? "udp" : "tcp"); if (sp) { if (strlen(sp->s_name) > servlen) return ENI_MEMORY; strcpy(serv, sp->s_name); } else return ENI_NOSERVNAME; } switch (sa->sa_family) { case AF_INET: v4a = ((struct sockaddr_in *)sa)->sin_addr.s_addr; if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) flags |= NI_NUMERICHOST; v4a >>= IN_CLASSA_NSHIFT; if (v4a == 0 || v4a == IN_LOOPBACKNET) flags |= NI_NUMERICHOST; break; #ifdef INET6 case AF_INET6: pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr8[0]; if (pfx == 0 || pfx == 0xfe || pfx == 0xff) flags |= NI_NUMERICHOST; break; #endif } if (host == NULL || hostlen == 0) { /* what should we do? */ } else if (flags & NI_NUMERICHOST) { if (inet_ntop(gni_afd->a_af, addr, numaddr, sizeof(numaddr)) == NULL) return ENI_SYSTEM; if (strlen(numaddr) > hostlen) return ENI_MEMORY; strcpy(host, numaddr); } else { #ifdef INET6 hp = getipnodebyaddr(addr, gni_afd->a_addrlen, gni_afd->a_af, &h_error); #else hp = gethostbyaddr(addr, gni_afd->a_addrlen, gni_afd->a_af); h_error = h_errno; #endif if (hp) { if (flags & NI_NOFQDN) { p = strchr(hp->h_name, '.'); if (p) *p = '\0'; } if (strlen(hp->h_name) > hostlen) { #ifdef INET6 freehostent(hp); #endif return ENI_MEMORY; } strcpy(host, hp->h_name); #ifdef INET6 freehostent(hp); #endif } else { if (flags & NI_NAMEREQD) return ENI_NOHOSTNAME; if (inet_ntop(gni_afd->a_af, addr, numaddr, sizeof(numaddr)) == NULL) return ENI_NOHOSTNAME; if (strlen(numaddr) > hostlen) return ENI_MEMORY; strcpy(host, numaddr); } } return SUCCESS; } --- NEW FILE: testcapi_long.h --- /* Poor-man's template. Macros used: TESTNAME name of the test (like test_long_api_inner) TYPENAME the signed type (like long) F_S_TO_PY convert signed to pylong; TYPENAME -> PyObject* F_PY_TO_S convert pylong to signed; PyObject* -> TYPENAME F_U_TO_PY convert unsigned to pylong; unsigned TYPENAME -> PyObject* F_PY_TO_U convert pylong to unsigned; PyObject* -> unsigned TYPENAME */ static PyObject * TESTNAME(PyObject *error(const char*)) { const int NBITS = sizeof(TYPENAME) * 8; unsigned TYPENAME base; PyObject *pyresult; int i; /* Note: This test lets PyObjects leak if an error is raised. Since an error should never be raised, leaks are impossible . */ /* Test native -> PyLong -> native roundtrip identity. * Generate all powers of 2, and test them and their negations, * plus the numbers +-1 off from them. */ base = 1; for (i = 0; i < NBITS + 1; /* on last, base overflows to 0 */ ++i, base <<= 1) { int j; for (j = 0; j < 6; ++j) { TYPENAME in, out; unsigned TYPENAME uin, uout; /* For 0, 1, 2 use base; for 3, 4, 5 use -base */ uin = j < 3 ? base : (unsigned TYPENAME)(-(TYPENAME)base); /* For 0 & 3, subtract 1. * For 1 & 4, leave alone. * For 2 & 5, add 1. */ uin += (unsigned TYPENAME)(TYPENAME)(j % 3 - 1); pyresult = F_U_TO_PY(uin); if (pyresult == NULL) return error( "unsigned unexpected null result"); uout = F_PY_TO_U(pyresult); if (uout == (unsigned TYPENAME)-1 && PyErr_Occurred()) return error( "unsigned unexpected -1 result"); if (uout != uin) return error( "unsigned output != input"); UNBIND(pyresult); in = (TYPENAME)uin; pyresult = F_S_TO_PY(in); if (pyresult == NULL) return error( "signed unexpected null result"); out = F_PY_TO_S(pyresult); if (out == (TYPENAME)-1 && PyErr_Occurred()) return error( "signed unexpected -1 result"); if (out != in) return error( "signed output != input"); UNBIND(pyresult); } } /* Overflow tests. The loop above ensured that all limit cases that * should not overflow don't overflow, so all we need to do here is * provoke one-over-the-limit cases (not exhaustive, but sharp). */ { PyObject *one, *x, *y; TYPENAME out; unsigned TYPENAME uout; one = PyLong_FromLong(1); if (one == NULL) return error( "unexpected NULL from PyLong_FromLong"); /* Unsigned complains about -1? */ x = PyNumber_Negative(one); if (x == NULL) return error( "unexpected NULL from PyNumber_Negative"); uout = F_PY_TO_U(x); if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred()) return error( "PyLong_AsUnsignedXXX(-1) didn't complain"); PyErr_Clear(); UNBIND(x); /* Unsigned complains about 2**NBITS? */ y = PyLong_FromLong((long)NBITS); if (y == NULL) return error( "unexpected NULL from PyLong_FromLong"); x = PyNumber_Lshift(one, y); /* 1L << NBITS, == 2**NBITS */ UNBIND(y); if (x == NULL) return error( "unexpected NULL from PyNumber_Lshift"); uout = F_PY_TO_U(x); if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred()) return error( "PyLong_AsUnsignedXXX(2**NBITS) didn't " "complain"); PyErr_Clear(); /* Signed complains about 2**(NBITS-1)? x still has 2**NBITS. */ y = PyNumber_Rshift(x, one); /* 2**(NBITS-1) */ UNBIND(x); if (y == NULL) return error( "unexpected NULL from PyNumber_Rshift"); out = F_PY_TO_S(y); if (out != (TYPENAME)-1 || !PyErr_Occurred()) return error( "PyLong_AsXXX(2**(NBITS-1)) didn't " "complain"); PyErr_Clear(); /* Signed complains about -2**(NBITS-1)-1?; y still has 2**(NBITS-1). */ x = PyNumber_Negative(y); /* -(2**(NBITS-1)) */ UNBIND(y); if (x == NULL) return error( "unexpected NULL from PyNumber_Negative"); y = PyNumber_Subtract(x, one); /* -(2**(NBITS-1))-1 */ UNBIND(x); if (y == NULL) return error( "unexpected NULL from PyNumber_Subtract"); out = F_PY_TO_S(y); if (out != (TYPENAME)-1 || !PyErr_Occurred()) return error( "PyLong_AsXXX(-2**(NBITS-1)-1) didn't " "complain"); PyErr_Clear(); UNBIND(y); Py_XDECREF(x); Py_XDECREF(y); Py_DECREF(one); } Py_INCREF(Py_None); return Py_None; } Index: _codecsmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_codecsmodule.c,v retrieving revision 2.6 retrieving revision 2.6.8.1 diff -C2 -r2.6 -r2.6.8.1 *** _codecsmodule.c 2000/09/21 21:09:45 2.6 --- _codecsmodule.c 2001/07/07 22:55:29 2.6.8.1 *************** *** 300,304 **** } ! #ifdef MS_WIN32 static PyObject * --- 300,304 ---- } ! #if defined(MS_WIN32) && defined(HAVE_USABLE_WCHAR_T) static PyObject * *************** *** 441,445 **** const char *errors = NULL; ! if (!PyArg_ParseTuple(args, "O|zi:utf_16_le_encode", &str, &errors)) return NULL; --- 441,445 ---- const char *errors = NULL; ! if (!PyArg_ParseTuple(args, "O|z:utf_16_le_encode", &str, &errors)) return NULL; *************** *** 464,468 **** const char *errors = NULL; ! if (!PyArg_ParseTuple(args, "O|zi:utf_16_be_encode", &str, &errors)) return NULL; --- 464,468 ---- const char *errors = NULL; ! if (!PyArg_ParseTuple(args, "O|z:utf_16_be_encode", &str, &errors)) return NULL; *************** *** 596,600 **** } ! #ifdef MS_WIN32 static PyObject * --- 596,600 ---- } ! #if defined(MS_WIN32) && defined(HAVE_USABLE_WCHAR_T) static PyObject * *************** *** 651,655 **** {"readbuffer_encode", readbuffer_encode, 1}, {"charbuffer_encode", charbuffer_encode, 1}, ! #ifdef MS_WIN32 {"mbcs_encode", mbcs_encode, 1}, {"mbcs_decode", mbcs_decode, 1}, --- 651,655 ---- {"readbuffer_encode", readbuffer_encode, 1}, {"charbuffer_encode", charbuffer_encode, 1}, ! #if defined(MS_WIN32) && defined(HAVE_USABLE_WCHAR_T) {"mbcs_encode", mbcs_encode, 1}, {"mbcs_decode", mbcs_decode, 1}, Index: _cursesmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_cursesmodule.c,v retrieving revision 2.51 retrieving revision 2.51.4.1 diff -C2 -r2.51 -r2.51.4.1 *** _cursesmodule.c 2001/04/10 19:53:37 2.51 --- _cursesmodule.c 2001/07/07 22:55:29 2.51.4.1 *************** *** 190,195 **** if (PyInt_Check(obj)) { *ch = (chtype) PyInt_AsLong(obj); ! } else if(PyString_Check(obj) & ! (PyString_Size(obj) == 1)) { *ch = (chtype) *PyString_AsString(obj); } else { --- 190,195 ---- if (PyInt_Check(obj)) { *ch = (chtype) PyInt_AsLong(obj); ! } else if(PyString_Check(obj) ! && (PyString_Size(obj) == 1)) { *ch = (chtype) *PyString_AsString(obj); } else { Index: _sre.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_sre.c,v retrieving revision 2.55 retrieving revision 2.55.4.1 diff -C2 -r2.55 -r2.55.4.1 *** _sre.c 2001/04/15 19:00:58 2.55 --- _sre.c 2001/07/07 22:55:29 2.55.4.1 *************** *** 29,32 **** --- 29,35 ---- * 2001-03-20 fl lots of fixes for 2.1b2 * 2001-04-15 fl export copyright as Python attribute, not global + * 2001-04-28 fl added __copy__ methods (work in progress) + * 2001-05-14 fl fixes for 1.5.2 + * 2001-07-01 fl added BIGCHARSET support (from Martin von Loewis) * * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. *************** *** 44,50 **** static char copyright[] = ! " SRE 2.1b2 Copyright (c) 1997-2001 by Secret Labs AB "; #include "Python.h" #include "sre.h" --- 47,54 ---- static char copyright[] = ! " SRE 2.1.1 Copyright (c) 1997-2001 by Secret Labs AB "; #include "Python.h" + #include "structmember.h" /* offsetof */ #include "sre.h" *************** *** 87,90 **** --- 91,97 ---- #undef USE_INLINE + /* enables copy/deepcopy handling (work in progress) */ + #undef USE_BUILTIN_COPY + #if PY_VERSION_HEX < 0x01060000 #define PyObject_DEL(op) PyMem_DEL((op)) *************** *** 445,448 **** --- 452,456 ---- return this == that; + #if defined(HAVE_UNICODE) case SRE_AT_UNI_BOUNDARY: if (state->beginning == state->end) *************** *** 462,465 **** --- 470,475 ---- SRE_UNI_IS_WORD((int) ptr[0]) : 0; return this == that; + #endif + } *************** *** 498,501 **** --- 508,524 ---- break; + case SRE_OP_BIGCHARSET: + /* <256 blockindices> */ + { + int count, block; + count = *(set++); + block = ((unsigned char*)set)[ch >> 8]; + set += 128; + if (set[block*16 + ((ch & 255)>>4)] & (1 << (ch & 15))) + return ok; + set += count*16; + break; + } + case SRE_OP_CATEGORY: /* */ *************** *** 1082,1086 **** state->repeat = rp->prev; /* FIXME: the following fix doesn't always work (#133283) */ ! if (0 && rp->pattern[2] == 65535) { /* unbounded repeat */ for (;;) { --- 1105,1109 ---- state->repeat = rp->prev; /* FIXME: the following fix doesn't always work (#133283) */ ! if (rp->pattern[2] == 65535) { /* unbounded repeat */ for (;;) { *************** *** 1287,1290 **** --- 1310,1315 ---- return NULL; + self->codesize = n; + for (i = 0; i < n; i++) { PyObject *o = PyList_GET_ITEM(code, i); *************** *** 1673,1692 **** static PyObject* ! call(char* function, PyObject* args) { PyObject* name; ! PyObject* module; PyObject* func; PyObject* result; ! name = PyString_FromString(SRE_MODULE); if (!name) return NULL; ! module = PyImport_Import(name); Py_DECREF(name); ! if (!module) return NULL; ! func = PyObject_GetAttrString(module, function); ! Py_DECREF(module); if (!func) return NULL; --- 1698,1717 ---- static PyObject* ! call(char* module, char* function, PyObject* args) { PyObject* name; ! PyObject* mod; PyObject* func; PyObject* result; ! name = PyString_FromString(module); if (!name) return NULL; ! mod = PyImport_Import(name); Py_DECREF(name); ! if (!mod) return NULL; ! func = PyObject_GetAttrString(mod, function); ! Py_DECREF(mod); if (!func) return NULL; *************** *** 1697,1700 **** --- 1722,1745 ---- } + #ifdef USE_BUILTIN_COPY + static int + deepcopy(PyObject** object, PyObject* memo) + { + PyObject* copy; + + copy = call( + "copy", "deepcopy", + Py_BuildValue("OO", *object, memo) + ); + if (!copy) + return 0; + + Py_DECREF(*object); + *object = copy; + + return 1; /* success */ + } + #endif + static PyObject* pattern_sub(PatternObject* self, PyObject* args, PyObject* kw) *************** *** 1709,1713 **** /* delegate to Python code */ ! return call("_sub", Py_BuildValue("OOOO", self, template, string, count)); } --- 1754,1761 ---- /* delegate to Python code */ ! return call( ! SRE_MODULE, "_sub", ! Py_BuildValue("OOOO", self, template, string, count) ! ); } *************** *** 1724,1728 **** /* delegate to Python code */ ! return call("_subn", Py_BuildValue("OOOO", self, template, string, count)); } --- 1772,1779 ---- /* delegate to Python code */ ! return call( ! SRE_MODULE, "_subn", ! Py_BuildValue("OOOO", self, template, string, count) ! ); } *************** *** 1738,1742 **** /* delegate to Python code */ ! return call("_split", Py_BuildValue("OOO", self, string, maxsplit)); } --- 1789,1796 ---- /* delegate to Python code */ ! return call( ! SRE_MODULE, "_split", ! Py_BuildValue("OOO", self, string, maxsplit) ! ); } *************** *** 1845,1848 **** --- 1899,1959 ---- } + static PyObject* + pattern_copy(PatternObject* self, PyObject* args) + { + #ifdef USE_BUILTIN_COPY + PatternObject* copy; + int offset; + + if (args != Py_None && !PyArg_ParseTuple(args, ":__copy__")) + return NULL; + + copy = PyObject_NEW_VAR(PatternObject, &Pattern_Type, self->codesize); + if (!copy) + return NULL; + + offset = offsetof(PatternObject, groups); + + Py_XINCREF(self->groupindex); + Py_XINCREF(self->indexgroup); + Py_XINCREF(self->pattern); + + memcpy((char*) copy + offset, (char*) self + offset, + sizeof(PatternObject) + self->codesize * sizeof(SRE_CODE) - offset); + + return (PyObject*) copy; + #else + PyErr_SetString(PyExc_TypeError, "cannot copy this pattern object"); + return NULL; + #endif + } + + static PyObject* + pattern_deepcopy(PatternObject* self, PyObject* args) + { + #ifdef USE_BUILTIN_COPY + PatternObject* copy; + + PyObject* memo; + if (!PyArg_ParseTuple(args, "O:__deepcopy__", &memo)) + return NULL; + + copy = (PatternObject*) pattern_copy(self, Py_None); + if (!copy) + return NULL; + + if (!deepcopy(©->groupindex, memo) || + !deepcopy(©->indexgroup, memo) || + !deepcopy(©->pattern, memo)) { + Py_DECREF(copy); + return NULL; + } + + #else + PyErr_SetString(PyExc_TypeError, "cannot deepcopy this pattern object"); + return NULL; + #endif + } + static PyMethodDef pattern_methods[] = { {"match", (PyCFunction) pattern_match, METH_VARARGS|METH_KEYWORDS}, *************** *** 1852,1857 **** {"split", (PyCFunction) pattern_split, METH_VARARGS|METH_KEYWORDS}, {"findall", (PyCFunction) pattern_findall, METH_VARARGS|METH_KEYWORDS}, - /* experimental */ {"scanner", (PyCFunction) pattern_scanner, METH_VARARGS}, {NULL, NULL} }; --- 1963,1969 ---- {"split", (PyCFunction) pattern_split, METH_VARARGS|METH_KEYWORDS}, {"findall", (PyCFunction) pattern_findall, METH_VARARGS|METH_KEYWORDS}, {"scanner", (PyCFunction) pattern_scanner, METH_VARARGS}, + {"__copy__", (PyCFunction) pattern_copy, METH_VARARGS}, + {"__deepcopy__", (PyCFunction) pattern_deepcopy, METH_VARARGS}, {NULL, NULL} }; *************** *** 1974,1978 **** /* delegate to Python code */ return call( ! "_expand", Py_BuildValue("OOO", self->pattern, self, template) ); --- 2086,2090 ---- /* delegate to Python code */ return call( ! SRE_MODULE, "_expand", Py_BuildValue("OOO", self->pattern, self, template) ); *************** *** 2212,2215 **** --- 2324,2388 ---- } + static PyObject* + match_copy(MatchObject* self, PyObject* args) + { + #ifdef USE_BUILTIN_COPY + MatchObject* copy; + int slots, offset; + + if (args != Py_None && !PyArg_ParseTuple(args, ":__copy__")) + return NULL; + + slots = 2 * (self->pattern->groups+1); + + copy = PyObject_NEW_VAR(MatchObject, &Match_Type, slots); + if (!copy) + return NULL; + + /* this value a constant, but any compiler should be able to + figure that out all by itself */ + offset = offsetof(MatchObject, string); + + Py_XINCREF(self->pattern); + Py_XINCREF(self->string); + Py_XINCREF(self->regs); + + memcpy((char*) copy + offset, (char*) self + offset, + sizeof(MatchObject) + slots * sizeof(int) - offset); + + return (PyObject*) copy; + #else + PyErr_SetString(PyExc_TypeError, "cannot copy this match object"); + return NULL; + #endif + } + + static PyObject* + match_deepcopy(MatchObject* self, PyObject* args) + { + #ifdef USE_BUILTIN_COPY + MatchObject* copy; + + PyObject* memo; + if (!PyArg_ParseTuple(args, "O:__deepcopy__", &memo)) + return NULL; + + copy = (MatchObject*) match_copy(self, Py_None); + if (!copy) + return NULL; + + if (!deepcopy((PyObject**) ©->pattern, memo) || + !deepcopy(©->string, memo) || + !deepcopy(©->regs, memo)) { + Py_DECREF(copy); + return NULL; + } + + #else + PyErr_SetString(PyExc_TypeError, "cannot deepcopy this match object"); + return NULL; + #endif + } + static PyMethodDef match_methods[] = { {"group", (PyCFunction) match_group, METH_VARARGS}, *************** *** 2220,2223 **** --- 2393,2398 ---- {"groupdict", (PyCFunction) match_groupdict, METH_VARARGS|METH_KEYWORDS}, {"expand", (PyCFunction) match_expand, METH_VARARGS}, + {"__copy__", (PyCFunction) match_copy, METH_VARARGS}, + {"__deepcopy__", (PyCFunction) match_deepcopy, METH_VARARGS}, {NULL, NULL} }; Index: _testcapimodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_testcapimodule.c,v retrieving revision 1.3 retrieving revision 1.3.4.1 diff -C2 -r1.3 -r1.3.4.1 *** _testcapimodule.c 2001/04/13 17:08:15 1.3 --- _testcapimodule.c 2001/07/07 22:55:29 1.3.4.1 *************** *** 10,13 **** --- 10,29 ---- static PyObject *TestError; /* set to exception object in init */ + /* Raise TestError with test_name + ": " + msg, and return NULL. */ + + static PyObject * + raiseTestError(const char* test_name, const char* msg) + { + char buf[2048]; + + if (strlen(test_name) + strlen(msg) > sizeof(buf) - 50) + PyErr_SetString(TestError, "internal error msg too large"); + else { + sprintf(buf, "%s: %s", test_name, msg); + PyErr_SetString(TestError, buf); + } + return NULL; + } + /* Test #defines from config.h (particularly the SIZEOF_* defines). *************** *** 37,40 **** --- 53,57 ---- return sizeof_error(#FATNAME, #TYPE, FATNAME, sizeof(TYPE)) + CHECK_SIZEOF(SIZEOF_SHORT, short); CHECK_SIZEOF(SIZEOF_INT, int); CHECK_SIZEOF(SIZEOF_LONG, long); *************** *** 146,150 **** if (!PyArg_ParseTuple(args, ":test_dict_iteration")) return NULL; ! for (i = 0; i < 200; i++) { if (test_dict_inner(i) < 0) { --- 163,167 ---- if (!PyArg_ParseTuple(args, ":test_dict_iteration")) return NULL; ! for (i = 0; i < 200; i++) { if (test_dict_inner(i) < 0) { *************** *** 157,164 **** } static PyMethodDef TestMethods[] = { ! {"test_config", test_config, METH_VARARGS}, ! {"test_list_api", test_list_api, METH_VARARGS}, ! {"test_dict_iteration", test_dict_iteration, METH_VARARGS}, {NULL, NULL} /* sentinel */ }; --- 174,270 ---- } + + /* Tests of PyLong_{As, From}{Unsigned,}Long(), and (#ifdef HAVE_LONG_LONG) + PyLong_{As, From}{Unsigned,}LongLong(). + + Note that the meat of the test is contained in testcapi_long.h. + This is revolting, but delicate code duplication is worse: "almost + exactly the same" code is needed to test LONG_LONG, but the ubiquitous + dependence on type names makes it impossible to use a parameterized + function. A giant macro would be even worse than this. A C++ template + would be perfect. + + The "report an error" functions are deliberately not part of the #include + file: if the test fails, you can set a breakpoint in the appropriate + error function directly, and crawl back from there in the debugger. + */ + + #define UNBIND(X) Py_DECREF(X); (X) = NULL + + static PyObject * + raise_test_long_error(const char* msg) + { + return raiseTestError("test_long_api", msg); + } + + #define TESTNAME test_long_api_inner + #define TYPENAME long + #define F_S_TO_PY PyLong_FromLong + #define F_PY_TO_S PyLong_AsLong + #define F_U_TO_PY PyLong_FromUnsignedLong + #define F_PY_TO_U PyLong_AsUnsignedLong + + #include "testcapi_long.h" + + static PyObject * + test_long_api(PyObject* self, PyObject* args) + { + if (!PyArg_ParseTuple(args, ":test_long_api")) + return NULL; + + return TESTNAME(raise_test_long_error); + } + + #undef TESTNAME + #undef TYPENAME + #undef F_S_TO_PY + #undef F_PY_TO_S + #undef F_U_TO_PY + #undef F_PY_TO_U + + #ifdef HAVE_LONG_LONG + + static PyObject * + raise_test_longlong_error(const char* msg) + { + return raiseTestError("test_longlong_api", msg); + } + + #define TESTNAME test_longlong_api_inner + #define TYPENAME LONG_LONG + #define F_S_TO_PY PyLong_FromLongLong + #define F_PY_TO_S PyLong_AsLongLong + #define F_U_TO_PY PyLong_FromUnsignedLongLong + #define F_PY_TO_U PyLong_AsUnsignedLongLong + + #include "testcapi_long.h" + + static PyObject * + test_longlong_api(PyObject* self, PyObject* args) + { + if (!PyArg_ParseTuple(args, ":test_longlong_api")) + return NULL; + + return TESTNAME(raise_test_longlong_error); + } + + #undef TESTNAME + #undef TYPENAME + #undef F_S_TO_PY + #undef F_PY_TO_S + #undef F_U_TO_PY + #undef F_PY_TO_U + + #endif /* ifdef HAVE_LONG_LONG */ + + static PyMethodDef TestMethods[] = { ! {"test_config", test_config, METH_VARARGS}, ! {"test_list_api", test_list_api, METH_VARARGS}, ! {"test_dict_iteration", test_dict_iteration, METH_VARARGS}, ! {"test_long_api", test_long_api, METH_VARARGS}, ! #ifdef HAVE_LONG_LONG ! {"test_longlong_api", test_longlong_api, METH_VARARGS}, ! #endif {NULL, NULL} /* sentinel */ }; Index: _tkinter.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_tkinter.c,v retrieving revision 1.115 retrieving revision 1.115.6.1 diff -C2 -r1.115 -r1.115.6.1 *** _tkinter.c 2000/10/29 00:44:43 1.115 --- _tkinter.c 2001/07/07 22:55:29 1.115.6.1 *************** *** 1852,1856 **** context->maxsize = maxsize; ! return _PyTuple_Resize(&context->tuple, maxsize, 0) >= 0; } --- 1852,1856 ---- context->maxsize = maxsize; ! return _PyTuple_Resize(&context->tuple, maxsize) >= 0; } *************** *** 1936,1940 **** return NULL; ! if (_PyTuple_Resize(&context.tuple, context.size, 0)) return NULL; --- 1936,1940 ---- return NULL; ! if (_PyTuple_Resize(&context.tuple, context.size)) return NULL; Index: _weakref.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_weakref.c,v retrieving revision 1.10 retrieving revision 1.10.4.1 diff -C2 -r1.10 -r1.10.4.1 *** _weakref.c 2001/04/13 17:15:47 1.10 --- _weakref.c 2001/07/07 22:55:29 1.10.4.1 *************** *** 737,741 **** || object->ob_refcnt != 0) { PyErr_BadInternalCall(); - /* not sure what we should return here */ return; } --- 737,740 ---- *************** *** 793,797 **** } } - return; } --- 792,795 ---- Index: arraymodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/arraymodule.c,v retrieving revision 2.62 retrieving revision 2.62.6.1 diff -C2 -r2.62 -r2.62.6.1 *** arraymodule.c 2001/01/25 22:12:43 2.62 --- arraymodule.c 2001/07/07 22:55:29 2.62.6.1 *************** *** 1543,1547 **** 0, /* tp_getattro */ 0, /* tp_setattro */ ! &array_as_buffer, /* tp_as _buffer*/ Py_TPFLAGS_DEFAULT, /* tp_flags */ arraytype_doc, /* tp_doc */ --- 1543,1547 ---- 0, /* tp_getattro */ 0, /* tp_setattro */ ! &array_as_buffer, /* tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /* tp_flags */ arraytype_doc, /* tp_doc */ Index: binascii.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/binascii.c,v retrieving revision 2.28 retrieving revision 2.28.6.1 diff -C2 -r2.28 -r2.28.6.1 *** binascii.c 2001/01/09 02:11:57 2.28 --- binascii.c 2001/07/07 22:55:29 2.28.6.1 *************** *** 336,339 **** --- 336,343 ---- return NULL; + if ( ascii_len == 0) { + PyErr_SetString(Error, "Cannot decode empty input"); + return NULL; + } bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */ Index: fcntlmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/fcntlmodule.c,v retrieving revision 2.28 retrieving revision 2.28.6.1 diff -C2 -r2.28 -r2.28.6.1 *** fcntlmodule.c 2001/01/25 10:10:39 2.28 --- fcntlmodule.c 2001/07/07 22:55:29 2.28.6.1 *************** *** 16,19 **** --- 16,31 ---- + static int + conv_descriptor(PyObject *object, int *target) + { + int fd = PyObject_AsFileDescriptor(object); + + if (fd < 0) + return 0; + *target = fd; + return 1; + } + + /* fcntl(fd, opt, [arg]) */ *************** *** 29,33 **** char buf[1024]; ! if (PyArg_ParseTuple(args, "iis#:fcntl", &fd, &code, &str, &len)) { if (len > sizeof buf) { PyErr_SetString(PyExc_ValueError, --- 41,46 ---- char buf[1024]; ! if (PyArg_ParseTuple(args, "O&is#:fcntl", ! conv_descriptor, &fd, &code, &str, &len)) { if (len > sizeof buf) { PyErr_SetString(PyExc_ValueError, *************** *** 48,53 **** PyErr_Clear(); arg = 0; ! if (!PyArg_ParseTuple(args, "ii|i;fcntl requires 2 integers and optionally a third integer or a string", ! &fd, &code, &arg)) { return NULL; } --- 61,68 ---- PyErr_Clear(); arg = 0; ! if (!PyArg_ParseTuple(args, ! "O&i|i;fcntl requires a file or file descriptor," ! " an integer and optionally a third integer or a string", ! conv_descriptor, &fd, &code, &arg)) { return NULL; } *************** *** 67,77 **** \n\ Perform the requested operation on file descriptor fd. The operation\n\ ! is defined by op and is operating system dependent. Typically these\n\ ! codes can be retrieved from the library module FCNTL. The argument arg\n\ ! is optional, and defaults to 0; it may be an int or a string. If arg is\n\ ! given as a string, the return value of fcntl is a string of that length,\n\ ! containing the resulting value put in the arg buffer by the operating system.\n\ ! The length of the arg string is not allowed to exceed 1024 bytes. If the arg\n\ ! given is an integer or if none is specified, the result value is an integer\n\ corresponding to the return value of the fcntl call in the C code."; --- 82,92 ---- \n\ Perform the requested operation on file descriptor fd. The operation\n\ ! is defined by op and is operating system dependent. These constants are\n\ ! available from the fcntl module. The argument arg is optional, and\n\ ! defaults to 0; it may be an int or a string. If arg is given as a string,\n\ ! the return value of fcntl is a string of that length, containing the\n\ ! resulting value put in the arg buffer by the operating system.The length\n\ ! of the arg string is not allowed to exceed 1024 bytes. If the arg given\n\ ! is an integer or if none is specified, the result value is an integer\n\ corresponding to the return value of the fcntl call in the C code."; *************** *** 90,94 **** char buf[1024]; ! if (PyArg_ParseTuple(args, "iis#:ioctl", &fd, &code, &str, &len)) { if (len > sizeof buf) { PyErr_SetString(PyExc_ValueError, --- 105,110 ---- char buf[1024]; ! if (PyArg_ParseTuple(args, "O&is#:ioctl", ! conv_descriptor, &fd, &code, &str, &len)) { if (len > sizeof buf) { PyErr_SetString(PyExc_ValueError, *************** *** 109,114 **** PyErr_Clear(); arg = 0; ! if (!PyArg_ParseTuple(args, "ii|i;ioctl requires 2 integers and optionally a third integer or a string", ! &fd, &code, &arg)) { return NULL; } --- 125,132 ---- PyErr_Clear(); arg = 0; ! if (!PyArg_ParseTuple(args, ! "O&i|i;ioctl requires a file or file descriptor," ! " an integer and optionally a third integer or a string", ! conv_descriptor, &fd, &code, &arg)) { return NULL; } *************** *** 146,150 **** int ret; ! if (!PyArg_ParseTuple(args, "ii:flock", &fd, &code)) return NULL; --- 164,169 ---- int ret; ! if (!PyArg_ParseTuple(args, "O&i:flock", ! conv_descriptor, &fd, &code)) return NULL; *************** *** 203,207 **** PyObject *lenobj = NULL, *startobj = NULL; ! if (!PyArg_ParseTuple(args, "ii|OOi:lockf", &fd, &code, &lenobj, &startobj, &whence)) return NULL; --- 222,227 ---- PyObject *lenobj = NULL, *startobj = NULL; ! if (!PyArg_ParseTuple(args, "O&i|OOi:lockf", ! conv_descriptor, &fd, &code, &lenobj, &startobj, &whence)) return NULL; *************** *** 325,328 **** --- 345,393 ---- if (ins(d, "LOCK_NB", (long)LOCK_NB)) return -1; if (ins(d, "LOCK_UN", (long)LOCK_UN)) return -1; + #ifdef F_DUPFD + if (ins(d, "F_DUPFD", (long)F_DUPFD)) return -1; + #endif + #ifdef F_GETFD + if (ins(d, "F_GETFD", (long)F_GETFD)) return -1; + #endif + #ifdef F_SETFD + if (ins(d, "F_SETFD", (long)F_SETFD)) return -1; + #endif + #ifdef F_GETFL + if (ins(d, "F_GETFL", (long)F_GETFL)) return -1; + #endif + #ifdef F_SETFL + if (ins(d, "F_SETFL", (long)F_SETFL)) return -1; + #endif + #ifdef F_GETLK + if (ins(d, "F_GETLK", (long)F_GETLK)) return -1; + #endif + #ifdef F_SETLK + if (ins(d, "F_SETLK", (long)F_SETLK)) return -1; + #endif + #ifdef F_SETLKW + if (ins(d, "F_SETLKW", (long)F_SETLKW)) return -1; + #endif + #ifdef F_GETOWN + if (ins(d, "F_GETOWN", (long)F_GETOWN)) return -1; + #endif + #ifdef F_SETOWN + if (ins(d, "F_SETOWN", (long)F_SETOWN)) return -1; + #endif + #ifdef F_GETSIG + if (ins(d, "F_GETSIG", (long)F_GETSIG)) return -1; + #endif + #ifdef F_SETSIG + if (ins(d, "F_SETSIG", (long)F_SETSIG)) return -1; + #endif + #ifdef F_RDLCK + if (ins(d, "F_RDLCK", (long)F_RDLCK)) return -1; + #endif + #ifdef F_WRLCK + if (ins(d, "F_WRLCK", (long)F_WRLCK)) return -1; + #endif + #ifdef F_UNLCK + if (ins(d, "F_UNLCK", (long)F_UNLCK)) return -1; + #endif return 0; } Index: main.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/main.c,v retrieving revision 1.52 retrieving revision 1.52.4.1 diff -C2 -r1.52 -r1.52.4.1 *** main.c 2001/04/10 22:07:07 1.52 --- main.c 2001/07/07 22:55:29 1.52.4.1 *************** *** 15,19 **** #define PYTHONHOMEHELP "\\lib" #else ! #define PYTHONHOMEHELP "/python2.0" #endif --- 15,19 ---- #define PYTHONHOMEHELP "\\lib" #else ! #define PYTHONHOMEHELP "/pythonX.X" #endif Index: makesetup =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/makesetup,v retrieving revision 1.35 retrieving revision 1.35.6.1 diff -C2 -r1.35 -r1.35.6.1 *** makesetup 2001/03/02 07:09:54 1.35 --- makesetup 2001/07/07 22:55:29 1.35.6.1 *************** *** 217,221 **** esac case $doconfig in ! no) cc="$cc \$(CCSHARED) \$(CFLAGS)";; *) cc="$cc \$(PY_CFLAGS)";; --- 217,221 ---- esac case $doconfig in ! no) cc="$cc \$(CCSHARED) \$(CFLAGS) \$(CPPFLAGS)";; *) cc="$cc \$(PY_CFLAGS)";; Index: mathmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/mathmodule.c,v retrieving revision 2.58 retrieving revision 2.58.8.1 diff -C2 -r2.58 -r2.58.8.1 *** mathmodule.c 2000/10/12 19:42:00 2.58 --- mathmodule.c 2001/07/07 22:55:29 2.58.8.1 *************** *** 129,133 **** FUNC1(floor, floor, "floor(x)\n\nReturn the floor of x as a real.") ! FUNC2(fmod, fmod, "fmod(x,y)\n\nReturn fmod(x, y), according to platform C." " x % y may differ.") --- 129,133 ---- FUNC1(floor, floor, "floor(x)\n\nReturn the floor of x as a real.") ! FUNC2(fmod, fmod, "fmod(x,y)\n\nReturn fmod(x, y), according to platform C." " x % y may differ.") Index: mmapmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/mmapmodule.c,v retrieving revision 2.28 retrieving revision 2.28.2.1 diff -C2 -r2.28 -r2.28.2.1 *** mmapmodule.c 2001/04/21 02:46:11 2.28 --- mmapmodule.c 2001/07/07 22:55:29 2.28.2.1 *************** *** 164,177 **** PyObject *args) { - char value; - char *where; CHECK_VALID(NULL); if (!PyArg_ParseTuple(args, ":read_byte")) return NULL; if (self->pos < self->size) { ! where = self->data + self->pos; ! value = (char) *(where); self->pos += 1; ! return Py_BuildValue("c", (char) *(where)); } else { PyErr_SetString (PyExc_ValueError, "read byte out of range"); --- 164,174 ---- PyObject *args) { CHECK_VALID(NULL); if (!PyArg_ParseTuple(args, ":read_byte")) return NULL; if (self->pos < self->size) { ! char value = self->data[self->pos]; self->pos += 1; ! return Py_BuildValue("c", value); } else { PyErr_SetString (PyExc_ValueError, "read byte out of range"); *************** *** 228,241 **** PyObject *args) { ! int start = self->pos; char *needle; int len; CHECK_VALID(NULL); ! if (!PyArg_ParseTuple (args, "s#|i:find", &needle, &len, &start)) { return NULL; } else { ! char *p = self->data+self->pos; ! char *e = self->data+self->size; while (p < e) { char *s = p; --- 225,247 ---- PyObject *args) { ! long start = self->pos; char *needle; int len; CHECK_VALID(NULL); ! if (!PyArg_ParseTuple (args, "s#|l:find", &needle, &len, &start)) { return NULL; } else { ! char *p; ! char *e = self->data + self->size; ! ! if (start < 0) ! start += self->size; ! if (start < 0) ! start = 0; ! else if ((size_t)start > self->size) ! start = self->size; ! p = self->data + start; ! while (p < e) { char *s = p; *************** *** 246,251 **** if (!*n) { return Py_BuildValue ( ! "i", ! (int) (p - (self->data + start))); } p++; --- 252,257 ---- if (!*n) { return Py_BuildValue ( ! "l", ! (long) (p - self->data)); } p++; Index: parsermodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/parsermodule.c,v retrieving revision 2.60 retrieving revision 2.60.6.1 diff -C2 -r2.60 -r2.60.6.1 *** parsermodule.c 2001/01/07 05:59:59 2.60 --- parsermodule.c 2001/07/07 22:55:29 2.60.6.1 *************** *** 2525,2529 **** node* next = 0; /* node to process after this one */ ! while (res & (tree != 0)) { nch = NCH(tree); next = 0; --- 2525,2529 ---- node* next = 0; /* node to process after this one */ ! while (res && (tree != 0)) { nch = NCH(tree); next = 0; Index: pcremodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/pcremodule.c,v retrieving revision 2.25 retrieving revision 2.25.8.1 diff -C2 -r2.25 -r2.25.8.1 *** pcremodule.c 2000/09/01 23:29:27 2.25 --- pcremodule.c 2001/07/07 22:55:29 2.25.8.1 *************** *** 75,79 **** PyObject *list; ! if (!PyArg_ParseTuple(args, "t#|iiii:match", &string, &stringlen, &pos, &endpos, &options)) return NULL; if (endpos == -1) {endpos = stringlen;} --- 75,80 ---- PyObject *list; ! if (!PyArg_ParseTuple(args, "t#|iii:match", &string, &stringlen, ! &pos, &endpos, &options)) return NULL; if (endpos == -1) {endpos = stringlen;} Index: posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.187 retrieving revision 2.187.4.1 diff -C2 -r2.187 -r2.187.4.1 *** posixmodule.c 2001/04/14 17:55:09 2.187 --- posixmodule.c 2001/07/07 22:55:29 2.187.4.1 *************** *** 64,73 **** #define HAVE_EXECV 1 #define HAVE_GETCWD 1 - #define HAVE_GETEGID 1 - #define HAVE_GETEUID 1 - #define HAVE_GETGID 1 - #define HAVE_GETPPID 1 - #define HAVE_GETUID 1 - #define HAVE_KILL 1 #define HAVE_OPENDIR 1 #define HAVE_PIPE 1 --- 64,67 ---- *************** *** 153,157 **** --- 147,155 ---- extern int rmdir(const char *); #endif + #ifdef __BORLANDC__ + extern int chmod(const char *, int); + #else extern int chmod(const char *, mode_t); + #endif extern int chown(const char *, uid_t, gid_t); extern char *getcwd(char *, int); *************** *** 355,358 **** --- 353,364 ---- } + static PyObject * + posix_error_with_allocated_filename(char* name) + { + PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name); + PyMem_Free(name); + return rc; + } + #ifdef MS_WIN32 static PyObject * *************** *** 469,475 **** posix_1str(PyObject *args, char *format, int (*func)(const char*)) { ! char *path1; int res; ! if (!PyArg_ParseTuple(args, format, &path1)) return NULL; Py_BEGIN_ALLOW_THREADS --- 475,482 ---- posix_1str(PyObject *args, char *format, int (*func)(const char*)) { ! char *path1 = NULL; int res; ! if (!PyArg_ParseTuple(args, format, ! Py_FileSystemDefaultEncoding, &path1)) return NULL; Py_BEGIN_ALLOW_THREADS *************** *** 477,481 **** Py_END_ALLOW_THREADS if (res < 0) ! return posix_error_with_filename(path1); Py_INCREF(Py_None); return Py_None; --- 484,489 ---- Py_END_ALLOW_THREADS if (res < 0) ! return posix_error_with_allocated_filename(path1); ! PyMem_Free(path1); Py_INCREF(Py_None); return Py_None; *************** *** 486,496 **** int (*func)(const char *, const char *)) { ! char *path1, *path2; int res; ! if (!PyArg_ParseTuple(args, format, &path1, &path2)) return NULL; Py_BEGIN_ALLOW_THREADS res = (*func)(path1, path2); Py_END_ALLOW_THREADS if (res != 0) /* XXX how to report both path1 and path2??? */ --- 494,508 ---- int (*func)(const char *, const char *)) { ! char *path1 = NULL, *path2 = NULL; int res; ! if (!PyArg_ParseTuple(args, format, ! Py_FileSystemDefaultEncoding, &path1, ! Py_FileSystemDefaultEncoding, &path2)) return NULL; Py_BEGIN_ALLOW_THREADS res = (*func)(path1, path2); Py_END_ALLOW_THREADS + PyMem_Free(path1); + PyMem_Free(path2); if (res != 0) /* XXX how to report both path1 and path2??? */ *************** *** 552,556 **** { STRUCT_STAT st; ! char *path; int res; --- 564,568 ---- { STRUCT_STAT st; ! char *path = NULL; int res; *************** *** 560,564 **** #endif /* MS_WIN32 */ ! if (!PyArg_ParseTuple(args, format, &path)) return NULL; --- 572,577 ---- #endif /* MS_WIN32 */ ! if (!PyArg_ParseTuple(args, format, ! Py_FileSystemDefaultEncoding, &path)) return NULL; *************** *** 567,570 **** --- 580,584 ---- /* the library call can blow up if the file name is too long! */ if (pathlen > MAX_PATH) { + PyMem_Free(path); errno = ENAMETOOLONG; return posix_error(); *************** *** 589,594 **** Py_END_ALLOW_THREADS if (res != 0) ! return posix_error_with_filename(path); return _pystat_fromstructstat(st); } --- 603,609 ---- Py_END_ALLOW_THREADS if (res != 0) ! return posix_error_with_allocated_filename(path); + PyMem_Free(path); return _pystat_fromstructstat(st); } *************** *** 682,686 **** posix_chdir(PyObject *self, PyObject *args) { ! return posix_1str(args, "s:chdir", chdir); } --- 697,701 ---- posix_chdir(PyObject *self, PyObject *args) { ! return posix_1str(args, "et:chdir", chdir); } *************** *** 693,700 **** posix_chmod(PyObject *self, PyObject *args) { ! char *path; int i; int res; ! if (!PyArg_ParseTuple(args, "si", &path, &i)) return NULL; Py_BEGIN_ALLOW_THREADS --- 708,716 ---- posix_chmod(PyObject *self, PyObject *args) { ! char *path = NULL; int i; int res; ! if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding, ! &path, &i)) return NULL; Py_BEGIN_ALLOW_THREADS *************** *** 702,706 **** Py_END_ALLOW_THREADS if (res < 0) ! return posix_error_with_filename(path); Py_INCREF(Py_None); return Py_None; --- 718,723 ---- Py_END_ALLOW_THREADS if (res < 0) ! return posix_error_with_allocated_filename(path); ! PyMem_Free(path); Py_INCREF(Py_None); return Py_None; *************** *** 747,754 **** posix_chown(PyObject *self, PyObject *args) { ! char *path; int uid, gid; int res; ! if (!PyArg_ParseTuple(args, "sii:chown", &path, &uid, &gid)) return NULL; Py_BEGIN_ALLOW_THREADS --- 764,773 ---- posix_chown(PyObject *self, PyObject *args) { ! char *path = NULL; int uid, gid; int res; ! if (!PyArg_ParseTuple(args, "etii:chown", ! Py_FileSystemDefaultEncoding, &path, ! &uid, &gid)) return NULL; Py_BEGIN_ALLOW_THREADS *************** *** 756,760 **** Py_END_ALLOW_THREADS if (res < 0) ! return posix_error_with_filename(path); Py_INCREF(Py_None); return Py_None; --- 775,780 ---- Py_END_ALLOW_THREADS if (res < 0) ! return posix_error_with_allocated_filename(path); ! PyMem_Free(path); Py_INCREF(Py_None); return Py_None; *************** *** 793,797 **** posix_link(PyObject *self, PyObject *args) { ! return posix_2str(args, "ss:link", link); } #endif /* HAVE_LINK */ --- 813,817 ---- posix_link(PyObject *self, PyObject *args) { ! return posix_2str(args, "etet:link", link); } #endif /* HAVE_LINK */ *************** *** 814,832 **** #if defined(MS_WIN32) && !defined(HAVE_OPENDIR) - char *name; - int len; PyObject *d, *v; HANDLE hFindFile; WIN32_FIND_DATA FileData; ! char namebuf[MAX_PATH+5]; char ch; ! if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len)) return NULL; - if (len >= MAX_PATH) { - PyErr_SetString(PyExc_ValueError, "path too long"); - return NULL; - } - strcpy(namebuf, name); ch = namebuf[len-1]; if (ch != '/' && ch != '\\' && ch != ':') --- 834,849 ---- #if defined(MS_WIN32) && !defined(HAVE_OPENDIR) PyObject *d, *v; HANDLE hFindFile; WIN32_FIND_DATA FileData; ! /* MAX_PATH characters could mean a bigger encoded string */ ! char namebuf[MAX_PATH*2+5]; ! char *bufptr = namebuf; ! int len = sizeof(namebuf)/sizeof(namebuf[0]); char ch; ! if (!PyArg_ParseTuple(args, "et#:listdir", ! Py_FileSystemDefaultEncoding, &bufptr, &len)) return NULL; ch = namebuf[len-1]; if (ch != '/' && ch != '\\' && ch != ':') *************** *** 842,846 **** if (errno == ERROR_FILE_NOT_FOUND) return PyList_New(0); ! return win32_error("FindFirstFile", name); } do { --- 859,863 ---- if (errno == ERROR_FILE_NOT_FOUND) return PyList_New(0); ! return win32_error("FindFirstFile", namebuf); } do { *************** *** 866,870 **** if (FindClose(hFindFile) == FALSE) ! return win32_error("FindClose", name); return d; --- 883,887 ---- if (FindClose(hFindFile) == FALSE) ! return win32_error("FindClose", namebuf); return d; *************** *** 1043,1046 **** --- 1060,1085 ---- } /* end of posix_listdir */ + #ifdef MS_WIN32 + /* A helper function for abspath on win32 */ + static PyObject * + posix__getfullpathname(PyObject *self, PyObject *args) + { + /* assume encoded strings wont more than double no of chars */ + char inbuf[MAX_PATH*2]; + char *inbufp = inbuf; + int insize = sizeof(inbuf)/sizeof(inbuf[0]); + char outbuf[MAX_PATH*2]; + char *temp; + if (!PyArg_ParseTuple (args, "et#:_getfullpathname", + Py_FileSystemDefaultEncoding, &inbufp, + &insize)) + return NULL; + if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]), + outbuf, &temp)) + return win32_error("GetFullPathName", inbuf); + return PyString_FromString(outbuf); + } /* end of posix__getfullpathname */ + #endif /* MS_WIN32 */ + static char posix_mkdir__doc__[] = "mkdir(path [, mode=0777]) -> None\n\ *************** *** 1051,1057 **** { int res; ! char *path; int mode = 0777; ! if (!PyArg_ParseTuple(args, "s|i:mkdir", &path, &mode)) return NULL; Py_BEGIN_ALLOW_THREADS --- 1090,1097 ---- { int res; ! char *path = NULL; int mode = 0777; ! if (!PyArg_ParseTuple(args, "et|i:mkdir", ! Py_FileSystemDefaultEncoding, &path, &mode)) return NULL; Py_BEGIN_ALLOW_THREADS *************** *** 1063,1067 **** Py_END_ALLOW_THREADS if (res < 0) ! return posix_error_with_filename(path); Py_INCREF(Py_None); return Py_None; --- 1103,1108 ---- Py_END_ALLOW_THREADS if (res < 0) ! return posix_error_with_allocated_filename(path); ! PyMem_Free(path); Py_INCREF(Py_None); return Py_None; *************** *** 1096,1100 **** posix_rename(PyObject *self, PyObject *args) { ! return posix_2str(args, "ss:rename", rename); } --- 1137,1141 ---- posix_rename(PyObject *self, PyObject *args) { ! return posix_2str(args, "etet:rename", rename); } *************** *** 1107,1111 **** posix_rmdir(PyObject *self, PyObject *args) { ! return posix_1str(args, "s:rmdir", rmdir); } --- 1148,1152 ---- posix_rmdir(PyObject *self, PyObject *args) { ! return posix_1str(args, "et:rmdir", rmdir); } *************** *** 1118,1122 **** posix_stat(PyObject *self, PyObject *args) { ! return posix_do_stat(self, args, "s:stat", STAT); } --- 1159,1163 ---- posix_stat(PyObject *self, PyObject *args) { ! return posix_do_stat(self, args, "et:stat", STAT); } *************** *** 1170,1174 **** posix_unlink(PyObject *self, PyObject *args) { ! return posix_1str(args, "s:remove", unlink); } --- 1211,1215 ---- posix_unlink(PyObject *self, PyObject *args) { ! return posix_1str(args, "et:remove", unlink); } *************** *** 3114,3120 **** { #ifdef HAVE_LSTAT ! return posix_do_stat(self, args, "s:lstat", lstat); #else /* !HAVE_LSTAT */ ! return posix_do_stat(self, args, "s:lstat", STAT); #endif /* !HAVE_LSTAT */ } --- 3155,3161 ---- { #ifdef HAVE_LSTAT ! return posix_do_stat(self, args, "et:lstat", lstat); #else /* !HAVE_LSTAT */ ! return posix_do_stat(self, args, "et:lstat", STAT); #endif /* !HAVE_LSTAT */ } *************** *** 3152,3156 **** posix_symlink(PyObject *self, PyObject *args) { ! return posix_2str(args, "ss:symlink", symlink); } #endif /* HAVE_SYMLINK */ --- 3193,3197 ---- posix_symlink(PyObject *self, PyObject *args) { ! return posix_2str(args, "etet:symlink", symlink); } #endif /* HAVE_SYMLINK */ *************** *** 3329,3337 **** posix_open(PyObject *self, PyObject *args) { ! char *file; int flag; int mode = 0777; int fd; ! if (!PyArg_ParseTuple(args, "si|i", &file, &flag, &mode)) return NULL; --- 3370,3380 ---- posix_open(PyObject *self, PyObject *args) { ! char *file = NULL; int flag; int mode = 0777; int fd; ! if (!PyArg_ParseTuple(args, "eti|i", ! Py_FileSystemDefaultEncoding, &file, ! &flag, &mode)) return NULL; *************** *** 3340,3344 **** Py_END_ALLOW_THREADS if (fd < 0) ! return posix_error_with_filename(file); return PyInt_FromLong((long)fd); } --- 3383,3388 ---- Py_END_ALLOW_THREADS if (fd < 0) ! return posix_error_with_allocated_filename(file); ! PyMem_Free(file); return PyInt_FromLong((long)fd); } *************** *** 5459,5462 **** --- 5503,5509 ---- #endif {"abort", posix_abort, METH_VARARGS, posix_abort__doc__}, + #ifdef MS_WIN32 + {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL}, + #endif {NULL, NULL} /* Sentinel */ }; *************** *** 5618,5632 **** ! #if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__) #define INITFUNC initnt #define MODNAME "nt" ! #else ! #if defined(PYOS_OS2) #define INITFUNC initos2 #define MODNAME "os2" #else #define INITFUNC initposix #define MODNAME "posix" - #endif #endif --- 5665,5679 ---- ! #if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__) #define INITFUNC initnt #define MODNAME "nt" ! ! #elif defined(PYOS_OS2) #define INITFUNC initos2 #define MODNAME "os2" + #else #define INITFUNC initposix #define MODNAME "posix" #endif Index: pyexpat.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/pyexpat.c,v retrieving revision 2.45 retrieving revision 2.45.4.1 diff -C2 -r2.45 -r2.45.4.1 *** pyexpat.c 2001/03/24 19:58:26 2.45 --- pyexpat.c 2001/07/07 22:55:29 2.45.4.1 *************** *** 964,970 **** int i; ! if (!PyArg_ParseTuple(args, "s|s:ExternalEntityParserCreate", &context, ! &encoding)) { ! return NULL; } --- 964,970 ---- int i; ! if (!PyArg_ParseTuple(args, "s|s:ExternalEntityParserCreate", ! &context, &encoding)) { ! return NULL; } *************** *** 1144,1148 **** self->in_callback = 0; self->handlers = NULL; ! if (namespace_separator) { self->itself = XML_ParserCreateNS(encoding, *namespace_separator); } --- 1144,1148 ---- self->in_callback = 0; self->handlers = NULL; ! if (namespace_separator != NULL) { self->itself = XML_ParserCreateNS(encoding, *namespace_separator); } *************** *** 1187,1192 **** if (self->handlers != NULL) { for (i = 0; handler_info[i].name != NULL; i++) { ! Py_XDECREF(self->handlers[i]); } free(self->handlers); --- 1187,1195 ---- if (self->handlers != NULL) { + PyObject *temp; for (i = 0; handler_info[i].name != NULL; i++) { ! temp = self->handlers[i]; ! self->handlers[i] = NULL; ! Py_XDECREF(temp); } free(self->handlers); *************** *** 1319,1331 **** xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg) { ! int i, err; ! for (i = 0; handler_info[i].name != NULL; i++) { ! if (!op->handlers[i]) ! continue; ! err = visit(op->handlers[i], arg); ! if (err) ! return err; ! } ! return 0; } --- 1322,1334 ---- xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg) { ! int i, err; ! for (i = 0; handler_info[i].name != NULL; i++) { ! if (!op->handlers[i]) ! continue; ! err = visit(op->handlers[i], arg); ! if (err) ! return err; ! } ! return 0; } *************** *** 1333,1338 **** xmlparse_clear(xmlparseobject *op) { ! clear_handlers(op, 1); ! return 0; } #endif --- 1336,1341 ---- xmlparse_clear(xmlparseobject *op) { ! clear_handlers(op, 1); ! return 0; } #endif *************** *** 1383,1401 **** pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw) { ! char *encoding = NULL; ! char *namespace_separator = NULL; ! static char *kwlist[] = {"encoding", "namespace_separator", NULL}; ! ! if (!PyArg_ParseTupleAndKeywords(args, kw, "|zz:ParserCreate", kwlist, ! &encoding, &namespace_separator)) ! return NULL; ! if (namespace_separator != NULL ! && strlen(namespace_separator) != 1) { ! PyErr_SetString(PyExc_ValueError, ! "namespace_separator must be one character," ! " omitted, or None"); ! return NULL; ! } ! return newxmlparseobject(encoding, namespace_separator); } --- 1386,1404 ---- pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw) { ! char *encoding = NULL; ! char *namespace_separator = NULL; ! static char *kwlist[] = {"encoding", "namespace_separator", NULL}; ! ! if (!PyArg_ParseTupleAndKeywords(args, kw, "|zz:ParserCreate", kwlist, ! &encoding, &namespace_separator)) ! return NULL; ! if (namespace_separator != NULL ! && strlen(namespace_separator) > 1) { ! PyErr_SetString(PyExc_ValueError, ! "namespace_separator must be at most one" ! " character, omitted, or None"); ! return NULL; ! } ! return newxmlparseobject(encoding, namespace_separator); } *************** *** 1430,1437 **** "Python wrapper for Expat parser."; - /* Initialization function for the module */ - - void initpyexpat(void); /* avoid compiler warnings */ - #if PY_VERSION_HEX < 0x20000F0 --- 1433,1436 ---- *************** *** 1440,1453 **** PyModule_AddObject(PyObject *m, char *name, PyObject *o) { ! PyObject *dict; ! if (!PyModule_Check(m) || o == NULL) ! return -1; ! dict = PyModule_GetDict(m); ! if (dict == NULL) ! return -1; ! if (PyDict_SetItemString(dict, name, o)) ! return -1; ! Py_DECREF(o); ! return 0; } --- 1439,1452 ---- PyModule_AddObject(PyObject *m, char *name, PyObject *o) { ! PyObject *dict; ! if (!PyModule_Check(m) || o == NULL) ! return -1; ! dict = PyModule_GetDict(m); ! if (dict == NULL) ! return -1; ! if (PyDict_SetItemString(dict, name, o)) ! return -1; ! Py_DECREF(o); ! return 0; } *************** *** 1455,1459 **** PyModule_AddIntConstant(PyObject *m, char *name, long value) { ! return PyModule_AddObject(m, name, PyInt_FromLong(value)); } --- 1454,1458 ---- PyModule_AddIntConstant(PyObject *m, char *name, long value) { ! return PyModule_AddObject(m, name, PyInt_FromLong(value)); } *************** *** 1461,1465 **** PyModule_AddStringConstant(PyObject *m, char *name, char *value) { ! return PyModule_AddObject(m, name, PyString_FromString(value)); } --- 1460,1464 ---- PyModule_AddStringConstant(PyObject *m, char *name, char *value) { ! return PyModule_AddObject(m, name, PyString_FromString(value)); } *************** *** 1487,1495 **** } DL_EXPORT(void) ! initpyexpat(void) { PyObject *m, *d; ! PyObject *errmod_name = PyString_FromString("pyexpat.errors"); PyObject *errors_module; PyObject *modelmod_name; --- 1486,1506 ---- } + /* Initialization function for the module */ + + #ifndef MODULE_NAME + #define MODULE_NAME "pyexpat" + #endif + + #ifndef MODULE_INITFUNC + #define MODULE_INITFUNC initpyexpat + #endif + + void MODULE_INITFUNC(void); /* avoid compiler warnings */ + DL_EXPORT(void) ! MODULE_INITFUNC(void) { PyObject *m, *d; ! PyObject *errmod_name = PyString_FromString(MODULE_NAME ".errors"); PyObject *errors_module; PyObject *modelmod_name; *************** *** 1499,1503 **** if (errmod_name == NULL) return; ! modelmod_name = PyString_FromString("pyexpat.model"); if (modelmod_name == NULL) return; --- 1510,1514 ---- if (errmod_name == NULL) return; ! modelmod_name = PyString_FromString(MODULE_NAME ".model"); if (modelmod_name == NULL) return; *************** *** 1506,1510 **** /* Create the module and add the functions */ ! m = Py_InitModule3("pyexpat", pyexpat_methods, pyexpat_module_documentation); --- 1517,1521 ---- /* Create the module and add the functions */ ! m = Py_InitModule3(MODULE_NAME, pyexpat_methods, pyexpat_module_documentation); *************** *** 1548,1552 **** errors_module = PyDict_GetItem(d, errmod_name); if (errors_module == NULL) { ! errors_module = PyModule_New("pyexpat.errors"); if (errors_module != NULL) { PyDict_SetItem(sys_modules, errmod_name, errors_module); --- 1559,1563 ---- errors_module = PyDict_GetItem(d, errmod_name); if (errors_module == NULL) { ! errors_module = PyModule_New(MODULE_NAME ".errors"); if (errors_module != NULL) { PyDict_SetItem(sys_modules, errmod_name, errors_module); *************** *** 1558,1562 **** model_module = PyDict_GetItem(d, modelmod_name); if (model_module == NULL) { ! model_module = PyModule_New("pyexpat.model"); if (model_module != NULL) { PyDict_SetItem(sys_modules, modelmod_name, model_module); --- 1569,1573 ---- model_module = PyDict_GetItem(d, modelmod_name); if (model_module == NULL) { ! model_module = PyModule_New(MODULE_NAME ".model"); if (model_module != NULL) { PyDict_SetItem(sys_modules, modelmod_name, model_module); *************** *** 1633,1645 **** clear_handlers(xmlparseobject *self, int decref) { ! int i = 0; ! for (; handler_info[i].name!=NULL; i++) { ! if (decref){ ! Py_XDECREF(self->handlers[i]); ! } ! self->handlers[i]=NULL; ! handler_info[i].setter(self->itself, NULL); ! } } --- 1644,1659 ---- clear_handlers(xmlparseobject *self, int decref) { ! int i = 0; ! PyObject *temp; ! for (; handler_info[i].name!=NULL; i++) { ! if (decref) { ! temp = self->handlers[i]; ! self->handlers[i] = NULL; ! Py_XDECREF(temp); ! } ! self->handlers[i]=NULL; ! handler_info[i].setter(self->itself, NULL); ! } } *************** *** 1652,1665 **** pairsetter setter) { ! void *start_handler=NULL; ! void *end_handler=NULL; if (self->handlers[startHandler] ! && self->handlers[endHandler]!=Py_None) { ! start_handler=handler_info[startHandler].handler; } if (self->handlers[EndElement] ! && self->handlers[EndElement] !=Py_None) { ! end_handler=handler_info[endHandler].handler; } setter(self->itself, start_handler, end_handler); --- 1666,1679 ---- pairsetter setter) { ! void *start_handler = NULL; ! void *end_handler = NULL; if (self->handlers[startHandler] ! && self->handlers[endHandler] != Py_None) { ! start_handler = handler_info[startHandler].handler; } if (self->handlers[EndElement] ! && self->handlers[EndElement] != Py_None) { ! end_handler = handler_info[endHandler].handler; } setter(self->itself, start_handler, end_handler); Index: regexpr.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/regexpr.c,v retrieving revision 1.33 retrieving revision 1.33.8.1 diff -C2 -r1.33 -r1.33.8.1 *** regexpr.c 2000/07/21 06:00:07 1.33 --- regexpr.c 2001/07/07 22:55:29 1.33.8.1 *************** *** 1384,1388 **** goto bad_match_register; ch = 10 * (a - '0') + ch - '0'; ! if (ch <= 0 || ch >= RE_NREGS) goto bad_match_register; bufp->uses_registers = 1; --- 1384,1388 ---- goto bad_match_register; ch = 10 * (a - '0') + ch - '0'; ! if (ch == 0 || ch >= RE_NREGS) goto bad_match_register; bufp->uses_registers = 1; Index: selectmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/selectmodule.c,v retrieving revision 2.50 retrieving revision 2.50.6.1 diff -C2 -r2.50 -r2.50.6.1 *** selectmodule.c 2001/03/02 06:28:17 2.50 --- selectmodule.c 2001/07/07 22:55:29 2.50.6.1 *************** *** 363,367 **** int fd, events = POLLIN | POLLPRI | POLLOUT; ! if (!PyArg_ParseTuple(args, "O|i", &o, &events)) { return NULL; } --- 363,367 ---- int fd, events = POLLIN | POLLPRI | POLLOUT; ! if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) { return NULL; } *************** *** 393,397 **** int fd; ! if (!PyArg_ParseTuple(args, "O", &o)) { return NULL; } --- 393,397 ---- int fd; ! if (!PyArg_ParseTuple(args, "O:unregister", &o)) { return NULL; } *************** *** 432,436 **** PyObject *value = NULL, *num = NULL; ! if (!PyArg_ParseTuple(args, "|O", &tout)) { return NULL; } --- 432,436 ---- PyObject *value = NULL, *num = NULL; ! if (!PyArg_ParseTuple(args, "|O:poll", &tout)) { return NULL; } Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.141 retrieving revision 1.141.4.1 diff -C2 -r1.141 -r1.141.4.1 *** socketmodule.c 2001/04/16 00:21:33 1.141 --- socketmodule.c 2001/07/07 22:55:29 1.141.4.1 *************** *** 179,182 **** --- 179,190 ---- #endif + #ifdef HAVE_STDDEF_H + #include + #endif + + #ifndef offsetof + #define offsetof(type, member) ((size_t)(&((type *)0)->member)) + #endif + #ifndef O_NDELAY #define O_NDELAY O_NONBLOCK /* For QNX only? */ *************** *** 188,191 **** --- 196,206 ---- #endif + /* XXX 24-Jun-2000 Tim: I have no idea what the code inside this block is + trying to do, and don't have time to look. Looks like Unix-specific code + in those files, though, which will never compile on Windows. */ + #ifndef MS_WINDOWS + #include "addrinfo.h" + #endif /* ifndef MS_WINDOWS hack */ + #ifdef USE_SSL #include "openssl/rsa.h" *************** *** 197,200 **** --- 212,235 ---- #endif /* USE_SSL */ + /* XXX 24-Jun-2000 Tim: I have no idea what the code inside this block is + trying to do, and don't have time to look. Looks like Unix-specific code + in those files, though, which will never compile on Windows. */ + #ifndef MS_WINDOWS + + #ifndef HAVE_INET_PTON + int inet_pton (int af, char *src, void *dst); + char *inet_ntop(int af, void *src, char *dst, socklen_t size); + #endif + + /* I know this is a bad practice, but it is the easiest... */ + #ifndef HAVE_GETADDRINFO + #include "getaddrinfo.c" + #endif + #ifndef HAVE_GETNAMEINFO + #include "getnameinfo.c" + #endif + + #endif /* ifndef MS_WINDOWS hack */ + #if defined(MS_WINDOWS) || defined(__BEOS__) /* BeOS suffers from the same socket dichotomy as Win32... - [cjh] */ *************** *** 791,794 **** --- 826,830 ---- if (!getsockaddrlen(s, &addrlen)) return NULL; + memset(addrbuf, 0, addrlen); Py_BEGIN_ALLOW_THREADS newfd = accept(s->sock_fd, (struct sockaddr *) addrbuf, &addrlen); *************** *** 962,967 **** #ifdef __BEOS__ ! /* We have incomplete socket support. */ ! PyErr_SetString( PySocket_Error, "getsockopt not supported" ); return NULL; #else --- 998,1003 ---- #ifdef __BEOS__ ! /* We have incomplete socket support. */ ! PyErr_SetString(PySocket_Error, "getsockopt not supported"); return NULL; #else *************** *** 989,993 **** return NULL; res = getsockopt(s->sock_fd, level, optname, ! (void *)PyString_AsString(buf), &buflen); if (res < 0) { Py_DECREF(buf); --- 1025,1029 ---- return NULL; res = getsockopt(s->sock_fd, level, optname, ! (void *)PyString_AS_STRING(buf), &buflen); if (res < 0) { Py_DECREF(buf); *************** *** 1213,1216 **** --- 1249,1253 ---- if (!getsockaddrlen(s, &addrlen)) return NULL; + memset(addrbuf, 0, addrlen); Py_BEGIN_ALLOW_THREADS res = getpeername(s->sock_fd, (struct sockaddr *) addrbuf, &addrlen); *************** *** 1361,1365 **** return NULL; Py_BEGIN_ALLOW_THREADS ! n = recvfrom(s->sock_fd, PyString_AsString(buf), len, flags, #ifndef MS_WINDOWS #if defined(PYOS_OS2) --- 1398,1403 ---- return NULL; Py_BEGIN_ALLOW_THREADS ! memset(addrbuf, 0, addrlen); ! n = recvfrom(s->sock_fd, PyString_AS_STRING(buf), len, flags, #ifndef MS_WINDOWS #if defined(PYOS_OS2) *************** *** 2919,2920 **** --- 2957,2995 ---- #endif } + + /* Simplistic emulation code for inet_pton that only works for IPv4 */ + #ifndef HAVE_INET_PTON + int + inet_pton (int af, char *src, void *dst) + { + if(af == AF_INET){ + long packed_addr; + #ifdef USE_GUSI1 + packed_addr = (long)inet_addr(src).s_addr; + #else + packed_addr = inet_addr(src); + #endif + if (packed_addr == INADDR_NONE) + return 0; + memcpy(dst, &packed_addr, 4); + return 1; + } + /* Should set errno to EAFNOSUPPORT */ + return -1; + } + + char * + inet_ntop(int af, void *src, char *dst, socklen_t size) + { + if (af == AF_INET) { + struct in_addr packed_addr; + if (size < 16) + /* Should set errno to ENOSPC. */ + return NULL; + memcpy(&packed_addr, src, sizeof(packed_addr)); + return strncpy(dst, inet_ntoa(packed_addr), size); + } + /* Should set errno to EAFNOSUPPORT */ + return NULL; + } + #endif Index: sre.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/sre.h,v retrieving revision 2.18 retrieving revision 2.18.10.1 diff -C2 -r2.18 -r2.18.10.1 *** sre.h 2000/08/03 16:29:50 2.18 --- sre.h 2001/07/07 22:55:29 2.18.10.1 *************** *** 4,8 **** * regular expression matching engine * ! * Copyright (c) 1997-2000 by Secret Labs AB. All rights reserved. * * See the _sre.c file for information on usage and redistribution. --- 4,8 ---- * regular expression matching engine * ! * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. * * See the _sre.c file for information on usage and redistribution. *************** *** 14,23 **** #include "sre_constants.h" ! /* size of a code word (must be unsigned short or larger) */ #define SRE_CODE unsigned short typedef struct { PyObject_VAR_HEAD ! int groups; PyObject* groupindex; PyObject* indexgroup; --- 14,30 ---- #include "sre_constants.h" ! /* size of a code word (must be unsigned short or larger, and ! large enough to hold a Py_UNICODE character) */ ! #ifdef Py_UNICODE_WIDE ! #define SRE_CODE unsigned long ! #else #define SRE_CODE unsigned short + #endif + #define SRE_CODE unsigned short + typedef struct { PyObject_VAR_HEAD ! int groups; /* must be first! */ PyObject* groupindex; PyObject* indexgroup; *************** *** 26,29 **** --- 33,37 ---- int flags; /* flags used when compiling pattern source */ /* pattern code */ + int codesize; SRE_CODE code[1]; } PatternObject; *************** *** 33,37 **** typedef struct { PyObject_VAR_HEAD ! PyObject* string; /* link to the target string */ PyObject* regs; /* cached list of matching spans */ PatternObject* pattern; /* link to the regex (pattern) object */ --- 41,45 ---- typedef struct { PyObject_VAR_HEAD ! PyObject* string; /* link to the target string (must be first) */ PyObject* regs; /* cached list of matching spans */ PatternObject* pattern; /* link to the regex (pattern) object */ Index: sre_constants.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/sre_constants.h,v retrieving revision 2.12 retrieving revision 2.12.4.1 diff -C2 -r2.12 -r2.12.4.1 *** sre_constants.h 2001/03/22 15:50:09 2.12 --- sre_constants.h 2001/07/07 22:55:29 2.12.4.1 *************** *** 12,16 **** */ ! #define SRE_MAGIC 20010320 #define SRE_OP_FAILURE 0 #define SRE_OP_SUCCESS 1 --- 12,16 ---- */ ! #define SRE_MAGIC 20010701 #define SRE_OP_FAILURE 0 #define SRE_OP_SUCCESS 1 *************** *** 24,45 **** #define SRE_OP_CATEGORY 9 #define SRE_OP_CHARSET 10 ! #define SRE_OP_GROUPREF 11 ! #define SRE_OP_GROUPREF_IGNORE 12 ! #define SRE_OP_IN 13 ! #define SRE_OP_IN_IGNORE 14 ! #define SRE_OP_INFO 15 ! #define SRE_OP_JUMP 16 ! #define SRE_OP_LITERAL 17 ! #define SRE_OP_LITERAL_IGNORE 18 ! #define SRE_OP_MARK 19 ! #define SRE_OP_MAX_UNTIL 20 ! #define SRE_OP_MIN_UNTIL 21 ! #define SRE_OP_NOT_LITERAL 22 ! #define SRE_OP_NOT_LITERAL_IGNORE 23 ! #define SRE_OP_NEGATE 24 ! #define SRE_OP_RANGE 25 ! #define SRE_OP_REPEAT 26 ! #define SRE_OP_REPEAT_ONE 27 ! #define SRE_OP_SUBPATTERN 28 #define SRE_AT_BEGINNING 0 #define SRE_AT_BEGINNING_LINE 1 --- 24,46 ---- #define SRE_OP_CATEGORY 9 #define SRE_OP_CHARSET 10 ! #define SRE_OP_BIGCHARSET 11 ! #define SRE_OP_GROUPREF 12 ! #define SRE_OP_GROUPREF_IGNORE 13 ! #define SRE_OP_IN 14 ! #define SRE_OP_IN_IGNORE 15 ! #define SRE_OP_INFO 16 ! #define SRE_OP_JUMP 17 ! #define SRE_OP_LITERAL 18 ! #define SRE_OP_LITERAL_IGNORE 19 ! #define SRE_OP_MARK 20 ! #define SRE_OP_MAX_UNTIL 21 ! #define SRE_OP_MIN_UNTIL 22 ! #define SRE_OP_NOT_LITERAL 23 ! #define SRE_OP_NOT_LITERAL_IGNORE 24 ! #define SRE_OP_NEGATE 25 ! #define SRE_OP_RANGE 26 ! #define SRE_OP_REPEAT 27 ! #define SRE_OP_REPEAT_ONE 28 ! #define SRE_OP_SUBPATTERN 29 #define SRE_AT_BEGINNING 0 #define SRE_AT_BEGINNING_LINE 1 Index: stropmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/stropmodule.c,v retrieving revision 2.75 retrieving revision 2.75.8.1 diff -C2 -r2.75 -r2.75.8.1 *** stropmodule.c 2000/09/26 05:46:01 2.75 --- stropmodule.c 2001/07/07 22:55:29 2.75.8.1 *************** *** 1,10 **** - /* strop module */ static char strop_module__doc__[] = ! "Common string manipulations, optimized for speed.\n\ ! \n\ ! Always use \"import string\" rather than referencing\n\ ! this module directly."; #include "Python.h" --- 1,9 ---- /* strop module */ static char strop_module__doc__[] = ! "Common string manipulations, optimized for speed.\n" ! "\n" ! "Always use \"import string\" rather than referencing\n" ! "this module directly."; #include "Python.h" *************** *** 14,17 **** --- 13,20 ---- XXX are defined for all 8-bit characters! */ + #define WARN if (PyErr_Warn(PyExc_DeprecationWarning, \ + "strop functions are obsolete; use string methods")) \ + return NULL + /* The lstrip(), rstrip() and strip() functions are implemented in do_strip(), which uses an additional parameter to indicate what *************** *** 79,91 **** static char splitfields__doc__[] = ! "split(s [,sep [,maxsplit]]) -> list of strings\n\ ! splitfields(s [,sep [,maxsplit]]) -> list of strings\n\ ! \n\ ! Return a list of the words in the string s, using sep as the\n\ ! delimiter string. If maxsplit is nonzero, splits into at most\n\ ! maxsplit words. If sep is not specified, any whitespace string\n\ ! is a separator. Maxsplit defaults to 0.\n\ ! \n\ ! (split and splitfields are synonymous)"; static PyObject * --- 82,94 ---- static char splitfields__doc__[] = ! "split(s [,sep [,maxsplit]]) -> list of strings\n" ! "splitfields(s [,sep [,maxsplit]]) -> list of strings\n" ! "\n" ! "Return a list of the words in the string s, using sep as the\n" ! "delimiter string. If maxsplit is nonzero, splits into at most\n" ! "maxsplit words. If sep is not specified, any whitespace string\n" ! "is a separator. Maxsplit defaults to 0.\n" ! "\n" ! "(split and splitfields are synonymous)"; static PyObject * *************** *** 97,100 **** --- 100,104 ---- PyObject *list, *item; + WARN; sub = NULL; n = 0; *************** *** 149,160 **** static char joinfields__doc__[] = ! "join(list [,sep]) -> string\n\ ! joinfields(list [,sep]) -> string\n\ ! \n\ ! Return a string composed of the words in list, with\n\ ! intervening occurrences of sep. Sep defaults to a single\n\ ! space.\n\ ! \n\ ! (join and joinfields are synonymous)"; static PyObject * --- 153,164 ---- static char joinfields__doc__[] = ! "join(list [,sep]) -> string\n" ! "joinfields(list [,sep]) -> string\n" ! "\n" ! "Return a string composed of the words in list, with\n" ! "intervening occurrences of sep. Sep defaults to a single\n" ! "space.\n" ! "\n" ! "(join and joinfields are synonymous)"; static PyObject * *************** *** 169,172 **** --- 173,177 ---- intargfunc getitemfunc; + WARN; if (!PyArg_ParseTuple(args, "O|t#:join", &seq, &sep, &seplen)) return NULL; *************** *** 280,290 **** static char find__doc__[] = ! "find(s, sub [,start [,end]]) -> in\n\ ! \n\ ! Return the lowest index in s where substring sub is found,\n\ ! such that sub is contained within s[start,end]. Optional\n\ ! arguments start and end are interpreted as in slice notation.\n\ ! \n\ ! Return -1 on failure."; static PyObject * --- 285,295 ---- static char find__doc__[] = ! "find(s, sub [,start [,end]]) -> in\n" ! "\n" ! "Return the lowest index in s where substring sub is found,\n" ! "such that sub is contained within s[start,end]. Optional\n" ! "arguments start and end are interpreted as in slice notation.\n" ! "\n" ! "Return -1 on failure."; static PyObject * *************** *** 294,297 **** --- 299,303 ---- int len, n, i = 0, last = INT_MAX; + WARN; if (!PyArg_ParseTuple(args, "t#t#|ii:find", &s, &len, &sub, &n, &i, &last)) return NULL; *************** *** 322,332 **** static char rfind__doc__[] = ! "rfind(s, sub [,start [,end]]) -> int\n\ ! \n\ ! Return the highest index in s where substring sub is found,\n\ ! such that sub is contained within s[start,end]. Optional\n\ ! arguments start and end are interpreted as in slice notation.\n\ ! \n\ ! Return -1 on failure."; static PyObject * --- 328,338 ---- static char rfind__doc__[] = ! "rfind(s, sub [,start [,end]]) -> int\n" ! "\n" ! "Return the highest index in s where substring sub is found,\n" ! "such that sub is contained within s[start,end]. Optional\n" ! "arguments start and end are interpreted as in slice notation.\n" ! "\n" ! "Return -1 on failure."; static PyObject * *************** *** 337,340 **** --- 343,347 ---- int i = 0, last = INT_MAX; + WARN; if (!PyArg_ParseTuple(args, "t#t#|ii:rfind", &s, &len, &sub, &n, &i, &last)) return NULL; *************** *** 398,409 **** static char strip__doc__[] = ! "strip(s) -> string\n\ ! \n\ ! Return a copy of the string s with leading and trailing\n\ ! whitespace removed."; static PyObject * strop_strip(PyObject *self, PyObject *args) { return do_strip(args, BOTHSTRIP); } --- 405,417 ---- static char strip__doc__[] = ! "strip(s) -> string\n" ! "\n" ! "Return a copy of the string s with leading and trailing\n" ! "whitespace removed."; static PyObject * strop_strip(PyObject *self, PyObject *args) { + WARN; return do_strip(args, BOTHSTRIP); } *************** *** 411,421 **** static char lstrip__doc__[] = ! "lstrip(s) -> string\n\ ! \n\ ! Return a copy of the string s with leading whitespace removed."; static PyObject * strop_lstrip(PyObject *self, PyObject *args) { return do_strip(args, LEFTSTRIP); } --- 419,430 ---- static char lstrip__doc__[] = ! "lstrip(s) -> string\n" ! "\n" ! "Return a copy of the string s with leading whitespace removed."; static PyObject * strop_lstrip(PyObject *self, PyObject *args) { + WARN; return do_strip(args, LEFTSTRIP); } *************** *** 423,433 **** static char rstrip__doc__[] = ! "rstrip(s) -> string\n\ ! \n\ ! Return a copy of the string s with trailing whitespace removed."; static PyObject * strop_rstrip(PyObject *self, PyObject *args) { return do_strip(args, RIGHTSTRIP); } --- 432,443 ---- static char rstrip__doc__[] = ! "rstrip(s) -> string\n" ! "\n" ! "Return a copy of the string s with trailing whitespace removed."; static PyObject * strop_rstrip(PyObject *self, PyObject *args) { + WARN; return do_strip(args, RIGHTSTRIP); } *************** *** 435,441 **** static char lower__doc__[] = ! "lower(s) -> string\n\ ! \n\ ! Return a copy of the string s converted to lowercase."; static PyObject * --- 445,451 ---- static char lower__doc__[] = ! "lower(s) -> string\n" ! "\n" ! "Return a copy of the string s converted to lowercase."; static PyObject * *************** *** 447,450 **** --- 457,461 ---- int changed; + WARN; if (!PyArg_Parse(args, "t#", &s, &n)) return NULL; *************** *** 473,479 **** static char upper__doc__[] = ! "upper(s) -> string\n\ ! \n\ ! Return a copy of the string s converted to uppercase."; static PyObject * --- 484,490 ---- static char upper__doc__[] = ! "upper(s) -> string\n" ! "\n" ! "Return a copy of the string s converted to uppercase."; static PyObject * *************** *** 485,488 **** --- 496,500 ---- int changed; + WARN; if (!PyArg_Parse(args, "t#", &s, &n)) return NULL; *************** *** 511,518 **** static char capitalize__doc__[] = ! "capitalize(s) -> string\n\ ! \n\ ! Return a copy of the string s with only its first character\n\ ! capitalized."; static PyObject * --- 523,530 ---- static char capitalize__doc__[] = ! "capitalize(s) -> string\n" ! "\n" ! "Return a copy of the string s with only its first character\n" ! "capitalized."; static PyObject * *************** *** 524,527 **** --- 536,540 ---- int changed; + WARN; if (!PyArg_Parse(args, "t#", &s, &n)) return NULL; *************** *** 559,568 **** static char expandtabs__doc__[] = ! "expandtabs(string, [tabsize]) -> string\n\ ! \n\ ! Expand tabs in a string, i.e. replace them by one or more spaces,\n\ ! depending on the current column and the given tab size (default 8).\n\ ! The column number is reset to zero after each newline occurring in the\n\ ! string. This doesn't understand other non-printing characters."; static PyObject * --- 572,581 ---- static char expandtabs__doc__[] = ! "expandtabs(string, [tabsize]) -> string\n" ! "\n" ! "Expand tabs in a string, i.e. replace them by one or more spaces,\n" ! "depending on the current column and the given tab size (default 8).\n" ! "The column number is reset to zero after each newline occurring in the\n" ! "string. This doesn't understand other non-printing characters."; static PyObject * *************** *** 579,582 **** --- 592,596 ---- int tabsize = 8; + WARN; /* Get arguments */ if (!PyArg_ParseTuple(args, "s#|i:expandtabs", &string, &stringlen, &tabsize)) *************** *** 630,638 **** static char count__doc__[] = ! "count(s, sub[, start[, end]]) -> int\n\ ! \n\ ! Return the number of occurrences of substring sub in string\n\ ! s[start:end]. Optional arguments start and end are\n\ ! interpreted as in slice notation."; static PyObject * --- 644,652 ---- static char count__doc__[] = ! "count(s, sub[, start[, end]]) -> int\n" ! "\n" ! "Return the number of occurrences of substring sub in string\n" ! "s[start:end]. Optional arguments start and end are\n" ! "interpreted as in slice notation."; static PyObject * *************** *** 644,647 **** --- 658,662 ---- int m, r; + WARN; if (!PyArg_ParseTuple(args, "t#t#|ii:count", &s, &len, &sub, &n, &i, &last)) return NULL; *************** *** 674,681 **** static char swapcase__doc__[] = ! "swapcase(s) -> string\n\ ! \n\ ! Return a copy of the string s with upper case characters\n\ ! converted to lowercase and vice versa."; static PyObject * --- 689,696 ---- static char swapcase__doc__[] = ! "swapcase(s) -> string\n" ! "\n" ! "Return a copy of the string s with upper case characters\n" ! "converted to lowercase and vice versa."; static PyObject * *************** *** 687,690 **** --- 702,706 ---- int changed; + WARN; if (!PyArg_Parse(args, "t#", &s, &n)) return NULL; *************** *** 718,729 **** static char atoi__doc__[] = ! "atoi(s [,base]) -> int\n\ ! \n\ ! Return the integer represented by the string s in the given\n\ ! base, which defaults to 10. The string s must consist of one\n\ ! or more digits, possibly preceded by a sign. If base is 0, it\n\ ! is chosen from the leading characters of s, 0 for octal, 0x or\n\ ! 0X for hexadecimal. If base is 16, a preceding 0x or 0X is\n\ ! accepted."; static PyObject * --- 734,745 ---- static char atoi__doc__[] = ! "atoi(s [,base]) -> int\n" ! "\n" ! "Return the integer represented by the string s in the given\n" ! "base, which defaults to 10. The string s must consist of one\n" ! "or more digits, possibly preceded by a sign. If base is 0, it\n" ! "is chosen from the leading characters of s, 0 for octal, 0x or\n" ! "0X for hexadecimal. If base is 16, a preceding 0x or 0X is\n" ! "accepted."; static PyObject * *************** *** 735,738 **** --- 751,755 ---- char buffer[256]; /* For errors */ + WARN; if (!PyArg_ParseTuple(args, "s|i:atoi", &s, &base)) return NULL; *************** *** 770,782 **** static char atol__doc__[] = ! "atol(s [,base]) -> long\n\ ! \n\ ! Return the long integer represented by the string s in the\n\ ! given base, which defaults to 10. The string s must consist\n\ ! of one or more digits, possibly preceded by a sign. If base\n\ ! is 0, it is chosen from the leading characters of s, 0 for\n\ ! octal, 0x or 0X for hexadecimal. If base is 16, a preceding\n\ ! 0x or 0X is accepted. A trailing L or l is not accepted,\n\ ! unless base is 0."; static PyObject * --- 787,799 ---- static char atol__doc__[] = ! "atol(s [,base]) -> long\n" ! "\n" ! "Return the long integer represented by the string s in the\n" ! "given base, which defaults to 10. The string s must consist\n" ! "of one or more digits, possibly preceded by a sign. If base\n" ! "is 0, it is chosen from the leading characters of s, 0 for\n" ! "octal, 0x or 0X for hexadecimal. If base is 16, a preceding\n" ! "0x or 0X is accepted. A trailing L or l is not accepted,\n" ! "unless base is 0."; static PyObject * *************** *** 788,791 **** --- 805,809 ---- char buffer[256]; /* For errors */ + WARN; if (!PyArg_ParseTuple(args, "s|i:atol", &s, &base)) return NULL; *************** *** 820,826 **** static char atof__doc__[] = ! "atof(s) -> float\n\ ! \n\ ! Return the floating point number represented by the string s."; static PyObject * --- 838,844 ---- static char atof__doc__[] = ! "atof(s) -> float\n" ! "\n" ! "Return the floating point number represented by the string s."; static PyObject * *************** *** 832,835 **** --- 850,854 ---- char buffer[256]; /* For errors */ + WARN; if (!PyArg_ParseTuple(args, "s:atof", &s)) return NULL; *************** *** 861,869 **** static char maketrans__doc__[] = ! "maketrans(frm, to) -> string\n\ ! \n\ ! Return a translation table (a string of 256 bytes long)\n\ ! suitable for use in string.translate. The strings frm and to\n\ ! must be of the same length."; static PyObject * --- 880,888 ---- static char maketrans__doc__[] = ! "maketrans(frm, to) -> string\n" ! "\n" ! "Return a translation table (a string of 256 bytes long)\n" ! "suitable for use in string.translate. The strings frm and to\n" ! "must be of the same length."; static PyObject * *************** *** 897,906 **** static char translate__doc__[] = ! "translate(s,table [,deletechars]) -> string\n\ ! \n\ ! Return a copy of the string s, where all characters occurring\n\ ! in the optional argument deletechars are removed, and the\n\ ! remaining characters have been mapped through the given\n\ ! translation table, which must be a string of length 256."; static PyObject * --- 916,925 ---- static char translate__doc__[] = ! "translate(s,table [,deletechars]) -> string\n" ! "\n" ! "Return a copy of the string s, where all characters occurring\n" ! "in the optional argument deletechars are removed, and the\n" ! "remaining characters have been mapped through the given\n" ! "translation table, which must be a string of length 256."; static PyObject * *************** *** 915,918 **** --- 934,938 ---- int trans_table[256]; + WARN; if (!PyArg_ParseTuple(args, "St#|t#:translate", &input_obj, &table1, &tablen, &del_table, &dellen)) *************** *** 983,987 **** MEM, the function returns -1. */ ! static int mymemfind(char *mem, int len, char *pat, int pat_len) { register int ii; --- 1003,1008 ---- MEM, the function returns -1. */ ! static int ! mymemfind(const char *mem, int len, const char *pat, int pat_len) { register int ii; *************** *** 1007,1011 **** mem=11111 and pat==11 also return 2. */ ! static int mymemcnt(char *mem, int len, char *pat, int pat_len) { register int offset = 0; --- 1028,1033 ---- mem=11111 and pat==11 also return 2. */ ! static int ! mymemcnt(const char *mem, int len, const char *pat, int pat_len) { register int offset = 0; *************** *** 1042,1046 **** NULL if an error occurred. */ ! static char *mymemreplace(char *str, int len, char *pat, int pat_len, char *sub, int sub_len, int count, int *out_len) { char *out_s; --- 1064,1073 ---- NULL if an error occurred. */ ! static char * ! mymemreplace(const char *str, int len, /* input string */ ! const char *pat, int pat_len, /* pattern string to find */ ! const char *sub, int sub_len, /* substitution string */ ! int count, /* number of replacements */ ! int *out_len) { char *out_s; *************** *** 1053,1104 **** /* find length of output string */ nfound = mymemcnt(str, len, pat, pat_len); ! if (count > 0) ! nfound = nfound > count ? count : nfound; if (nfound == 0) goto return_same; new_len = len + nfound*(sub_len - pat_len); ! new_s = (char *)PyMem_MALLOC(new_len); ! if (new_s == NULL) return NULL; *out_len = new_len; - out_s = new_s; - - while (len > 0) { - /* find index of next instance of pattern */ - offset = mymemfind(str, len, pat, pat_len); - /* if not found, break out of loop */ - if (offset == -1) break; - - /* copy non matching part of input string */ - memcpy(new_s, str, offset); /* copy part of str before pat */ - str += offset + pat_len; /* move str past pattern */ - len -= offset + pat_len; /* reduce length of str remaining */ - - /* copy substitute into the output string */ - new_s += offset; /* move new_s to dest for sub string */ - memcpy(new_s, sub, sub_len); /* copy substring into new_s */ - new_s += sub_len; /* offset new_s past sub string */ - - /* break when we've done count replacements */ - if (--count == 0) break; - } - /* copy any remaining values into output string */ - if (len > 0) - memcpy(new_s, str, len); return out_s; return_same: *out_len = -1; ! return str; } static char replace__doc__[] = ! "replace (str, old, new[, maxsplit]) -> string\n\ ! \n\ ! Return a copy of string str with all occurrences of substring\n\ ! old replaced by new. If the optional argument maxsplit is\n\ ! given, only the first maxsplit occurrences are replaced."; static PyObject * --- 1080,1140 ---- /* find length of output string */ nfound = mymemcnt(str, len, pat, pat_len); ! if (count < 0) ! count = INT_MAX; ! else if (nfound > count) ! nfound = count; if (nfound == 0) goto return_same; + new_len = len + nfound*(sub_len - pat_len); + if (new_len == 0) { + /* Have to allocate something for the caller to free(). */ + out_s = (char *)PyMem_MALLOC(1); + if (out_s == NULL) + return NULL; + out_s[0] = '\0'; + } + else { + assert(new_len > 0); + new_s = (char *)PyMem_MALLOC(new_len); + if (new_s == NULL) + return NULL; + out_s = new_s; ! for (; count > 0 && len > 0; --count) { ! /* find index of next instance of pattern */ ! offset = mymemfind(str, len, pat, pat_len); ! if (offset == -1) ! break; + /* copy non matching part of input string */ + memcpy(new_s, str, offset); + str += offset + pat_len; + len -= offset + pat_len; + + /* copy substitute into the output string */ + new_s += offset; + memcpy(new_s, sub, sub_len); + new_s += sub_len; + } + /* copy any remaining values into output string */ + if (len > 0) + memcpy(new_s, str, len); + } *out_len = new_len; return out_s; return_same: *out_len = -1; ! return (char *)str; /* cast away const */ } static char replace__doc__[] = ! "replace (str, old, new[, maxsplit]) -> string\n" ! "\n" ! "Return a copy of string str with all occurrences of substring\n" ! "old replaced by new. If the optional argument maxsplit is\n" ! "given, only the first maxsplit occurrences are replaced."; static PyObject * *************** *** 1107,1113 **** char *str, *pat,*sub,*new_s; int len,pat_len,sub_len,out_len; ! int count = 0; PyObject *new; if (!PyArg_ParseTuple(args, "t#t#t#|i:replace", &str, &len, &pat, &pat_len, &sub, &sub_len, --- 1143,1150 ---- char *str, *pat,*sub,*new_s; int len,pat_len,sub_len,out_len; ! int count = -1; PyObject *new; + WARN; if (!PyArg_ParseTuple(args, "t#t#t#|i:replace", &str, &len, &pat, &pat_len, &sub, &sub_len, *************** *** 1118,1121 **** --- 1155,1164 ---- return NULL; } + /* CAUTION: strop treats a replace count of 0 as infinity, unlke + * current (2.1) string.py and string methods. Preserve this for + * ... well, hard to say for what . + */ + if (count == 0) + count = -1; new_s = mymemreplace(str,len,pat,pat_len,sub,sub_len,count,&out_len); if (new_s == NULL) { *************** *** 1140,1185 **** static PyMethodDef strop_methods[] = { ! {"atof", strop_atof, ! METH_VARARGS, atof__doc__}, ! {"atoi", strop_atoi, ! METH_VARARGS, atoi__doc__}, ! {"atol", strop_atol, ! METH_VARARGS, atol__doc__}, ! {"capitalize", strop_capitalize, ! METH_OLDARGS, capitalize__doc__}, ! {"count", strop_count, ! METH_VARARGS, count__doc__}, ! {"expandtabs", strop_expandtabs, ! METH_VARARGS, expandtabs__doc__}, ! {"find", strop_find, ! METH_VARARGS, find__doc__}, ! {"join", strop_joinfields, ! METH_VARARGS, joinfields__doc__}, ! {"joinfields", strop_joinfields, ! METH_VARARGS, joinfields__doc__}, ! {"lstrip", strop_lstrip, ! METH_OLDARGS, lstrip__doc__}, ! {"lower", strop_lower, ! METH_OLDARGS, lower__doc__}, ! {"maketrans", strop_maketrans, ! METH_VARARGS, maketrans__doc__}, ! {"replace", strop_replace, ! METH_VARARGS, replace__doc__}, ! {"rfind", strop_rfind, ! METH_VARARGS, rfind__doc__}, ! {"rstrip", strop_rstrip, ! METH_OLDARGS, rstrip__doc__}, ! {"split", strop_splitfields, ! METH_VARARGS, splitfields__doc__}, ! {"splitfields", strop_splitfields, ! METH_VARARGS, splitfields__doc__}, ! {"strip", strop_strip, ! METH_OLDARGS, strip__doc__}, ! {"swapcase", strop_swapcase, ! METH_OLDARGS, swapcase__doc__}, ! {"translate", strop_translate, ! METH_VARARGS, translate__doc__}, ! {"upper", strop_upper, ! METH_OLDARGS, upper__doc__}, {NULL, NULL} /* sentinel */ }; --- 1183,1207 ---- static PyMethodDef strop_methods[] = { ! {"atof", strop_atof, METH_VARARGS, atof__doc__}, ! {"atoi", strop_atoi, METH_VARARGS, atoi__doc__}, ! {"atol", strop_atol, METH_VARARGS, atol__doc__}, ! {"capitalize", strop_capitalize, METH_OLDARGS, capitalize__doc__}, ! {"count", strop_count, METH_VARARGS, count__doc__}, ! {"expandtabs", strop_expandtabs, METH_VARARGS, expandtabs__doc__}, ! {"find", strop_find, METH_VARARGS, find__doc__}, ! {"join", strop_joinfields, METH_VARARGS, joinfields__doc__}, ! {"joinfields", strop_joinfields, METH_VARARGS, joinfields__doc__}, ! {"lstrip", strop_lstrip, METH_OLDARGS, lstrip__doc__}, ! {"lower", strop_lower, METH_OLDARGS, lower__doc__}, ! {"maketrans", strop_maketrans, METH_VARARGS, maketrans__doc__}, ! {"replace", strop_replace, METH_VARARGS, replace__doc__}, ! {"rfind", strop_rfind, METH_VARARGS, rfind__doc__}, ! {"rstrip", strop_rstrip, METH_OLDARGS, rstrip__doc__}, ! {"split", strop_splitfields, METH_VARARGS, splitfields__doc__}, ! {"splitfields", strop_splitfields, METH_VARARGS, splitfields__doc__}, ! {"strip", strop_strip, METH_OLDARGS, strip__doc__}, ! {"swapcase", strop_swapcase, METH_OLDARGS, swapcase__doc__}, ! {"translate", strop_translate, METH_VARARGS, translate__doc__}, ! {"upper", strop_upper, METH_OLDARGS, upper__doc__}, {NULL, NULL} /* sentinel */ }; Index: structmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/structmodule.c,v retrieving revision 2.42 retrieving revision 2.42.4.1 diff -C2 -r2.42 -r2.42.4.1 *** structmodule.c 2001/04/08 23:39:38 2.42 --- structmodule.c 2001/07/07 22:55:29 2.42.4.1 *************** *** 10,19 **** and also as format strings to describe the layout of data in the C struct.\n\ \n\ ! The optional first format char indicates byte ordering and alignment:\n\ ! @: native w/native alignment(default)\n\ ! =: native w/standard alignment\n\ ! <: little-endian, std. alignment\n\ ! >: big-endian, std. alignment\n\ ! !: network, std (same as >)\n\ \n\ The remaining chars indicate types of args and must match exactly;\n\ --- 10,19 ---- and also as format strings to describe the layout of data in the C struct.\n\ \n\ ! The optional first format char indicates byte order, size and alignment:\n\ ! @: native order, size & alignment (default)\n\ ! =: native order, std. size & alignment\n\ ! <: little-endian, std. size & alignment\n\ ! >: big-endian, std. size & alignment\n\ ! !: same as >\n\ \n\ The remaining chars indicate types of args and must match exactly;\n\ *************** *** 23,29 **** l:long; L:unsigned long; f:float; d:double.\n\ Special cases (preceding decimal count indicates length):\n\ ! s:string (array of char); p: pascal string (w. count byte).\n\ Special case (only available in native format):\n\ P:an integer type that is wide enough to hold a pointer.\n\ Whitespace between formats is ignored.\n\ \n\ --- 23,31 ---- l:long; L:unsigned long; f:float; d:double.\n\ Special cases (preceding decimal count indicates length):\n\ ! s:string (array of char); p: pascal string (with count byte).\n\ Special case (only available in native format):\n\ P:an integer type that is wide enough to hold a pointer.\n\ + Special case (not in native mode unless 'long long' in platform C):\n\ + q:long long; Q:unsigned long long\n\ Whitespace between formats is ignored.\n\ \n\ *************** *** 45,49 **** /* ** XXXX We have a problem here. There are no unique alignment rules ! ** on the PowerPC mac. */ #ifdef __powerc --- 47,51 ---- /* ** XXXX We have a problem here. There are no unique alignment rules ! ** on the PowerPC mac. */ #ifdef __powerc *************** *** 66,69 **** --- 68,78 ---- #define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void *)) + /* We can't support q and Q in native mode unless the compiler does; + in std mode, they're 8 bytes on all platforms. */ + #ifdef HAVE_LONG_LONG + typedef struct { char c; LONG_LONG x; } s_long_long; + #define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(LONG_LONG)) + #endif + #define STRINGIFY(x) #x *************** *** 72,75 **** --- 81,112 ---- #endif + /* Helper to get a PyLongObject by hook or by crook. Caller should decref. */ + + static PyObject * + get_pylong(PyObject *v) + { + PyNumberMethods *m; + + assert(v != NULL); + if (PyInt_Check(v)) + return PyLong_FromLong(PyInt_AS_LONG(v)); + if (PyLong_Check(v)) { + Py_INCREF(v); + return v; + } + m = v->ob_type->tp_as_number; + if (m != NULL && m->nb_long != NULL) { + v = m->nb_long(v); + if (v == NULL) + return NULL; + if (PyLong_Check(v)) + return v; + Py_DECREF(v); + } + PyErr_SetString(StructError, + "cannot convert argument to long"); + return NULL; + } + /* Helper routine to get a Python integer and raise the appropriate error if it isn't one */ *************** *** 107,111 **** --- 144,189 ---- } + #ifdef HAVE_LONG_LONG + + /* Same, but handling native long long. */ + static int + get_longlong(PyObject *v, LONG_LONG *p) + { + LONG_LONG x; + + v = get_pylong(v); + if (v == NULL) + return -1; + assert(PyLong_Check(v)); + x = PyLong_AsLongLong(v); + Py_DECREF(v); + if (x == (LONG_LONG)-1 && PyErr_Occurred()) + return -1; + *p = x; + return 0; + } + + /* Same, but handling native unsigned long long. */ + + static int + get_ulonglong(PyObject *v, unsigned LONG_LONG *p) + { + unsigned LONG_LONG x; + + v = get_pylong(v); + if (v == NULL) + return -1; + assert(PyLong_Check(v)); + x = PyLong_AsUnsignedLongLong(v); + Py_DECREF(v); + if (x == (unsigned LONG_LONG)-1 && PyErr_Occurred()) + return -1; + *p = x; + return 0; + } + + #endif + /* Floating point helpers */ *************** *** 396,399 **** --- 474,488 ---- } formatdef; + /* A large number of small routines follow, with names of the form + + [bln][up]_TYPE + + [bln] distiguishes among big-endian, little-endian and native. + [pu] distiguishes between pack (to struct) and unpack (from struct). + TYPE is one of char, byte, ubyte, etc. + */ + + /* Native mode routines. ****************************************************/ + static PyObject * nu_char(const char *p, const formatdef *f) *************** *** 451,454 **** --- 540,561 ---- } + /* Native mode doesn't support q or Q unless the platform C supports + long long (or, on Windows, __int64). */ + + #ifdef HAVE_LONG_LONG + + static PyObject * + nu_longlong(const char *p, const formatdef *f) + { + return PyLong_FromLongLong(*(LONG_LONG *)p); + } + + static PyObject * + nu_ulonglong(const char *p, const formatdef *f) + { + return PyLong_FromUnsignedLongLong(*(unsigned LONG_LONG *)p); + } + #endif + static PyObject * nu_float(const char *p, const formatdef *f) *************** *** 586,590 **** --- 693,720 ---- } + #ifdef HAVE_LONG_LONG + static int + np_longlong(char *p, PyObject *v, const formatdef *f) + { + LONG_LONG x; + if (get_longlong(v, &x) < 0) + return -1; + * (LONG_LONG *)p = x; + return 0; + } + + static int + np_ulonglong(char *p, PyObject *v, const formatdef *f) + { + unsigned LONG_LONG x; + if (get_ulonglong(v, &x) < 0) + return -1; + * (unsigned LONG_LONG *)p = x; + return 0; + } + #endif + + static int np_float(char *p, PyObject *v, const formatdef *f) { *************** *** 643,649 **** --- 773,785 ---- {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double}, {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p}, + #ifdef HAVE_LONG_LONG + {'q', sizeof(LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong}, + {'Q', sizeof(LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong}, + #endif {0} }; + /* Big-endian routines. *****************************************************/ + static PyObject * bu_int(const char *p, const formatdef *f) *************** *** 675,678 **** --- 811,832 ---- static PyObject * + bu_longlong(const char *p, const formatdef *f) + { + return _PyLong_FromByteArray((const unsigned char *)p, + 8, + 0, /* little-endian */ + 1 /* signed */); + } + + static PyObject * + bu_ulonglong(const char *p, const formatdef *f) + { + return _PyLong_FromByteArray((const unsigned char *)p, + 8, + 0, /* little-endian */ + 0 /* signed */); + } + + static PyObject * bu_float(const char *p, const formatdef *f) { *************** *** 717,720 **** --- 871,906 ---- static int + bp_longlong(char *p, PyObject *v, const formatdef *f) + { + int res; + v = get_pylong(v); + if (v == NULL) + return -1; + res = _PyLong_AsByteArray((PyLongObject *)v, + (unsigned char *)p, + 8, + 0, /* little_endian */ + 1 /* signed */); + Py_DECREF(v); + return res; + } + + static int + bp_ulonglong(char *p, PyObject *v, const formatdef *f) + { + int res; + v = get_pylong(v); + if (v == NULL) + return -1; + res = _PyLong_AsByteArray((PyLongObject *)v, + (unsigned char *)p, + 8, + 0, /* little_endian */ + 0 /* signed */); + Py_DECREF(v); + return res; + } + + static int bp_float(char *p, PyObject *v, const formatdef *f) { *************** *** 753,756 **** --- 939,944 ---- {'l', 4, 0, bu_int, bp_int}, {'L', 4, 0, bu_uint, bp_uint}, + {'q', 8, 0, bu_longlong, bp_longlong}, + {'Q', 8, 0, bu_ulonglong, bp_ulonglong}, {'f', 4, 0, bu_float, bp_float}, {'d', 8, 0, bu_double, bp_double}, *************** *** 758,761 **** --- 946,951 ---- }; + /* Little-endian routines. *****************************************************/ + static PyObject * lu_int(const char *p, const formatdef *f) *************** *** 787,790 **** --- 977,998 ---- static PyObject * + lu_longlong(const char *p, const formatdef *f) + { + return _PyLong_FromByteArray((const unsigned char *)p, + 8, + 1, /* little-endian */ + 1 /* signed */); + } + + static PyObject * + lu_ulonglong(const char *p, const formatdef *f) + { + return _PyLong_FromByteArray((const unsigned char *)p, + 8, + 1, /* little-endian */ + 0 /* signed */); + } + + static PyObject * lu_float(const char *p, const formatdef *f) { *************** *** 829,832 **** --- 1037,1072 ---- static int + lp_longlong(char *p, PyObject *v, const formatdef *f) + { + int res; + v = get_pylong(v); + if (v == NULL) + return -1; + res = _PyLong_AsByteArray((PyLongObject*)v, + (unsigned char *)p, + 8, + 1, /* little_endian */ + 1 /* signed */); + Py_DECREF(v); + return res; + } + + static int + lp_ulonglong(char *p, PyObject *v, const formatdef *f) + { + int res; + v = get_pylong(v); + if (v == NULL) + return -1; + res = _PyLong_AsByteArray((PyLongObject*)v, + (unsigned char *)p, + 8, + 1, /* little_endian */ + 0 /* signed */); + Py_DECREF(v); + return res; + } + + static int lp_float(char *p, PyObject *v, const formatdef *f) { *************** *** 865,868 **** --- 1105,1110 ---- {'l', 4, 0, lu_int, lp_int}, {'L', 4, 0, lu_uint, lp_uint}, + {'q', 8, 0, lu_longlong, lp_longlong}, + {'Q', 8, 0, lu_ulonglong, lp_ulonglong}, {'f', 4, 0, lu_float, lp_float}, {'d', 8, 0, lu_double, lp_double}, *************** *** 961,965 **** else num = 1; ! e = getentry(c, f); if (e == NULL) --- 1203,1207 ---- else num = 1; ! e = getentry(c, f); if (e == NULL) *************** *** 1021,1025 **** (n = PyTuple_Size(args)) < 1) { ! PyErr_SetString(PyExc_TypeError, "struct.pack requires at least one argument"); return NULL; --- 1263,1267 ---- (n = PyTuple_Size(args)) < 1) { ! PyErr_SetString(PyExc_TypeError, "struct.pack requires at least one argument"); return NULL; Index: termios.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/termios.c,v retrieving revision 2.24 retrieving revision 2.24.4.1 diff -C2 -r2.24 -r2.24.4.1 *** termios.c 2001/04/11 20:57:57 2.24 --- termios.c 2001/07/07 22:55:30 2.24.4.1 *************** *** 6,42 **** #include ! /* XXX Some systems need this to get all the symbols, while ! this breaks for others. #include - */ static char termios__doc__[] = "\ This module provides an interface to the Posix calls for tty I/O control.\n\ For a complete description of these calls, see the Posix or Unix manual\n\ pages. It is only available for those Unix versions that support Posix\n\ ! termios style tty I/O control (and then only if configured at installation\n\ ! time).\n\ \n\ All functions in this module take a file descriptor fd as their first\n\ ! argument. This must be an integer file descriptor, such as returned by\n\ ! sys.stdin.fileno()."; ! ! ! #ifdef __BEOS__ ! #include ! #endif - #define BAD "bad termios argument" - static PyObject *TermiosError; ! /* termios = tcgetattr(fd) ! termios is ! [iflag, oflag, cflag, lflag, ispeed, ospeed, [cc[0], ..., cc[NCCS]]] ! Return the attributes of the terminal device. */ static char termios_tcgetattr__doc__[] = "\ tcgetattr(fd) -> list_of_attrs\n\ Get the tty attributes for file descriptor fd, as follows:\n\ [iflag, oflag, cflag, lflag, ispeed, ospeed, cc] where cc is a list\n\ --- 6,55 ---- #include ! #ifdef __osf__ ! /* On OSF, sys/ioctl.h requires that struct termio already be defined, ! * so this needs to be included first on that platform. */ ! #include ! #endif #include + #ifdef __BEOS__ + #include + #endif + + /* HP-UX requires that this be included to pick up MDCD, MCTS, MDSR, + * MDTR, MRI, and MRTS (appearantly used internally by some things + * defined as macros; these are not used here directly). + */ + #ifdef HAVE_SYS_MODEM_H + #include + #endif + static char termios__doc__[] = "\ This module provides an interface to the Posix calls for tty I/O control.\n\ For a complete description of these calls, see the Posix or Unix manual\n\ pages. It is only available for those Unix versions that support Posix\n\ ! termios style tty I/O control.\n\ \n\ All functions in this module take a file descriptor fd as their first\n\ ! argument. This can be an integer file descriptor, such as returned by\n\ ! sys.stdin.fileno(), or a file object, such as sys.stdin itself."; static PyObject *TermiosError; ! static int fdconv(PyObject* obj, void* p) ! { ! int fd; ! fd = PyObject_AsFileDescriptor(obj); ! if (fd >= 0) { ! *(int*)p = fd; ! return 1; ! } ! return 0; ! } static char termios_tcgetattr__doc__[] = "\ tcgetattr(fd) -> list_of_attrs\n\ + \n\ Get the tty attributes for file descriptor fd, as follows:\n\ [iflag, oflag, cflag, lflag, ispeed, ospeed, cc] where cc is a list\n\ *************** *** 58,62 **** char ch; ! if (!PyArg_Parse(args, "i", &fd)) return NULL; --- 71,76 ---- char ch; ! if (!PyArg_ParseTuple(args, "O&:tcgetattr", ! fdconv, (void*)&fd)) return NULL; *************** *** 112,120 **** } - /* tcsetattr(fd, when, termios) - Set the attributes of the terminal device. */ - static char termios_tcsetattr__doc__[] = "\ tcsetattr(fd, when, attributes) -> None\n\ Set the tty attributes for file descriptor fd.\n\ The attributes to be set are taken from the attributes argument, which\n\ --- 126,132 ---- } static char termios_tcsetattr__doc__[] = "\ tcsetattr(fd, when, attributes) -> None\n\ + \n\ Set the tty attributes for file descriptor fd.\n\ The attributes to be set are taken from the attributes argument, which\n\ *************** *** 134,141 **** int i; ! if (!PyArg_Parse(args, "(iiO)", &fd, &when, &term)) return NULL; if (!PyList_Check(term) || PyList_Size(term) != 7) { ! PyErr_SetString(PyExc_TypeError, BAD); return NULL; } --- 146,155 ---- int i; ! if (!PyArg_ParseTuple(args, "O&iO:tcsetattr", ! fdconv, &fd, &when, &term)) return NULL; if (!PyList_Check(term) || PyList_Size(term) != 7) { ! PyErr_SetString(PyExc_TypeError, ! "tcsetattr, arg 3: must be 7 element list"); return NULL; } *************** *** 155,159 **** if (!PyList_Check(cc) || PyList_Size(cc) != NCCS) { ! PyErr_SetString(PyExc_TypeError, BAD); return NULL; } --- 169,175 ---- if (!PyList_Check(cc) || PyList_Size(cc) != NCCS) { ! PyErr_Format(PyExc_TypeError, ! "tcsetattr: attributes[6] must be %d element list", ! NCCS); return NULL; } *************** *** 167,171 **** mode.c_cc[i] = (cc_t) PyInt_AsLong(v); else { ! PyErr_SetString(PyExc_TypeError, BAD); return NULL; } --- 183,188 ---- mode.c_cc[i] = (cc_t) PyInt_AsLong(v); else { ! PyErr_SetString(PyExc_TypeError, ! "tcsetattr: elements of attributes must be characters or integers"); return NULL; } *************** *** 183,194 **** } - /* tcsendbreak(fd, duration) - Generate a break condition. */ - static char termios_tcsendbreak__doc__[] = "\ tcsendbreak(fd, duration) -> None\n\ Send a break on file descriptor fd.\n\ ! A zero duration sends a break for 0.25-0.5 seconds; a nonzero duration \n\ ! has a system dependent meaning. "; static PyObject * --- 200,209 ---- } static char termios_tcsendbreak__doc__[] = "\ tcsendbreak(fd, duration) -> None\n\ + \n\ Send a break on file descriptor fd.\n\ ! A zero duration sends a break for 0.25-0.5 seconds; a nonzero duration\n\ ! has a system dependent meaning."; static PyObject * *************** *** 197,201 **** int fd, duration; ! if (!PyArg_Parse(args, "(ii)", &fd, &duration)) return NULL; if (tcsendbreak(fd, duration) == -1) --- 212,217 ---- int fd, duration; ! if (!PyArg_ParseTuple(args, "O&i:tcsendbreak", ! fdconv, &fd, &duration)) return NULL; if (tcsendbreak(fd, duration) == -1) *************** *** 206,216 **** } - /* tcdrain(fd) - Wait until all queued output to the terminal has been - transmitted. */ - static char termios_tcdrain__doc__[] = "\ tcdrain(fd) -> None\n\ ! Wait until all output written to file descriptor fd has been transmitted. "; static PyObject * --- 222,229 ---- } static char termios_tcdrain__doc__[] = "\ tcdrain(fd) -> None\n\ ! \n\ ! Wait until all output written to file descriptor fd has been transmitted."; static PyObject * *************** *** 219,223 **** int fd; ! if (!PyArg_Parse(args, "i", &fd)) return NULL; if (tcdrain(fd) == -1) --- 232,237 ---- int fd; ! if (!PyArg_ParseTuple(args, "O&:tcdrain", ! fdconv, &fd)) return NULL; if (tcdrain(fd) == -1) *************** *** 228,237 **** } - /* tcflush(fd, queue) - Clear the input and/or output queues associated with - the terminal. */ - static char termios_tcflush__doc__[] = "\ tcflush(fd, queue) -> None\n\ Discard queued data on file descriptor fd.\n\ The queue selector specifies which queue: termios.TCIFLUSH for the input\n\ --- 242,248 ---- } static char termios_tcflush__doc__[] = "\ tcflush(fd, queue) -> None\n\ + \n\ Discard queued data on file descriptor fd.\n\ The queue selector specifies which queue: termios.TCIFLUSH for the input\n\ *************** *** 244,248 **** int fd, queue; ! if (!PyArg_Parse(args, "(ii)", &fd, &queue)) return NULL; if (tcflush(fd, queue) == -1) --- 255,260 ---- int fd, queue; ! if (!PyArg_ParseTuple(args, "O&i:tcflush", ! fdconv, &fd, &queue)) return NULL; if (tcflush(fd, queue) == -1) *************** *** 253,262 **** } - /* tcflow(fd, action) - Perform operations relating to XON/XOFF flow control on - the terminal. */ - static char termios_tcflow__doc__[] = "\ tcflow(fd, action) -> None\n\ Suspend or resume input or output on file descriptor fd.\n\ The action argument can be termios.TCOOFF to suspend output,\n\ --- 265,271 ---- } static char termios_tcflow__doc__[] = "\ tcflow(fd, action) -> None\n\ + \n\ Suspend or resume input or output on file descriptor fd.\n\ The action argument can be termios.TCOOFF to suspend output,\n\ *************** *** 269,273 **** int fd, action; ! if (!PyArg_Parse(args, "(ii)", &fd, &action)) return NULL; if (tcflow(fd, action) == -1) --- 278,283 ---- int fd, action; ! if (!PyArg_ParseTuple(args, "O&i:tcflow", ! fdconv, &fd, &action)) return NULL; if (tcflow(fd, action) == -1) *************** *** 281,295 **** { {"tcgetattr", termios_tcgetattr, ! METH_OLDARGS, termios_tcgetattr__doc__}, {"tcsetattr", termios_tcsetattr, ! METH_OLDARGS, termios_tcsetattr__doc__}, {"tcsendbreak", termios_tcsendbreak, ! METH_OLDARGS, termios_tcsendbreak__doc__}, {"tcdrain", termios_tcdrain, ! METH_OLDARGS, termios_tcdrain__doc__}, {"tcflush", termios_tcflush, ! METH_OLDARGS, termios_tcflush__doc__}, {"tcflow", termios_tcflow, ! METH_OLDARGS, termios_tcflow__doc__}, {NULL, NULL} }; --- 291,305 ---- { {"tcgetattr", termios_tcgetattr, ! METH_VARARGS, termios_tcgetattr__doc__}, {"tcsetattr", termios_tcsetattr, ! METH_VARARGS, termios_tcsetattr__doc__}, {"tcsendbreak", termios_tcsendbreak, ! METH_VARARGS, termios_tcsendbreak__doc__}, {"tcdrain", termios_tcdrain, ! METH_VARARGS, termios_tcdrain__doc__}, {"tcflush", termios_tcflush, ! METH_VARARGS, termios_tcflush__doc__}, {"tcflow", termios_tcflow, ! METH_VARARGS, termios_tcflow__doc__}, {NULL, NULL} }; *************** *** 370,374 **** --- 380,386 ---- {"IXANY", IXANY}, {"IXOFF", IXOFF}, + #ifdef IMAXBEL {"IMAXBEL", IMAXBEL}, + #endif /* struct termios.c_oflag constants */ *************** *** 496,505 **** --- 508,523 ---- {"ECHOK", ECHOK}, {"ECHONL", ECHONL}, + #ifdef ECHOCTL {"ECHOCTL", ECHOCTL}, + #endif #ifdef ECHOPRT {"ECHOPRT", ECHOPRT}, #endif + #ifdef ECHOKE {"ECHOKE", ECHOKE}, + #endif + #ifdef FLUSHO {"FLUSHO", FLUSHO}, + #endif {"NOFLSH", NOFLSH}, {"TOSTOP", TOSTOP}, *************** *** 527,534 **** --- 545,560 ---- {"VSUSP", VSUSP}, {"VEOL", VEOL}, + #ifdef VREPRINT {"VREPRINT", VREPRINT}, + #endif + #ifdef VDISCARD {"VDISCARD", VDISCARD}, + #endif + #ifdef VWERASE {"VWERASE", VWERASE}, + #endif + #ifdef VLNEXT {"VLNEXT", VLNEXT}, + #endif {"VEOL2", VEOL2}, Index: timemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/timemodule.c,v retrieving revision 2.110 retrieving revision 2.110.4.1 diff -C2 -r2.110 -r2.110.4.1 *** timemodule.c 2001/04/10 22:07:07 2.110 --- timemodule.c 2001/07/07 22:55:30 2.110.4.1 *************** *** 42,50 **** #ifdef MS_WINDOWS #include ! #ifdef MS_WIN16 /* These overrides not needed for Win32 */ #define timezone _timezone #define tzname _tzname #define daylight _daylight #define altzone _altzone #endif /* MS_WIN16 */ --- 42,52 ---- #ifdef MS_WINDOWS #include ! #if defined(MS_WIN16) || defined(__BORLANDC__) /* These overrides not needed for Win32 */ #define timezone _timezone #define tzname _tzname #define daylight _daylight + #endif /* MS_WIN16 || __BORLANDC__ */ + #ifdef MS_WIN16 #define altzone _altzone #endif /* MS_WIN16 */ *************** *** 52,56 **** #endif /* !__WATCOMC__ || __QNX__ */ ! #if defined(MS_WIN32) && !defined(MS_WIN64) /* Win32 has better clock replacement XXX Win64 does not yet, but might when the platform matures. */ --- 54,58 ---- #endif /* !__WATCOMC__ || __QNX__ */ ! #if defined(MS_WIN32) && !defined(MS_WIN64) && !defined(__BORLANDC__) /* Win32 has better clock replacement XXX Win64 does not yet, but might when the platform matures. */ *************** *** 147,151 **** #endif /* HAVE_CLOCK */ ! #if defined(MS_WIN32) && !defined(MS_WIN64) /* Due to Mark Hammond */ static PyObject * --- 149,153 ---- #endif /* HAVE_CLOCK */ ! #if defined(MS_WIN32) && !defined(MS_WIN64) && !defined(__BORLANDC__) /* Due to Mark Hammond */ static PyObject * Index: xreadlinesmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/xreadlinesmodule.c,v retrieving revision 1.5 retrieving revision 1.5.4.1 diff -C2 -r1.5 -r1.5.4.1 *** xreadlinesmodule.c 2001/03/23 18:30:19 1.5 --- xreadlinesmodule.c 2001/07/07 22:55:30 1.5.4.1 *************** *** 55,65 **** static PyObject * ! xreadlines_item(PyXReadlinesObject *a, int i) { - if (i != a->abslineno) { - PyErr_SetString(PyExc_RuntimeError, - "xreadlines object accessed out of order"); - return NULL; - } if (a->lineno >= a->lineslen) { Py_XDECREF(a->lines); --- 55,60 ---- static PyObject * ! xreadlines_common(PyXReadlinesObject *a) { if (a->lineno >= a->lineslen) { Py_XDECREF(a->lines); *************** *** 76,79 **** --- 71,129 ---- } + static PyObject * + xreadlines_item(PyXReadlinesObject *a, int i) + { + if (i != a->abslineno) { + PyErr_SetString(PyExc_RuntimeError, + "xreadlines object accessed out of order"); + return NULL; + } + return xreadlines_common(a); + } + + static PyObject * + xreadlines_getiter(PyXReadlinesObject *a) + { + Py_INCREF(a); + return (PyObject *)a; + } + + static PyObject * + xreadlines_iternext(PyXReadlinesObject *a) + { + PyObject *res; + + res = xreadlines_common(a); + if (res == NULL && PyErr_ExceptionMatches(PyExc_IndexError)) + PyErr_Clear(); + return res; + } + + static PyObject * + xreadlines_next(PyXReadlinesObject *a, PyObject *args) + { + PyObject *res; + + if (!PyArg_ParseTuple(args, "")) + return NULL; + res = xreadlines_common(a); + if (res == NULL && PyErr_ExceptionMatches(PyExc_IndexError)) + PyErr_SetObject(PyExc_StopIteration, Py_None); + return res; + } + + static char next_doc[] = "x.next() -> the next line or raise StopIteration"; + + static PyMethodDef xreadlines_methods[] = { + {"next", (PyCFunction)xreadlines_next, METH_VARARGS, next_doc}, + {NULL, NULL} + }; + + static PyObject * + xreadlines_getattr(PyObject *a, char *name) + { + return Py_FindMethod(xreadlines_methods, a, name); + } + static PySequenceMethods xreadlines_as_sequence = { 0, /*sq_length*/ *************** *** 89,112 **** sizeof(PyXReadlinesObject) + PyGC_HEAD_SIZE, 0, ! (destructor)xreadlines_dealloc, /*tp_dealloc*/ ! 0, /*tp_print*/ ! 0, /*tp_getattr*/ ! 0, /*tp_setattr*/ ! 0, /*tp_compare*/ ! 0, /*tp_repr*/ ! 0, /*tp_as_number*/ ! &xreadlines_as_sequence, /*tp_as_sequence*/ ! 0, /*tp_as_mapping*/ ! 0, /*tp_hash*/ ! 0, /*tp_call*/ ! 0, /*tp_str*/ ! 0, /*tp_getattro*/ ! 0, /*tp_setattro*/ ! 0, /*tp_as_buffer*/ ! Py_TPFLAGS_DEFAULT, /*tp_flags*/ ! 0, /* tp_doc */ }; ! static PyMethodDef xreadlines_methods[] = { {"xreadlines", xreadlines, METH_VARARGS, xreadlines_doc}, {NULL, NULL} --- 139,168 ---- sizeof(PyXReadlinesObject) + PyGC_HEAD_SIZE, 0, ! (destructor)xreadlines_dealloc, /* tp_dealloc */ ! 0, /* tp_print */ ! xreadlines_getattr, /* tp_getattr */ ! 0, /* tp_setattr */ ! 0, /* tp_compare */ ! 0, /* tp_repr */ ! 0, /* tp_as_number */ ! &xreadlines_as_sequence, /* tp_as_sequence */ ! 0, /* tp_as_mapping */ ! 0, /* tp_hash */ ! 0, /* tp_call */ ! 0, /* tp_str */ ! 0, /* tp_getattro */ ! 0, /* tp_setattro */ ! 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ ! 0, /* tp_doc */ ! 0, /* tp_traverse */ ! 0, /* tp_clear */ ! 0, /* tp_richcompare */ ! 0, /* tp_weaklistoffset */ ! (getiterfunc)xreadlines_getiter, /* tp_iter */ ! (iternextfunc)xreadlines_iternext, /* tp_iternext */ }; ! static PyMethodDef xreadlines_functions[] = { {"xreadlines", xreadlines, METH_VARARGS, xreadlines_doc}, {NULL, NULL} *************** *** 119,122 **** XReadlinesObject_Type.ob_type = &PyType_Type; ! m = Py_InitModule("xreadlines", xreadlines_methods); } --- 175,178 ---- XReadlinesObject_Type.ob_type = &PyType_Type; ! m = Py_InitModule("xreadlines", xreadlines_functions); } From tim_one@users.sourceforge.net Sat Jul 7 23:55:33 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 15:55:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects abstract.c,2.60.2.4,2.60.2.5 classobject.c,2.127.2.8,2.127.2.9 dictobject.c,2.80.2.14,2.80.2.15 fileobject.c,2.112.2.3,2.112.2.4 floatobject.c,2.81.6.4,2.81.6.5 frameobject.c,2.49.4.4,2.49.4.5 intobject.c,2.56.6.5,2.56.6.6 iterobject.c,1.3.2.2,1.3.2.3 listobject.c,2.92.6.9,2.92.6.10 longobject.c,1.71.6.3,1.71.6.4 object.c,2.124.4.22,2.124.4.23 rangeobject.c,2.24.6.3,2.24.6.4 stringobject.c,2.103.2.6,2.103.2.7 tupleobject.c,2.48.6.3,2.48.6.4 typeobject.c,2.16.8.62,2.16.8.63 unicodectype.c,2.7,2.7.8.1 unicodeobject.c,2.87.2.4,2.87.2.5 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv24450/mergedescr/dist/src/Objects Modified Files: Tag: descr-branch abstract.c classobject.c dictobject.c fileobject.c floatobject.c frameobject.c intobject.c iterobject.c listobject.c longobject.c object.c rangeobject.c stringobject.c tupleobject.c typeobject.c unicodectype.c unicodeobject.c Log Message: Merge of trunk tag date2001-07-06 into descr-branch. Index: abstract.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v retrieving revision 2.60.2.4 retrieving revision 2.60.2.5 diff -C2 -r2.60.2.4 -r2.60.2.5 *** abstract.c 2001/06/11 19:09:46 2.60.2.4 --- abstract.c 2001/07/07 22:55:30 2.60.2.5 *************** *** 1177,1235 **** PySequence_Tuple(PyObject *v) { ! PySequenceMethods *m; if (v == NULL) return null_error(); if (PyTuple_Check(v)) { Py_INCREF(v); return v; } - if (PyList_Check(v)) return PyList_AsTuple(v); - - /* There used to be code for strings here, but tuplifying strings is - not a common activity, so I nuked it. Down with code bloat! */ ! /* Generic sequence object */ ! m = v->ob_type->tp_as_sequence; ! if (m && m->sq_item) { ! int i; ! PyObject *t; ! int n = PySequence_Size(v); ! if (n < 0) ! return NULL; ! t = PyTuple_New(n); ! if (t == NULL) ! return NULL; ! for (i = 0; ; i++) { ! PyObject *item = (*m->sq_item)(v, i); ! if (item == NULL) { ! if (PyErr_ExceptionMatches(PyExc_IndexError)) ! PyErr_Clear(); ! else { ! Py_DECREF(t); ! t = NULL; ! } ! break; ! } ! if (i >= n) { ! if (n < 500) ! n += 10; ! else ! n += 100; ! if (_PyTuple_Resize(&t, n, 0) != 0) ! break; } - PyTuple_SET_ITEM(t, i, item); } ! if (i < n && t != NULL) ! _PyTuple_Resize(&t, i, 0); ! return t; } ! /* None of the above */ ! return type_error("tuple() argument must be a sequence"); } --- 1177,1244 ---- PySequence_Tuple(PyObject *v) { ! PyObject *it; /* iter(v) */ ! int n; /* guess for result tuple size */ ! PyObject *result; ! int j; if (v == NULL) return null_error(); + /* Special-case the common tuple and list cases, for efficiency. */ if (PyTuple_Check(v)) { Py_INCREF(v); return v; } if (PyList_Check(v)) return PyList_AsTuple(v); ! /* Get iterator. */ ! it = PyObject_GetIter(v); ! if (it == NULL) ! return type_error("tuple() argument must support iteration"); ! ! /* Guess result size and allocate space. */ ! n = PySequence_Size(v); ! if (n < 0) { ! PyErr_Clear(); ! n = 10; /* arbitrary */ ! } ! result = PyTuple_New(n); ! if (result == NULL) ! goto Fail; ! ! /* Fill the tuple. */ ! for (j = 0; ; ++j) { ! PyObject *item = PyIter_Next(it); ! if (item == NULL) { ! if (PyErr_Occurred()) ! goto Fail; ! break; ! } ! if (j >= n) { ! if (n < 500) ! n += 10; ! else ! n += 100; ! if (_PyTuple_Resize(&result, n) != 0) { ! Py_DECREF(item); ! goto Fail; } } ! PyTuple_SET_ITEM(result, j, item); } ! /* Cut tuple back if guess was too large. */ ! if (j < n && ! _PyTuple_Resize(&result, j) != 0) ! goto Fail; ! ! Py_DECREF(it); ! return result; ! ! Fail: ! Py_XDECREF(result); ! Py_DECREF(it); ! return NULL; } *************** *** 1237,1243 **** PySequence_List(PyObject *v) { if (v == NULL) return null_error(); ! return PyObject_CallFunction((PyObject *) &PyList_Type, "(O)", v); } --- 1246,1317 ---- PySequence_List(PyObject *v) { + PyObject *it; /* iter(v) */ + PyObject *result; /* result list */ + int n; /* guess for result list size */ + int i; + if (v == NULL) return null_error(); ! ! /* Special-case list(a_list), for speed. */ ! if (PyList_Check(v)) ! return PyList_GetSlice(v, 0, PyList_GET_SIZE(v)); ! ! /* Get iterator. There may be some low-level efficiency to be gained ! * by caching the tp_iternext slot instead of using PyIter_Next() ! * later, but premature optimization is the root etc. ! */ ! it = PyObject_GetIter(v); ! if (it == NULL) ! return NULL; ! ! /* Guess a result list size. */ ! n = -1; /* unknown */ ! if (PySequence_Check(v) && ! v->ob_type->tp_as_sequence->sq_length) { ! n = PySequence_Size(v); ! if (n < 0) ! PyErr_Clear(); ! } ! if (n < 0) ! n = 8; /* arbitrary */ ! result = PyList_New(n); ! if (result == NULL) { ! Py_DECREF(it); ! return NULL; ! } ! ! /* Run iterator to exhaustion. */ ! for (i = 0; ; i++) { ! PyObject *item = PyIter_Next(it); ! if (item == NULL) { ! if (PyErr_Occurred()) { ! Py_DECREF(result); ! result = NULL; ! } ! break; ! } ! if (i < n) ! PyList_SET_ITEM(result, i, item); /* steals ref */ ! else { ! int status = PyList_Append(result, item); ! Py_DECREF(item); /* append creates a new ref */ ! if (status < 0) { ! Py_DECREF(result); ! result = NULL; ! break; ! } ! } ! } ! ! /* Cut back result list if initial guess was too large. */ ! if (i < n && result != NULL) { ! if (PyList_SetSlice(result, i, n, (PyObject *)NULL) != 0) { ! Py_DECREF(result); ! result = NULL; ! } ! } ! Py_DECREF(it); ! return result; } *************** *** 1260,1268 **** } int PySequence_Count(PyObject *s, PyObject *o) { ! int l, i, n, cmp, err; ! PyObject *item; if (s == NULL || o == NULL) { --- 1334,1343 ---- } + /* Return # of times o appears in s. */ int PySequence_Count(PyObject *s, PyObject *o) { ! int n; /* running count of o hits */ ! PyObject *it; /* iter(s) */ if (s == NULL || o == NULL) { *************** *** 1270,1333 **** return -1; } ! ! l = PySequence_Size(s); ! if (l < 0) return -1; n = 0; ! for (i = 0; i < l; i++) { ! item = PySequence_GetItem(s, i); ! if (item == NULL) ! return -1; ! err = PyObject_Cmp(item, o, &cmp); Py_DECREF(item); ! if (err < 0) ! return err; ! if (cmp == 0) n++; } return n; } int ! PySequence_Contains(PyObject *w, PyObject *v) /* v in w */ { ! int i, cmp; ! PyObject *x; ! PySequenceMethods *sq; ! ! if(PyType_HasFeature(w->ob_type, Py_TPFLAGS_HAVE_SEQUENCE_IN)) { ! sq = w->ob_type->tp_as_sequence; ! if(sq != NULL && sq->sq_contains != NULL) ! return (*sq->sq_contains)(w, v); ! } ! ! /* If there is no better way to check whether an item is is contained, ! do it the hard way */ ! sq = w->ob_type->tp_as_sequence; ! if (sq == NULL || sq->sq_item == NULL) { PyErr_SetString(PyExc_TypeError, ! "'in' or 'not in' needs sequence right argument"); return -1; } ! for (i = 0; ; i++) { ! x = (*sq->sq_item)(w, i); ! if (x == NULL) { ! if (PyErr_ExceptionMatches(PyExc_IndexError)) { ! PyErr_Clear(); ! break; ! } ! return -1; } ! cmp = PyObject_RichCompareBool(v, x, Py_EQ); ! Py_XDECREF(x); ! if (cmp > 0) ! return 1; ! if (cmp < 0) ! return -1; } ! return 0; } --- 1345,1429 ---- return -1; } ! ! it = PyObject_GetIter(s); ! if (it == NULL) { ! type_error(".count() requires iterable argument"); return -1; + } n = 0; ! for (;;) { ! int cmp; ! PyObject *item = PyIter_Next(it); ! if (item == NULL) { ! if (PyErr_Occurred()) ! goto Fail; ! break; ! } ! cmp = PyObject_RichCompareBool(o, item, Py_EQ); Py_DECREF(item); ! if (cmp < 0) ! goto Fail; ! if (cmp > 0) { ! if (n == INT_MAX) { ! PyErr_SetString(PyExc_OverflowError, ! "count exceeds C int size"); ! goto Fail; ! } n++; + } } + Py_DECREF(it); return n; + + Fail: + Py_DECREF(it); + return -1; } + /* Return -1 if error; 1 if ob in seq; 0 if ob not in seq. + * Always uses the iteration protocol, and only Py_EQ comparison. + */ int ! _PySequence_IterContains(PyObject *seq, PyObject *ob) { ! int result; ! PyObject *it = PyObject_GetIter(seq); ! if (it == NULL) { PyErr_SetString(PyExc_TypeError, ! "'in' or 'not in' needs iterable right argument"); return -1; } ! for (;;) { ! int cmp; ! PyObject *item = PyIter_Next(it); ! if (item == NULL) { ! result = PyErr_Occurred() ? -1 : 0; ! break; } ! cmp = PyObject_RichCompareBool(ob, item, Py_EQ); ! Py_DECREF(item); ! if (cmp == 0) ! continue; ! result = cmp > 0 ? 1 : -1; ! break; } + Py_DECREF(it); + return result; + } ! /* Return -1 if error; 1 if ob in seq; 0 if ob not in seq. ! * Use sq_contains if possible, else defer to _PySequence_IterContains(). ! */ ! int ! PySequence_Contains(PyObject *seq, PyObject *ob) ! { ! if (PyType_HasFeature(seq->ob_type, Py_TPFLAGS_HAVE_SEQUENCE_IN)) { ! PySequenceMethods *sqm = seq->ob_type->tp_as_sequence; ! if (sqm != NULL && sqm->sq_contains != NULL) ! return (*sqm->sq_contains)(seq, ob); ! } ! return _PySequence_IterContains(seq, ob); } Index: classobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v retrieving revision 2.127.2.8 retrieving revision 2.127.2.9 diff -C2 -r2.127.2.8 -r2.127.2.9 *** classobject.c 2001/07/03 09:56:52 2.127.2.8 --- classobject.c 2001/07/07 22:55:30 2.127.2.9 *************** *** 1165,1173 **** } ! static int instance_contains(PyInstanceObject *inst, PyObject *member) { static PyObject *__contains__; ! PyObject *func, *arg, *res; ! int ret; if(__contains__ == NULL) { --- 1165,1177 ---- } ! static int ! instance_contains(PyInstanceObject *inst, PyObject *member) { static PyObject *__contains__; ! PyObject *func; ! ! /* Try __contains__ first. ! * If that can't be done, try iterator-based searching. ! */ if(__contains__ == NULL) { *************** *** 1177,1219 **** } func = instance_getattr(inst, __contains__); ! if(func == NULL) { ! /* fall back to previous behavior */ ! int i, cmp_res; ! ! if(!PyErr_ExceptionMatches(PyExc_AttributeError)) return -1; - PyErr_Clear(); - for(i=0;;i++) { - PyObject *obj = instance_item(inst, i); - int ret = 0; - - if(obj == NULL) { - if(!PyErr_ExceptionMatches(PyExc_IndexError)) - return -1; - PyErr_Clear(); - return 0; - } - if(PyObject_Cmp(obj, member, &cmp_res) == -1) - ret = -1; - if(cmp_res == 0) - ret = 1; - Py_DECREF(obj); - if(ret) - return ret; } ! } ! arg = Py_BuildValue("(O)", member); ! if(arg == NULL) { Py_DECREF(func); ! return -1; } ! res = PyEval_CallObject(func, arg); ! Py_DECREF(func); ! Py_DECREF(arg); ! if(res == NULL) return -1; - ret = PyObject_IsTrue(res); - Py_DECREF(res); - return ret; } --- 1181,1212 ---- } func = instance_getattr(inst, __contains__); ! if (func) { ! PyObject *res; ! int ret; ! PyObject *arg = Py_BuildValue("(O)", member); ! if(arg == NULL) { ! Py_DECREF(func); return -1; } ! res = PyEval_CallObject(func, arg); Py_DECREF(func); ! Py_DECREF(arg); ! if(res == NULL) ! return -1; ! ret = PyObject_IsTrue(res); ! Py_DECREF(res); ! return ret; } ! ! /* Couldn't find __contains__. */ ! if (PyErr_ExceptionMatches(PyExc_AttributeError)) { ! /* Assume the failure was simply due to that there is no ! * __contains__ attribute, and try iterating instead. ! */ ! PyErr_Clear(); ! return _PySequence_IterContains((PyObject *)inst, member); ! } ! else return -1; } *************** *** 1692,1708 **** /* Map rich comparison operators to their __xx__ namesakes */ ! static char *name_op[] = { ! "__lt__", ! "__le__", ! "__eq__", ! "__ne__", ! "__gt__", ! "__ge__", ! }; static PyObject * half_richcompare(PyObject *v, PyObject *w, int op) { - PyObject *name; PyObject *method; PyObject *args; --- 1685,1718 ---- /* Map rich comparison operators to their __xx__ namesakes */ ! #define NAME_OPS 6 ! static PyObject **name_op = NULL; ! ! static int ! init_name_op(void) ! { ! int i; ! char *_name_op[] = { ! "__lt__", ! "__le__", ! "__eq__", ! "__ne__", ! "__gt__", ! "__ge__", ! }; + name_op = (PyObject **)malloc(sizeof(PyObject *) * NAME_OPS); + if (name_op == NULL) + return -1; + for (i = 0; i < NAME_OPS; ++i) { + name_op[i] = PyString_InternFromString(_name_op[i]); + if (name_op[i] == NULL) + return -1; + } + return 0; + } + static PyObject * half_richcompare(PyObject *v, PyObject *w, int op) { PyObject *method; PyObject *args; *************** *** 1710,1727 **** assert(PyInstance_Check(v)); - - name = PyString_InternFromString(name_op[op]); - if (name == NULL) - return NULL; ! method = PyObject_GetAttr(v, name); ! Py_DECREF(name); ! if (method == NULL) { ! if (!PyErr_ExceptionMatches(PyExc_AttributeError)) return NULL; ! PyErr_Clear(); ! res = Py_NotImplemented; ! Py_INCREF(res); ! return res; } --- 1720,1750 ---- assert(PyInstance_Check(v)); ! if (name_op == NULL) { ! if (init_name_op() < 0) return NULL; ! } ! /* If the instance doesn't define an __getattr__ method, use ! instance_getattr2 directly because it will not set an ! exception on failure. */ ! if (((PyInstanceObject *)v)->in_class->cl_getattr == NULL) { ! method = instance_getattr2((PyInstanceObject *)v, ! name_op[op]); ! if (method == NULL) { ! assert(!PyErr_Occurred()); ! res = Py_NotImplemented; ! Py_INCREF(res); ! return res; ! } ! } else { ! method = PyObject_GetAttr(v, name_op[op]); ! if (method == NULL) { ! if (!PyErr_ExceptionMatches(PyExc_AttributeError)) ! return NULL; ! PyErr_Clear(); ! res = Py_NotImplemented; ! Py_INCREF(res); ! return res; ! } } *************** *** 2184,2188 **** (setattrofunc)instancemethod_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, 0, /* tp_doc */ (traverseproc)instancemethod_traverse, /* tp_traverse */ --- 2207,2211 ---- (setattrofunc)instancemethod_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */ 0, /* tp_doc */ (traverseproc)instancemethod_traverse, /* tp_traverse */ Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.80.2.14 retrieving revision 2.80.2.15 diff -C2 -r2.80.2.14 -r2.80.2.15 *** dictobject.c 2001/06/28 16:36:53 2.80.2.14 --- dictobject.c 2001/07/07 22:55:30 2.80.2.15 *************** *** 7,55 **** typedef PyDictObject dictobject; ! /* ! * MINSIZE is the minimum size of a dictionary. ! */ ! ! #define MINSIZE 4 ! ! /* define this out if you don't want conversion statistics on exit */ #undef SHOW_CONVERSION_COUNTS [...1830 lines suppressed...] } ! if (PyDict_Next((PyObject *)(di->di_dict), &di->di_pos, &key, NULL)) { ! Py_INCREF(key); ! return key; } return NULL; --- 1842,1854 ---- static PyObject *dictiter_iternext(dictiterobject *di) { ! PyObject *key, *value; ! if (di->di_used != di->di_dict->ma_used) { PyErr_SetString(PyExc_RuntimeError, "dictionary changed size during iteration"); return NULL; } ! if (PyDict_Next((PyObject *)(di->di_dict), &di->di_pos, &key, &value)) { ! return (*di->di_select)(key, value); } return NULL; Index: fileobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.112.2.3 retrieving revision 2.112.2.4 diff -C2 -r2.112.2.3 -r2.112.2.4 *** fileobject.c 2001/06/06 14:27:54 2.112.2.3 --- fileobject.c 2001/07/07 22:55:30 2.112.2.4 *************** *** 1285,1300 **** static PyObject * ! file_getiter(PyFileObject *f) { ! static PyObject *es; ! PyObject *iter; ! PyObject *rl = Py_FindMethod(file_methods, (PyObject *)f, "readline"); ! if (rl == NULL) ! return NULL; ! if (es == NULL) ! es = PyString_FromString(""); ! iter = PyCallIter_New(rl, es); ! Py_DECREF(rl); ! return iter; } --- 1285,1291 ---- static PyObject * ! file_getiter(PyObject *f) { ! return PyObject_CallMethod(f, "xreadlines", ""); } *************** *** 1326,1330 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)file_getiter, /* tp_iter */ 0, /* tp_iternext */ file_methods, /* tp_methods */ --- 1317,1321 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! file_getiter, /* tp_iter */ 0, /* tp_iternext */ file_methods, /* tp_methods */ Index: floatobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v retrieving revision 2.81.6.4 retrieving revision 2.81.6.5 diff -C2 -r2.81.6.4 -r2.81.6.5 *** floatobject.c 2001/06/14 01:01:16 2.81.6.4 --- floatobject.c 2001/07/07 22:55:30 2.81.6.5 *************** *** 312,315 **** --- 312,321 ---- } + void + PyFloat_AsReprString(char *buf, PyFloatObject *v) + { + PyFloat_AsStringEx(buf, v, PREC_REPR); + } + /* ARGSUSED */ static int Index: frameobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/frameobject.c,v retrieving revision 2.49.4.4 retrieving revision 2.49.4.5 diff -C2 -r2.49.4.4 -r2.49.4.5 *** frameobject.c 2001/06/11 18:40:38 2.49.4.4 --- frameobject.c 2001/07/07 22:55:30 2.49.4.5 *************** *** 66,69 **** --- 66,70 ---- int i, slots; PyObject **fastlocals; + PyObject **p; Py_TRASHCAN_SAFE_BEGIN(f) *************** *** 75,78 **** --- 76,85 ---- } + /* Free stack */ + if (f->f_stacktop != NULL) { + for (p = f->f_valuestack; p < f->f_stacktop; p++) + Py_XDECREF(*p); + } + Py_XDECREF(f->f_back); Py_XDECREF(f->f_code); *************** *** 239,242 **** --- 246,250 ---- f->f_valuestack = f->f_localsplus + (f->f_nlocals + ncells + nfrees); + f->f_stacktop = f->f_valuestack; return f; *************** *** 301,310 **** Py_XINCREF(value); if (deref) { ! if (value) { if (PyCell_Set(values[j], value) < 0) PyErr_Clear(); - } else if (clear) { - Py_XDECREF(values[j]); - values[j] = value; } } else if (value != NULL || clear) { --- 309,315 ---- Py_XINCREF(value); if (deref) { ! if (value || clear) { if (PyCell_Set(values[j], value) < 0) PyErr_Clear(); } } else if (value != NULL || clear) { *************** *** 388,395 **** dict_to_map(f->f_code->co_cellvars, PyTuple_GET_SIZE(f->f_code->co_cellvars), ! locals, fast, 1, clear); dict_to_map(f->f_code->co_freevars, PyTuple_GET_SIZE(f->f_code->co_freevars), ! locals, fast, 1, clear); } PyErr_Restore(error_type, error_value, error_traceback); --- 393,400 ---- dict_to_map(f->f_code->co_cellvars, PyTuple_GET_SIZE(f->f_code->co_cellvars), ! locals, fast + f->f_nlocals, 1, clear); dict_to_map(f->f_code->co_freevars, PyTuple_GET_SIZE(f->f_code->co_freevars), ! locals, fast + f->f_nlocals + f->f_ncells, 1, clear); } PyErr_Restore(error_type, error_value, error_traceback); Index: intobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v retrieving revision 2.56.6.5 retrieving revision 2.56.6.6 diff -C2 -r2.56.6.5 -r2.56.6.6 *** intobject.c 2001/06/14 00:53:34 2.56.6.5 --- intobject.c 2001/07/07 22:55:30 2.56.6.6 *************** *** 435,470 **** static int ! i_divmod(register long xi, register long yi, long *p_xdivy, long *p_xmody) { long xdivy, xmody; ! if (yi == 0) { PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero"); return -1; } ! if (yi < 0) { ! if (xi < 0) { ! if (yi == -1 && -xi < 0) { ! /* most negative / -1 */ ! err_ovf("integer division"); ! return -1; ! } ! xdivy = -xi / -yi; ! } ! else ! xdivy = - (xi / -yi); ! } ! else { ! if (xi < 0) ! xdivy = - (-xi / yi); ! else ! xdivy = xi / yi; } ! xmody = xi - xdivy*yi; ! if ((xmody < 0 && yi > 0) || (xmody > 0 && yi < 0)) { ! xmody += yi; ! xdivy -= 1; } *p_xdivy = xdivy; --- 435,464 ---- static int ! i_divmod(register long x, register long y, long *p_xdivy, long *p_xmody) { long xdivy, xmody; ! if (y == 0) { PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero"); return -1; } ! /* (-sys.maxint-1)/-1 is the only overflow case. */ ! if (y == -1 && x < 0 && x == -x) { ! err_ovf("integer division"); ! return -1; } ! xdivy = x / y; ! xmody = x - xdivy * y; ! /* If the signs of x and y differ, and the remainder is non-0, ! * C89 doesn't define whether xdivy is now the floor or the ! * ceiling of the infinitely precise quotient. We want the floor, ! * and we have it iff the remainder's sign matches y's. ! */ ! if (xmody && ((y ^ xmody) < 0) /* i.e. and signs differ */) { ! xmody += y; ! --xdivy; ! assert(xmody && ((y ^ xmody) >= 0)); } *p_xdivy = xdivy; Index: iterobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/iterobject.c,v retrieving revision 1.3.2.2 retrieving revision 1.3.2.3 diff -C2 -r1.3.2.2 -r1.3.2.3 *** iterobject.c 2001/06/06 14:27:54 1.3.2.2 --- iterobject.c 2001/07/07 22:55:30 1.3.2.3 *************** *** 46,50 **** } - /* Return (value, 0) if OK; (NULL, 0) at end; (NULL, -1) if exception */ static PyObject * iter_iternext(PyObject *iterator) --- 46,49 ---- Index: listobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v retrieving revision 2.92.6.9 retrieving revision 2.92.6.10 diff -C2 -r2.92.6.9 -r2.92.6.10 *** listobject.c 2001/06/17 23:18:19 2.92.6.9 --- listobject.c 2001/07/07 22:55:30 2.92.6.10 *************** *** 10,25 **** #endif - #define ROUNDUP(n, PyTryBlock) \ - ((((n)+(PyTryBlock)-1)/(PyTryBlock))*(PyTryBlock)) - static int roundupsize(int n) { ! if (n < 500) ! return ROUNDUP(n, 10); ! else ! return ROUNDUP(n, 100); ! } #define NRESIZE(var, type, nitems) PyMem_RESIZE(var, type, roundupsize(nitems)) --- 10,48 ---- #endif static int roundupsize(int n) { ! unsigned int nbits = 0; ! unsigned int n2 = (unsigned int)n >> 5; + /* Round up: + * If n < 256, to a multiple of 8. + * If n < 2048, to a multiple of 64. + * If n < 16384, to a multiple of 512. + * If n < 131072, to a multiple of 4096. + * If n < 1048576, to a multiple of 32768. + * If n < 8388608, to a multiple of 262144. + * If n < 67108864, to a multiple of 2097152. + * If n < 536870912, to a multiple of 16777216. + * ... + * If n < 2**(5+3*i), to a multiple of 2**(3*i). + * + * This over-allocates proportional to the list size, making room + * for additional growth. The over-allocation is mild, but is + * enough to give linear-time amortized behavior over a long + * sequence of appends() in the presence of a poorly-performing + * system realloc() (which is a reality, e.g., across all flavors + * of Windows, with Win9x behavior being particularly bad -- and + * we've still got address space fragmentation problems on Win9x + * even with this scheme, although it requires much longer lists to + * provoke them than it used to). + */ + do { + n2 >>= 3; + nbits += 3; + } while (n2); + return ((n >> nbits) + 1) << nbits; + } + #define NRESIZE(var, type, nitems) PyMem_RESIZE(var, type, roundupsize(nitems)) *************** *** 224,247 **** list_repr(PyListObject *v) { - PyObject *s, *comma; int i; i = Py_ReprEnter((PyObject*)v); if (i != 0) { ! if (i > 0) ! return PyString_FromString("[...]"); ! return NULL; } ! s = PyString_FromString("["); ! comma = PyString_FromString(", "); ! for (i = 0; i < v->ob_size && s != NULL; i++) { ! if (i > 0) ! PyString_Concat(&s, comma); ! PyString_ConcatAndDel(&s, PyObject_Repr(v->ob_item[i])); } ! Py_XDECREF(comma); ! PyString_ConcatAndDel(&s, PyString_FromString("]")); Py_ReprLeave((PyObject *)v); ! return s; } --- 247,312 ---- list_repr(PyListObject *v) { int i; + PyObject *s, *temp; + PyObject *pieces = NULL, *result = NULL; i = Py_ReprEnter((PyObject*)v); if (i != 0) { ! return i > 0 ? PyString_FromString("[...]") : NULL; } ! ! if (v->ob_size == 0) { ! result = PyString_FromString("[]"); ! goto Done; } ! ! pieces = PyList_New(0); ! if (pieces == NULL) ! goto Done; ! ! /* Do repr() on each element. Note that this may mutate the list, ! so must refetch the list size on each iteration. */ ! for (i = 0; i < v->ob_size; ++i) { ! int status; ! s = PyObject_Repr(v->ob_item[i]); ! if (s == NULL) ! goto Done; ! status = PyList_Append(pieces, s); ! Py_DECREF(s); /* append created a new ref */ ! if (status < 0) ! goto Done; ! } ! ! /* Add "[]" decorations to the first and last items. */ ! assert(PyList_GET_SIZE(pieces) > 0); ! s = PyString_FromString("["); ! if (s == NULL) ! goto Done; ! temp = PyList_GET_ITEM(pieces, 0); ! PyString_ConcatAndDel(&s, temp); ! PyList_SET_ITEM(pieces, 0, s); ! if (s == NULL) ! goto Done; ! ! s = PyString_FromString("]"); ! if (s == NULL) ! goto Done; ! temp = PyList_GET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1); ! PyString_ConcatAndDel(&temp, s); ! PyList_SET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1, temp); ! if (temp == NULL) ! goto Done; ! ! /* Paste them all together with ", " between. */ ! s = PyString_FromString(", "); ! if (s == NULL) ! goto Done; ! result = _PyString_Join(s, pieces); ! Py_DECREF(s); ! ! Done: ! Py_XDECREF(pieces); Py_ReprLeave((PyObject *)v); ! return result; } *************** *** 558,580 **** } - /* Define NO_STRICT_LIST_APPEND to enable multi-argument append() */ - - #ifndef NO_STRICT_LIST_APPEND - #define PyArg_ParseTuple_Compat1 PyArg_ParseTuple - #else - #define PyArg_ParseTuple_Compat1(args, format, ret) \ - ( \ - PyTuple_GET_SIZE(args) > 1 ? (*ret = args, 1) : \ - PyTuple_GET_SIZE(args) == 1 ? (*ret = PyTuple_GET_ITEM(args, 0), 1) : \ - PyArg_ParseTuple(args, format, ret) \ - ) - #endif - - static PyObject * listappend(PyListObject *self, PyObject *args) { PyObject *v; ! if (!PyArg_ParseTuple_Compat1(args, "O:append", &v)) return NULL; return ins(self, (int) self->ob_size, v); --- 623,631 ---- } static PyObject * listappend(PyListObject *self, PyObject *args) { PyObject *v; ! if (!PyArg_ParseTuple(args, "O:append", &v)) return NULL; return ins(self, (int) self->ob_size, v); *************** *** 640,644 **** list_inplace_concat(PyListObject *self, PyObject *other) { ! other = PySequence_Fast(other, "argument to += must be a sequence"); if (!other) return NULL; --- 691,695 ---- list_inplace_concat(PyListObject *self, PyObject *other) { ! other = PySequence_Fast(other, "argument to += must be iterable"); if (!other) return NULL; *************** *** 660,664 **** return NULL; ! b = PySequence_Fast(b, "list.extend() argument must be a sequence"); if (!b) return NULL; --- 711,715 ---- return NULL; ! b = PySequence_Fast(b, "list.extend() argument must be iterable"); if (!b) return NULL; *************** *** 1345,1349 **** PyObject *v; ! if (!PyArg_ParseTuple_Compat1(args, "O:index", &v)) return NULL; for (i = 0; i < self->ob_size; i++) { --- 1396,1400 ---- PyObject *v; ! if (!PyArg_ParseTuple(args, "O:index", &v)) return NULL; for (i = 0; i < self->ob_size; i++) { *************** *** 1365,1369 **** PyObject *v; ! if (!PyArg_ParseTuple_Compat1(args, "O:count", &v)) return NULL; for (i = 0; i < self->ob_size; i++) { --- 1416,1420 ---- PyObject *v; ! if (!PyArg_ParseTuple(args, "O:count", &v)) return NULL; for (i = 0; i < self->ob_size; i++) { *************** *** 1383,1387 **** PyObject *v; ! if (!PyArg_ParseTuple_Compat1(args, "O:remove", &v)) return NULL; for (i = 0; i < self->ob_size; i++) { --- 1434,1438 ---- PyObject *v; ! if (!PyArg_ParseTuple(args, "O:remove", &v)) return NULL; for (i = 0; i < self->ob_size; i++) { Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.71.6.3 retrieving revision 1.71.6.4 diff -C2 -r1.71.6.3 -r1.71.6.4 *** longobject.c 2001/06/14 01:01:16 1.71.6.3 --- longobject.c 2001/07/07 22:55:30 1.71.6.4 *************** *** 58,76 **** PyLong_FromLong(long ival) { ! /* Assume a C long fits in at most 5 'digits' */ ! /* Works on both 32- and 64-bit machines */ ! PyLongObject *v = _PyLong_New(5); if (v != NULL) { ! unsigned long t = ival; ! int i; ! if (ival < 0) { ! t = -ival; ! v->ob_size = -(v->ob_size); ! } ! for (i = 0; i < 5; i++) { ! v->ob_digit[i] = (digit) (t & MASK); t >>= SHIFT; } - v = long_normalize(v); } return (PyObject *)v; --- 58,89 ---- PyLong_FromLong(long ival) { ! PyLongObject *v; ! unsigned long t; /* unsigned so >> doesn't propagate sign bit */ ! int ndigits = 0; ! int negative = 0; ! ! if (ival < 0) { ! ival = -ival; ! negative = 1; ! } ! ! /* Count the number of Python digits. ! We used to pick 5 ("big enough for anything"), but that's a ! waste of time and space given that 5*15 = 75 bits are rarely ! needed. */ ! t = (unsigned long)ival; ! while (t) { ! ++ndigits; ! t >>= SHIFT; ! } ! v = _PyLong_New(ndigits); if (v != NULL) { ! digit *p = v->ob_digit; ! v->ob_size = negative ? -ndigits : ndigits; ! t = (unsigned long)ival; ! while (t) { ! *p++ = (digit)(t & MASK); t >>= SHIFT; } } return (PyObject *)v; *************** *** 82,96 **** PyLong_FromUnsignedLong(unsigned long ival) { ! /* Assume a C long fits in at most 5 'digits' */ ! /* Works on both 32- and 64-bit machines */ ! PyLongObject *v = _PyLong_New(5); if (v != NULL) { ! unsigned long t = ival; ! int i; ! for (i = 0; i < 5; i++) { ! v->ob_digit[i] = (digit) (t & MASK); ! t >>= SHIFT; } - v = long_normalize(v); } return (PyObject *)v; --- 95,116 ---- PyLong_FromUnsignedLong(unsigned long ival) { ! PyLongObject *v; ! unsigned long t; ! int ndigits = 0; ! ! /* Count the number of Python digits. */ ! t = (unsigned long)ival; ! while (t) { ! ++ndigits; ! t >>= SHIFT; ! } ! v = _PyLong_New(ndigits); if (v != NULL) { ! digit *p = v->ob_digit; ! v->ob_size = ndigits; ! while (ival) { ! *p++ = (digit)(ival & MASK); ! ival >>= SHIFT; } } return (PyObject *)v; *************** *** 212,215 **** --- 232,479 ---- } + PyObject * + _PyLong_FromByteArray(const unsigned char* bytes, size_t n, + int little_endian, int is_signed) + { + const unsigned char* pstartbyte;/* LSB of bytes */ + int incr; /* direction to move pstartbyte */ + const unsigned char* pendbyte; /* MSB of bytes */ + size_t numsignificantbytes; /* number of bytes that matter */ + size_t ndigits; /* number of Python long digits */ + PyLongObject* v; /* result */ + int idigit = 0; /* next free index in v->ob_digit */ + + if (n == 0) + return PyLong_FromLong(0L); + + if (little_endian) { + pstartbyte = bytes; + pendbyte = bytes + n - 1; + incr = 1; + } + else { + pstartbyte = bytes + n - 1; + pendbyte = bytes; + incr = -1; + } + + if (is_signed) + is_signed = *pendbyte >= 0x80; + + /* Compute numsignificantbytes. This consists of finding the most + significant byte. Leading 0 bytes are insignficant if the number + is positive, and leading 0xff bytes if negative. */ + { + size_t i; + const unsigned char* p = pendbyte; + const int pincr = -incr; /* search MSB to LSB */ + const unsigned char insignficant = is_signed ? 0xff : 0x00; + + for (i = 0; i < n; ++i, p += pincr) { + if (*p != insignficant) + break; + } + numsignificantbytes = n - i; + /* 2's-comp is a bit tricky here, e.g. 0xff00 == -0x0100, so + actually has 2 significant bytes. OTOH, 0xff0001 == + -0x00ffff, so we wouldn't *need* to bump it there; but we + do for 0xffff = -0x0001. To be safe without bothering to + check every case, bump it regardless. */ + if (is_signed && numsignificantbytes < n) + ++numsignificantbytes; + } + + /* How many Python long digits do we need? We have + 8*numsignificantbytes bits, and each Python long digit has SHIFT + bits, so it's the ceiling of the quotient. */ + ndigits = (numsignificantbytes * 8 + SHIFT - 1) / SHIFT; + if (ndigits > (size_t)INT_MAX) + return PyErr_NoMemory(); + v = _PyLong_New((int)ndigits); + if (v == NULL) + return NULL; + + /* Copy the bits over. The tricky parts are computing 2's-comp on + the fly for signed numbers, and dealing with the mismatch between + 8-bit bytes and (probably) 15-bit Python digits.*/ + { + size_t i; + twodigits carry = 1; /* for 2's-comp calculation */ + twodigits accum = 0; /* sliding register */ + unsigned int accumbits = 0; /* number of bits in accum */ + const unsigned char* p = pstartbyte; + + for (i = 0; i < numsignificantbytes; ++i, p += incr) { + twodigits thisbyte = *p; + /* Compute correction for 2's comp, if needed. */ + if (is_signed) { + thisbyte = (0xff ^ thisbyte) + carry; + carry = thisbyte >> 8; + thisbyte &= 0xff; + } + /* Because we're going LSB to MSB, thisbyte is + more significant than what's already in accum, + so needs to be prepended to accum. */ + accum |= thisbyte << accumbits; + accumbits += 8; + if (accumbits >= SHIFT) { + /* There's enough to fill a Python digit. */ + assert(idigit < (int)ndigits); + v->ob_digit[idigit] = (digit)(accum & MASK); + ++idigit; + accum >>= SHIFT; + accumbits -= SHIFT; + assert(accumbits < SHIFT); + } + } + assert(accumbits < SHIFT); + if (accumbits) { + assert(idigit < (int)ndigits); + v->ob_digit[idigit] = (digit)accum; + ++idigit; + } + } + + v->ob_size = is_signed ? -idigit : idigit; + return (PyObject *)long_normalize(v); + } + + int + _PyLong_AsByteArray(PyLongObject* v, + unsigned char* bytes, size_t n, + int little_endian, int is_signed) + { + int i; /* index into v->ob_digit */ + int ndigits; /* |v->ob_size| */ + twodigits accum; /* sliding register */ + unsigned int accumbits; /* # bits in accum */ + int do_twos_comp; /* store 2's-comp? is_signed and v < 0 */ + twodigits carry; /* for computing 2's-comp */ + size_t j; /* # bytes filled */ + unsigned char* p; /* pointer to next byte in bytes */ + int pincr; /* direction to move p */ + + assert(v != NULL && PyLong_Check(v)); + + if (v->ob_size < 0) { + ndigits = -(v->ob_size); + if (!is_signed) { + PyErr_SetString(PyExc_TypeError, + "can't convert negative long to unsigned"); + return -1; + } + do_twos_comp = 1; + } + else { + ndigits = v->ob_size; + do_twos_comp = 0; + } + + if (little_endian) { + p = bytes; + pincr = 1; + } + else { + p = bytes + n - 1; + pincr = -1; + } + + /* Copy over all the Python digits. + It's crucial that every Python digit except for the MSD contribute + exactly SHIFT bits to the total, so first assert that the long is + normalized. */ + assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); + j = 0; + accum = 0; + accumbits = 0; + carry = do_twos_comp ? 1 : 0; + for (i = 0; i < ndigits; ++i) { + twodigits thisdigit = v->ob_digit[i]; + if (do_twos_comp) { + thisdigit = (thisdigit ^ MASK) + carry; + carry = thisdigit >> SHIFT; + thisdigit &= MASK; + } + /* Because we're going LSB to MSB, thisdigit is more + significant than what's already in accum, so needs to be + prepended to accum. */ + accum |= thisdigit << accumbits; + accumbits += SHIFT; + + /* The most-significant digit may be (probably is) at least + partly empty. */ + if (i == ndigits - 1) { + /* Count # of sign bits -- they needn't be stored, + * although for signed conversion we need later to + * make sure at least one sign bit gets stored. + * First shift conceptual sign bit to real sign bit. + */ + stwodigits s = (stwodigits)(thisdigit << + (8*sizeof(stwodigits) - SHIFT)); + unsigned int nsignbits = 0; + while ((s < 0) == do_twos_comp && nsignbits < SHIFT) { + ++nsignbits; + s <<= 1; + } + accumbits -= nsignbits; + } + + /* Store as many bytes as possible. */ + while (accumbits >= 8) { + if (j >= n) + goto Overflow; + ++j; + *p = (unsigned char)(accum & 0xff); + p += pincr; + accumbits -= 8; + accum >>= 8; + } + } + + /* Store the straggler (if any). */ + assert(accumbits < 8); + assert(carry == 0); /* else do_twos_comp and *every* digit was 0 */ + if (accumbits > 0) { + if (j >= n) + goto Overflow; + ++j; + if (do_twos_comp) { + /* Fill leading bits of the byte with sign bits + (appropriately pretending that the long had an + infinite supply of sign bits). */ + accum |= (~(twodigits)0) << accumbits; + } + *p = (unsigned char)(accum & 0xff); + p += pincr; + } + else if (j == n && n > 0 && is_signed) { + /* The main loop filled the byte array exactly, so the code + just above didn't get to ensure there's a sign bit, and the + loop below wouldn't add one either. Make sure a sign bit + exists. */ + unsigned char msb = *(p - pincr); + int sign_bit_set = msb >= 0x80; + assert(accumbits == 0); + if (sign_bit_set == do_twos_comp) + return 0; + else + goto Overflow; + } + + /* Fill remaining bytes with copies of the sign bit. */ + { + unsigned char signbyte = do_twos_comp ? 0xffU : 0U; + for ( ; j < n; ++j, p += pincr) + *p = signbyte; + } + + return 0; + + Overflow: + PyErr_SetString(PyExc_OverflowError, "long too big to convert"); + return -1; + + } + /* Get a C double from a long int object. */ *************** *** 245,260 **** PyLong_FromVoidPtr(void *p) { ! #if SIZEOF_VOID_P == SIZEOF_LONG return PyInt_FromLong((long)p); #else /* optimize null pointers */ ! if ( p == NULL ) return PyInt_FromLong(0); - - /* we can assume that HAVE_LONG_LONG is true. if not, then the - configuration process should have bailed (having big pointers - without long longs seems non-sensical) */ return PyLong_FromLongLong((LONG_LONG)p); ! #endif /* SIZEOF_VOID_P == SIZEOF_LONG */ } --- 509,528 ---- PyLong_FromVoidPtr(void *p) { ! #if SIZEOF_VOID_P <= SIZEOF_LONG return PyInt_FromLong((long)p); #else + + #ifndef HAVE_LONG_LONG + # error "PyLong_FromVoidPtr: sizeof(void*) > sizeof(long), but no long long" + #endif + #if SIZEOF_LONG_LONG < SIZEOF_VOID_P + # error "PyLong_FromVoidPtr: sizeof(LONG_LONG) < sizeof(void*)" + #endif /* optimize null pointers */ ! if (p == NULL) return PyInt_FromLong(0); return PyLong_FromLongLong((LONG_LONG)p); ! ! #endif /* SIZEOF_VOID_P <= SIZEOF_LONG */ } *************** *** 268,291 **** PyExc_SystemError, "bad argument to internal function" */ ! ! #if SIZEOF_VOID_P == SIZEOF_LONG long x; ! if ( PyInt_Check(vv) ) x = PyInt_AS_LONG(vv); else x = PyLong_AsLong(vv); #else ! /* we can assume that HAVE_LONG_LONG is true. if not, then the ! configuration process should have bailed (having big pointers ! without long longs seems non-sensical) */ LONG_LONG x; ! if ( PyInt_Check(vv) ) x = PyInt_AS_LONG(vv); else x = PyLong_AsLongLong(vv); - #endif /* SIZEOF_VOID_P == SIZEOF_LONG */ if (x == -1 && PyErr_Occurred()) return NULL; --- 536,563 ---- PyExc_SystemError, "bad argument to internal function" */ ! #if SIZEOF_VOID_P <= SIZEOF_LONG long x; ! if (PyInt_Check(vv)) x = PyInt_AS_LONG(vv); else x = PyLong_AsLong(vv); #else ! ! #ifndef HAVE_LONG_LONG ! # error "PyLong_AsVoidPtr: sizeof(void*) > sizeof(long), but no long long" ! #endif ! #if SIZEOF_LONG_LONG < SIZEOF_VOID_P ! # error "PyLong_AsVoidPtr: sizeof(LONG_LONG) < sizeof(void*)" ! #endif LONG_LONG x; ! if (PyInt_Check(vv)) x = PyInt_AS_LONG(vv); else x = PyLong_AsLongLong(vv); + #endif /* SIZEOF_VOID_P <= SIZEOF_LONG */ + if (x == -1 && PyErr_Occurred()) return NULL; *************** *** 294,391 **** #ifdef HAVE_LONG_LONG ! /* ! * LONG_LONG support by Chris Herborth (chrish@qnx.com) ! * ! * For better or worse :-), I tried to follow the coding style already ! * here. */ ! /* Create a new long int object from a C LONG_LONG int */ PyObject * PyLong_FromLongLong(LONG_LONG ival) { ! #if SIZEOF_LONG_LONG == SIZEOF_LONG ! /* In case the compiler is faking it. */ ! return PyLong_FromLong( (long)ival ); ! #else ! if ((LONG_LONG)LONG_MIN <= ival && ival <= (LONG_LONG)LONG_MAX) { ! return PyLong_FromLong( (long)ival ); ! } ! else if (0 <= ival && ival <= (unsigned LONG_LONG)ULONG_MAX) { ! return PyLong_FromUnsignedLong( (unsigned long)ival ); ! } ! else { ! /* Assume a C LONG_LONG fits in at most 10 'digits'. ! * Should be OK if we're assuming long fits in 5. ! */ ! PyLongObject *v = _PyLong_New(10); ! ! if (v != NULL) { ! unsigned LONG_LONG t = ival; ! int i; ! if (ival < 0) { ! t = -ival; ! v->ob_size = -(v->ob_size); ! } ! ! for (i = 0; i < 10; i++) { ! v->ob_digit[i] = (digit) (t & MASK); ! t >>= SHIFT; ! } ! ! v = long_normalize(v); ! } ! ! return (PyObject *)v; ! } ! #endif } ! /* Create a new long int object from a C unsigned LONG_LONG int */ PyObject * PyLong_FromUnsignedLongLong(unsigned LONG_LONG ival) { ! #if SIZEOF_LONG_LONG == SIZEOF_LONG ! /* In case the compiler is faking it. */ ! return PyLong_FromUnsignedLong( (unsigned long)ival ); ! #else ! if( ival <= (unsigned LONG_LONG)ULONG_MAX ) { ! return PyLong_FromUnsignedLong( (unsigned long)ival ); ! } ! else { ! /* Assume a C long fits in at most 10 'digits'. */ ! PyLongObject *v = _PyLong_New(10); ! ! if (v != NULL) { ! unsigned LONG_LONG t = ival; ! int i; ! for (i = 0; i < 10; i++) { ! v->ob_digit[i] = (digit) (t & MASK); ! t >>= SHIFT; ! } ! ! v = long_normalize(v); ! } ! ! return (PyObject *)v; ! } ! #endif } /* Get a C LONG_LONG int from a long int object. ! Returns -1 and sets an error condition if overflow occurs. */ LONG_LONG PyLong_AsLongLong(PyObject *vv) { ! #if SIZEOF_LONG_LONG == SIZEOF_LONG ! /* In case the compiler is faking it. */ ! return (LONG_LONG)PyLong_AsLong( vv ); ! #else ! register PyLongObject *v; ! LONG_LONG x, prev; ! int i, sign; ! if (vv == NULL || !PyLong_Check(vv)) { PyErr_BadInternalCall(); --- 566,610 ---- #ifdef HAVE_LONG_LONG ! ! /* Initial LONG_LONG support by Chris Herborth (chrish@qnx.com), later ! * rewritten to use the newer PyLong_{As,From}ByteArray API. */ ! #define IS_LITTLE_ENDIAN (int)*(unsigned char*)&one + /* Create a new long int object from a C LONG_LONG int. */ + PyObject * PyLong_FromLongLong(LONG_LONG ival) { ! LONG_LONG bytes = ival; ! int one = 1; ! return _PyLong_FromByteArray( ! (unsigned char *)&bytes, ! SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1); } ! /* Create a new long int object from a C unsigned LONG_LONG int. */ ! PyObject * PyLong_FromUnsignedLongLong(unsigned LONG_LONG ival) { ! unsigned LONG_LONG bytes = ival; ! int one = 1; ! return _PyLong_FromByteArray( ! (unsigned char *)&bytes, ! SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0); } /* Get a C LONG_LONG int from a long int object. ! Return -1 and set an error if overflow occurs. */ LONG_LONG PyLong_AsLongLong(PyObject *vv) { ! LONG_LONG bytes; ! int one = 1; ! int res; ! if (vv == NULL || !PyLong_Check(vv)) { PyErr_BadInternalCall(); *************** *** 393,459 **** } ! v = (PyLongObject *)vv; ! i = v->ob_size; ! sign = 1; ! x = 0; ! if (i < 0) { ! sign = -1; ! i = -(i); ! } ! ! while (--i >= 0) { ! prev = x; ! x = (x << SHIFT) + v->ob_digit[i]; ! if ((x >> SHIFT) != prev) { ! PyErr_SetString(PyExc_OverflowError, ! "long int too long to convert"); ! return -1; ! } ! } ! ! return x * sign; ! #endif } unsigned LONG_LONG PyLong_AsUnsignedLongLong(PyObject *vv) { ! #if SIZEOF_LONG_LONG == 4 ! /* In case the compiler is faking it. */ ! return (unsigned LONG_LONG)PyLong_AsUnsignedLong( vv ); ! #else ! register PyLongObject *v; ! unsigned LONG_LONG x, prev; ! int i; ! if (vv == NULL || !PyLong_Check(vv)) { PyErr_BadInternalCall(); ! return (unsigned LONG_LONG) -1; } ! v = (PyLongObject *)vv; ! i = v->ob_size; ! x = 0; ! if (i < 0) { ! PyErr_SetString(PyExc_OverflowError, ! "can't convert negative value to unsigned long"); ! return (unsigned LONG_LONG) -1; ! } ! while (--i >= 0) { ! prev = x; ! x = (x << SHIFT) + v->ob_digit[i]; ! if ((x >> SHIFT) != prev) { ! PyErr_SetString(PyExc_OverflowError, ! "long int too long to convert"); ! return (unsigned LONG_LONG) -1; ! } ! } - return x; - #endif - } #endif /* HAVE_LONG_LONG */ --- 612,646 ---- } ! res = _PyLong_AsByteArray( ! (PyLongObject *)vv, (unsigned char *)&bytes, ! SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1); ! return res < 0 ? (LONG_LONG)res : bytes; } + /* Get a C unsigned LONG_LONG int from a long int object. + Return -1 and set an error if overflow occurs. */ + unsigned LONG_LONG PyLong_AsUnsignedLongLong(PyObject *vv) { ! unsigned LONG_LONG bytes; ! int one = 1; ! int res; ! if (vv == NULL || !PyLong_Check(vv)) { PyErr_BadInternalCall(); ! return -1; } ! res = _PyLong_AsByteArray( ! (PyLongObject *)vv, (unsigned char *)&bytes, ! SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0); ! return res < 0 ? (unsigned LONG_LONG)res : bytes; ! } ! #undef IS_LITTLE_ENDIAN #endif /* HAVE_LONG_LONG */ Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.124.4.22 retrieving revision 2.124.4.23 diff -C2 -r2.124.4.22 -r2.124.4.23 *** object.c 2001/07/03 00:48:14 2.124.4.22 --- object.c 2001/07/07 22:55:30 2.124.4.23 *************** *** 438,442 **** switch (try_rich_compare_bool(v, w, tries[i].op)) { case -1: ! return -1; case 1: return tries[i].outcome; --- 438,442 ---- switch (try_rich_compare_bool(v, w, tries[i].op)) { case -1: ! return -2; case 1: return tries[i].outcome; *************** *** 468,481 **** return (*w->ob_type->tp_compare)(v, w); - /* If the types are equal, don't bother with coercions etc. */ - if (v->ob_type == w->ob_type) { - if ((f = v->ob_type->tp_compare) == NULL) - return 2; - c = (*f)(v, w); - if (PyErr_Occurred()) - return -2; - return c < 0 ? -1 : c > 0 ? 1 : 0; - } - /* Try coercion; if it fails, give up */ c = PyNumber_CoerceEx(&v, &w); --- 468,471 ---- *************** *** 490,494 **** Py_DECREF(v); Py_DECREF(w); ! if (PyErr_Occurred()) return -2; return c < 0 ? -1 : c > 0 ? 1 : 0; --- 480,484 ---- Py_DECREF(v); Py_DECREF(w); ! if (c < 0 && PyErr_Occurred()) return -2; return c < 0 ? -1 : c > 0 ? 1 : 0; *************** *** 500,504 **** Py_DECREF(v); Py_DECREF(w); ! if (PyErr_Occurred()) return -2; return c < 0 ? 1 : c > 0 ? -1 : 0; /* negated! */ --- 490,494 ---- Py_DECREF(v); Py_DECREF(w); ! if (c < 0 && PyErr_Occurred()) return -2; return c < 0 ? 1 : c > 0 ? -1 : 0; /* negated! */ *************** *** 576,584 **** --- 566,586 ---- #define CHECK_TYPES(o) PyType_HasFeature((o)->ob_type, Py_TPFLAGS_CHECKTYPES) + /* Do a 3-way comparison, by hook or by crook. Return: + -2 for an exception; + -1 if v < w; + 0 if v == w; + 1 if v > w; + If the object implements a tp_compare function, it returns + whatever this function returns (whether with an exception or not). + */ static int do_cmp(PyObject *v, PyObject *w) { int c; + cmpfunc f; + if (v->ob_type == w->ob_type + && (f = v->ob_type->tp_compare) != NULL) + return (*f)(v, w); c = try_rich_to_3way_compare(v, w); if (c < 2) *************** *** 745,758 **** static PyObject * ! try_3way_to_rich_compare(PyObject *v, PyObject *w, int op) { - int c; PyObject *result; - - c = try_3way_compare(v, w); - if (c >= 2) - c = default_3way_compare(v, w); - if (c <= -2) - return NULL; switch (op) { case Py_LT: c = c < 0; break; --- 747,753 ---- static PyObject * ! convert_3way_to_object(int op, int c) { PyObject *result; switch (op) { case Py_LT: c = c < 0; break; *************** *** 767,775 **** --- 762,810 ---- return result; } + static PyObject * + try_3way_to_rich_compare(PyObject *v, PyObject *w, int op) + { + int c; + + c = try_3way_compare(v, w); + if (c >= 2) + c = default_3way_compare(v, w); + if (c <= -2) + return NULL; + return convert_3way_to_object(op, c); + } + + static PyObject * do_richcmp(PyObject *v, PyObject *w, int op) { PyObject *res; + cmpfunc f; + + /* If the types are equal, don't bother with coercions etc. + Instances are special-cased in try_3way_compare, since + a result of 2 does *not* mean one value being greater + than the other. */ + if (v->ob_type == w->ob_type + && (f = v->ob_type->tp_compare) != NULL + && !PyInstance_Check(v)) { + int c; + richcmpfunc f1; + if ((f1 = RICHCOMPARE(v->ob_type)) != NULL) { + /* If the type has richcmp, try it first. + try_rich_compare would try it two-sided, + which is not needed since we've a single + type only. */ + res = (*f1)(v, w, op); + if (res != Py_NotImplemented) + return res; + Py_DECREF(res); + } + c = (*f)(v, w); + if (c < 0 && PyErr_Occurred()) + return NULL; + return convert_3way_to_object(op, c); + } res = try_rich_compare(v, w, op); *************** *** 826,829 **** --- 861,865 ---- } + /* Return -1 if error; 1 if v op w; 0 if not (v op w). */ int PyObject_RichCompareBool(PyObject *v, PyObject *w, int op) Index: rangeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/rangeobject.c,v retrieving revision 2.24.6.3 retrieving revision 2.24.6.4 diff -C2 -r2.24.6.3 -r2.24.6.4 *** rangeobject.c 2001/06/06 14:27:54 2.24.6.3 --- rangeobject.c 2001/07/07 22:55:30 2.24.6.4 *************** *** 11,55 **** long step; long len; - int reps; - long totlen; } rangeobject; - static int - long_mul(long i, long j, long *kk) - { - PyObject *a; - PyObject *b; - PyObject *c; - - if ((a = PyInt_FromLong(i)) == NULL) - return 0; - - if ((b = PyInt_FromLong(j)) == NULL) - return 0; - - c = PyNumber_Multiply(a, b); - - Py_DECREF(a); - Py_DECREF(b); - - if (c == NULL) - return 0; - - *kk = PyInt_AS_LONG(c); - Py_DECREF(c); - - if (*kk > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "integer multiplication"); - return 0; - } - else - return 1; - } - PyObject * ! PyRange_New(long start, long len, long step, int reps) { - long totlen = -1; rangeobject *obj = PyObject_NEW(rangeobject, &PyRange_Type); --- 11,19 ---- long step; long len; } rangeobject; PyObject * ! PyRange_New(long start, long len, long step) { rangeobject *obj = PyObject_NEW(rangeobject, &PyRange_Type); *************** *** 57,66 **** return NULL; ! if (len == 0 || reps <= 0) { start = 0; len = 0; step = 1; - reps = 1; - totlen = 0; } else { --- 21,28 ---- return NULL; ! if (len == 0) { start = 0; len = 0; step = 1; } else { *************** *** 72,81 **** "integer addition"); return NULL; - } - if (! long_mul(len, (long) reps, &totlen)) { - if(!PyErr_ExceptionMatches(PyExc_OverflowError)) - return NULL; - PyErr_Clear(); - totlen = -1; } } --- 34,37 ---- *************** *** 84,89 **** obj->len = len; obj->step = step; - obj->reps = reps; - obj->totlen = totlen; return (PyObject *) obj; --- 40,43 ---- *************** *** 99,108 **** range_item(rangeobject *r, int i) { ! if (i < 0 || i >= r->totlen) ! if (r->totlen!=-1) { ! PyErr_SetString(PyExc_IndexError, "xrange object index out of range"); ! return NULL; ! } return PyInt_FromLong(r->start + (i % r->len) * r->step); --- 53,61 ---- range_item(rangeobject *r, int i) { ! if (i < 0 || i >= r->len) { ! PyErr_SetString(PyExc_IndexError, "xrange object index out of range"); ! return NULL; ! } return PyInt_FromLong(r->start + (i % r->len) * r->step); *************** *** 112,119 **** range_length(rangeobject *r) { ! if (r->totlen == -1) ! PyErr_SetString(PyExc_OverflowError, ! "xrange object has too many items"); ! return r->totlen; } --- 65,69 ---- range_length(rangeobject *r) { ! return r->len; } *************** *** 125,129 **** */ char buf1[250]; - char buf2[250]; if (r->start == 0 && r->step == 1) --- 75,78 ---- *************** *** 140,306 **** r->start + r->len * r->step, r->step); - - if (r->reps != 1) - sprintf(buf2, "(%s * %d)", buf1, r->reps); - - return PyString_FromString(r->reps == 1 ? buf1 : buf2); - } - - static PyObject * - range_concat(rangeobject *r, PyObject *obj) - { - PyErr_SetString(PyExc_TypeError, "cannot concatenate xrange objects"); - return NULL; - } - - static PyObject * - range_repeat(rangeobject *r, int n) - { - long lreps = 0; - - if (n <= 0) - return (PyObject *) PyRange_New(0, 0, 1, 1); - - else if (n == 1) { - Py_INCREF(r); - return (PyObject *) r; - } - - else if (! long_mul((long) r->reps, (long) n, &lreps)) - return NULL; - - else - return (PyObject *) PyRange_New( - r->start, - r->len, - r->step, - (int) lreps); - } ! static int ! range_compare(rangeobject *r1, rangeobject *r2) ! { ! if (r1->start != r2->start) ! return r1->start - r2->start; ! ! else if (r1->step != r2->step) ! return r1->step - r2->step; ! ! else if (r1->len != r2->len) ! return r1->len - r2->len; ! ! else ! return r1->reps - r2->reps; ! } ! ! static PyObject * ! range_slice(rangeobject *r, int low, int high) ! { ! if (r->reps != 1) { ! PyErr_SetString(PyExc_TypeError, ! "cannot slice a replicated xrange"); ! return NULL; ! } ! if (low < 0) ! low = 0; ! else if (low > r->len) ! low = r->len; ! if (high < 0) ! high = 0; ! if (high < low) ! high = low; ! else if (high > r->len) ! high = r->len; ! ! if (low == 0 && high == r->len) { ! Py_INCREF(r); ! return (PyObject *) r; ! } ! ! return (PyObject *) PyRange_New( ! low * r->step + r->start, ! high - low, ! r->step, ! 1); ! } ! ! static PyObject * ! range_tolist(rangeobject *self, PyObject *args) ! { ! PyObject *thelist; ! int j; ! ! if (! PyArg_ParseTuple(args, ":tolist")) ! return NULL; ! ! if (self->totlen == -1) ! return PyErr_NoMemory(); ! ! if ((thelist = PyList_New(self->totlen)) == NULL) ! return NULL; ! ! for (j = 0; j < self->totlen; ++j) ! if ((PyList_SetItem(thelist, j, (PyObject *) PyInt_FromLong( ! self->start + (j % self->len) * self->step))) < 0) ! return NULL; ! ! return thelist; ! } ! ! static PyObject * ! range_getstop(rangeobject *r, void *closure) ! { ! return PyInt_FromLong(r->start + (r->len * r->step)); ! } ! ! static PyMethodDef range_methods[] = { ! {"tolist", (PyCFunction)range_tolist, METH_VARARGS, ! "tolist() -> list\n" ! "Return a list object with the same values."}, ! {NULL, NULL} ! }; ! static struct memberlist range_members[] = { ! {"step", T_LONG, offsetof(rangeobject, step), RO}, ! {"start", T_LONG, offsetof(rangeobject, start), RO}, ! {NULL, 0, 0, 0} ! }; ! ! static struct getsetlist range_getsets[] = { ! {"stop", (getter)range_getstop, NULL, NULL}, ! {0} ! }; ! ! static int ! range_contains(rangeobject *r, PyObject *obj) ! { ! long num = PyInt_AsLong(obj); ! ! if (num < 0 && PyErr_Occurred()) ! return -1; ! ! if (r->step > 0) { ! if ((num < r->start) || ((num - r->start) % r->step)) ! return 0; ! if (num >= (r->start + (r->len * r->step))) ! return 0; ! } ! else { ! if ((num > r->start) || ((num - r->start) % r->step)) ! return 0; ! if (num <= (r->start + (r->len * r->step))) ! return 0; ! } ! return 1; } static PySequenceMethods range_as_sequence = { (inquiry)range_length, /*sq_length*/ ! (binaryfunc)range_concat, /*sq_concat*/ ! (intargfunc)range_repeat, /*sq_repeat*/ ! (intargfunc)range_item, /*sq_item*/ ! (intintargfunc)range_slice, /*sq_slice*/ 0, /*sq_ass_item*/ 0, /*sq_ass_slice*/ ! (objobjproc)range_contains, /*sq_contains*/ }; --- 89,105 ---- r->start + r->len * r->step, r->step); ! return PyString_FromString(buf1); } static PySequenceMethods range_as_sequence = { (inquiry)range_length, /*sq_length*/ ! 0, /*sq_concat*/ ! 0, /*sq_repeat*/ ! (intargfunc)range_item, /*sq_item*/ ! 0, /*sq_slice*/ 0, /*sq_ass_item*/ 0, /*sq_ass_slice*/ ! 0, /*sq_contains*/ }; *************** *** 315,319 **** 0, /* tp_getattr */ 0, /* tp_setattr */ ! (cmpfunc)range_compare, /* tp_compare */ (reprfunc)range_repr, /* tp_repr */ 0, /* tp_as_number */ --- 114,118 ---- 0, /* tp_getattr */ 0, /* tp_setattr */ ! 0, /* tp_compare */ (reprfunc)range_repr, /* tp_repr */ 0, /* tp_as_number */ *************** *** 334,340 **** 0, /* tp_iter */ 0, /* tp_iternext */ ! range_methods, /* tp_methods */ ! range_members, /* tp_members */ ! range_getsets, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ --- 133,139 ---- 0, /* tp_iter */ 0, /* tp_iternext */ ! 0, /* tp_methods */ ! 0, /* tp_members */ ! 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ Index: stringobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v retrieving revision 2.103.2.6 retrieving revision 2.103.2.7 diff -C2 -r2.103.2.6 -r2.103.2.7 *** stringobject.c 2001/06/16 14:38:37 2.103.2.6 --- stringobject.c 2001/07/07 22:55:30 2.103.2.7 *************** *** 74,80 **** --- 74,86 ---- #ifndef DONT_SHARE_SHORT_STRINGS if (size == 0) { + PyObject *t = (PyObject *)op; + PyString_InternInPlace(&t); + op = (PyStringObject *)t; nullstring = op; Py_INCREF(op); } else if (size == 1 && str != NULL) { + PyObject *t = (PyObject *)op; + PyString_InternInPlace(&t); + op = (PyStringObject *)t; characters[*str & UCHAR_MAX] = op; Py_INCREF(op); *************** *** 126,132 **** --- 132,144 ---- #ifndef DONT_SHARE_SHORT_STRINGS if (size == 0) { + PyObject *t = (PyObject *)op; + PyString_InternInPlace(&t); + op = (PyStringObject *)t; nullstring = op; Py_INCREF(op); } else if (size == 1) { + PyObject *t = (PyObject *)op; + PyString_InternInPlace(&t); + op = (PyStringObject *)t; characters[*str & UCHAR_MAX] = op; Py_INCREF(op); *************** *** 141,176 **** const char *errors) { ! PyObject *buffer = NULL, *str; ! ! if (encoding == NULL) encoding = PyUnicode_GetDefaultEncoding(); /* Decode via the codec registry */ ! buffer = PyBuffer_FromMemory((void *)s, size); ! if (buffer == NULL) goto onError; ! str = PyCodec_Decode(buffer, encoding, errors); ! if (str == NULL) goto onError; /* Convert Unicode to a string using the default encoding */ ! if (PyUnicode_Check(str)) { ! PyObject *temp = str; ! str = PyUnicode_AsEncodedString(str, NULL, NULL); Py_DECREF(temp); ! if (str == NULL) goto onError; } ! if (!PyString_Check(str)) { PyErr_Format(PyExc_TypeError, "decoder did not return a string object (type=%.400s)", ! str->ob_type->tp_name); ! Py_DECREF(str); goto onError; } ! Py_DECREF(buffer); ! return str; ! onError: - Py_XDECREF(buffer); return NULL; } --- 153,220 ---- const char *errors) { ! PyObject *v, *str; ! ! str = PyString_FromStringAndSize(s, size); ! if (str == NULL) ! return NULL; ! v = PyString_AsDecodedString(str, encoding, errors); ! Py_DECREF(str); ! return v; ! } ! ! PyObject *PyString_AsDecodedObject(PyObject *str, ! const char *encoding, ! const char *errors) ! { ! PyObject *v; ! ! if (!PyString_Check(str)) { ! PyErr_BadArgument(); ! goto onError; ! } ! ! if (encoding == NULL) encoding = PyUnicode_GetDefaultEncoding(); /* Decode via the codec registry */ ! v = PyCodec_Decode(str, encoding, errors); ! if (v == NULL) goto onError; ! ! return v; ! ! onError: ! return NULL; ! } ! ! PyObject *PyString_AsDecodedString(PyObject *str, ! const char *encoding, ! const char *errors) ! { ! PyObject *v; ! ! v = PyString_AsDecodedObject(str, encoding, errors); ! if (v == NULL) goto onError; + /* Convert Unicode to a string using the default encoding */ ! if (PyUnicode_Check(v)) { ! PyObject *temp = v; ! v = PyUnicode_AsEncodedString(v, NULL, NULL); Py_DECREF(temp); ! if (v == NULL) goto onError; } ! if (!PyString_Check(v)) { PyErr_Format(PyExc_TypeError, "decoder did not return a string object (type=%.400s)", ! v->ob_type->tp_name); ! Py_DECREF(v); goto onError; } ! ! return v; ! onError: return NULL; } *************** *** 182,186 **** { PyObject *v, *str; ! str = PyString_FromStringAndSize(s, size); if (str == NULL) --- 226,230 ---- { PyObject *v, *str; ! str = PyString_FromStringAndSize(s, size); if (str == NULL) *************** *** 191,200 **** } ! PyObject *PyString_AsEncodedString(PyObject *str, const char *encoding, const char *errors) { PyObject *v; ! if (!PyString_Check(str)) { PyErr_BadArgument(); --- 235,244 ---- } ! PyObject *PyString_AsEncodedObject(PyObject *str, const char *encoding, const char *errors) { PyObject *v; ! if (!PyString_Check(str)) { PyErr_BadArgument(); *************** *** 202,206 **** } ! if (encoding == NULL) encoding = PyUnicode_GetDefaultEncoding(); --- 246,250 ---- } ! if (encoding == NULL) encoding = PyUnicode_GetDefaultEncoding(); *************** *** 209,212 **** --- 253,273 ---- if (v == NULL) goto onError; + + return v; + + onError: + return NULL; + } + + PyObject *PyString_AsEncodedString(PyObject *str, + const char *encoding, + const char *errors) + { + PyObject *v; + + v = PyString_AsEncodedObject(str, encoding, errors); + if (v == NULL) + goto onError; + /* Convert Unicode to a string using the default encoding */ if (PyUnicode_Check(v)) { *************** *** 224,229 **** goto onError; } return v; ! onError: return NULL; --- 285,291 ---- goto onError; } + return v; ! onError: return NULL; *************** *** 273,277 **** /* Internal API needed by PyString_AsStringAndSize(): */ ! extern PyObject *_PyUnicode_AsDefaultEncodedString(PyObject *unicode, const char *errors); --- 335,339 ---- /* Internal API needed by PyString_AsStringAndSize(): */ ! extern PyObject *_PyUnicode_AsDefaultEncodedString(PyObject *unicode, const char *errors); *************** *** 423,427 **** if (PyUnicode_Check(bb)) return PyUnicode_Concat((PyObject *)a, bb); ! PyErr_Format(PyExc_TypeError, "cannot add type \"%.200s\" to string", bb->ob_type->tp_name); --- 485,489 ---- if (PyUnicode_Check(bb)) return PyUnicode_Concat((PyObject *)a, bb); ! PyErr_Format(PyExc_TypeError, "cannot add type \"%.200s\" to string", bb->ob_type->tp_name); *************** *** 550,592 **** string_item(PyStringObject *a, register int i) { - int c; PyObject *v; if (i < 0 || i >= a->ob_size) { PyErr_SetString(PyExc_IndexError, "string index out of range"); return NULL; } ! c = a->ob_sval[i] & UCHAR_MAX; ! v = (PyObject *) characters[c]; #ifdef COUNT_ALLOCS - if (v != NULL) one_strings++; #endif ! if (v == NULL) { ! v = PyString_FromStringAndSize((char *)NULL, 1); ! if (v == NULL) ! return NULL; ! characters[c] = (PyStringObject *) v; ! ((PyStringObject *)v)->ob_sval[0] = c; } - Py_INCREF(v); return v; } ! static int ! string_compare(PyStringObject *a, PyStringObject *b) { ! int len_a = a->ob_size, len_b = b->ob_size; ! int min_len = (len_a < len_b) ? len_a : len_b; ! int cmp; if (min_len > 0) { ! cmp = Py_CHARMASK(*a->ob_sval) - Py_CHARMASK(*b->ob_sval); ! if (cmp == 0) ! cmp = memcmp(a->ob_sval, b->ob_sval, min_len); ! if (cmp != 0) ! return cmp; } ! return (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0; } static long string_hash(PyStringObject *a) --- 612,709 ---- string_item(PyStringObject *a, register int i) { PyObject *v; + char *pchar; if (i < 0 || i >= a->ob_size) { PyErr_SetString(PyExc_IndexError, "string index out of range"); return NULL; } ! pchar = a->ob_sval + i; ! v = (PyObject *)characters[*pchar & UCHAR_MAX]; ! if (v == NULL) ! v = PyString_FromStringAndSize(pchar, 1); ! else { #ifdef COUNT_ALLOCS one_strings++; #endif ! Py_INCREF(v); } return v; } ! static PyObject* ! string_richcompare(PyStringObject *a, PyStringObject *b, int op) { ! int c; ! int len_a, len_b; ! int min_len; ! PyObject *result; ! ! /* One of the objects is a string object. Make sure the ! other one is one, too. */ ! if (a->ob_type != b->ob_type) { ! result = Py_NotImplemented; ! goto out; ! } ! if (a == b) { ! switch (op) { ! case Py_EQ:case Py_LE:case Py_GE: ! result = Py_True; ! goto out; ! case Py_NE:case Py_LT:case Py_GT: ! result = Py_False; ! goto out; ! } ! } ! if (op == Py_EQ) { ! /* Supporting Py_NE here as well does not save ! much time, since Py_NE is rarely used. */ ! if (a->ob_size == b->ob_size ! && (a->ob_sval[0] == b->ob_sval[0] ! && memcmp(a->ob_sval, b->ob_sval, ! a->ob_size) == 0)) { ! result = Py_True; ! } else { ! result = Py_False; ! } ! goto out; ! } ! len_a = a->ob_size; len_b = b->ob_size; ! min_len = (len_a < len_b) ? len_a : len_b; if (min_len > 0) { ! c = Py_CHARMASK(*a->ob_sval) - Py_CHARMASK(*b->ob_sval); ! if (c==0) ! c = memcmp(a->ob_sval, b->ob_sval, min_len); ! }else ! c = 0; ! if (c == 0) ! c = (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0; ! switch (op) { ! case Py_LT: c = c < 0; break; ! case Py_LE: c = c <= 0; break; ! case Py_EQ: assert(0); break; /* unreachable */ ! case Py_NE: c = c != 0; break; ! case Py_GT: c = c > 0; break; ! case Py_GE: c = c >= 0; break; ! default: ! result = Py_NotImplemented; ! goto out; } ! result = c ? Py_True : Py_False; ! out: ! Py_INCREF(result); ! return result; } + int + _PyString_Eq(PyObject *o1, PyObject *o2) + { + PyStringObject *a, *b; + a = (PyStringObject*)o1; + b = (PyStringObject*)o2; + return a->ob_size == b->ob_size + && *a->ob_sval == *b->ob_sval + && memcmp(a->ob_sval, b->ob_sval, a->ob_size) == 0; + } + static long string_hash(PyStringObject *a) *************** *** 862,867 **** if (!PyString_Check(item)){ if (PyUnicode_Check(item)) { Py_DECREF(seq); ! return PyUnicode_Join((PyObject *)self, orig); } PyErr_Format(PyExc_TypeError, --- 979,991 ---- if (!PyString_Check(item)){ if (PyUnicode_Check(item)) { + /* Defer to Unicode join. + * CAUTION: There's no gurantee that the + * original sequence can be iterated over + * again, so we must pass seq here. + */ + PyObject *result; + result = PyUnicode_Join((PyObject *)self, seq); Py_DECREF(seq); ! return result; } PyErr_Format(PyExc_TypeError, *************** *** 908,911 **** --- 1032,1053 ---- } + PyObject * + _PyString_Join(PyObject *sep, PyObject *x) + { + PyObject* args; + PyObject* result = NULL; + + assert(sep != NULL && PyString_Check(sep)); + assert(x != NULL); + args = PyTuple_New(1); + if (args != NULL) { + Py_INCREF(x); + PyTuple_SET_ITEM(args, 0, x); + result = string_join((PyStringObject *)sep, args); + Py_DECREF(args); + } + return result; + } + static long string_find_internal(PyStringObject *self, PyObject *args, int dir) *************** *** 916,920 **** PyObject *subobj; ! if (!PyArg_ParseTuple(args, "O|O&O&:find/rfind/index/rindex", &subobj, _PyEval_SliceIndex, &i, _PyEval_SliceIndex, &last)) return -2; --- 1058,1062 ---- PyObject *subobj; ! if (!PyArg_ParseTuple(args, "O|O&O&:find/rfind/index/rindex", &subobj, _PyEval_SliceIndex, &i, _PyEval_SliceIndex, &last)) return -2; *************** *** 949,953 **** else { int j; ! if (n == 0 && i <= last) return (long)last; --- 1091,1095 ---- else { int j; ! if (n == 0 && i <= last) return (long)last; *************** *** 956,960 **** return (long)j; } ! return -1; } --- 1098,1102 ---- return (long)j; } ! return -1; } *************** *** 1372,1376 **** } else if (PyUnicode_Check(tableobj)) { ! /* Unicode .translate() does not support the deletechars parameter; instead a mapping to None will cause characters to be deleted. */ --- 1514,1518 ---- } else if (PyUnicode_Check(tableobj)) { ! /* Unicode .translate() does not support the deletechars parameter; instead a mapping to None will cause characters to be deleted. */ *************** *** 1468,1472 **** MEM, the function returns -1. */ ! static int mymemfind(const char *mem, int len, const char *pat, int pat_len) { --- 1610,1614 ---- MEM, the function returns -1. */ ! static int mymemfind(const char *mem, int len, const char *pat, int pat_len) { *************** *** 1491,1495 **** mem=11111 and pat==11 also return 2. */ ! static int mymemcnt(const char *mem, int len, const char *pat, int pat_len) { --- 1633,1637 ---- mem=11111 and pat==11 also return 2. */ ! static int mymemcnt(const char *mem, int len, const char *pat, int pat_len) { *************** *** 1532,1536 **** const char *sub, int sub_len, /* substitution string */ int count, /* number of replacements */ ! int *out_len) { char *out_s; --- 1674,1678 ---- const char *sub, int sub_len, /* substitution string */ int count, /* number of replacements */ ! int *out_len) { char *out_s; *************** *** 1549,1587 **** if (nfound == 0) goto return_same; new_len = len + nfound*(sub_len - pat_len); ! new_s = (char *)PyMem_MALLOC(new_len); ! if (new_s == NULL) return NULL; *out_len = new_len; - out_s = new_s; - - while (len > 0) { - /* find index of next instance of pattern */ - offset = mymemfind(str, len, pat, pat_len); - /* if not found, break out of loop */ - if (offset == -1) break; - - /* copy non matching part of input string */ - memcpy(new_s, str, offset); /* copy part of str before pat */ - str += offset + pat_len; /* move str past pattern */ - len -= offset + pat_len; /* reduce length of str remaining */ - - /* copy substitute into the output string */ - new_s += offset; /* move new_s to dest for sub string */ - memcpy(new_s, sub, sub_len); /* copy substring into new_s */ - new_s += sub_len; /* offset new_s past sub string */ - - /* break when we've done count replacements */ - if (--count == 0) break; - } - /* copy any remaining values into output string */ - if (len > 0) - memcpy(new_s, str, len); return out_s; return_same: *out_len = -1; ! return (char*)str; /* have to cast away constness here */ } --- 1691,1736 ---- if (nfound == 0) goto return_same; + new_len = len + nfound*(sub_len - pat_len); + if (new_len == 0) { + /* Have to allocate something for the caller to free(). */ + out_s = (char *)PyMem_MALLOC(1); + if (out_s == NULL) + return NULL; + out_s[0] = '\0'; + } + else { + assert(new_len > 0); + new_s = (char *)PyMem_MALLOC(new_len); + if (new_s == NULL) + return NULL; + out_s = new_s; ! for (; count > 0 && len > 0; --count) { ! /* find index of next instance of pattern */ ! offset = mymemfind(str, len, pat, pat_len); ! if (offset == -1) ! break; + /* copy non matching part of input string */ + memcpy(new_s, str, offset); + str += offset + pat_len; + len -= offset + pat_len; + + /* copy substitute into the output string */ + new_s += offset; + memcpy(new_s, sub, sub_len); + new_s += sub_len; + } + /* copy any remaining values into output string */ + if (len > 0) + memcpy(new_s, str, len); + } *out_len = new_len; return out_s; return_same: *out_len = -1; ! return (char *)str; /* cast away const */ } *************** *** 1613,1617 **** } else if (PyUnicode_Check(subobj)) ! return PyUnicode_Replace((PyObject *)self, subobj, replobj, count); else if (PyObject_AsCharBuffer(subobj, &sub, &sub_len)) --- 1762,1766 ---- } else if (PyUnicode_Check(subobj)) ! return PyUnicode_Replace((PyObject *)self, subobj, replobj, count); else if (PyObject_AsCharBuffer(subobj, &sub, &sub_len)) *************** *** 1623,1627 **** } else if (PyUnicode_Check(replobj)) ! return PyUnicode_Replace((PyObject *)self, subobj, replobj, count); else if (PyObject_AsCharBuffer(replobj, &repl, &repl_len)) --- 1772,1776 ---- } else if (PyUnicode_Check(replobj)) ! return PyUnicode_Replace((PyObject *)self, subobj, replobj, count); else if (PyObject_AsCharBuffer(replobj, &repl, &repl_len)) *************** *** 1677,1681 **** else if (PyUnicode_Check(subobj)) { int rc; ! rc = PyUnicode_Tailmatch((PyObject *)self, subobj, start, end, -1); if (rc == -1) --- 1826,1830 ---- else if (PyUnicode_Check(subobj)) { int rc; ! rc = PyUnicode_Tailmatch((PyObject *)self, subobj, start, end, -1); if (rc == -1) *************** *** 1735,1739 **** else if (PyUnicode_Check(subobj)) { int rc; ! rc = PyUnicode_Tailmatch((PyObject *)self, subobj, start, end, +1); if (rc == -1) --- 1884,1888 ---- else if (PyUnicode_Check(subobj)) { int rc; ! rc = PyUnicode_Tailmatch((PyObject *)self, subobj, start, end, +1); if (rc == -1) *************** *** 1758,1765 **** static char encode__doc__[] = ! "S.encode([encoding[,errors]]) -> string\n\ \n\ ! Return an encoded string version of S. Default encoding is the current\n\ ! default string encoding. errors may be given to set a different error\n\ handling scheme. Default is 'strict' meaning that encoding errors raise\n\ a ValueError. Other possible values are 'ignore' and 'replace'."; --- 1907,1914 ---- static char encode__doc__[] = ! "S.encode([encoding[,errors]]) -> object\n\ \n\ ! Encodes S using the codec registered for encoding. encoding defaults\n\ ! to the default encoding. errors may be given to set a different error\n\ handling scheme. Default is 'strict' meaning that encoding errors raise\n\ a ValueError. Other possible values are 'ignore' and 'replace'."; *************** *** 1772,1779 **** if (!PyArg_ParseTuple(args, "|ss:encode", &encoding, &errors)) return NULL; ! return PyString_AsEncodedString((PyObject *)self, encoding, errors); } static char expandtabs__doc__[] = "S.expandtabs([tabsize]) -> string\n\ --- 1921,1947 ---- if (!PyArg_ParseTuple(args, "|ss:encode", &encoding, &errors)) return NULL; ! return PyString_AsEncodedObject((PyObject *)self, encoding, errors); } + static char decode__doc__[] = + "S.decode([encoding[,errors]]) -> object\n\ + \n\ + Decodes S using the codec registered for encoding. encoding defaults\n\ + to the default encoding. errors may be given to set a different error\n\ + handling scheme. Default is 'strict' meaning that encoding errors raise\n\ + a ValueError. Other possible values are 'ignore' and 'replace'."; + + static PyObject * + string_decode(PyStringObject *self, PyObject *args) + { + char *encoding = NULL; + char *errors = NULL; + if (!PyArg_ParseTuple(args, "|ss:decode", &encoding, &errors)) + return NULL; + return PyString_AsDecodedObject((PyObject *)self, encoding, errors); + } + + static char expandtabs__doc__[] = "S.expandtabs([tabsize]) -> string\n\ *************** *** 1837,1843 **** } ! static ! PyObject *pad(PyStringObject *self, ! int left, int right, char fill) --- 2005,2011 ---- } ! static ! PyObject *pad(PyStringObject *self, ! int left, int right, char fill) *************** *** 1855,1865 **** } ! u = PyString_FromStringAndSize(NULL, left + PyString_GET_SIZE(self) + right); if (u) { if (left) memset(PyString_AS_STRING(u), fill, left); ! memcpy(PyString_AS_STRING(u) + left, ! PyString_AS_STRING(self), PyString_GET_SIZE(self)); if (right) --- 2023,2033 ---- } ! u = PyString_FromStringAndSize(NULL, left + PyString_GET_SIZE(self) + right); if (u) { if (left) memset(PyString_AS_STRING(u), fill, left); ! memcpy(PyString_AS_STRING(u) + left, ! PyString_AS_STRING(self), PyString_GET_SIZE(self)); if (right) *************** *** 2316,2320 **** ! static PyMethodDef string_methods[] = { /* Counterparts of the obsolete stropmodule functions; except --- 2484,2488 ---- ! static PyMethodDef string_methods[] = { /* Counterparts of the obsolete stropmodule functions; except *************** *** 2350,2353 **** --- 2518,2522 ---- {"center", (PyCFunction)string_center, 1, center__doc__}, {"encode", (PyCFunction)string_encode, 1, encode__doc__}, + {"decode", (PyCFunction)string_decode, 1, decode__doc__}, {"expandtabs", (PyCFunction)string_expandtabs, 1, expandtabs__doc__}, {"splitlines", (PyCFunction)string_splitlines, 1, splitlines__doc__}, *************** *** 2388,2392 **** 0, /* tp_getattr */ 0, /* tp_setattr */ ! (cmpfunc)string_compare, /* tp_compare */ (reprfunc)string_repr, /* tp_repr */ 0, /* tp_as_number */ --- 2557,2561 ---- 0, /* tp_getattr */ 0, /* tp_setattr */ ! 0, /* tp_compare */ (reprfunc)string_repr, /* tp_repr */ 0, /* tp_as_number */ *************** *** 2403,2407 **** 0, /* tp_traverse */ 0, /* tp_clear */ ! 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ --- 2572,2576 ---- 0, /* tp_traverse */ 0, /* tp_clear */ ! (richcmpfunc)string_richcompare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ *************** *** 2532,2536 **** fmt = %#.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 --- 2701,2705 ---- fmt = %#.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 *************** *** 2555,2559 **** * "-"? ("0x" | "0X")? digit+ * "0x"/"0X" are present only for x and X conversions, with F_ALT ! * set in flags. The case of hex digits will be correct, * There will be at least prec digits, zero-filled on the left if * necessary to get that many. --- 2724,2728 ---- * "-"? ("0x" | "0X")? digit+ * "0x"/"0X" are present only for x and X conversions, with F_ALT ! * set in flags. The case of hex digits will be correct, * There will be at least prec digits, zero-filled on the left if * necessary to get that many. *************** *** 2711,2717 **** * but we want it (for consistency with other %#x conversions, and * for consistency with Python's hex() function). */ ! if (x == 0 && (flags & F_ALT) && (type == 'x' || type == 'X')) { ! assert(buf[1] != type); /* else this C *is* adding 0x/0X */ memmove(buf+2, buf, strlen(buf) + 1); buf[0] = '0'; --- 2880,2892 ---- * but we want it (for consistency with other %#x conversions, and * for consistency with Python's hex() function). + * BUG 28-Apr-2001 tim: At least two platform Cs (Metrowerks & + * Compaq Tru64) violate the std by converting 0 w/ leading 0x anyway. + * So add it only if the platform didn't already. */ ! if (x == 0 && ! (flags & F_ALT) && ! (type == 'x' || type == 'X') && ! buf[1] != (char)type) /* this last always true under std C */ ! { memmove(buf+2, buf, strlen(buf) + 1); buf[0] = '0'; *************** *** 2796,2800 **** int width = -1; int prec = -1; - int size = 0; int c = '\0'; int fill; --- 2971,2974 ---- *************** *** 2806,2810 **** char formatbuf[FORMATBUFLEN]; /* For format{float,int,char}() */ char *fmt_start = fmt; ! fmt++; if (*fmt == '(') { --- 2980,2985 ---- char formatbuf[FORMATBUFLEN]; /* For format{float,int,char}() */ char *fmt_start = fmt; ! int argidx_start = argidx; ! fmt++; if (*fmt == '(') { *************** *** 2816,2820 **** if (dict == NULL) { PyErr_SetString(PyExc_TypeError, ! "format requires a mapping"); goto error; } --- 2991,2995 ---- if (dict == NULL) { PyErr_SetString(PyExc_TypeError, ! "format requires a mapping"); goto error; } *************** *** 2933,2937 **** if (fmtcnt >= 0) { if (c == 'h' || c == 'l' || c == 'L') { - size = c; if (--fmtcnt >= 0) c = *fmt++; --- 3108,3111 ---- *************** *** 2959,2962 **** --- 3133,3137 ---- if (PyUnicode_Check(v)) { fmt = fmt_start; + argidx = argidx_start; goto unicode; } *************** *** 3123,3128 **** args_owned = 0; } ! /* Fiddle args right (remove the first argidx-1 arguments) */ ! --argidx; if (PyTuple_Check(orig_args) && argidx > 0) { PyObject *v; --- 3298,3302 ---- args_owned = 0; } ! /* Fiddle args right (remove the first argidx arguments) */ if (PyTuple_Check(orig_args) && argidx > 0) { PyObject *v; *************** *** 3163,3167 **** Py_DECREF(args); return w; ! error: Py_DECREF(result); --- 3337,3341 ---- Py_DECREF(args); return w; ! error: Py_DECREF(result); Index: tupleobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/tupleobject.c,v retrieving revision 2.48.6.3 retrieving revision 2.48.6.4 diff -C2 -r2.48.6.3 -r2.48.6.4 *** tupleobject.c 2001/06/14 01:01:16 2.48.6.3 --- tupleobject.c 2001/07/07 22:55:30 2.48.6.4 *************** *** 185,202 **** tuplerepr(PyTupleObject *v) { ! PyObject *s, *comma; ! int i; s = PyString_FromString("("); ! comma = PyString_FromString(", "); ! for (i = 0; i < v->ob_size && s != NULL; i++) { ! if (i > 0) ! PyString_Concat(&s, comma); ! PyString_ConcatAndDel(&s, PyObject_Repr(v->ob_item[i])); ! } ! Py_DECREF(comma); ! if (v->ob_size == 1) ! PyString_ConcatAndDel(&s, PyString_FromString(",")); ! PyString_ConcatAndDel(&s, PyString_FromString(")")); ! return s; } --- 185,238 ---- tuplerepr(PyTupleObject *v) { ! int i, n; ! PyObject *s, *temp; ! PyObject *pieces, *result = NULL; ! ! n = v->ob_size; ! if (n == 0) ! return PyString_FromString("()"); ! ! pieces = PyTuple_New(n); ! if (pieces == NULL) ! return NULL; ! ! /* Do repr() on each element. */ ! for (i = 0; i < n; ++i) { ! s = PyObject_Repr(v->ob_item[i]); ! if (s == NULL) ! goto Done; ! PyTuple_SET_ITEM(pieces, i, s); ! } ! ! /* Add "()" decorations to the first and last items. */ ! assert(n > 0); s = PyString_FromString("("); ! if (s == NULL) ! goto Done; ! temp = PyTuple_GET_ITEM(pieces, 0); ! PyString_ConcatAndDel(&s, temp); ! PyTuple_SET_ITEM(pieces, 0, s); ! if (s == NULL) ! goto Done; ! ! s = PyString_FromString(n == 1 ? ",)" : ")"); ! if (s == NULL) ! goto Done; ! temp = PyTuple_GET_ITEM(pieces, n-1); ! PyString_ConcatAndDel(&temp, s); ! PyTuple_SET_ITEM(pieces, n-1, temp); ! if (temp == NULL) ! goto Done; ! ! /* Paste them all together with ", " between. */ ! s = PyString_FromString(", "); ! if (s == NULL) ! goto Done; ! result = _PyString_Join(s, pieces); ! Py_DECREF(s); ! ! Done: ! Py_DECREF(pieces); ! return result; } *************** *** 377,380 **** --- 413,417 ---- PyTupleObject *vt, *wt; int i; + int vlen, wlen; if (!PyTuple_Check(v) || !PyTuple_Check(w)) { *************** *** 386,402 **** wt = (PyTupleObject *)w; ! if (vt->ob_size != wt->ob_size && (op == Py_EQ || op == Py_NE)) { ! /* Shortcut: if the lengths differ, the tuples differ */ ! PyObject *res; ! if (op == Py_EQ) ! res = Py_False; ! else ! res = Py_True; ! Py_INCREF(res); ! return res; ! } ! /* Search for the first index where items are different */ ! for (i = 0; i < vt->ob_size && i < wt->ob_size; i++) { int k = PyObject_RichCompareBool(vt->ob_item[i], wt->ob_item[i], Py_EQ); --- 423,441 ---- wt = (PyTupleObject *)w; ! vlen = vt->ob_size; ! wlen = wt->ob_size; ! /* Note: the corresponding code for lists has an "early out" test ! * here when op is EQ or NE and the lengths differ. That pays there, ! * but Tim was unable to find any real code where EQ/NE tuple ! * compares don't have the same length, so testing for it here would ! * have cost without benefit. ! */ ! ! /* Search for the first index where items are different. ! * Note that because tuples are immutable, it's safe to reuse ! * vlen and wlen across the comparison calls. ! */ ! for (i = 0; i < vlen && i < wlen; i++) { int k = PyObject_RichCompareBool(vt->ob_item[i], wt->ob_item[i], Py_EQ); *************** *** 407,423 **** } ! if (i >= vt->ob_size || i >= wt->ob_size) { /* No more items to compare -- compare sizes */ - int vs = vt->ob_size; - int ws = wt->ob_size; int cmp; PyObject *res; switch (op) { ! case Py_LT: cmp = vs < ws; break; ! case Py_LE: cmp = ws <= ws; break; ! case Py_EQ: cmp = vs == ws; break; ! case Py_NE: cmp = vs != ws; break; ! case Py_GT: cmp = vs > ws; break; ! case Py_GE: cmp = vs >= ws; break; default: return NULL; /* cannot happen */ } --- 446,460 ---- } ! if (i >= vlen || i >= wlen) { /* No more items to compare -- compare sizes */ int cmp; PyObject *res; switch (op) { ! case Py_LT: cmp = vlen < wlen; break; ! case Py_LE: cmp = vlen <= wlen; break; ! case Py_EQ: cmp = vlen == wlen; break; ! case Py_NE: cmp = vlen != wlen; break; ! case Py_GT: cmp = vlen > wlen; break; ! case Py_GE: cmp = vlen >= wlen; break; default: return NULL; /* cannot happen */ } *************** *** 524,532 **** as creating a new tuple object and destroying the old one, only more efficiently. In any case, don't use this if the tuple may already be ! known to some other part of the code. The last_is_sticky is not used ! and must always be false. */ int ! _PyTuple_Resize(PyObject **pv, int newsize, int last_is_sticky) { register PyTupleObject *v; --- 561,568 ---- as creating a new tuple object and destroying the old one, only more efficiently. In any case, don't use this if the tuple may already be ! known to some other part of the code. */ int ! _PyTuple_Resize(PyObject **pv, int newsize) { register PyTupleObject *v; *************** *** 536,541 **** v = (PyTupleObject *) *pv; ! if (v == NULL || !PyTuple_Check(v) || v->ob_refcnt != 1 || ! last_is_sticky) { *pv = 0; Py_XDECREF(v); --- 572,577 ---- v = (PyTupleObject *) *pv; ! if (v == NULL || !PyTuple_Check(v) || ! (v->ob_size != 0 && v->ob_refcnt != 1)) { *pv = 0; Py_XDECREF(v); *************** *** 546,549 **** --- 582,594 ---- if (sizediff == 0) return 0; + + if (v->ob_size == 0) { + /* Empty tuples are often shared, so we should never + resize them in-place even if we do own the only + (current) reference */ + Py_DECREF(v); + *pv = PyTuple_New(newsize); + return *pv == NULL ? -1 : 0; + } /* XXX UNREF/NEWREF interface should be more symmetrical */ Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.62 retrieving revision 2.16.8.63 diff -C2 -r2.16.8.62 -r2.16.8.63 *** typeobject.c 2001/07/05 21:39:52 2.16.8.62 --- typeobject.c 2001/07/07 22:55:30 2.16.8.63 *************** *** 75,78 **** --- 75,88 ---- }; + static int + type_compare(PyObject *v, PyObject *w) + { + /* This is called with type objects only. So we + can just compare the addresses. */ + Py_uintptr_t vv = (Py_uintptr_t)v; + Py_uintptr_t ww = (Py_uintptr_t)w; + return (vv < ww) ? -1 : (vv > ww) ? 1 : 0; + } + static PyObject * type_repr(PyTypeObject *type) *************** *** 774,783 **** 0, /* tp_getattr */ 0, /* tp_setattr */ ! 0, /* tp_compare */ (reprfunc)type_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ ! 0, /* tp_hash */ (ternaryfunc)type_call, /* tp_call */ 0, /* tp_str */ --- 784,793 ---- 0, /* tp_getattr */ 0, /* tp_setattr */ ! type_compare, /* tp_compare */ (reprfunc)type_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ ! (hashfunc)_Py_HashPointer, /* tp_hash */ (ternaryfunc)type_call, /* tp_call */ 0, /* tp_str */ Index: unicodectype.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodectype.c,v retrieving revision 2.7 retrieving revision 2.7.8.1 diff -C2 -r2.7 -r2.7.8.1 *** unicodectype.c 2000/09/25 21:48:13 2.7 --- unicodectype.c 2001/07/07 22:55:30 2.7.8.1 *************** *** 33,41 **** static const _PyUnicode_TypeRecord * ! gettyperecord(int code) { int index; ! if (code < 0 || code >= 65536) index = 0; else { --- 33,41 ---- static const _PyUnicode_TypeRecord * ! gettyperecord(Py_UNICODE code) { int index; ! if (code >= 65536) index = 0; else { *************** *** 43,46 **** --- 43,47 ---- index = index2[(index<title) ! return ch + ctype->title; ! ! return ch + ctype->upper; } --- 60,78 ---- ch if no titlecase mapping is known. */ ! Py_UNICODE _PyUnicode_ToTitlecase(register Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); if (ctype->title) ! ch += ctype->title; ! else ! ch += ctype->upper; ! ! #ifdef Py_UNICODE_WIDE ! /* The database assumes that the values wrap around at 0x10000. */ ! if (ch > 0x10000) ! ch -= 0x10000; ! #endif ! return ch; } *************** *** 72,76 **** otherwise. */ ! int _PyUnicode_IsTitlecase(register const Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); --- 80,84 ---- otherwise. */ ! int _PyUnicode_IsTitlecase(Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); *************** *** 82,86 **** this property, -1 otherwise. */ ! int _PyUnicode_ToDecimalDigit(register const Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); --- 90,94 ---- this property, -1 otherwise. */ ! int _PyUnicode_ToDecimalDigit(Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); *************** *** 89,93 **** } ! int _PyUnicode_IsDecimalDigit(register const Py_UNICODE ch) { if (_PyUnicode_ToDecimalDigit(ch) < 0) --- 97,101 ---- } ! int _PyUnicode_IsDecimalDigit(Py_UNICODE ch) { if (_PyUnicode_ToDecimalDigit(ch) < 0) *************** *** 99,103 **** this property, -1 otherwise. */ ! int _PyUnicode_ToDigit(register const Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); --- 107,111 ---- this property, -1 otherwise. */ ! int _PyUnicode_ToDigit(Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); *************** *** 106,110 **** } ! int _PyUnicode_IsDigit(register const Py_UNICODE ch) { if (_PyUnicode_ToDigit(ch) < 0) --- 114,118 ---- } ! int _PyUnicode_IsDigit(Py_UNICODE ch) { if (_PyUnicode_ToDigit(ch) < 0) *************** *** 118,122 **** /* TODO: replace with unicodetype_db.h table */ ! double _PyUnicode_ToNumeric(register const Py_UNICODE ch) { switch (ch) { --- 126,130 ---- /* TODO: replace with unicodetype_db.h table */ ! double _PyUnicode_ToNumeric(Py_UNICODE ch) { switch (ch) { *************** *** 306,310 **** } ! int _PyUnicode_IsNumeric(register const Py_UNICODE ch) { if (_PyUnicode_ToNumeric(ch) < 0.0) --- 314,318 ---- } ! int _PyUnicode_IsNumeric(Py_UNICODE ch) { if (_PyUnicode_ToNumeric(ch) < 0.0) *************** *** 318,322 **** 'WS', 'B' or 'S' or the category 'Zs', 0 otherwise. */ ! int _PyUnicode_IsWhitespace(register const Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); --- 326,330 ---- 'WS', 'B' or 'S' or the category 'Zs', 0 otherwise. */ ! int _PyUnicode_IsWhitespace(Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); *************** *** 328,332 **** otherwise. */ ! int _PyUnicode_IsLowercase(register const Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); --- 336,340 ---- otherwise. */ ! int _PyUnicode_IsLowercase(Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); *************** *** 338,342 **** otherwise. */ ! int _PyUnicode_IsUppercase(register const Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); --- 346,350 ---- otherwise. */ ! int _PyUnicode_IsUppercase(Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); *************** *** 348,356 **** ch if no uppercase mapping is known. */ ! Py_UNICODE _PyUnicode_ToUppercase(register const Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); ! return ch + ctype->upper; } --- 356,370 ---- ch if no uppercase mapping is known. */ ! Py_UNICODE _PyUnicode_ToUppercase(Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); ! ch += ctype->upper; ! #ifdef Py_UNICODE_WIDE ! /* The database assumes that the values wrap around at 0x10000. */ ! if (ch > 0x10000) ! ch -= 0x10000; ! #endif ! return ch; } *************** *** 358,366 **** ch if no lowercase mapping is known. */ ! Py_UNICODE _PyUnicode_ToLowercase(register const Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); ! return ch + ctype->lower; } --- 372,386 ---- ch if no lowercase mapping is known. */ ! Py_UNICODE _PyUnicode_ToLowercase(Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); ! ch += ctype->lower; ! #ifdef Py_UNICODE_WIDE ! /* The database assumes that the values wrap around at 0x10000. */ ! if (ch > 0x10000) ! ch -= 0x10000; ! #endif ! return ch; } *************** *** 368,372 **** 'Lo' or 'Lm', 0 otherwise. */ ! int _PyUnicode_IsAlpha(register const Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); --- 388,392 ---- 'Lo' or 'Lm', 0 otherwise. */ ! int _PyUnicode_IsAlpha(Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); *************** *** 380,409 **** reasons: */ ! int _PyUnicode_IsWhitespace(register const Py_UNICODE ch) { return iswspace(ch); } ! int _PyUnicode_IsLowercase(register const Py_UNICODE ch) { return iswlower(ch); } ! int _PyUnicode_IsUppercase(register const Py_UNICODE ch) { return iswupper(ch); } ! Py_UNICODE _PyUnicode_ToLowercase(register const Py_UNICODE ch) { return towlower(ch); } ! Py_UNICODE _PyUnicode_ToUppercase(register const Py_UNICODE ch) { return towupper(ch); } ! int _PyUnicode_IsAlpha(register const Py_UNICODE ch) { return iswalpha(ch); --- 400,429 ---- reasons: */ ! int _PyUnicode_IsWhitespace(Py_UNICODE ch) { return iswspace(ch); } ! int _PyUnicode_IsLowercase(Py_UNICODE ch) { return iswlower(ch); } ! int _PyUnicode_IsUppercase(Py_UNICODE ch) { return iswupper(ch); } ! Py_UNICODE _PyUnicode_ToLowercase(Py_UNICODE ch) { return towlower(ch); } ! Py_UNICODE _PyUnicode_ToUppercase(Py_UNICODE ch) { return towupper(ch); } ! int _PyUnicode_IsAlpha(Py_UNICODE ch) { return iswalpha(ch); Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.87.2.4 retrieving revision 2.87.2.5 diff -C2 -r2.87.2.4 -r2.87.2.5 *** unicodeobject.c 2001/06/14 18:12:02 2.87.2.4 --- unicodeobject.c 2001/07/07 22:55:30 2.87.2.5 *************** *** 104,107 **** --- 104,119 ---- static char unicode_default_encoding[100]; + Py_UNICODE + PyUnicode_GetMax() + { + #ifdef Py_UNICODE_WIDE + return 0x10FFFF; + #else + /* This is actually an illegal character, so it should + not be passed to unichr. */ + return 0xFFFF; + #endif + } + /* --- Unicode Object ----------------------------------------------------- */ *************** *** 184,191 **** } } ! else { unicode->str = PyMem_NEW(Py_UNICODE, length + 1); ! } ! PyObject_INIT(unicode, &PyUnicode_Type); } else { --- 196,203 ---- } } ! else { unicode->str = PyMem_NEW(Py_UNICODE, length + 1); ! } ! PyObject_INIT(unicode, &PyUnicode_Type); } else { *************** *** 298,304 **** if (!unicode) { unicode = _PyUnicode_New(1); - unicode->str[0] = *u; if (!unicode) return NULL; unicode_latin1[*u] = unicode; } --- 310,316 ---- if (!unicode) { unicode = _PyUnicode_New(1); if (!unicode) return NULL; + unicode->str[0] = *u; unicode_latin1[*u] = unicode; } *************** *** 530,534 **** if (errors == NULL) { if (strcmp(encoding, "utf-8") == 0) ! return PyUnicode_AsUTF8String(unicode); else if (strcmp(encoding, "latin-1") == 0) return PyUnicode_AsLatin1String(unicode); --- 542,546 ---- if (errors == NULL) { if (strcmp(encoding, "utf-8") == 0) ! return PyUnicode_AsUTF8String(unicode); else if (strcmp(encoding, "latin-1") == 0) return PyUnicode_AsLatin1String(unicode); *************** *** 772,782 **** ((s[2] & 0x3f) << 6) + (s[3] & 0x3f); /* validate and convert to UTF-16 */ ! if ((ch < 0x10000) || /* minimum value allowed for 4 byte encoding */ ! (ch > 0x10ffff)) { /* maximum value allowed for UTF-16 */ errmsg = "illegal encoding"; goto utf8Error; } /* compute and append the two surrogates: */ --- 784,798 ---- ((s[2] & 0x3f) << 6) + (s[3] & 0x3f); /* validate and convert to UTF-16 */ ! if ((ch < 0x10000) /* minimum value allowed for 4 byte encoding */ ! || (ch > 0x10ffff)) /* maximum value allowed for UTF-16 */ + { errmsg = "illegal encoding"; goto utf8Error; } + #ifdef Py_UNICODE_WIDE + *p++ = (Py_UNICODE)ch; + #else /* compute and append the two surrogates: */ *************** *** 788,792 **** /* low surrogate = bottom 10 bits added to DC00 */ ! *p++ = (Py_UNICODE)(0xDC00 + (ch & ~0xFC00)); break; --- 804,809 ---- /* low surrogate = bottom 10 bits added to DC00 */ ! *p++ = (Py_UNICODE)(0xDC00 + (ch & 0x03FF)); ! #endif break; *************** *** 879,883 **** cbWritten += 2; } ! else { /* Check for high surrogate */ if (0xD800 <= ch && ch <= 0xDBFF) { --- 896,900 ---- cbWritten += 2; } ! else if (ch < 0x10000) { /* Check for high surrogate */ if (0xD800 <= ch && ch <= 0xDBFF) { *************** *** 910,914 **** *p++ = (char)(0x80 | ((ch >> 6) & 0x3f)); *p++ = (char)(0x80 | (ch & 0x3f)); ! } } *p = '\0'; --- 927,937 ---- *p++ = (char)(0x80 | ((ch >> 6) & 0x3f)); *p++ = (char)(0x80 | (ch & 0x3f)); ! } else { ! *p++ = 0xf0 | (ch>>18); ! *p++ = 0x80 | ((ch>>12) & 0x3f); ! *p++ = 0x80 | ((ch>>6) & 0x3f); ! *p++ = 0x80 | (ch & 0x3f); ! cbWritten += 4; ! } } *p = '\0'; *************** *** 936,940 **** static ! int utf16_decoding_error(const Py_UNICODE **source, Py_UNICODE **dest, const char *errors, --- 959,963 ---- static ! int utf16_decoding_error(const Py_UCS2 **source, Py_UNICODE **dest, const char *errors, *************** *** 974,983 **** PyUnicodeObject *unicode; Py_UNICODE *p; ! const Py_UNICODE *q, *e; int bo = 0; const char *errmsg = ""; /* size should be an even number */ ! if (size % sizeof(Py_UNICODE) != 0) { if (utf16_decoding_error(NULL, NULL, errors, "truncated data")) return NULL; --- 997,1006 ---- PyUnicodeObject *unicode; Py_UNICODE *p; ! const Py_UCS2 *q, *e; int bo = 0; const char *errmsg = ""; /* size should be an even number */ ! if (size % sizeof(Py_UCS2) != 0) { if (utf16_decoding_error(NULL, NULL, errors, "truncated data")) return NULL; *************** *** 996,1030 **** /* Unpack UTF-16 encoded data */ p = unicode->str; ! q = (Py_UNICODE *)s; ! e = q + (size / sizeof(Py_UNICODE)); if (byteorder) bo = *byteorder; - - while (q < e) { - register Py_UNICODE ch = *q++; ! /* Check for BOM marks (U+FEFF) in the input and adjust ! current byte order setting accordingly. Swap input ! bytes if needed. (This assumes sizeof(Py_UNICODE) == 2 ! !) */ #ifdef BYTEORDER_IS_LITTLE_ENDIAN ! if (ch == 0xFEFF) { bo = -1; ! continue; ! } else if (ch == 0xFFFE) { bo = 1; - continue; } - if (bo == 1) - ch = (ch >> 8) | (ch << 8); #else ! if (ch == 0xFEFF) { bo = 1; ! continue; ! } else if (ch == 0xFFFE) { bo = -1; - continue; } if (bo == -1) ch = (ch >> 8) | (ch << 8); --- 1019,1061 ---- /* Unpack UTF-16 encoded data */ p = unicode->str; ! q = (Py_UCS2 *)s; ! e = q + (size / sizeof(Py_UCS2)); if (byteorder) bo = *byteorder; ! /* Check for BOM marks (U+FEFF) in the input and adjust current ! byte order setting accordingly. In native mode, the leading BOM ! mark is skipped, in all other modes, it is copied to the output ! stream as-is (giving a ZWNBSP character). */ ! if (bo == 0) { #ifdef BYTEORDER_IS_LITTLE_ENDIAN ! if (*q == 0xFEFF) { ! q++; bo = -1; ! } else if (*q == 0xFFFE) { ! q++; bo = 1; } #else ! if (*q == 0xFEFF) { ! q++; bo = 1; ! } else if (*q == 0xFFFE) { ! q++; bo = -1; } + #endif + } + + while (q < e) { + register Py_UCS2 ch = *q++; + + /* Swap input bytes if needed. (This assumes + sizeof(Py_UNICODE) == 2 !) */ + #ifdef BYTEORDER_IS_LITTLE_ENDIAN + if (bo == 1) + ch = (ch >> 8) | (ch << 8); + #else if (bo == -1) ch = (ch >> 8) | (ch << 8); *************** *** 1040,1046 **** goto utf16Error; } ! if (0xDC00 <= *q && *q <= 0xDFFF) { ! q++; ! if (0xD800 <= *q && *q <= 0xDBFF) { /* This is valid data (a UTF-16 surrogate pair), but we are not able to store this information since our --- 1071,1085 ---- goto utf16Error; } ! if (0xD800 <= ch && ch <= 0xDBFF) { ! Py_UCS2 ch2 = *q++; ! #ifdef BYTEORDER_IS_LITTLE_ENDIAN ! if (bo == 1) ! ch2 = (ch2 >> 8) | (ch2 << 8); ! #else ! if (bo == -1) ! ch2 = (ch2 >> 8) | (ch2 << 8); ! #endif ! if (0xDC00 <= ch2 && ch2 <= 0xDFFF) { ! #ifndef Py_UNICODE_WIDE /* This is valid data (a UTF-16 surrogate pair), but we are not able to store this information since our *************** *** 1049,1055 **** errmsg = "code pairs are not supported"; goto utf16Error; ! } ! else continue; } errmsg = "illegal encoding"; --- 1088,1102 ---- errmsg = "code pairs are not supported"; goto utf16Error; ! #else ! *p++ = (((ch & 0x3FF)<<10) | (ch2 & 0x3FF)) + 0x10000; continue; + #endif + + } + else { + errmsg = "illegal UTF-16 surrogate"; + goto utf16Error; + } + } errmsg = "illegal encoding"; *************** *** 1083,1097 **** { PyObject *v; ! Py_UNICODE *p; char *q; ! /* We don't create UTF-16 pairs... */ v = PyString_FromStringAndSize(NULL, ! sizeof(Py_UNICODE) * (size + (byteorder == 0))); if (v == NULL) return NULL; q = PyString_AS_STRING(v); ! p = (Py_UNICODE *)q; if (byteorder == 0) *p++ = 0xFEFF; --- 1130,1147 ---- { PyObject *v; ! Py_UCS2 *p; char *q; + int i, pairs, doswap = 1; ! for (i = pairs = 0; i < size; i++) ! if (s[i] >= 0x10000) ! pairs++; v = PyString_FromStringAndSize(NULL, ! sizeof(Py_UCS2) * (size + pairs + (byteorder == 0))); if (v == NULL) return NULL; q = PyString_AS_STRING(v); ! p = (Py_UCS2 *)q; if (byteorder == 0) *p++ = 0xFEFF; *************** *** 1105,1114 **** #endif ) ! Py_UNICODE_COPY(p, s, size); ! else ! while (size-- > 0) { ! Py_UNICODE ch = *s++; *p++ = (ch >> 8) | (ch << 8); } return v; } --- 1155,1176 ---- #endif ) ! doswap = 0; ! while (size-- > 0) { ! Py_UNICODE ch = *s++; ! Py_UNICODE ch2 = 0; ! if (ch >= 0x10000) { ! ch2 = 0xDC00|((ch-0x10000) & 0x3FF); ! ch = 0xD800|((ch-0x10000)>>10); ! } ! if (doswap){ *p++ = (ch >> 8) | (ch << 8); + if (ch2) + *p++ = (ch2 >> 8) | (ch2 << 8); + }else{ + *p++ = ch; + if(ch2) + *p++ = ch2; } + } return v; } *************** *** 1264,1271 **** *p++ = (Py_UNICODE) chr; else if (chr <= 0x10ffff) { ! /* UCS-4 character. store as two surrogate characters */ chr -= 0x10000L; *p++ = 0xD800 + (Py_UNICODE) (chr >> 10); ! *p++ = 0xDC00 + (Py_UNICODE) (chr & ~0xFC00); } else { if (unicodeescape_decoding_error( --- 1326,1337 ---- *p++ = (Py_UNICODE) chr; else if (chr <= 0x10ffff) { ! /* UCS-4 character. Either store directly, or as surrogate pair. */ ! #ifdef Py_UNICODE_WIDE ! *p++ = chr; ! #else chr -= 0x10000L; *p++ = 0xD800 + (Py_UNICODE) (chr >> 10); ! *p++ = 0xDC00 + (Py_UNICODE) (chr & 0x03FF); ! #endif } else { if (unicodeescape_decoding_error( *************** *** 1372,1379 **** Py_UNICODE ch = *s++; /* Escape quotes */ ! if (quotes && (ch == q[1] || ch == '\\')) { *p++ = '\\'; *p++ = (char) ch; } /* Map 16-bit characters to '\uxxxx' */ else if (ch >= 256) { --- 1438,1458 ---- Py_UNICODE ch = *s++; /* Escape quotes */ ! if (quotes && (ch == (Py_UNICODE) q[1] || ch == '\\')) { *p++ = '\\'; *p++ = (char) ch; } + /* Map 21-bit characters to '\U00xxxxxx' */ + else if (ch >= 0x10000) { + *p++ = '\\'; + *p++ = 'U'; + *p++ = hexdigit[(ch >> 28) & 0xf]; + *p++ = hexdigit[(ch >> 24) & 0xf]; + *p++ = hexdigit[(ch >> 20) & 0xf]; + *p++ = hexdigit[(ch >> 16) & 0xf]; + *p++ = hexdigit[(ch >> 12) & 0xf]; + *p++ = hexdigit[(ch >> 8) & 0xf]; + *p++ = hexdigit[(ch >> 4) & 0xf]; + *p++ = hexdigit[ch & 15]; + } /* Map 16-bit characters to '\uxxxx' */ else if (ch >= 256) { *************** *** 1824,1828 **** } ! #ifdef MS_WIN32 /* --- MBCS codecs for Windows -------------------------------------------- */ --- 1903,1907 ---- } ! #if defined(MS_WIN32) && defined(HAVE_USABLE_WCHAR_T) /* --- MBCS codecs for Windows -------------------------------------------- */ *************** *** 2722,2732 **** int reslen = 0; Py_UNICODE *p; - int seqlen = 0; int sz = 100; int i; ! seqlen = PySequence_Size(seq); ! if (seqlen < 0 && PyErr_Occurred()) ! return NULL; if (separator == NULL) { --- 2801,2811 ---- int reslen = 0; Py_UNICODE *p; int sz = 100; int i; + PyObject *it; ! it = PyObject_GetIter(seq); ! if (it == NULL) ! return NULL; if (separator == NULL) { *************** *** 2738,2742 **** separator = PyUnicode_FromObject(separator); if (separator == NULL) ! return NULL; sep = PyUnicode_AS_UNICODE(separator); seplen = PyUnicode_GET_SIZE(separator); --- 2817,2821 ---- separator = PyUnicode_FromObject(separator); if (separator == NULL) ! goto onError; sep = PyUnicode_AS_UNICODE(separator); seplen = PyUnicode_GET_SIZE(separator); *************** *** 2749,2759 **** reslen = 0; ! for (i = 0; i < seqlen; i++) { int itemlen; ! PyObject *item; ! ! item = PySequence_GetItem(seq, i); ! if (item == NULL) ! goto onError; if (!PyUnicode_Check(item)) { PyObject *v; --- 2828,2839 ---- reslen = 0; ! for (i = 0; ; ++i) { int itemlen; ! PyObject *item = PyIter_Next(it); ! if (item == NULL) { ! if (PyErr_Occurred()) ! goto onError; ! break; ! } if (!PyUnicode_Check(item)) { PyObject *v; *************** *** 2785,2793 **** Py_XDECREF(separator); return (PyObject *)res; onError: Py_XDECREF(separator); ! Py_DECREF(res); return NULL; } --- 2865,2875 ---- Py_XDECREF(separator); + Py_DECREF(it); return (PyObject *)res; onError: Py_XDECREF(separator); ! Py_XDECREF(res); ! Py_DECREF(it); return NULL; } *************** *** 3250,3266 **** while (len1 > 0 && len2 > 0) { Py_UNICODE c1, c2; - long diff; c1 = *s1++; c2 = *s2++; if (c1 > (1<<11) * 26) c1 += utf16Fixup[c1>>11]; if (c2 > (1<<11) * 26) c2 += utf16Fixup[c2>>11]; - /* now c1 and c2 are in UTF-32-compatible order */ ! diff = (long)c1 - (long)c2; ! if (diff) ! return (diff < 0) ? -1 : (diff != 0); len1--; len2--; } --- 3332,3348 ---- while (len1 > 0 && len2 > 0) { Py_UNICODE c1, c2; c1 = *s1++; c2 = *s2++; + if (c1 > (1<<11) * 26) c1 += utf16Fixup[c1>>11]; if (c2 > (1<<11) * 26) c2 += utf16Fixup[c2>>11]; /* now c1 and c2 are in UTF-32-compatible order */ ! ! if (c1 != c2) ! return (c1 < c2) ? -1 : 1; ! len1--; len2--; } *************** *** 3283,3291 **** while (len1 > 0 && len2 > 0) { ! register long diff; ! diff = (long)*s1++ - (long)*s2++; ! if (diff) ! return (diff < 0) ? -1 : (diff != 0); len1--; len2--; } --- 3365,3376 ---- while (len1 > 0 && len2 > 0) { ! Py_UNICODE c1, c2; ! ! c1 = *s1++; ! c2 = *s2++; ! if (c1 != c2) ! return (c1 < c2) ? -1 : 1; ! len1--; len2--; } *************** *** 4732,4735 **** --- 4817,4821 ---- char fmt[64]; /* plenty big enough! */ long x; + int use_native_c_format = 1; x = PyInt_AsLong(v); *************** *** 4748,4756 **** * but we want it (for consistency with other %#x conversions, and * for consistency with Python's hex() function). */ ! if (x == 0 && (flags & F_ALT) && (type == 'x' || type == 'X')) ! sprintf(fmt, "0%c%%%s.%dl%c", type, "#", prec, type); ! else ! sprintf(fmt, "%%%s.%dl%c", (flags & F_ALT) ? "#" : "", prec, type); return usprintf(buf, fmt, x); } --- 4834,4852 ---- * but we want it (for consistency with other %#x conversions, and * for consistency with Python's hex() function). + * BUG 28-Apr-2001 tim: At least two platform Cs (Metrowerks & + * Compaq Tru64) violate the std by converting 0 w/ leading 0x anyway. + * So add it only if the platform doesn't already. */ ! if (x == 0 && (flags & F_ALT) && (type == 'x' || type == 'X')) { ! /* Only way to know what the platform does is to try it. */ ! sprintf(fmt, type == 'x' ? "%#x" : "%#X", 0); ! if (fmt[1] != (char)type) { ! /* Supply our own leading 0x/0X -- needed under std C */ ! use_native_c_format = 0; ! sprintf(fmt, "0%c%%#.%dl%c", type, prec, type); ! } ! } ! if (use_native_c_format) ! sprintf(fmt, "%%%s.%dl%c", (flags & F_ALT) ? "#" : "", prec, type); return usprintf(buf, fmt, x); } *************** *** 5292,5300 **** { int i; - - /* Doublecheck the configuration... */ - if (sizeof(Py_UNICODE) != 2) - Py_FatalError("Unicode configuration error: " - "sizeof(Py_UNICODE) != 2 bytes"); /* Init the implementation */ --- 5388,5391 ---- From tim_one@users.sourceforge.net Sat Jul 7 23:55:33 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 15:55:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.198.2.6,2.198.2.7 ceval.c,2.241.2.4,2.241.2.5 compile.c,2.197,2.197.2.1 dynload_win.c,2.7,2.7.8.1 errors.c,2.62,2.62.6.1 getargs.c,2.54.6.1,2.54.6.2 graminit.c,2.28,2.28.8.1 import.c,2.176.2.1,2.176.2.2 marshal.c,1.62,1.62.4.1 pystate.c,2.16,2.16.6.1 pythonrun.c,2.133.4.3,2.133.4.4 symtable.c,2.4,2.4.6.1 sysmodule.c,2.85,2.85.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv24450/mergedescr/dist/src/Python Modified Files: Tag: descr-branch bltinmodule.c ceval.c compile.c dynload_win.c errors.c getargs.c graminit.c import.c marshal.c pystate.c pythonrun.c symtable.c sysmodule.c Log Message: Merge of trunk tag date2001-07-06 into descr-branch. Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.198.2.6 retrieving revision 2.198.2.7 diff -C2 -r2.198.2.6 -r2.198.2.7 *** bltinmodule.c 2001/07/04 00:13:58 2.198.2.6 --- bltinmodule.c 2001/07/07 22:55:30 2.198.2.7 *************** *** 14,17 **** --- 14,26 ---- #endif + /* The default encoding used by the platform file system APIs + Can remain NULL for all platforms that don't have such a concept + */ + #if defined(MS_WIN32) && defined(HAVE_USABLE_WCHAR_T) + const char *Py_FileSystemDefaultEncoding = "mbcs"; + #else + const char *Py_FileSystemDefaultEncoding = NULL; /* use default */ + #endif + /* Forward */ static PyObject *filterstring(PyObject *, PyObject *); *************** *** 143,193 **** builtin_filter(PyObject *self, PyObject *args) { ! PyObject *func, *seq, *result; ! PySequenceMethods *sqf; ! int len; ! register int i, j; if (!PyArg_ParseTuple(args, "OO:filter", &func, &seq)) return NULL; - - if (PyString_Check(seq)) { - PyObject *r = filterstring(func, seq); - return r; - } - - if (PyTuple_Check(seq)) { - PyObject *r = filtertuple(func, seq); - return r; - } ! sqf = seq->ob_type->tp_as_sequence; ! if (sqf == NULL || sqf->sq_length == NULL || sqf->sq_item == NULL) { ! PyErr_SetString(PyExc_TypeError, ! "filter() arg 2 must be a sequence"); ! goto Fail_2; } ! if ((len = (*sqf->sq_length)(seq)) < 0) ! goto Fail_2; ! if (PyList_Check(seq) && seq->ob_refcnt == 1) { Py_INCREF(seq); result = seq; } else { ! if ((result = PyList_New(len)) == NULL) ! goto Fail_2; } ! for (i = j = 0; ; ++i) { PyObject *item, *good; int ok; ! if ((item = (*sqf->sq_item)(seq, i)) == NULL) { ! if (PyErr_ExceptionMatches(PyExc_IndexError)) { ! PyErr_Clear(); ! break; ! } ! goto Fail_1; } --- 152,207 ---- builtin_filter(PyObject *self, PyObject *args) { ! PyObject *func, *seq, *result, *it; ! int len; /* guess for result list size */ ! register int j; if (!PyArg_ParseTuple(args, "OO:filter", &func, &seq)) return NULL; ! /* Strings and tuples return a result of the same type. */ ! if (PyString_Check(seq)) ! return filterstring(func, seq); ! if (PyTuple_Check(seq)) ! return filtertuple(func, seq); ! ! /* Get iterator. */ ! it = PyObject_GetIter(seq); ! if (it == NULL) ! return NULL; ! ! /* Guess a result list size. */ ! len = -1; /* unknown */ ! if (PySequence_Check(seq) && ! seq->ob_type->tp_as_sequence->sq_length) { ! len = PySequence_Size(seq); ! if (len < 0) ! PyErr_Clear(); } + if (len < 0) + len = 8; /* arbitrary */ ! /* Get a result list. */ if (PyList_Check(seq) && seq->ob_refcnt == 1) { + /* Eww - can modify the list in-place. */ Py_INCREF(seq); result = seq; } else { ! result = PyList_New(len); ! if (result == NULL) ! goto Fail_it; } ! /* Build the result list. */ ! j = 0; ! for (;;) { PyObject *item, *good; int ok; ! item = PyIter_Next(it); ! if (item == NULL) { ! if (PyErr_Occurred()) ! goto Fail_result_it; ! break; } *************** *** 198,208 **** else { PyObject *arg = Py_BuildValue("(O)", item); ! if (arg == NULL) ! goto Fail_1; good = PyEval_CallObject(func, arg); Py_DECREF(arg); if (good == NULL) { Py_DECREF(item); ! goto Fail_1; } } --- 212,224 ---- else { PyObject *arg = Py_BuildValue("(O)", item); ! if (arg == NULL) { ! Py_DECREF(item); ! goto Fail_result_it; ! } good = PyEval_CallObject(func, arg); Py_DECREF(arg); if (good == NULL) { Py_DECREF(item); ! goto Fail_result_it; } } *************** *** 210,238 **** Py_DECREF(good); if (ok) { ! if (j < len) { ! if (PyList_SetItem(result, j++, item) < 0) ! goto Fail_1; ! } else { int status = PyList_Append(result, item); - j++; Py_DECREF(item); if (status < 0) ! goto Fail_1; } ! } else { ! Py_DECREF(item); } } if (j < len && PyList_SetSlice(result, j, len, NULL) < 0) ! goto Fail_1; return result; ! Fail_1: Py_DECREF(result); ! Fail_2: return NULL; } --- 226,255 ---- Py_DECREF(good); if (ok) { ! if (j < len) ! PyList_SET_ITEM(result, j, item); else { int status = PyList_Append(result, item); Py_DECREF(item); if (status < 0) ! goto Fail_result_it; } ! ++j; } + else + Py_DECREF(item); } + /* Cut back result list if len is too big. */ if (j < len && PyList_SetSlice(result, j, len, NULL) < 0) ! goto Fail_result_it; + Py_DECREF(it); return result; ! Fail_result_it: Py_DECREF(result); ! Fail_it: ! Py_DECREF(it); return NULL; } *************** *** 272,286 **** { long x; ! Py_UNICODE s[1]; if (!PyArg_ParseTuple(args, "l:unichr", &x)) return NULL; ! if (x < 0 || x >= 65536) { PyErr_SetString(PyExc_ValueError, ! "unichr() arg not in range(65536)"); return NULL; } - s[0] = (Py_UNICODE)x; - return PyUnicode_FromUnicode(s, 1); } --- 289,320 ---- { long x; ! Py_UNICODE s[2]; if (!PyArg_ParseTuple(args, "l:unichr", &x)) return NULL; ! ! if (x < 0 || x > 0x10ffff) { PyErr_SetString(PyExc_ValueError, ! "unichr() arg not in range(0x110000)"); return NULL; + } + + if (x <= 0xffff) { + /* UCS-2 character */ + s[0] = (Py_UNICODE) x; + return PyUnicode_FromUnicode(s, 1); + } + else { + #ifndef Py_UNICODE_WIDE + /* UCS-4 character. store as two surrogate characters */ + x -= 0x10000L; + s[0] = 0xD800 + (Py_UNICODE) (x >> 10); + s[1] = 0xDC00 + (Py_UNICODE) (x & 0x03FF); + return PyUnicode_FromUnicode(s, 2); + #else + s[0] = (Py_UNICODE)x; + return PyUnicode_FromUnicode(s, 1); + #endif } } *************** *** 288,292 **** "unichr(i) -> Unicode character\n\ \n\ ! Return a Unicode string of one character with ordinal i; 0 <= i < 65536."; --- 322,326 ---- "unichr(i) -> Unicode character\n\ \n\ ! Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff."; *************** *** 546,553 **** PyCompilerFlags cf; cf.cf_nested_scopes = 1; ! res = PyRun_FileExFlags(fp, filename, Py_file_input, globals, locals, 1, &cf); ! } else ! res = PyRun_FileEx(fp, filename, Py_file_input, globals, locals, 1); return res; --- 580,587 ---- PyCompilerFlags cf; cf.cf_nested_scopes = 1; ! res = PyRun_FileExFlags(fp, filename, Py_file_input, globals, locals, 1, &cf); ! } else ! res = PyRun_FileEx(fp, filename, Py_file_input, globals, locals, 1); return res; *************** *** 652,658 **** { typedef struct { ! PyObject *seq; ! PySequenceMethods *sqf; ! int len; } sequence; --- 686,691 ---- { typedef struct { ! PyObject *it; /* the iterator object */ ! int saw_StopIteration; /* bool: did the iterator end? */ } sequence; *************** *** 677,762 **** } if ((seqs = PyMem_NEW(sequence, n)) == NULL) { PyErr_NoMemory(); ! goto Fail_2; } ! for (len = 0, i = 0, sqp = seqs; i < n; ++i, ++sqp) { int curlen; - PySequenceMethods *sqf; - - if ((sqp->seq = PyTuple_GetItem(args, i + 1)) == NULL) - goto Fail_2; ! sqp->sqf = sqf = sqp->seq->ob_type->tp_as_sequence; ! if (sqf == NULL || ! sqf->sq_length == NULL || ! sqf->sq_item == NULL) ! { static char errmsg[] = ! "argument %d to map() must be a sequence object"; char errbuf[sizeof(errmsg) + 25]; - sprintf(errbuf, errmsg, i+2); PyErr_SetString(PyExc_TypeError, errbuf); goto Fail_2; } - - if ((curlen = sqp->len = (*sqp->sqf->sq_length)(sqp->seq)) < 0) - goto Fail_2; ! if (curlen > len) ! len = curlen; } if ((result = (PyObject *) PyList_New(len)) == NULL) goto Fail_2; for (i = 0; ; ++i) { PyObject *alist, *item=NULL, *value; ! int any = 0; if (func == Py_None && n == 1) alist = NULL; ! else { ! if ((alist = PyTuple_New(n)) == NULL) ! goto Fail_1; ! } for (j = 0, sqp = seqs; j < n; ++j, ++sqp) { ! if (sqp->len < 0) { Py_INCREF(Py_None); item = Py_None; } else { ! item = (*sqp->sqf->sq_item)(sqp->seq, i); ! if (item == NULL) { ! if (PyErr_ExceptionMatches( ! PyExc_IndexError)) ! { ! PyErr_Clear(); ! Py_INCREF(Py_None); ! item = Py_None; ! sqp->len = -1; ! } ! else { ! goto Fail_0; } } - else - any = 1; - } ! if (!alist) break; - if (PyTuple_SetItem(alist, j, item) < 0) { - Py_DECREF(item); - goto Fail_0; - } - continue; - - Fail_0: - Py_XDECREF(alist); - goto Fail_1; } --- 710,796 ---- } + /* Get space for sequence descriptors. Must NULL out the iterator + * pointers so that jumping to Fail_2 later doesn't see trash. + */ if ((seqs = PyMem_NEW(sequence, n)) == NULL) { PyErr_NoMemory(); ! return NULL; } + for (i = 0; i < n; ++i) { + seqs[i].it = (PyObject*)NULL; + seqs[i].saw_StopIteration = 0; + } ! /* Do a first pass to obtain iterators for the arguments, and set len ! * to the largest of their lengths. ! */ ! len = 0; ! for (i = 0, sqp = seqs; i < n; ++i, ++sqp) { ! PyObject *curseq; int curlen; ! /* Get iterator. */ ! curseq = PyTuple_GetItem(args, i+1); ! sqp->it = PyObject_GetIter(curseq); ! if (sqp->it == NULL) { static char errmsg[] = ! "argument %d to map() must support iteration"; char errbuf[sizeof(errmsg) + 25]; sprintf(errbuf, errmsg, i+2); PyErr_SetString(PyExc_TypeError, errbuf); goto Fail_2; } ! /* Update len. */ ! curlen = -1; /* unknown */ ! if (PySequence_Check(curseq) && ! curseq->ob_type->tp_as_sequence->sq_length) { ! curlen = PySequence_Size(curseq); ! if (curlen < 0) ! PyErr_Clear(); ! } ! if (curlen < 0) ! curlen = 8; /* arbitrary */ ! if (curlen > len) ! len = curlen; } + /* Get space for the result list. */ if ((result = (PyObject *) PyList_New(len)) == NULL) goto Fail_2; + /* Iterate over the sequences until all have stopped. */ for (i = 0; ; ++i) { PyObject *alist, *item=NULL, *value; ! int numactive = 0; if (func == Py_None && n == 1) alist = NULL; ! else if ((alist = PyTuple_New(n)) == NULL) ! goto Fail_1; for (j = 0, sqp = seqs; j < n; ++j, ++sqp) { ! if (sqp->saw_StopIteration) { Py_INCREF(Py_None); item = Py_None; } else { ! item = PyIter_Next(sqp->it); ! if (item) ! ++numactive; ! else { ! if (PyErr_Occurred()) { ! Py_XDECREF(alist); ! goto Fail_1; } + Py_INCREF(Py_None); + item = Py_None; + sqp->saw_StopIteration = 1; } } ! if (alist) ! PyTuple_SET_ITEM(alist, j, item); ! else break; } *************** *** 764,768 **** alist = item; ! if (!any) { Py_DECREF(alist); break; --- 798,802 ---- alist = item; ! if (numactive == 0) { Py_DECREF(alist); break; *************** *** 782,790 **** if (status < 0) goto Fail_1; - } - else { - if (PyList_SetItem(result, i, value) < 0) - goto Fail_1; } } --- 816,822 ---- if (status < 0) goto Fail_1; } + else if (PyList_SetItem(result, i, value) < 0) + goto Fail_1; } *************** *** 792,803 **** goto Fail_1; ! PyMem_DEL(seqs); ! return result; Fail_1: Py_DECREF(result); Fail_2: ! if (seqs) PyMem_DEL(seqs); ! return NULL; } --- 824,839 ---- goto Fail_1; ! goto Succeed; Fail_1: Py_DECREF(result); Fail_2: ! result = NULL; ! Succeed: ! assert(seqs); ! for (i = 0; i < n; ++i) ! Py_XDECREF(seqs[i].it); ! PyMem_DEL(seqs); ! return result; } *************** *** 1048,1054 **** min_max(PyObject *args, int op) { ! int i; ! PyObject *v, *w, *x; ! PySequenceMethods *sq; if (PyTuple_Size(args) > 1) --- 1084,1088 ---- min_max(PyObject *args, int op) { ! PyObject *v, *w, *x, *it; if (PyTuple_Size(args) > 1) *************** *** 1056,1076 **** else if (!PyArg_ParseTuple(args, "O:min/max", &v)) return NULL; ! sq = v->ob_type->tp_as_sequence; ! if (sq == NULL || sq->sq_item == NULL) { ! PyErr_SetString(PyExc_TypeError, ! "min() or max() arg must be a sequence"); return NULL; ! } ! w = NULL; ! for (i = 0; ; i++) { ! x = (*sq->sq_item)(v, i); /* Implies INCREF */ if (x == NULL) { ! if (PyErr_ExceptionMatches(PyExc_IndexError)) { ! PyErr_Clear(); ! break; } ! Py_XDECREF(w); ! return NULL; } if (w == NULL) w = x; --- 1090,1110 ---- else if (!PyArg_ParseTuple(args, "O:min/max", &v)) return NULL; ! ! it = PyObject_GetIter(v); ! if (it == NULL) return NULL; ! ! w = NULL; /* the result */ ! for (;;) { ! x = PyIter_Next(it); if (x == NULL) { ! if (PyErr_Occurred()) { ! Py_XDECREF(w); ! Py_DECREF(it); ! return NULL; } ! break; } + if (w == NULL) w = x; *************** *** 1083,1087 **** else if (cmp < 0) { Py_DECREF(x); ! Py_XDECREF(w); return NULL; } --- 1117,1122 ---- else if (cmp < 0) { Py_DECREF(x); ! Py_DECREF(w); ! Py_DECREF(it); return NULL; } *************** *** 1093,1096 **** --- 1128,1132 ---- PyErr_SetString(PyExc_ValueError, "min() or max() arg is an empty sequence"); + Py_DECREF(it); return w; } *************** *** 1150,1161 **** builtin_open(PyObject *self, PyObject *args) { ! char *name; char *mode = "r"; int bufsize = -1; PyObject *f; ! if (!PyArg_ParseTuple(args, "s|si:open", &name, &mode, &bufsize)) return NULL; f = PyFile_FromString(name, mode); if (f != NULL) PyFile_SetBufSize(f, bufsize); --- 1186,1199 ---- builtin_open(PyObject *self, PyObject *args) { ! char *name = NULL; char *mode = "r"; int bufsize = -1; PyObject *f; ! if (!PyArg_ParseTuple(args, "et|si:open", Py_FileSystemDefaultEncoding, ! &name, &mode, &bufsize)) return NULL; f = PyFile_FromString(name, mode); + PyMem_Free(name); /* free the encoded string */ if (f != NULL) PyFile_SetBufSize(f, bufsize); *************** *** 1354,1358 **** return NULL; } ! return PyRange_New(ilow, n, istep, 1); } --- 1392,1396 ---- return NULL; } ! return PyRange_New(ilow, n, istep); } *************** *** 1445,1451 **** builtin_reduce(PyObject *self, PyObject *args) { ! PyObject *seq, *func, *result = NULL; ! PySequenceMethods *sqf; ! register int i; if (!PyArg_ParseTuple(args, "OO|O:reduce", &func, &seq, &result)) --- 1483,1487 ---- builtin_reduce(PyObject *self, PyObject *args) { ! PyObject *seq, *func, *result = NULL, *it; if (!PyArg_ParseTuple(args, "OO|O:reduce", &func, &seq, &result)) *************** *** 1454,1461 **** Py_INCREF(result); ! sqf = seq->ob_type->tp_as_sequence; ! if (sqf == NULL || sqf->sq_item == NULL) { PyErr_SetString(PyExc_TypeError, ! "reduce() arg 2 must be a sequence"); return NULL; } --- 1490,1498 ---- Py_INCREF(result); ! it = PyObject_GetIter(seq); ! if (it == NULL) { PyErr_SetString(PyExc_TypeError, ! "reduce() arg 2 must support iteration"); ! Py_XDECREF(result); return NULL; } *************** *** 1464,1468 **** goto Fail; ! for (i = 0; ; ++i) { PyObject *op2; --- 1501,1505 ---- goto Fail; ! for (;;) { PyObject *op2; *************** *** 1473,1482 **** } ! if ((op2 = (*sqf->sq_item)(seq, i)) == NULL) { ! if (PyErr_ExceptionMatches(PyExc_IndexError)) { ! PyErr_Clear(); ! break; ! } ! goto Fail; } --- 1510,1518 ---- } ! op2 = PyIter_Next(it); ! if (op2 == NULL) { ! if (PyErr_Occurred()) ! goto Fail; ! break; } *************** *** 1497,1500 **** --- 1533,1537 ---- "reduce() of empty sequence with no initial value"); + Py_DECREF(it); return result; *************** *** 1502,1505 **** --- 1539,1543 ---- Py_XDECREF(args); Py_XDECREF(result); + Py_DECREF(it); return NULL; } *************** *** 1670,1674 **** PyObject *ret; int itemsize = PySequence_Length(args); ! int i, j; if (itemsize < 1) { --- 1708,1713 ---- PyObject *ret; int itemsize = PySequence_Length(args); ! int i; ! PyObject *itlist; /* tuple of iterators */ if (itemsize < 1) { *************** *** 1680,1712 **** assert(PyTuple_Check(args)); if ((ret = PyList_New(0)) == NULL) return NULL; ! for (i = 0;; i++) { ! PyObject *next = PyTuple_New(itemsize); ! if (!next) { ! Py_DECREF(ret); ! return NULL; } ! for (j = 0; j < itemsize; j++) { ! PyObject *seq = PyTuple_GET_ITEM(args, j); ! PyObject *item = PySequence_GetItem(seq, i); if (!item) { ! if (PyErr_ExceptionMatches(PyExc_IndexError)) { ! PyErr_Clear(); ! Py_DECREF(next); ! return ret; } Py_DECREF(next); ! Py_DECREF(ret); ! return NULL; } ! PyTuple_SET_ITEM(next, j, item); } ! PyList_Append(ret, next); Py_DECREF(next); } ! /* no return */ } --- 1719,1776 ---- assert(PyTuple_Check(args)); + /* allocate result list */ if ((ret = PyList_New(0)) == NULL) return NULL; ! /* obtain iterators */ ! itlist = PyTuple_New(itemsize); ! if (itlist == NULL) ! goto Fail_ret; ! for (i = 0; i < itemsize; ++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, ! "zip argument #%d must support iteration", ! i+1); ! goto Fail_ret_itlist; } ! PyTuple_SET_ITEM(itlist, i, it); ! } ! ! /* build result into ret list */ ! for (;;) { ! int status; ! PyObject *next = PyTuple_New(itemsize); ! if (!next) ! goto Fail_ret_itlist; + for (i = 0; i < itemsize; i++) { + PyObject *it = PyTuple_GET_ITEM(itlist, i); + PyObject *item = PyIter_Next(it); if (!item) { ! if (PyErr_Occurred()) { ! Py_DECREF(ret); ! ret = NULL; } Py_DECREF(next); ! Py_DECREF(itlist); ! return ret; } ! PyTuple_SET_ITEM(next, i, item); } ! ! status = PyList_Append(ret, next); Py_DECREF(next); + if (status < 0) + goto Fail_ret_itlist; } ! ! Fail_ret_itlist: ! Py_DECREF(itlist); ! Fail_ret: ! Py_DECREF(ret); ! return NULL; } *************** *** 1884,1888 **** } ! if (_PyTuple_Resize(&result, j, 0) < 0) return NULL; --- 1948,1952 ---- } ! if (_PyTuple_Resize(&result, j) < 0) return NULL; Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.241.2.4 retrieving revision 2.241.2.5 diff -C2 -r2.241.2.4 -r2.241.2.5 *** ceval.c 2001/06/28 20:32:44 2.241.2.4 --- ceval.c 2001/07/07 22:55:30 2.241.2.5 *************** *** 3,7 **** /* XXX TO DO: ! XXX how to pass arguments to call_trace? XXX speed up searching for keywords by using a dictionary XXX document it! --- 3,7 ---- /* XXX TO DO: ! XXX how to pass arguments to profile and trace functions? XXX speed up searching for keywords by using a dictionary [...1630 lines suppressed...] + /* XXX This is broken if the caller deletes dict items! */ + } + else { + k = NULL; + nk = 0; + } + + result = PyEval_EvalCodeEx( + (PyCodeObject *)PyFunction_GET_CODE(func), + PyFunction_GET_GLOBALS(func), (PyObject *)NULL, + &PyTuple_GET_ITEM(arg, 0), PyTuple_Size(arg), + k, nk, d, nd, + PyFunction_GET_CLOSURE(func)); + + if (k != NULL) + PyMem_DEL(k); + + return result; } Index: compile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v retrieving revision 2.197 retrieving revision 2.197.2.1 diff -C2 -r2.197 -r2.197.2.1 *** compile.c 2001/04/20 19:13:02 2.197 --- compile.c 2001/07/07 22:55:30 2.197.2.1 *************** *** 337,340 **** --- 337,384 ---- */ + /* All about c_lnotab. + + c_lnotab is an array of unsigned bytes disguised as a Python string. In -O + mode, SET_LINENO opcodes aren't generated, and bytecode offsets are mapped + to source code line #s (when needed for tracebacks) via c_lnotab instead. + The array is conceptually a list of + (bytecode offset increment, line number increment) + pairs. The details are important and delicate, best illustrated by example: + + byte code offset source code line number + 0 1 + 6 2 + 50 7 + 350 307 + 361 308 + + The first trick is that these numbers aren't stored, only the increments + from one row to the next (this doesn't really work, but it's a start): + + 0, 1, 6, 1, 44, 5, 300, 300, 11, 1 + + The second trick is that an unsigned byte can't hold negative values, or + values larger than 255, so (a) there's a deep assumption that byte code + offsets and their corresponding line #s both increase monotonically, and (b) + if at least one column jumps by more than 255 from one row to the next, more + than one pair is written to the table. In case #b, there's no way to know + from looking at the table later how many were written. That's the delicate + part. A user of c_lnotab desiring to find the source line number + corresponding to a bytecode address A should do something like this + + lineno = addr = 0 + for addr_incr, line_incr in c_lnotab: + addr += addr_incr + if addr > A: + return lineno + lineno += line_incr + + In order for this to work, when the addr field increments by more than 255, + the line # increment in each pair generated must be 0 until the remaining addr + increment is < 256. So, in the example above, com_set_lineno should not (as + was actually done until 2.2) expand 300, 300 to 255, 255, 45, 45, but to + 255, 0, 45, 255, 0, 45. + */ + struct compiling { PyObject *c_code; /* string */ *************** *** 693,707 **** int incr_addr = c->c_nexti - c->c_last_addr; int incr_line = lineno - c->c_last_line; ! while (incr_addr > 0 || incr_line > 0) { ! int trunc_addr = incr_addr; ! int trunc_line = incr_line; ! if (trunc_addr > 255) ! trunc_addr = 255; ! if (trunc_line > 255) ! trunc_line = 255; ! com_add_lnotab(c, trunc_addr, trunc_line); ! incr_addr -= trunc_addr; ! incr_line -= trunc_line; } c->c_last_addr = c->c_nexti; c->c_last_line = lineno; --- 737,751 ---- int incr_addr = c->c_nexti - c->c_last_addr; int incr_line = lineno - c->c_last_line; ! while (incr_addr > 255) { ! com_add_lnotab(c, 255, 0); ! incr_addr -= 255; ! } ! while (incr_line > 255) { ! com_add_lnotab(c, incr_addr, 255); ! incr_line -=255; ! incr_addr = 0; } + if (incr_addr > 0 || incr_line > 0) + com_add_lnotab(c, incr_addr, incr_line); c->c_last_addr = c->c_nexti; c->c_last_line = lineno; *************** *** 2591,2594 **** --- 2635,2644 ---- com_error(c, PyExc_SyntaxError, "'return' outside function"); } + if (c->c_flags & CO_GENERATOR) { + if (NCH(n) > 1) { + com_error(c, PyExc_SyntaxError, + "'return' with argument inside generator"); + } + } if (NCH(n) < 2) { com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None)); *************** *** 2602,2605 **** --- 2652,2677 ---- static void + com_yield_stmt(struct compiling *c, node *n) + { + int i; + REQ(n, yield_stmt); /* 'yield' testlist */ + if (!c->c_infunction) { + com_error(c, PyExc_SyntaxError, "'yield' outside function"); + } + + for (i = 0; i < c->c_nblocks; ++i) { + if (c->c_block[i] == SETUP_FINALLY) { + com_error(c, PyExc_SyntaxError, + "'yield' not allowed in a 'try' block " + "with a 'finally' clause"); + return; + } + } + com_node(c, CHILD(n, 1)); + com_addbyte(c, YIELD_VALUE); + com_pop(c, 1); + } + + static void com_raise_stmt(struct compiling *c, node *n) { *************** *** 2805,2808 **** --- 2877,2919 ---- } + + /* Look under n for a return stmt with an expression. + * This hack is used to find illegal returns under "if 0:" blocks in + * functions already known to be generators (as determined by the symtable + * pass). + * Return the offending return node if found, else NULL. + */ + static node * + look_for_offending_return(node *n) + { + int i; + + for (i = 0; i < NCH(n); ++i) { + node *kid = CHILD(n, i); + + switch (TYPE(kid)) { + case classdef: + case funcdef: + case lambdef: + /* Stuff in nested functions & classes doesn't + affect the code block we started in. */ + return NULL; + + case return_stmt: + if (NCH(kid) > 1) + return kid; + break; + + default: { + node *bad = look_for_offending_return(kid); + if (bad != NULL) + return bad; + } + } + } + + return NULL; + } + static void com_if_stmt(struct compiling *c, node *n) *************** *** 2815,2820 **** int a = 0; node *ch = CHILD(n, i+1); ! if (is_constant_false(c, ch)) continue; if (i > 0) com_addoparg(c, SET_LINENO, ch->n_lineno); --- 2926,2947 ---- int a = 0; node *ch = CHILD(n, i+1); ! if (is_constant_false(c, ch)) { ! /* We're going to skip this block. However, if this ! is a generator, we have to check the dead code ! anyway to make sure there aren't any return stmts ! with expressions, in the same scope. */ ! if (c->c_flags & CO_GENERATOR) { ! node *p = look_for_offending_return(n); ! if (p != NULL) { ! int savelineno = c->c_lineno; ! c->c_lineno = p->n_lineno; ! com_error(c, PyExc_SyntaxError, ! "'return' with argument " ! "inside generator"); ! c->c_lineno = savelineno; ! } ! } continue; + } if (i > 0) com_addoparg(c, SET_LINENO, ch->n_lineno); *************** *** 3412,3415 **** --- 3539,3545 ---- com_return_stmt(c, n); break; + case yield_stmt: + com_yield_stmt(c, n); + break; case raise_stmt: com_raise_stmt(c, n); *************** *** 3540,3544 **** node *ch = CHILD(n, i); node *fp; - char *name; if (TYPE(ch) == STAR || TYPE(ch) == DOUBLESTAR) break; --- 3670,3673 ---- *************** *** 3546,3550 **** fp = CHILD(ch, 0); if (TYPE(fp) != NAME) { - name = nbuf; sprintf(nbuf, ".%d", i); complex = 1; --- 3675,3678 ---- *************** *** 4058,4062 **** static int ! symtable_resolve_free(struct compiling *c, PyObject *name, struct symbol_info *si) { --- 4186,4190 ---- static int ! symtable_resolve_free(struct compiling *c, PyObject *name, int flags, struct symbol_info *si) { *************** *** 4068,4076 **** method and a free variable with the same name. */ - if (c->c_symtable->st_cur->ste_type == TYPE_FUNCTION) { v = PyInt_FromLong(si->si_ncells++); dict = c->c_cellvars; } else { v = PyInt_FromLong(si->si_nfrees++); dict = c->c_freevars; --- 4196,4212 ---- method and a free variable with the same name. */ if (c->c_symtable->st_cur->ste_type == TYPE_FUNCTION) { + /* If it isn't declared locally, it can't be a cell. */ + if (!(flags & (DEF_LOCAL | DEF_PARAM))) + return 0; v = PyInt_FromLong(si->si_ncells++); dict = c->c_cellvars; } else { + /* If it is free anyway, then there is no need to do + anything here. + */ + if (is_free(flags ^ DEF_FREE_CLASS) + || (flags == DEF_FREE_CLASS)) + return 0; v = PyInt_FromLong(si->si_nfrees++); dict = c->c_freevars; *************** *** 4253,4256 **** --- 4389,4393 ---- if (!(flags & DEF_BOUND)) return 0; + /* The semantics of this code will change with nested scopes. It is defined in the current scope and referenced in a *************** *** 4292,4295 **** --- 4429,4434 ---- if (c->c_future && c->c_future->ff_nested_scopes) c->c_flags |= CO_NESTED; + if (ste->ste_generator) + c->c_flags |= CO_GENERATOR; if (ste->ste_type != TYPE_MODULE) c->c_flags |= CO_NEWLOCALS; *************** *** 4357,4365 **** variables or declared global. */ ! if (flags & (DEF_FREE | DEF_FREE_CLASS)) { ! if ((ste->ste_type == TYPE_CLASS ! && flags != DEF_FREE_CLASS) ! || (flags & (DEF_LOCAL | DEF_PARAM))) ! symtable_resolve_free(c, name, &si); } --- 4496,4503 ---- variables or declared global. */ ! if (st->st_nested_scopes) { ! if (flags & (DEF_FREE | DEF_FREE_CLASS)) { ! symtable_resolve_free(c, name, flags, &si); ! } } *************** *** 4421,4424 **** --- 4559,4567 ---- } + assert(PyDict_Size(c->c_freevars) == si.si_nfrees); + + if (st->st_nested_scopes == 0) + assert(si.si_nfrees == 0); + if (si.si_ncells > 1) { /* one cell is always in order */ if (symtable_cellvar_offsets(&c->c_cellvars, c->c_argcount, *************** *** 4525,4529 **** indirectly) in A and there are no scopes with bindings for N between B and A, then N ! is global in B. */ if (v && (ste->ste_type != TYPE_CLASS)) { --- 4668,4674 ---- indirectly) in A and there are no scopes with bindings for N between B and A, then N ! is global in B. Unless A is a class scope, ! because class scopes are not considered for ! nested scopes. */ if (v && (ste->ste_type != TYPE_CLASS)) { *************** *** 4751,4754 **** --- 4896,4931 ---- #define symtable_add_use(ST, NAME) symtable_add_def((ST), (NAME), USE) + /* Look for a yield stmt under n. Return 1 if found, else 0. + This hack is used to look inside "if 0:" blocks (which are normally + ignored) in case those are the only places a yield occurs (so that this + function is a generator). */ + static int + look_for_yield(node *n) + { + int i; + + for (i = 0; i < NCH(n); ++i) { + node *kid = CHILD(n, i); + + switch (TYPE(kid)) { + + case classdef: + case funcdef: + case lambdef: + /* Stuff in nested functions and classes can't make + the parent a generator. */ + return 0; + + case yield_stmt: + return 1; + + default: + if (look_for_yield(kid)) + return 1; + } + } + return 0; + } + static void symtable_node(struct symtable *st, node *n) *************** *** 4794,4799 **** case if_stmt: for (i = 0; i + 3 < NCH(n); i += 4) { ! if (is_constant_false(NULL, (CHILD(n, i + 1)))) continue; symtable_node(st, CHILD(n, i + 1)); symtable_node(st, CHILD(n, i + 3)); --- 4971,4980 ---- case if_stmt: for (i = 0; i + 3 < NCH(n); i += 4) { ! if (is_constant_false(NULL, (CHILD(n, i + 1)))) { ! if (st->st_cur->ste_generator == 0) ! st->st_cur->ste_generator = ! look_for_yield(CHILD(n, i+3)); continue; + } symtable_node(st, CHILD(n, i + 1)); symtable_node(st, CHILD(n, i + 3)); *************** *** 4844,4847 **** --- 5025,5032 ---- symtable_assign(st, CHILD(n, 1), 0); break; + case yield_stmt: + st->st_cur->ste_generator = 1; + n = CHILD(n, 1); + goto loop; case expr_stmt: if (NCH(n) == 1) Index: dynload_win.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/dynload_win.c,v retrieving revision 2.7 retrieving revision 2.7.8.1 diff -C2 -r2.7 -r2.7.8.1 *** dynload_win.c 2000/10/05 10:54:45 2.7 --- dynload_win.c 2001/07/07 22:55:30 2.7.8.1 *************** *** 164,185 **** #ifdef MS_WIN32 { ! HINSTANCE hDLL; char pathbuf[260]; ! if (strchr(pathname, '\\') == NULL && ! strchr(pathname, '/') == NULL) ! { ! /* Prefix bare filename with ".\" */ ! char *p = pathbuf; ! *p = '\0'; ! _getcwd(pathbuf, sizeof pathbuf); ! if (*p != '\0' && p[1] == ':') ! p += 2; ! sprintf(p, ".\\%-.255s", pathname); ! pathname = pathbuf; ! } ! /* Look for dependent DLLs in directory of pathname first */ ! /* XXX This call doesn't exist in Windows CE */ ! hDLL = LoadLibraryEx(pathname, NULL, ! LOAD_WITH_ALTERED_SEARCH_PATH); if (hDLL==NULL){ char errBuf[256]; --- 164,182 ---- #ifdef MS_WIN32 { ! HINSTANCE hDLL = NULL; char pathbuf[260]; ! LPTSTR dummy; ! /* We use LoadLibraryEx so Windows looks for dependent DLLs ! in directory of pathname first. However, Windows95 ! can sometimes not work correctly unless the absolute ! path is used. If GetFullPathName() fails, the LoadLibrary ! will certainly fail too, so use its error code */ ! if (GetFullPathName(pathname, ! sizeof(pathbuf), ! pathbuf, ! &dummy)) ! /* XXX This call doesn't exist in Windows CE */ ! hDLL = LoadLibraryEx(pathname, NULL, ! LOAD_WITH_ALTERED_SEARCH_PATH); if (hDLL==NULL){ char errBuf[256]; Index: errors.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/errors.c,v retrieving revision 2.62 retrieving revision 2.62.6.1 diff -C2 -r2.62 -r2.62.6.1 *** errors.c 2001/03/06 12:12:02 2.62 --- errors.c 2001/07/07 22:55:30 2.62.6.1 *************** *** 76,80 **** PyErr_Occurred(void) { ! PyThreadState *tstate = PyThreadState_Get(); return tstate->curexc_type; --- 76,80 ---- PyErr_Occurred(void) { ! PyThreadState *tstate = PyThreadState_GET(); return tstate->curexc_type; Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.54.6.1 retrieving revision 2.54.6.2 diff -C2 -r2.54.6.1 -r2.54.6.2 *** getargs.c 2001/06/07 11:28:06 2.54.6.1 --- getargs.c 2001/07/07 22:55:30 2.54.6.2 *************** *** 26,30 **** int *, char *, int); static char *convertsimple(PyObject *, char **, va_list *, char *); ! static char *convertsimple1(PyObject *, char **, va_list *); static int vgetargskeywords(PyObject *, PyObject *, --- 26,30 ---- int *, char *, int); static char *convertsimple(PyObject *, char **, va_list *, char *); ! static int convertbuffer(PyObject *, void **p, char **); [...1349 lines suppressed...] /* do a cursory check of the keywords just to see how many we got */ --- 1039,1043 ---- } ! tplen = PyTuple_GET_SIZE(args); /* do a cursory check of the keywords just to see how many we got */ *************** *** 1096,1100 **** if (*format == '|') format++; ! msg = convertitem(PyTuple_GetItem(args, i), &format, p_va, levels, msgbuf); if (msg) { --- 1115,1119 ---- if (*format == '|') format++; ! msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va, levels, msgbuf); if (msg) { Index: graminit.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/graminit.c,v retrieving revision 2.28 retrieving revision 2.28.8.1 diff -C2 -r2.28 -r2.28.8.1 *** graminit.c 2000/08/24 20:11:32 2.28 --- graminit.c 2001/07/07 22:55:30 2.28.8.1 *************** *** 342,350 **** {1, arcs_15_1}, }; ! static arc arcs_16_0[4] = { {54, 1}, {55, 1}, {56, 1}, {57, 1}, }; static arc arcs_16_1[1] = { --- 342,351 ---- [...2505 lines suppressed...] {25, 0}, {2, 0}, {3, 0}, ! {319, 0}, {1, "lambda"}, ! {316, 0}, {309, 0}, {310, 0}, + {311, 0}, {1, "class"}, {317, 0}, ! {318, 0}, ! {320, 0}, }; grammar _PyParser_Grammar = { ! 65, dfas, ! {144, labels}, 256 }; Index: import.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/import.c,v retrieving revision 2.176.2.1 retrieving revision 2.176.2.2 diff -C2 -r2.176.2.1 -r2.176.2.2 *** import.c 2001/06/28 16:21:07 2.176.2.1 --- import.c 2001/07/07 22:55:31 2.176.2.2 *************** *** 959,970 **** and there's an __init__ module in that directory */ #ifdef HAVE_STAT ! if (stat(buf, &statbuf) == 0 && ! S_ISDIR(statbuf.st_mode) && ! find_init_module(buf)) { ! if (case_ok(buf, len, namelen, name)) ! return &fd_package; ! else ! return NULL; ! } #else /* XXX How are you going to test for directories? */ --- 959,967 ---- and there's an __init__ module in that directory */ #ifdef HAVE_STAT ! if (stat(buf, &statbuf) == 0 && /* it exists */ ! S_ISDIR(statbuf.st_mode) && /* it's a directory */ ! find_init_module(buf) && /* it has __init__.py */ ! case_ok(buf, len, namelen, name)) /* and case matches */ ! return &fd_package; #else /* XXX How are you going to test for directories? */ *************** *** 1198,1221 **** find_init_module(char *buf) { ! size_t save_len = strlen(buf); size_t i = save_len; struct stat statbuf; if (save_len + 13 >= MAXPATHLEN) return 0; buf[i++] = SEP; ! strcpy(buf+i, "__init__.py"); if (stat(buf, &statbuf) == 0) { ! buf[save_len] = '\0'; ! return 1; } ! i += strlen(buf+i); ! if (Py_OptimizeFlag) ! strcpy(buf+i, "o"); ! else ! strcpy(buf+i, "c"); if (stat(buf, &statbuf) == 0) { ! buf[save_len] = '\0'; ! return 1; } buf[save_len] = '\0'; --- 1195,1235 ---- find_init_module(char *buf) { ! const size_t save_len = strlen(buf); size_t i = save_len; + char *pname; /* pointer to start of __init__ */ struct stat statbuf; + /* For calling case_ok(buf, len, namelen, name): + * /a/b/c/d/e/f/g/h/i/j/k/some_long_module_name.py\0 + * ^ ^ ^ ^ + * |--------------------- buf ---------------------| + * |------------------- len ------------------| + * |------ name -------| + * |----- namelen -----| + */ if (save_len + 13 >= MAXPATHLEN) return 0; buf[i++] = SEP; ! pname = buf + i; ! strcpy(pname, "__init__.py"); if (stat(buf, &statbuf) == 0) { ! if (case_ok(buf, ! save_len + 9, /* len("/__init__") */ ! 8, /* len("__init__") */ ! pname)) { ! buf[save_len] = '\0'; ! return 1; ! } } ! i += strlen(pname); ! strcpy(buf+i, Py_OptimizeFlag ? "o" : "c"); if (stat(buf, &statbuf) == 0) { ! if (case_ok(buf, ! save_len + 9, /* len("/__init__") */ ! 8, /* len("__init__") */ ! pname)) { ! buf[save_len] = '\0'; ! return 1; ! } } buf[save_len] = '\0'; Index: marshal.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/marshal.c,v retrieving revision 1.62 retrieving revision 1.62.4.1 diff -C2 -r1.62 -r1.62.4.1 *** marshal.c 2001/04/10 05:02:52 1.62 --- marshal.c 2001/07/07 22:55:31 1.62.4.1 *************** *** 18,21 **** --- 18,22 ---- #define TYPE_NULL '0' #define TYPE_NONE 'N' + #define TYPE_STOPITER 'S' #define TYPE_ELLIPSIS '.' #define TYPE_INT 'i' *************** *** 121,124 **** --- 122,128 ---- w_byte(TYPE_NONE, p); } + else if (v == PyExc_StopIteration) { + w_byte(TYPE_STOPITER, p); + } else if (v == Py_Ellipsis) { w_byte(TYPE_ELLIPSIS, p); *************** *** 150,156 **** } else if (PyFloat_Check(v)) { - extern void PyFloat_AsString(char *, PyFloatObject *); char buf[256]; /* Plenty to format any double */ ! PyFloat_AsString(buf, (PyFloatObject *)v); n = strlen(buf); w_byte(TYPE_FLOAT, p); --- 154,159 ---- } else if (PyFloat_Check(v)) { char buf[256]; /* Plenty to format any double */ ! PyFloat_AsReprString(buf, (PyFloatObject *)v); n = strlen(buf); w_byte(TYPE_FLOAT, p); *************** *** 160,164 **** #ifndef WITHOUT_COMPLEX else if (PyComplex_Check(v)) { - extern void PyFloat_AsString(char *, PyFloatObject *); char buf[256]; /* Plenty to format any double */ PyFloatObject *temp; --- 163,166 ---- *************** *** 166,170 **** temp = (PyFloatObject*)PyFloat_FromDouble( PyComplex_RealAsDouble(v)); ! PyFloat_AsString(buf, temp); Py_DECREF(temp); n = strlen(buf); --- 168,172 ---- temp = (PyFloatObject*)PyFloat_FromDouble( PyComplex_RealAsDouble(v)); ! PyFloat_AsReprString(buf, temp); Py_DECREF(temp); n = strlen(buf); *************** *** 173,177 **** temp = (PyFloatObject*)PyFloat_FromDouble( PyComplex_ImagAsDouble(v)); ! PyFloat_AsString(buf, temp); Py_DECREF(temp); n = strlen(buf); --- 175,179 ---- temp = (PyFloatObject*)PyFloat_FromDouble( PyComplex_ImagAsDouble(v)); ! PyFloat_AsReprString(buf, temp); Py_DECREF(temp); n = strlen(buf); *************** *** 378,381 **** --- 380,387 ---- Py_INCREF(Py_None); return Py_None; + + case TYPE_STOPITER: + Py_INCREF(PyExc_StopIteration); + return PyExc_StopIteration; case TYPE_ELLIPSIS: Index: pystate.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pystate.c,v retrieving revision 2.16 retrieving revision 2.16.6.1 diff -C2 -r2.16 -r2.16.6.1 *** pystate.c 2001/01/23 01:46:06 2.16 --- pystate.c 2001/07/07 22:55:31 2.16.6.1 *************** *** 110,113 **** --- 110,114 ---- tstate->ticker = 0; tstate->tracing = 0; + tstate->use_tracing = 0; tstate->dict = NULL; *************** *** 121,126 **** tstate->exc_traceback = NULL; ! tstate->sys_profilefunc = NULL; ! tstate->sys_tracefunc = NULL; HEAD_LOCK(); --- 122,129 ---- tstate->exc_traceback = NULL; ! tstate->c_profilefunc = NULL; ! tstate->c_tracefunc = NULL; ! tstate->c_profileobj = NULL; ! tstate->c_traceobj = NULL; HEAD_LOCK(); *************** *** 153,158 **** ZAP(tstate->exc_traceback); ! ZAP(tstate->sys_profilefunc); ! ZAP(tstate->sys_tracefunc); } --- 156,163 ---- ZAP(tstate->exc_traceback); ! tstate->c_profilefunc = NULL; ! tstate->c_tracefunc = NULL; ! ZAP(tstate->c_profileobj); ! ZAP(tstate->c_traceobj); } Index: pythonrun.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.133.4.3 retrieving revision 2.133.4.4 diff -C2 -r2.133.4.3 -r2.133.4.4 *** pythonrun.c 2001/07/05 16:25:52 2.133.4.3 --- pythonrun.c 2001/07/07 22:55:31 2.133.4.4 *************** *** 1080,1085 **** if (co->co_flags & CO_NESTED) flags->cf_nested_scopes = 1; fprintf(stderr, "run_pyc_file: nested_scopes: %d\n", ! flags->cf_nested_scopes); } Py_DECREF(co); --- 1080,1087 ---- if (co->co_flags & CO_NESTED) flags->cf_nested_scopes = 1; + #if 0 fprintf(stderr, "run_pyc_file: nested_scopes: %d\n", ! flags->cf_nested_scopes); ! #endif } Py_DECREF(co); Index: symtable.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/symtable.c,v retrieving revision 2.4 retrieving revision 2.4.6.1 diff -C2 -r2.4 -r2.4.6.1 *** symtable.c 2001/02/27 19:07:02 2.4 --- symtable.c 2001/07/07 22:55:31 2.4.6.1 *************** *** 70,73 **** --- 70,74 ---- ste->ste_nested = 0; ste->ste_child_free = 0; + ste->ste_generator = 0; if (PyDict_SetItem(st->st_symbols, ste->ste_id, (PyObject *)ste) < 0) Index: sysmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/sysmodule.c,v retrieving revision 2.85 retrieving revision 2.85.4.1 diff -C2 -r2.85 -r2.85.4.1 *** sysmodule.c 2001/04/10 22:07:43 2.85 --- sysmodule.c 2001/07/07 22:55:31 2.85.4.1 *************** *** 197,210 **** Set the current default string encoding used by the Unicode implementation."; static PyObject * sys_settrace(PyObject *self, PyObject *args) { ! PyThreadState *tstate = PyThreadState_Get(); if (args == Py_None) ! args = NULL; else ! Py_XINCREF(args); ! Py_XDECREF(tstate->sys_tracefunc); ! tstate->sys_tracefunc = args; Py_INCREF(Py_None); return Py_None; --- 197,314 ---- Set the current default string encoding used by the Unicode implementation."; + /* + * Cached interned string objects used for calling the profile and + * trace functions. Initialized by trace_init(). + */ + static PyObject *whatstrings[4] = {NULL, NULL, NULL, NULL}; + + static int + trace_init(void) + { + static char *whatnames[4] = {"call", "exception", "line", "return"}; + PyObject *name; + int i; + for (i = 0; i < 4; ++i) { + if (whatstrings[i] == NULL) { + name = PyString_InternFromString(whatnames[i]); + if (name == NULL) + return -1; + whatstrings[i] = name; + } + } + return 0; + } + + static PyObject * + call_trampoline(PyThreadState *tstate, PyObject* callback, + PyFrameObject *frame, int what, PyObject *arg) + { + PyObject *args = PyTuple_New(3); + PyObject *whatstr; + PyObject *result; + + if (args == NULL) + return NULL; + Py_INCREF(frame); + whatstr = whatstrings[what]; + Py_INCREF(whatstr); + if (arg == NULL) + arg = Py_None; + Py_INCREF(arg); + PyTuple_SET_ITEM(args, 0, (PyObject *)frame); + PyTuple_SET_ITEM(args, 1, whatstr); + PyTuple_SET_ITEM(args, 2, arg); + + /* call the Python-level function */ + PyFrame_FastToLocals(frame); + result = PyEval_CallObject(callback, args); + PyFrame_LocalsToFast(frame, 1); + if (result == NULL) + PyTraceBack_Here(frame); + + /* cleanup */ + Py_DECREF(args); + return result; + } + + static int + profile_trampoline(PyObject *self, PyFrameObject *frame, + int what, PyObject *arg) + { + PyThreadState *tstate = frame->f_tstate; + PyObject *result; + + result = call_trampoline(tstate, self, frame, what, arg); + if (result == NULL) { + PyEval_SetProfile(NULL, NULL); + return -1; + } + Py_DECREF(result); + return 0; + } + + static int + trace_trampoline(PyObject *self, PyFrameObject *frame, + int what, PyObject *arg) + { + PyThreadState *tstate = frame->f_tstate; + PyObject *callback; + PyObject *result; + + if (what == PyTrace_CALL) + callback = self; + else + callback = frame->f_trace; + if (callback == NULL) + return 0; + result = call_trampoline(tstate, callback, frame, what, arg); + if (result == NULL) { + PyEval_SetTrace(NULL, NULL); + Py_XDECREF(frame->f_trace); + frame->f_trace = NULL; + return -1; + } + if (result != Py_None) { + PyObject *temp = frame->f_trace; + frame->f_trace = NULL; + Py_XDECREF(temp); + frame->f_trace = result; + } + else { + Py_DECREF(result); + } + return 0; + } + + static PyObject * sys_settrace(PyObject *self, PyObject *args) { ! if (trace_init() == -1) ! return NULL; if (args == Py_None) ! PyEval_SetTrace(NULL, NULL); else ! PyEval_SetTrace(trace_trampoline, args); Py_INCREF(Py_None); return Py_None; *************** *** 220,230 **** sys_setprofile(PyObject *self, PyObject *args) { ! PyThreadState *tstate = PyThreadState_Get(); if (args == Py_None) ! args = NULL; else ! Py_XINCREF(args); ! Py_XDECREF(tstate->sys_profilefunc); ! tstate->sys_profilefunc = args; Py_INCREF(Py_None); return Py_None; --- 324,333 ---- sys_setprofile(PyObject *self, PyObject *args) { ! if (trace_init() == -1) ! return NULL; if (args == Py_None) ! PyEval_SetProfile(NULL, NULL); else ! PyEval_SetProfile(profile_trampoline, args); Py_INCREF(Py_None); return Py_None; *************** *** 528,531 **** --- 631,635 ---- \n\ maxint -- the largest supported integer (the smallest is -maxint-1)\n\ + maxunicode -- the largest supported character\n\ builtin_module_names -- tuple of module names built into this intepreter\n\ version -- the version of this interpreter as a string\n\ *************** *** 637,640 **** --- 741,747 ---- PyDict_SetItemString(sysdict, "maxint", v = PyInt_FromLong(PyInt_GetMax())); + Py_XDECREF(v); + PyDict_SetItemString(sysdict, "maxunicode", + v = PyInt_FromLong(PyUnicode_GetMax())); Py_XDECREF(v); PyDict_SetItemString(sysdict, "builtin_module_names", From tim_one@users.sourceforge.net Sat Jul 7 23:55:59 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 15:55:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Grammar Grammar,1.42,1.42.6.1 Message-ID: Update of /cvsroot/python/python/dist/src/Grammar In directory usw-pr-cvs1:/tmp/cvs-serv24450/mergedescr/dist/src/Grammar Modified Files: Tag: descr-branch Grammar Log Message: Merge of trunk tag date2001-07-06 into descr-branch. Index: Grammar =================================================================== RCS file: /cvsroot/python/python/dist/src/Grammar/Grammar,v retrieving revision 1.42 retrieving revision 1.42.6.1 diff -C2 -r1.42 -r1.42.6.1 *** Grammar 2001/02/27 18:36:14 1.42 --- Grammar 2001/07/07 22:55:27 1.42.6.1 *************** *** 44,51 **** del_stmt: 'del' exprlist pass_stmt: 'pass' ! flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt break_stmt: 'break' continue_stmt: 'continue' return_stmt: 'return' [testlist] raise_stmt: 'raise' [test [',' test [',' test]]] import_stmt: 'import' dotted_as_name (',' dotted_as_name)* | 'from' dotted_name 'import' ('*' | import_as_name (',' import_as_name)*) --- 44,52 ---- del_stmt: 'del' exprlist pass_stmt: 'pass' ! flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt break_stmt: 'break' continue_stmt: 'continue' return_stmt: 'return' [testlist] + yield_stmt: 'yield' testlist raise_stmt: 'raise' [test [',' test [',' test]]] import_stmt: 'import' dotted_as_name (',' dotted_as_name)* | 'from' dotted_name 'import' ('*' | import_as_name (',' import_as_name)*) From tim_one@users.sourceforge.net Sat Jul 7 23:56:00 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 15:56:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include abstract.h,2.31.2.1,2.31.2.2 cStringIO.h,2.14,2.14.8.1 ceval.h,2.41.4.1,2.41.4.2 compile.h,2.29,2.29.4.1 dictobject.h,2.20.8.2,2.20.8.3 fileobject.h,2.22,2.22.8.1 floatobject.h,2.17,2.17.8.1 frameobject.h,2.31,2.31.4.1 graminit.h,2.16,2.16.8.1 longobject.h,2.19,2.19.8.1 opcode.h,2.35,2.35.2.1 pyport.h,2.26,2.26.6.1 pystate.h,2.14,2.14.6.1 rangeobject.h,2.15,2.15.8.1 stringobject.h,2.25,2.25.6.1 symtable.h,2.7,2.7.4.1 tupleobject.h,2.24,2.24.8.1 unicodeobject.h,2.20,2.20.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv24450/mergedescr/dist/src/Include Modified Files: Tag: descr-branch abstract.h cStringIO.h ceval.h compile.h dictobject.h fileobject.h floatobject.h frameobject.h graminit.h longobject.h opcode.h pyport.h pystate.h rangeobject.h stringobject.h symtable.h tupleobject.h unicodeobject.h Log Message: Merge of trunk tag date2001-07-06 into descr-branch. Index: abstract.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/abstract.h,v retrieving revision 2.31.2.1 retrieving revision 2.31.2.2 diff -C2 -r2.31.2.1 -r2.31.2.2 *** abstract.h 2001/05/05 11:37:29 2.31.2.1 --- abstract.h 2001/07/07 22:55:27 2.31.2.2 *************** *** 496,502 **** /* Takes an iterator object and calls its tp_iternext slot, returning the next value. If the iterator is exhausted, ! this can return NULL without setting an exception, *or* ! NULL with a StopIteration exception. ! NULL with any other exception means an error occurred. */ /* Number Protocol:*/ --- 496,501 ---- /* Takes an iterator object and calls its tp_iternext slot, returning the next value. If the iterator is exhausted, ! this returns NULL without setting an exception. ! NULL with an exception means an error occurred. */ /* Number Protocol:*/ *************** *** 924,928 **** members of this list. ! Returns NULL on failure. If the object is not a sequence, raises a TypeError exception with m as the message text. */ --- 923,927 ---- members of this list. ! Returns NULL on failure. If the object does not support iteration, raises a TypeError exception with m as the message text. */ *************** *** 945,949 **** */ ! DL_IMPORT(int) PySequence_Contains(PyObject *o, PyObject *value); /* For DLL-level backwards compatibility */ --- 944,958 ---- */ ! DL_IMPORT(int) PySequence_Contains(PyObject *seq, PyObject *ob); ! /* ! Return -1 if error; 1 if ob in seq; 0 if ob not in seq. ! Use __contains__ if possible, else _PySequence_IterContains(). ! */ ! ! DL_IMPORT(int) _PySequence_IterContains(PyObject *seq, PyObject *ob); ! /* ! Return -1 if error; 1 if ob in seq; 0 if ob not in seq. ! Always uses the iteration protocol, and only Py_EQ comparisons. ! */ /* For DLL-level backwards compatibility */ Index: cStringIO.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/cStringIO.h,v retrieving revision 2.14 retrieving revision 2.14.8.1 diff -C2 -r2.14 -r2.14.8.1 *** cStringIO.h 2000/07/22 19:25:51 2.14 --- cStringIO.h 2001/07/07 22:55:27 2.14.8.1 *************** *** 127,131 **** #define PycString_IMPORT \ ! PycStringIO=xxxPyCObject_Import("cStringIO", "cStringIO_CAPI") #endif /* CSTRINGIO_INCLUDED */ --- 127,131 ---- #define PycString_IMPORT \ ! PycStringIO=(struct PycStringIO_CAPI*)xxxPyCObject_Import("cStringIO", "cStringIO_CAPI") #endif /* CSTRINGIO_INCLUDED */ Index: ceval.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/ceval.h,v retrieving revision 2.41.4.1 retrieving revision 2.41.4.2 diff -C2 -r2.41.4.1 -r2.41.4.2 *** ceval.h 2001/05/05 11:37:29 2.41.4.1 --- ceval.h 2001/07/07 22:55:27 2.41.4.2 *************** *** 23,26 **** --- 23,29 ---- char *methodname, char *format, ...); + DL_IMPORT(void) PyEval_SetProfile(Py_tracefunc, PyObject *); + DL_IMPORT(void) PyEval_SetTrace(Py_tracefunc, PyObject *); + DL_IMPORT(PyObject *) PyEval_GetBuiltins(void); DL_IMPORT(PyObject *) PyEval_GetGlobals(void); Index: compile.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/compile.h,v retrieving revision 2.29 retrieving revision 2.29.4.1 diff -C2 -r2.29 -r2.29.4.1 *** compile.h 2001/03/22 02:32:48 2.29 --- compile.h 2001/07/07 22:55:27 2.29.4.1 *************** *** 34,37 **** --- 34,38 ---- #define CO_VARKEYWORDS 0x0008 #define CO_NESTED 0x0010 + #define CO_GENERATOR 0x0020 extern DL_IMPORT(PyTypeObject) PyCode_Type; Index: dictobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/dictobject.h,v retrieving revision 2.20.8.2 retrieving revision 2.20.8.3 diff -C2 -r2.20.8.2 -r2.20.8.3 *** dictobject.h 2001/06/28 16:36:53 2.20.8.2 --- dictobject.h 2001/07/07 22:55:27 2.20.8.3 *************** *** 31,34 **** --- 31,45 ---- meaning otherwise. */ + + /* PyDict_MINSIZE is the minimum size of a dictionary. This many slots are + * allocated directly in the dict object (in the ma_smalltable member). + * It must be a power of 2, and at least 4. 8 allows dicts with no more + * than 5 active entries to live in ma_smalltable (and so avoid an + * additional malloc); instrumentation suggested this suffices for the + * majority of dicts (consisting mostly of usually-small instance dicts and + * usually-small dicts created to pass keyword arguments). + */ + #define PyDict_MINSIZE 8 + typedef struct { long me_hash; /* cached hash code of me_key */ *************** *** 54,61 **** int ma_fill; /* # Active + # Dummy */ int ma_used; /* # Active */ ! int ma_size; /* total # slots in ma_table */ ! int ma_poly; /* appopriate entry from polys vector */ PyDictEntry *ma_table; PyDictEntry *(*ma_lookup)(PyDictObject *mp, PyObject *key, long hash); }; --- 65,83 ---- int ma_fill; /* # Active + # Dummy */ int ma_used; /* # Active */ ! ! /* The table contains ma_mask + 1 slots, and that's a power of 2. ! * We store the mask instead of the size because the mask is more ! * frequently needed. ! */ ! int ma_mask; ! ! /* ma_table points to ma_smalltable for small tables, else to ! * additional malloc'ed memory. ma_table is never NULL! This rule ! * saves repeated runtime null-tests in the workhorse getitem and ! * setitem calls. ! */ PyDictEntry *ma_table; PyDictEntry *(*ma_lookup)(PyDictObject *mp, PyObject *key, long hash); + PyDictEntry ma_smalltable[PyDict_MINSIZE]; }; Index: fileobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/fileobject.h,v retrieving revision 2.22 retrieving revision 2.22.8.1 diff -C2 -r2.22 -r2.22.8.1 *** fileobject.h 2000/09/01 23:29:26 2.22 --- fileobject.h 2001/07/07 22:55:27 2.22.8.1 *************** *** 24,27 **** --- 24,32 ---- extern DL_IMPORT(int) PyObject_AsFileDescriptor(PyObject *); + /* The default encoding used by the platform file system APIs + If non-NULL, this is different than the default encoding for strings + */ + extern DL_IMPORT(const char *) Py_FileSystemDefaultEncoding; + #ifdef __cplusplus } Index: floatobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/floatobject.h,v retrieving revision 2.17 retrieving revision 2.17.8.1 diff -C2 -r2.17 -r2.17.8.1 *** floatobject.h 2000/09/01 23:29:26 2.17 --- floatobject.h 2001/07/07 22:55:27 2.17.8.1 *************** *** 21,30 **** #define PyFloat_Check(op) ((op)->ob_type == &PyFloat_Type) ! extern DL_IMPORT(PyObject *) PyFloat_FromString(PyObject*, char**); extern DL_IMPORT(PyObject *) PyFloat_FromDouble(double); - extern DL_IMPORT(double) PyFloat_AsDouble(PyObject *); ! /* Macro, trading safety for speed */ #define PyFloat_AS_DOUBLE(op) (((PyFloatObject *)(op))->ob_fval) #ifdef __cplusplus --- 21,49 ---- #define PyFloat_Check(op) ((op)->ob_type == &PyFloat_Type) ! /* Return Python float from string PyObject. Second argument ignored on ! input, and, if non-NULL, NULL is stored into *junk (this tried to serve a ! purpose once but can't be made to work as intended). */ ! extern DL_IMPORT(PyObject *) PyFloat_FromString(PyObject*, char** junk); ! ! /* Return Python float from C double. */ extern DL_IMPORT(PyObject *) PyFloat_FromDouble(double); ! /* Extract C double from Python float. The macro version trades safety for ! speed. */ ! extern DL_IMPORT(double) PyFloat_AsDouble(PyObject *); #define PyFloat_AS_DOUBLE(op) (((PyFloatObject *)(op))->ob_fval) + + /* Write repr(v) into the char buffer argument, followed by null byte. The + buffer must be "big enough"; >= 100 is very safe. + PyFloat_AsReprString(buf, x) strives to print enough digits so that + PyFloat_FromString(buf) then reproduces x exactly. */ + extern DL_IMPORT(void) PyFloat_AsReprString(char*, PyFloatObject *v); + + /* Write str(v) into the char buffer argument, followed by null byte. The + buffer must be "big enough"; >= 100 is very safe. Note that it's + unusual to be able to get back the float you started with from + PyFloat_AsString's result -- use PyFloat_AsReprString() if you want to + preserve precision across conversions. */ + extern DL_IMPORT(void) PyFloat_AsString(char*, PyFloatObject *v); #ifdef __cplusplus Index: frameobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/frameobject.h,v retrieving revision 2.31 retrieving revision 2.31.4.1 diff -C2 -r2.31 -r2.31.4.1 *** frameobject.h 2001/03/13 01:58:21 2.31 --- frameobject.h 2001/07/07 22:55:27 2.31.4.1 *************** *** 22,25 **** --- 22,29 ---- PyObject *f_locals; /* local symbol table (PyDictObject) */ PyObject **f_valuestack; /* points after the last local */ + /* Next free slot in f_valuestack. Frame creation sets to f_valuestack. + Frame evaluation usually NULLs it, but a frame that yields sets it + to the current stack top. */ + PyObject **f_stacktop; PyObject *f_trace; /* Trace function */ PyObject *f_exc_type, *f_exc_value, *f_exc_traceback; Index: graminit.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/graminit.h,v retrieving revision 2.16 retrieving revision 2.16.8.1 diff -C2 -r2.16 -r2.16.8.1 *** graminit.h 2000/08/24 20:09:45 2.16 --- graminit.h 2001/07/07 22:55:27 2.16.8.1 *************** *** 19,64 **** #define continue_stmt 274 #define return_stmt 275 ! #define raise_stmt 276 ! #define import_stmt 277 ! #define import_as_name 278 ! #define dotted_as_name 279 ! #define dotted_name 280 ! #define global_stmt 281 ! #define exec_stmt 282 ! #define assert_stmt 283 ! #define compound_stmt 284 ! #define if_stmt 285 ! #define while_stmt 286 ! #define for_stmt 287 ! #define try_stmt 288 ! #define except_clause 289 ! #define suite 290 ! #define test 291 ! #define and_test 292 ! #define not_test 293 ! #define comparison 294 ! #define comp_op 295 ! #define expr 296 ! #define xor_expr 297 ! #define and_expr 298 ! #define shift_expr 299 ! #define arith_expr 300 ! #define term 301 ! #define factor 302 ! #define power 303 ! #define atom 304 ! #define listmaker 305 ! #define lambdef 306 ! #define trailer 307 ! #define subscriptlist 308 ! #define subscript 309 ! #define sliceop 310 ! #define exprlist 311 ! #define testlist 312 ! #define dictmaker 313 ! #define classdef 314 ! #define arglist 315 ! #define argument 316 ! #define list_iter 317 ! #define list_for 318 ! #define list_if 319 --- 19,65 ---- #define continue_stmt 274 #define return_stmt 275 ! #define yield_stmt 276 ! #define raise_stmt 277 ! #define import_stmt 278 ! #define import_as_name 279 ! #define dotted_as_name 280 ! #define dotted_name 281 ! #define global_stmt 282 ! #define exec_stmt 283 ! #define assert_stmt 284 ! #define compound_stmt 285 ! #define if_stmt 286 ! #define while_stmt 287 ! #define for_stmt 288 ! #define try_stmt 289 ! #define except_clause 290 ! #define suite 291 ! #define test 292 ! #define and_test 293 ! #define not_test 294 ! #define comparison 295 ! #define comp_op 296 ! #define expr 297 ! #define xor_expr 298 ! #define and_expr 299 ! #define shift_expr 300 ! #define arith_expr 301 ! #define term 302 ! #define factor 303 ! #define power 304 ! #define atom 305 ! #define listmaker 306 ! #define lambdef 307 ! #define trailer 308 ! #define subscriptlist 309 ! #define subscript 310 ! #define sliceop 311 ! #define exprlist 312 ! #define testlist 313 ! #define dictmaker 314 ! #define classdef 315 ! #define arglist 316 ! #define argument 317 ! #define list_iter 318 ! #define list_for 319 ! #define list_if 320 Index: longobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/longobject.h,v retrieving revision 2.19 retrieving revision 2.19.8.1 diff -C2 -r2.19 -r2.19.8.1 *** longobject.h 2000/09/26 05:45:59 2.19 --- longobject.h 2001/07/07 22:55:27 2.19.8.1 *************** *** 45,48 **** --- 45,88 ---- DL_IMPORT(PyObject *) PyLong_FromUnicode(Py_UNICODE*, int, int); + /* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in + base 256, and return a Python long with the same numeric value. + If n is 0, the integer is 0. Else: + If little_endian is 1/true, bytes[n-1] is the MSB and bytes[0] the LSB; + else (little_endian is 0/false) bytes[0] is the MSB and bytes[n-1] the + LSB. + If is_signed is 0/false, view the bytes as a non-negative integer. + If is_signed is 1/true, view the bytes as a 2's-complement integer, + non-negative if bit 0x80 of the MSB is clear, negative if set. + Error returns: + + Return NULL with the appropriate exception set if there's not + enough memory to create the Python long. + */ + extern DL_IMPORT(PyObject *) _PyLong_FromByteArray( + const unsigned char* bytes, size_t n, + int little_endian, int is_signed); + + /* _PyLong_AsByteArray: Convert the least-significant 8*n bits of long + v to a base-256 integer, stored in array bytes. Normally return 0, + return -1 on error. + If little_endian is 1/true, store the MSB at bytes[n-1] and the LSB at + bytes[0]; else (little_endian is 0/false) store the MSB at bytes[0] and + the LSB at bytes[n-1]. + If is_signed is 0/false, it's an error if v < 0; else (v >= 0) n bytes + are filled and there's nothing special about bit 0x80 of the MSB. + If is_signed is 1/true, bytes is filled with the 2's-complement + representation of v's value. Bit 0x80 of the MSB is the sign bit. + Error returns (-1): + + is_signed is 0 and v < 0. TypeError is set in this case, and bytes + isn't altered. + + n isn't big enough to hold the full mathematical value of v. For + example, if is_signed is 0 and there are more digits in the v than + fit in n; or if is_signed is 1, v < 0, and n is just 1 bit shy of + being large enough to hold a sign bit. OverflowError is set in this + case, but bytes holds the least-signficant n bytes of the true value. + */ + extern DL_IMPORT(int) _PyLong_AsByteArray(PyLongObject* v, + unsigned char* bytes, size_t n, + int little_endian, int is_signed); + #ifdef __cplusplus } Index: opcode.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/opcode.h,v retrieving revision 2.35 retrieving revision 2.35.2.1 diff -C2 -r2.35 -r2.35.2.1 *** opcode.h 2001/04/20 19:13:01 2.35 --- opcode.h 2001/07/07 22:55:27 2.35.2.1 *************** *** 72,75 **** --- 72,76 ---- #define IMPORT_STAR 84 #define EXEC_STMT 85 + #define YIELD_VALUE 86 #define POP_BLOCK 87 Index: pyport.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pyport.h,v retrieving revision 2.26 retrieving revision 2.26.6.1 diff -C2 -r2.26 -r2.26.6.1 *** pyport.h 2001/01/22 16:50:11 2.26 --- pyport.h 2001/07/07 22:55:27 2.26.6.1 *************** *** 435,438 **** --- 435,447 ---- #endif + /* + * Rename some functions for the Borland compiler + */ + #ifdef __BORLANDC__ + # include + # define _chsize chsize + # define _setmode setmode + #endif + #ifdef __cplusplus } Index: pystate.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pystate.h,v retrieving revision 2.14 retrieving revision 2.14.6.1 diff -C2 -r2.14 -r2.14.6.1 *** pystate.h 2001/01/23 01:44:35 2.14 --- pystate.h 2001/07/07 22:55:27 2.14.6.1 *************** *** 32,35 **** --- 32,44 ---- struct _frame; /* Avoid including frameobject.h */ + /* Py_tracefunc return -1 when raising an exception, or 0 for success. */ + typedef int (*Py_tracefunc)(PyObject *, struct _frame *, int, PyObject *); + + /* The following values are used for 'what' for tracefunc functions: */ + #define PyTrace_CALL 0 + #define PyTrace_EXCEPTION 1 + #define PyTrace_LINE 2 + #define PyTrace_RETURN 3 + typedef struct _ts { *************** *** 41,47 **** int ticker; int tracing; ! PyObject *sys_profilefunc; ! PyObject *sys_tracefunc; PyObject *curexc_type; --- 50,59 ---- int ticker; int tracing; + int use_tracing; ! Py_tracefunc c_profilefunc; ! Py_tracefunc c_tracefunc; ! PyObject *c_profileobj; ! PyObject *c_traceobj; PyObject *curexc_type; Index: rangeobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/rangeobject.h,v retrieving revision 2.15 retrieving revision 2.15.8.1 diff -C2 -r2.15 -r2.15.8.1 *** rangeobject.h 2000/09/01 23:29:26 2.15 --- rangeobject.h 2001/07/07 22:55:27 2.15.8.1 *************** *** 2,5 **** --- 2,11 ---- /* Range object interface */ + #ifndef Py_RANGEOBJECT_H + #define Py_RANGEOBJECT_H + #ifdef __cplusplus + extern "C" { + #endif + /* A range object represents an integer range. This is an immutable object; *************** *** 13,16 **** #define PyRange_Check(op) ((op)->ob_type == &PyRange_Type) ! extern DL_IMPORT(PyObject *) PyRange_New(long, long, long, int); --- 19,27 ---- #define PyRange_Check(op) ((op)->ob_type == &PyRange_Type) + + extern DL_IMPORT(PyObject *) PyRange_New(long, long, long); ! #ifdef __cplusplus ! } ! #endif ! #endif /* !Py_RANGEOBJECT_H */ Index: stringobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/stringobject.h,v retrieving revision 2.25 retrieving revision 2.25.6.1 diff -C2 -r2.25 -r2.25.6.1 *** stringobject.h 2001/02/23 16:40:48 2.25 --- stringobject.h 2001/07/07 22:55:27 2.25.6.1 *************** *** 59,62 **** --- 59,63 ---- extern DL_IMPORT(void) PyString_ConcatAndDel(PyObject **, PyObject *); extern DL_IMPORT(int) _PyString_Resize(PyObject **, int); + extern DL_IMPORT(int) _PyString_Eq(PyObject *, PyObject*); extern DL_IMPORT(PyObject *) PyString_Format(PyObject *, PyObject *); extern DL_IMPORT(PyObject *) _PyString_FormatLong(PyObject*, int, int, *************** *** 77,83 **** #define PyString_GET_SIZE(op) (((PyStringObject *)(op))->ob_size) /* --- Generic Codecs ----------------------------------------------------- */ ! /* Create a string object by decoding the encoded string s of the given size. */ --- 78,88 ---- #define PyString_GET_SIZE(op) (((PyStringObject *)(op))->ob_size) + /* _PyString_Join(sep, x) is like sep.join(x). sep must be PyStringObject*, + x must be an iterable object. */ + extern DL_IMPORT(PyObject *) _PyString_Join(PyObject *sep, PyObject *x); + /* --- Generic Codecs ----------------------------------------------------- */ ! /* Create an object by decoding the encoded string s of the given size. */ *************** *** 90,94 **** /* Encodes a char buffer of the given size and returns a ! Python string object. */ extern DL_IMPORT(PyObject*) PyString_Encode( --- 95,99 ---- /* Encodes a char buffer of the given size and returns a ! Python object. */ extern DL_IMPORT(PyObject*) PyString_Encode( *************** *** 99,106 **** ); ! /* Encodes a string object and returns the result as Python string object. */ extern DL_IMPORT(PyObject*) PyString_AsEncodedString( PyObject *str, /* string object */ const char *encoding, /* encoding */ --- 104,148 ---- ); ! /* Encodes a string object and returns the result as Python object. */ + extern DL_IMPORT(PyObject*) PyString_AsEncodedObject( + PyObject *str, /* string object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + + /* Encodes a string object and returns the result as Python string + object. + + If the codec returns an Unicode object, the object is converted + back to a string using the default encoding. + + DEPRECATED - use PyString_AsEncodedObject() instead. */ + extern DL_IMPORT(PyObject*) PyString_AsEncodedString( + PyObject *str, /* string object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + + /* Decodes a string object and returns the result as Python + object. */ + + extern DL_IMPORT(PyObject*) PyString_AsDecodedObject( + PyObject *str, /* string object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + + /* Decodes a string object and returns the result as Python string + object. + + If the codec returns an Unicode object, the object is converted + back to a string using the default encoding. + + DEPRECATED - use PyString_AsDecodedObject() instead. */ + + extern DL_IMPORT(PyObject*) PyString_AsDecodedString( PyObject *str, /* string object */ const char *encoding, /* encoding */ Index: symtable.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/symtable.h,v retrieving revision 2.7 retrieving revision 2.7.4.1 diff -C2 -r2.7 -r2.7.4.1 *** symtable.h 2001/03/22 03:57:58 2.7 --- symtable.h 2001/07/07 22:55:27 2.7.4.1 *************** *** 47,50 **** --- 47,51 ---- int ste_child_free; /* true if a child scope has free variables, including free refs to globals */ + int ste_generator; /* true if namespace is a generator */ int ste_opt_lineno; /* lineno of last exec or import * */ struct symtable *ste_table; Index: tupleobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/tupleobject.h,v retrieving revision 2.24 retrieving revision 2.24.8.1 diff -C2 -r2.24 -r2.24.8.1 *** tupleobject.h 2000/09/01 23:29:26 2.24 --- tupleobject.h 2001/07/07 22:55:27 2.24.8.1 *************** *** 34,38 **** extern DL_IMPORT(int) PyTuple_SetItem(PyObject *, int, PyObject *); extern DL_IMPORT(PyObject *) PyTuple_GetSlice(PyObject *, int, int); ! extern DL_IMPORT(int) _PyTuple_Resize(PyObject **, int, int); /* Macro, trading safety for speed */ --- 34,38 ---- extern DL_IMPORT(int) PyTuple_SetItem(PyObject *, int, PyObject *); extern DL_IMPORT(PyObject *) PyTuple_GetSlice(PyObject *, int, int); ! extern DL_IMPORT(int) _PyTuple_Resize(PyObject **, int); /* Macro, trading safety for speed */ Index: unicodeobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/unicodeobject.h,v retrieving revision 2.20 retrieving revision 2.20.2.1 diff -C2 -r2.20 -r2.20.2.1 *** unicodeobject.h 2001/04/23 14:44:21 2.20 --- unicodeobject.h 2001/07/07 22:55:27 2.20.2.1 *************** *** 59,62 **** --- 59,77 ---- /* --- Internal Unicode Format -------------------------------------------- */ + /* FIXME: MvL's new implementation assumes that Py_UNICODE_SIZE is + properly set, but the default rules below doesn't set it. I'll + sort this out some other day -- fredrik@pythonware.com */ + + #ifndef Py_UNICODE_SIZE + #error Must define Py_UNICODE_SIZE + #endif + + /* Setting Py_UNICODE_WIDE enables UCS-4 storage. Otherwise, Unicode + strings are stored as UCS-2 (with limited support for UTF-16) */ + + #if Py_UNICODE_SIZE >= 4 + #define Py_UNICODE_WIDE + #endif + /* Set these flags if the platform has "wchar.h", "wctype.h" and the wchar_t type is a 16-bit unsigned type */ *************** *** 65,75 **** /* Defaults for various platforms */ ! #ifndef HAVE_USABLE_WCHAR_T ! /* Windows has a usable wchar_t type */ ! # if defined(MS_WIN32) # define HAVE_USABLE_WCHAR_T # endif #endif --- 80,95 ---- /* Defaults for various platforms */ ! #ifndef PY_UNICODE_TYPE ! /* Windows has a usable wchar_t type (unless we're using UCS-4) */ ! # if defined(MS_WIN32) && Py_UNICODE_SIZE == 2 # define HAVE_USABLE_WCHAR_T + # define PY_UNICODE_TYPE wchar_t # endif + # if defined(Py_UNICODE_WIDE) + # define PY_UNICODE_TYPE Py_UCS4 + # endif + #endif *************** *** 92,113 **** #endif - #ifdef HAVE_USABLE_WCHAR_T - - /* If the compiler defines whcar_t as a 16-bit unsigned type we can - use the compiler type directly. Works fine with all modern Windows - platforms. */ - - typedef wchar_t Py_UNICODE; - - #else - - /* Use if you have a standard ANSI compiler, without wchar_t support. - If a short is not 16 bits on your platform, you have to fix the - typedef below, or the module initialization code will complain. */ - - typedef unsigned short Py_UNICODE; - - #endif - /* * Use this typedef when you need to represent a UTF-16 surrogate pair --- 112,115 ---- *************** *** 118,123 **** --- 120,132 ---- #elif SIZEOF_LONG >= 4 typedef unsigned long Py_UCS4; + #endif + + #if SIZEOF_SHORT == 2 + typedef unsigned short Py_UCS2; + #else + #error Cannot find a two-byte type #endif + typedef PY_UNICODE_TYPE Py_UNICODE; /* --- Internal Unicode Operations ---------------------------------------- */ *************** *** 267,270 **** --- 276,282 ---- ); + /* Get the maximum ordinal for a Unicode character. */ + extern DL_IMPORT(Py_UNICODE) PyUnicode_GetMax(void); + /* Resize an already allocated Unicode object to the new size length. *************** *** 460,467 **** *byteorder == 1: big endian ! and then switches according to all BOM marks it finds in the input ! data. BOM marks are not copied into the resulting Unicode string. ! After completion, *byteorder is set to the current byte order at ! the end of input data. If byteorder is NULL, the codec starts in native order mode. --- 472,480 ---- *byteorder == 1: big endian ! In native mode, the first two bytes of the stream are checked for a ! BOM mark. If found, the BOM mark is analysed, the byte order ! adjusted and the BOM skipped. In the other modes, no BOM mark ! interpretation is done. After completion, *byteorder is set to the ! current byte order at the end of input data. If byteorder is NULL, the codec starts in native order mode. *************** *** 852,912 **** extern DL_IMPORT(int) _PyUnicode_IsLowercase( ! register const Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(int) _PyUnicode_IsUppercase( ! register const Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(int) _PyUnicode_IsTitlecase( ! register const Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(int) _PyUnicode_IsWhitespace( ! register const Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(int) _PyUnicode_IsLinebreak( ! register const Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(Py_UNICODE) _PyUnicode_ToLowercase( ! register const Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(Py_UNICODE) _PyUnicode_ToUppercase( ! register const Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(Py_UNICODE) _PyUnicode_ToTitlecase( ! register const Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(int) _PyUnicode_ToDecimalDigit( ! register const Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(int) _PyUnicode_ToDigit( ! register const Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(double) _PyUnicode_ToNumeric( ! register const Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(int) _PyUnicode_IsDecimalDigit( ! register const Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(int) _PyUnicode_IsDigit( ! register const Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(int) _PyUnicode_IsNumeric( ! register const Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(int) _PyUnicode_IsAlpha( ! register const Py_UNICODE ch /* Unicode character */ ); --- 865,925 ---- extern DL_IMPORT(int) _PyUnicode_IsLowercase( ! Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(int) _PyUnicode_IsUppercase( ! Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(int) _PyUnicode_IsTitlecase( ! Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(int) _PyUnicode_IsWhitespace( ! Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(int) _PyUnicode_IsLinebreak( ! Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(Py_UNICODE) _PyUnicode_ToLowercase( ! Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(Py_UNICODE) _PyUnicode_ToUppercase( ! Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(Py_UNICODE) _PyUnicode_ToTitlecase( ! Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(int) _PyUnicode_ToDecimalDigit( ! Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(int) _PyUnicode_ToDigit( ! Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(double) _PyUnicode_ToNumeric( ! Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(int) _PyUnicode_IsDecimalDigit( ! Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(int) _PyUnicode_IsDigit( ! Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(int) _PyUnicode_IsNumeric( ! Py_UNICODE ch /* Unicode character */ ); extern DL_IMPORT(int) _PyUnicode_IsAlpha( ! Py_UNICODE ch /* Unicode character */ ); From tim_one@users.sourceforge.net Sat Jul 7 23:56:00 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 15:56:00 -0700 Subject: [Python-checkins] CVS: python/dist/src LICENSE,1.15,1.15.4.1 Makefile.pre.in,1.37.2.1,1.37.2.2 PLAN.txt,1.1.2.16,1.1.2.17 README,1.123,1.123.2.1 acconfig.h,1.46,1.46.4.1 config.h.in,2.92,2.92.2.1 configure,1.209,1.209.2.1 configure.in,1.217,1.217.2.1 setup.py,1.38,1.38.4.1 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv24450/mergedescr/dist/src Modified Files: Tag: descr-branch LICENSE Makefile.pre.in PLAN.txt README acconfig.h config.h.in configure configure.in setup.py Log Message: Merge of trunk tag date2001-07-06 into descr-branch. Index: LICENSE =================================================================== RCS file: /cvsroot/python/python/dist/src/LICENSE,v retrieving revision 1.15 retrieving revision 1.15.4.1 diff -C2 -r1.15 -r1.15.4.1 *** LICENSE 2001/04/13 19:41:28 1.15 --- LICENSE 2001/07/07 22:55:27 1.15.4.1 *************** *** 26,34 **** After Python 2.0 was released by BeOpen.com, Guido van Rossum and the other PythonLabs developers joined Digital Creations. All ! intellectual property added from this point on, starting with Python ! 2.1 and its alpha and beta releases, is owned by the Python Software ! Foundation (PSF), a non-profit modeled after the Apache Software ! Foundation. See http://www.python.org/psf/ for more information about ! the PSF. Thanks to the many outside volunteers who have worked under Guido's --- 26,33 ---- After Python 2.0 was released by BeOpen.com, Guido van Rossum and the other PythonLabs developers joined Digital Creations. All ! intellectual property added from this point on, including Python ! 2.0.1, is owned by the Python Software Foundation (PSF), a non-profit ! modeled after the Apache Software Foundation. See ! http://www.python.org/psf/ for more information about the PSF. Thanks to the many outside volunteers who have worked under Guido's *************** *** 77,96 **** breach of its terms and conditions. ! 7. This License Agreement shall be governed by the federal ! intellectual property law of the United States, including without ! limitation the federal copyright law, and, to the extent such ! U.S. federal law does not apply, by the law of the Commonwealth of ! Virginia, excluding Virginia's conflict of law provisions. ! Notwithstanding the foregoing, with regard to derivative works based ! on Python 2.1 that incorporate non-separable material that was ! previously distributed under the GNU General Public License (GPL), the ! law of the Commonwealth of Virginia shall govern this License ! Agreement only as to issues arising under or with respect to ! Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this ! License Agreement shall be deemed to create any relationship of ! agency, partnership, or joint venture between PSF and Licensee. This ! License Agreement does not grant permission to use PSF trademarks or ! trade name in a trademark sense to endorse or promote products or ! services of Licensee, or any third party. 8. By copying, installing or otherwise using Python 2.1, Licensee --- 76,84 ---- breach of its terms and conditions. ! 7. Nothing in this License Agreement shall be deemed to create any ! relationship of agency, partnership, or joint venture between PSF and ! Licensee. This License Agreement does not grant permission to use PSF ! trademarks or trade name in a trademark sense to endorse or promote ! products or services of Licensee, or any third party. 8. By copying, installing or otherwise using Python 2.1, Licensee Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.37.2.1 retrieving revision 1.37.2.2 diff -C2 -r1.37.2.1 -r1.37.2.2 *** Makefile.pre.in 2001/04/24 00:49:08 1.37.2.1 --- Makefile.pre.in 2001/07/07 22:55:27 1.37.2.2 *************** *** 56,60 **** OPT= @OPT@ DEFS= @DEFS@ ! CFLAGS= $(OPT) -I. -I$(srcdir)/Include $(DEFS) LDFLAGS= @LDFLAGS@ LDLAST= @LDLAST@ --- 56,61 ---- OPT= @OPT@ DEFS= @DEFS@ ! CFLAGS= $(OPT) ! CPPFLAGS= -I. -I$(srcdir)/Include $(DEFS) LDFLAGS= @LDFLAGS@ LDLAST= @LDLAST@ *************** *** 65,69 **** CFLAGSFORSHARED=@CFLAGSFORSHARED@ # C flags used for building the interpreter object files ! PY_CFLAGS= $(CFLAGS) $(CFLAGSFORSHARED) --- 66,70 ---- CFLAGSFORSHARED=@CFLAGSFORSHARED@ # C flags used for building the interpreter object files ! PY_CFLAGS= $(CFLAGS) $(CPPFLAGS) $(CFLAGSFORSHARED) *************** *** 138,141 **** --- 139,143 ---- DLINCLDIR= @DLINCLDIR@ DYNLOADFILE= @DYNLOADFILE@ + MACHDEP_OBJS= @MACHDEP_OBJS@ PYTHON= python$(EXE) *************** *** 222,225 **** --- 224,228 ---- Python/getopt.o \ Python/$(DYNLOADFILE) \ + $(MACHDEP_OBJS) \ $(LIBOBJS) *************** *** 285,289 **** # Build the shared modules sharedmods: $(PYTHON) ! PYTHONPATH= ./$(PYTHON) $(srcdir)/setup.py build # buildno should really depend on something like LIBRARY_SRC --- 288,293 ---- # Build the shared modules sharedmods: $(PYTHON) ! unset PYTHONPATH PYTHONHOME PYTHONSTARTUP; \ ! ./$(PYTHON) $(srcdir)/setup.py build # buildno should really depend on something like LIBRARY_SRC *************** *** 401,408 **** Python/getplatform.o: $(srcdir)/Python/getplatform.c ! $(CC) -c $(CFLAGS) -DPLATFORM='"$(MACHDEP)"' -o $@ $(srcdir)/Python/getplatform.c Python/importdl.o: $(srcdir)/Python/importdl.c ! $(CC) -c $(CFLAGS) -I$(DLINCLDIR) -o $@ $(srcdir)/Python/importdl.c Objects/object.o: $(srcdir)/Objects/object.c $(srcdir)/Objects/obmalloc.c --- 405,412 ---- Python/getplatform.o: $(srcdir)/Python/getplatform.c ! $(CC) -c $(CFLAGS) $(CPPFLAGS) -DPLATFORM='"$(MACHDEP)"' -o $@ $(srcdir)/Python/getplatform.c Python/importdl.o: $(srcdir)/Python/importdl.c ! $(CC) -c $(CFLAGS) $(CPPFLAGS) -I$(DLINCLDIR) -o $@ $(srcdir)/Python/importdl.c Objects/object.o: $(srcdir)/Objects/object.c $(srcdir)/Objects/obmalloc.c *************** *** 411,414 **** --- 415,420 ---- $(srcdir)/Objects/unicodetype_db.h + Mac/Python/macglue.o: $(srcdir)/Mac/Python/macglue.c + $(CC) -c $(CFLAGS) $(CPPFLAGS) -I$(srcdir)/Mac/Include -I$(srcdir)/Python -o $@ $(srcdir)/Mac/Python/macglue.c ############################################################################ *************** *** 764,768 **** tags TAGS \ config.cache config.log config.h Modules/config.c ! -rm -rf build # Make things extra clean, before making a distribution: --- 770,774 ---- tags TAGS \ config.cache config.log config.h Modules/config.c ! -rm -rf build platform # Make things extra clean, before making a distribution: Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Attic/PLAN.txt,v retrieving revision 1.1.2.16 retrieving revision 1.1.2.17 diff -C2 -r1.1.2.16 -r1.1.2.17 *** PLAN.txt 2001/07/07 22:45:44 1.1.2.16 --- PLAN.txt 2001/07/07 22:55:27 1.1.2.17 *************** *** 252,258 **** ------------------------------------------------------------------ ! Merge of trunk tag date2001-07-06 into descr-branch was committed on ! 2001-07-07. Merge issues: --- 252,261 ---- ------------------------------------------------------------------ ! 2001-07-07 + Merge of trunk tag date2001-07-06 into descr-branch, via + cvs -q -z3 up -j date2001-07-06 mergedescr + was committed on 2001-07-07. + Merge issues: *************** *** 266,987 **** that has been removed on the trunk since descr-fork, it will probably fail. The cure is to remove the expected-output file in descr-branch too. - ------------------------------------------------------------------ - 2001-07-06 - - Screen dump from initial merge attempt, less the lines that apply to files - already merged. - - C:\Code>cvs -q -z3 up -j date2001-07-06 mergedescr - RCS file: /cvsroot/python/python/dist/src/LICENSE,v - retrieving revision 1.15 - retrieving revision 1.17 - Merging differences between 1.15 and 1.17 into LICENSE - RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v - retrieving revision 1.37 - retrieving revision 1.40 - Merging differences between 1.37 and 1.40 into Makefile.pre.in - RCS file: /cvsroot/python/python/dist/src/README,v - retrieving revision 1.123 - retrieving revision 1.124 - Merging differences between 1.123 and 1.124 into README - RCS file: /cvsroot/python/python/dist/src/acconfig.h,v - retrieving revision 1.46 - retrieving revision 1.49 - Merging differences between 1.46 and 1.49 into acconfig.h - RCS file: /cvsroot/python/python/dist/src/config.h.in,v - retrieving revision 2.92 - retrieving revision 2.97 - Merging differences between 2.92 and 2.97 into config.h.in - RCS file: /cvsroot/python/python/dist/src/configure,v - retrieving revision 1.209 - retrieving revision 1.215 - Merging differences between 1.209 and 1.215 into configure - RCS file: /cvsroot/python/python/dist/src/configure.in,v - retrieving revision 1.217 - retrieving revision 1.223 - Merging differences between 1.217 and 1.223 into configure.in - RCS file: /cvsroot/python/python/dist/src/setup.py,v - retrieving revision 1.38 - retrieving revision 1.41 - Merging differences between 1.38 and 1.41 into setup.py - RCS file: /cvsroot/python/python/dist/src/Grammar/Grammar,v - retrieving revision 1.42 - retrieving revision 1.43 - Merging differences between 1.42 and 1.43 into Grammar - RCS file: /cvsroot/python/python/dist/src/Include/abstract.h,v - retrieving revision 2.31 - retrieving revision 2.34 - Merging differences between 2.31 and 2.34 into abstract.h - RCS file: /cvsroot/python/python/dist/src/Include/cStringIO.h,v - retrieving revision 2.14 - retrieving revision 2.15 - Merging differences between 2.14 and 2.15 into cStringIO.h - RCS file: /cvsroot/python/python/dist/src/Include/fileobject.h,v - retrieving revision 2.22 - retrieving revision 2.23 - Merging differences between 2.22 and 2.23 into fileobject.h - RCS file: /cvsroot/python/python/dist/src/Include/floatobject.h,v - retrieving revision 2.17 - retrieving revision 2.18 - Merging differences between 2.17 and 2.18 into floatobject.h - RCS file: /cvsroot/python/python/dist/src/Include/longobject.h,v - retrieving revision 2.19 - retrieving revision 2.20 - Merging differences between 2.19 and 2.20 into longobject.h - RCS file: /cvsroot/python/python/dist/src/Include/pyport.h,v - retrieving revision 2.26 - retrieving revision 2.27 - Merging differences between 2.26 and 2.27 into pyport.h - RCS file: /cvsroot/python/python/dist/src/Include/rangeobject.h,v - retrieving revision 2.15 - retrieving revision 2.17 - Merging differences between 2.15 and 2.17 into rangeobject.h - RCS file: /cvsroot/python/python/dist/src/Include/tupleobject.h,v - retrieving revision 2.24 - retrieving revision 2.25 - Merging differences between 2.24 and 2.25 into tupleobject.h - RCS file: /cvsroot/python/python/dist/src/Include/unicodeobject.h,v - retrieving revision 2.20 - retrieving revision 2.27 - Merging differences between 2.20 and 2.27 into unicodeobject.h - RCS file: /cvsroot/python/python/dist/src/Lib/UserDict.py,v - retrieving revision 1.12 - retrieving revision 1.14 - Merging differences between 1.12 and 1.14 into UserDict.py - RCS file: /cvsroot/python/python/dist/src/Lib/UserList.py,v - retrieving revision 1.16 - retrieving revision 1.17 - Merging differences between 1.16 and 1.17 into UserList.py - RCS file: /cvsroot/python/python/dist/src/Lib/UserString.py,v - retrieving revision 1.9 - retrieving revision 1.10 - Merging differences between 1.9 and 1.10 into UserString.py - RCS file: /cvsroot/python/python/dist/src/Lib/anydbm.py,v - retrieving revision 1.10 - retrieving revision 1.11 - Merging differences between 1.10 and 1.11 into anydbm.py - RCS file: /cvsroot/python/python/dist/src/Lib/asyncore.py,v - retrieving revision 1.11 - retrieving revision 1.14 - Merging differences between 1.11 and 1.14 into asyncore.py - RCS file: /cvsroot/python/python/dist/src/Lib/base64.py,v - retrieving revision 1.11 - retrieving revision 1.12 - Merging differences between 1.11 and 1.12 into base64.py - RCS file: /cvsroot/python/python/dist/src/Lib/bdb.py,v - retrieving revision 1.31 - retrieving revision 1.32 - Merging differences between 1.31 and 1.32 into bdb.py - RCS file: /cvsroot/python/python/dist/src/Lib/calendar.py,v - retrieving revision 1.21 - retrieving revision 1.22 - Merging differences between 1.21 and 1.22 into calendar.py - RCS file: /cvsroot/python/python/dist/src/Lib/cgi.py,v - retrieving revision 1.63 - retrieving revision 1.64 - Merging differences between 1.63 and 1.64 into cgi.py - RCS file: /cvsroot/python/python/dist/src/Lib/chunk.py,v - retrieving revision 1.10 - retrieving revision 1.11 - Merging differences between 1.10 and 1.11 into chunk.py - RCS file: /cvsroot/python/python/dist/src/Lib/code.py,v - retrieving revision 1.15 - retrieving revision 1.16 - Merging differences between 1.15 and 1.16 into code.py - RCS file: /cvsroot/python/python/dist/src/Lib/dbhash.py,v - retrieving revision 1.5 - retrieving revision 1.6 - Merging differences between 1.5 and 1.6 into dbhash.py - RCS file: /cvsroot/python/python/dist/src/Lib/dis.py,v - retrieving revision 1.34 - retrieving revision 1.35 - Merging differences between 1.34 and 1.35 into dis.py - RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v - retrieving revision 1.10 - retrieving revision 1.14 - Merging differences between 1.10 and 1.14 into doctest.py - RCS file: /cvsroot/python/python/dist/src/Lib/dumbdbm.py,v - retrieving revision 1.10 - retrieving revision 1.11 - Merging differences between 1.10 and 1.11 into dumbdbm.py - RCS file: /cvsroot/python/python/dist/src/Lib/fnmatch.py,v - retrieving revision 1.11 - retrieving revision 1.12 - Merging differences between 1.11 and 1.12 into fnmatch.py - RCS file: /cvsroot/python/python/dist/src/Lib/formatter.py,v - retrieving revision 1.17 - retrieving revision 1.18 - Merging differences between 1.17 and 1.18 into formatter.py - RCS file: /cvsroot/python/python/dist/src/Lib/glob.py,v - retrieving revision 1.9 - retrieving revision 1.10 - Merging differences between 1.9 and 1.10 into glob.py - RCS file: /cvsroot/python/python/dist/src/Lib/htmllib.py,v - retrieving revision 1.17 - retrieving revision 1.18 - Merging differences between 1.17 and 1.18 into htmllib.py - RCS file: /cvsroot/python/python/dist/src/Lib/httplib.py,v - retrieving revision 1.34 - retrieving revision 1.35 - Merging differences between 1.34 and 1.35 into httplib.py - RCS file: /cvsroot/python/python/dist/src/Lib/imaplib.py,v - retrieving revision 1.27 - retrieving revision 1.29 - Merging differences between 1.27 and 1.29 into imaplib.py - RCS file: /cvsroot/python/python/dist/src/Lib/inspect.py,v - retrieving revision 1.16 - retrieving revision 1.18 - Merging differences between 1.16 and 1.18 into inspect.py - RCS file: /cvsroot/python/python/dist/src/Lib/keyword.py,v - retrieving revision 1.10 - retrieving revision 1.11 - Merging differences between 1.10 and 1.11 into keyword.py - RCS file: /cvsroot/python/python/dist/src/Lib/linecache.py,v - retrieving revision 1.7 - retrieving revision 1.8 - Merging differences between 1.7 and 1.8 into linecache.py - RCS file: /cvsroot/python/python/dist/src/Lib/mailbox.py,v - retrieving revision 1.30 - retrieving revision 1.31 - Merging differences between 1.30 and 1.31 into mailbox.py - RCS file: /cvsroot/python/python/dist/src/Lib/mailcap.py,v - retrieving revision 1.9 - retrieving revision 1.10 - Merging differences between 1.9 and 1.10 into mailcap.py - RCS file: /cvsroot/python/python/dist/src/Lib/mhlib.py,v - retrieving revision 1.26 - retrieving revision 1.27 - Merging differences between 1.26 and 1.27 into mhlib.py - RCS file: /cvsroot/python/python/dist/src/Lib/mimetypes.py,v - retrieving revision 1.13 - retrieving revision 1.14 - Merging differences between 1.13 and 1.14 into mimetypes.py - RCS file: /cvsroot/python/python/dist/src/Lib/mimify.py,v - retrieving revision 1.20 - retrieving revision 1.21 - Merging differences between 1.20 and 1.21 into mimify.py - RCS file: /cvsroot/python/python/dist/src/Lib/ntpath.py,v - retrieving revision 1.34 - retrieving revision 1.36 - Merging differences between 1.34 and 1.36 into ntpath.py - RCS file: /cvsroot/python/python/dist/src/Lib/pipes.py,v - retrieving revision 1.8 - retrieving revision 1.9 - Merging differences between 1.8 and 1.9 into pipes.py - RCS file: /cvsroot/python/python/dist/src/Lib/posixfile.py,v - retrieving revision 1.20 - retrieving revision 1.21 - Merging differences between 1.20 and 1.21 into posixfile.py - RCS file: /cvsroot/python/python/dist/src/Lib/pprint.py,v - retrieving revision 1.12 - retrieving revision 1.14 - Merging differences between 1.12 and 1.14 into pprint.py - RCS file: /cvsroot/python/python/dist/src/Lib/pre.py,v - retrieving revision 1.9 - retrieving revision 1.10 - Merging differences between 1.9 and 1.10 into pre.py - RCS file: /cvsroot/python/python/dist/src/Lib/profile.py,v - retrieving revision 1.27 - retrieving revision 1.29 - Merging differences between 1.27 and 1.29 into profile.py - RCS file: /cvsroot/python/python/dist/src/Lib/pstats.py,v - retrieving revision 1.15 - retrieving revision 1.18 - Merging differences between 1.15 and 1.18 into pstats.py - RCS file: /cvsroot/python/python/dist/src/Lib/pty.py,v - retrieving revision 1.7 - retrieving revision 1.11 - Merging differences between 1.7 and 1.11 into pty.py - RCS file: /cvsroot/python/python/dist/src/Lib/pydoc.py,v - retrieving revision 1.38 - retrieving revision 1.39 - Merging differences between 1.38 and 1.39 into pydoc.py - RCS file: /cvsroot/python/python/dist/src/Lib/quopri.py,v - retrieving revision 1.11 - retrieving revision 1.14 - Merging differences between 1.11 and 1.14 into quopri.py - RCS file: /cvsroot/python/python/dist/src/Lib/rexec.py,v - retrieving revision 1.28 - retrieving revision 1.30 - Merging differences between 1.28 and 1.30 into rexec.py - RCS file: /cvsroot/python/python/dist/src/Lib/rfc822.py,v - retrieving revision 1.54 - retrieving revision 1.57 - Merging differences between 1.54 and 1.57 into rfc822.py - RCS file: /cvsroot/python/python/dist/src/Lib/sgmllib.py,v - retrieving revision 1.30 - retrieving revision 1.32 - Merging differences between 1.30 and 1.32 into sgmllib.py - RCS file: /cvsroot/python/python/dist/src/Lib/site.py,v - retrieving revision 1.26 - retrieving revision 1.28 - Merging differences between 1.26 and 1.28 into site.py - RCS file: /cvsroot/python/python/dist/src/Lib/sre_compile.py,v - retrieving revision 1.37 - retrieving revision 1.38 - Merging differences between 1.37 and 1.38 into sre_compile.py - RCS file: /cvsroot/python/python/dist/src/Lib/sre_constants.py,v - retrieving revision 1.28 - retrieving revision 1.29 - Merging differences between 1.28 and 1.29 into sre_constants.py - RCS file: /cvsroot/python/python/dist/src/Lib/tabnanny.py,v - retrieving revision 1.13 - retrieving revision 1.15 - Merging differences between 1.13 and 1.15 into tabnanny.py - RCS file: /cvsroot/python/python/dist/src/Lib/tokenize.py,v - retrieving revision 1.22 - retrieving revision 1.24 - Merging differences between 1.22 and 1.24 into tokenize.py - RCS file: /cvsroot/python/python/dist/src/Lib/traceback.py,v - retrieving revision 1.25 - retrieving revision 1.26 - Merging differences between 1.25 and 1.26 into traceback.py - RCS file: /cvsroot/python/python/dist/src/Lib/types.py,v - retrieving revision 1.14 - retrieving revision 1.15 - Merging differences between 1.14 and 1.15 into types.py - RCS file: /cvsroot/python/python/dist/src/Lib/unittest.py,v - retrieving revision 1.7 - retrieving revision 1.8 - Merging differences between 1.7 and 1.8 into unittest.py - RCS file: /cvsroot/python/python/dist/src/Lib/urllib.py,v - retrieving revision 1.126 - retrieving revision 1.127 - Merging differences between 1.126 and 1.127 into urllib.py - RCS file: /cvsroot/python/python/dist/src/Lib/urllib2.py,v - retrieving revision 1.13 - retrieving revision 1.15 - Merging differences between 1.13 and 1.15 into urllib2.py - RCS file: /cvsroot/python/python/dist/src/Lib/weakref.py,v - retrieving revision 1.9 - retrieving revision 1.10 - Merging differences between 1.9 and 1.10 into weakref.py - RCS file: /cvsroot/python/python/dist/src/Lib/zipfile.py,v - retrieving revision 1.13 - retrieving revision 1.14 - Merging differences between 1.13 and 1.14 into zipfile.py - RCS file: /cvsroot/python/python/dist/src/Lib/distutils/mwerkscompiler.py,v - retrieving revision 1.1 - retrieving revision 1.4 - Merging differences between 1.1 and 1.4 into mwerkscompiler.py - RCS file: /cvsroot/python/python/dist/src/Lib/distutils/sysconfig.py,v - retrieving revision 1.34 - retrieving revision 1.36 - Merging differences between 1.34 and 1.36 into sysconfig.py - RCS file: /cvsroot/python/python/dist/src/Lib/distutils/command/bdist_rpm.py,v - retrieving revision 1.23 - retrieving revision 1.24 - Merging differences between 1.23 and 1.24 into bdist_rpm.py - RCS file: /cvsroot/python/python/dist/src/Lib/distutils/command/bdist_wininst.py,v - retrieving revision 1.21 - retrieving revision 1.22 - Merging differences between 1.21 and 1.22 into bdist_wininst.py - RCS file: /cvsroot/python/python/dist/src/Lib/lib-old/lockfile.py,v - retrieving revision 1.1 - retrieving revision 1.2 - Merging differences between 1.1 and 1.2 into lockfile.py - U mergedescr/dist/src/Lib/test/double_const.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/re_tests.py,v - retrieving revision 1.28 - retrieving revision 1.29 - Merging differences between 1.28 and 1.29 into re_tests.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/string_tests.py,v - retrieving revision 1.7 - retrieving revision 1.9 - Merging differences between 1.7 and 1.9 into string_tests.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_b1.py,v - retrieving revision 1.34 - retrieving revision 1.35 - Merging differences between 1.34 and 1.35 into test_b1.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_b2.py,v - retrieving revision 1.24 - retrieving revision 1.26 - Merging differences between 1.24 and 1.26 into test_b2.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_binhex.py,v - retrieving revision 1.10 - retrieving revision 1.11 - Merging differences between 1.10 and 1.11 into test_binhex.py - U mergedescr/dist/src/Lib/test/test_call.py - U mergedescr/dist/src/Lib/test/test_codecs.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_complex.py,v - retrieving revision 1.1 - retrieving revision 1.2 - Merging differences between 1.1 and 1.2 into test_complex.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_contains.py,v - retrieving revision 1.6 - retrieving revision 1.7 - Merging differences between 1.6 and 1.7 into test_contains.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_copy_reg.py,v - retrieving revision 1.1 - retrieving revision 1.2 - Merging differences between 1.1 and 1.2 into test_copy_reg.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_difflib.py,v - retrieving revision 1.1 - retrieving revision 1.3 - Merging differences between 1.1 and 1.3 into test_difflib.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_doctest.py,v - retrieving revision 1.1 - retrieving revision 1.2 - Merging differences between 1.1 and 1.2 into test_doctest.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_dospath.py,v - retrieving revision 1.3 - retrieving revision 1.4 - Merging differences between 1.3 and 1.4 into test_dospath.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_fcntl.py,v - retrieving revision 1.17 - retrieving revision 1.18 - Merging differences between 1.17 and 1.18 into test_fcntl.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_fnmatch.py,v - retrieving revision 1.1 - retrieving revision 1.2 - Merging differences between 1.1 and 1.2 into test_fnmatch.py - U mergedescr/dist/src/Lib/test/test_generators.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_grp.py,v - retrieving revision 1.7 - retrieving revision 1.8 - Merging differences between 1.7 and 1.8 into test_grp.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_hash.py,v - retrieving revision 1.2 - retrieving revision 1.4 - Merging differences between 1.2 and 1.4 into test_hash.py - U mergedescr/dist/src/Lib/test/test_htmlparser.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_import.py,v - retrieving revision 1.3 - retrieving revision 1.4 - Merging differences between 1.3 and 1.4 into test_import.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_iter.py,v - retrieving revision 1.2 - retrieving revision 1.17 - Merging differences between 1.2 and 1.17 into test_iter.py - rcsmerge: warning: conflicts during merge - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_locale.py,v - retrieving revision 1.2 - retrieving revision 1.3 - Merging differences between 1.2 and 1.3 into test_locale.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_mailbox.py,v - retrieving revision 1.3 - retrieving revision 1.6 - Merging differences between 1.3 and 1.6 into test_mailbox.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_minidom.py,v - retrieving revision 1.26 - retrieving revision 1.27 - Merging differences between 1.26 and 1.27 into test_minidom.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_mmap.py,v - retrieving revision 1.15 - retrieving revision 1.17 - Merging differences between 1.15 and 1.17 into test_mmap.py - U mergedescr/dist/src/Lib/test/test_mutants.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_operations.py,v - retrieving revision 1.3 - retrieving revision 1.5 - Merging differences between 1.3 and 1.5 into test_operations.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_parser.py,v - retrieving revision 1.6 - retrieving revision 1.7 - Merging differences between 1.6 and 1.7 into test_parser.py - U mergedescr/dist/src/Lib/test/test_pprint.py - U mergedescr/dist/src/Lib/test/test_quopri.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_rfc822.py,v - retrieving revision 1.9 - retrieving revision 1.11 - Merging differences between 1.9 and 1.11 into test_rfc822.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_richcmp.py,v - retrieving revision 1.5 - retrieving revision 1.6 - Merging differences between 1.5 and 1.6 into test_richcmp.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_scope.py,v - retrieving revision 1.14 - retrieving revision 1.16 - Merging differences between 1.14 and 1.16 into test_scope.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sha.py,v - retrieving revision 1.1 - retrieving revision 1.2 - Merging differences between 1.1 and 1.2 into test_sha.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sre.py,v - retrieving revision 1.24 - retrieving revision 1.25 - Merging differences between 1.24 and 1.25 into test_sre.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_strop.py,v - retrieving revision 1.10 - retrieving revision 1.14 - Merging differences between 1.10 and 1.14 into test_strop.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_struct.py,v - retrieving revision 1.7 - retrieving revision 1.13 - Merging differences between 1.7 and 1.13 into test_struct.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_time.py,v - retrieving revision 1.6 - retrieving revision 1.7 - Merging differences between 1.6 and 1.7 into test_time.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_types.py,v - retrieving revision 1.20 - retrieving revision 1.21 - Merging differences between 1.20 and 1.21 into test_types.py - U mergedescr/dist/src/Lib/test/test_unicode_file.py - U mergedescr/dist/src/Lib/test/test_urllib2.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_weakref.py,v - retrieving revision 1.7 - retrieving revision 1.9 - Merging differences between 1.7 and 1.9 into test_weakref.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/test_xmllib.py,v - retrieving revision 1.4 - retrieving revision 1.5 - Merging differences between 1.4 and 1.5 into test_xmllib.py - RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_coercion,v - retrieving revision 1.3 - retrieving revision 1.4 - Merging differences between 1.3 and 1.4 into test_coercion - RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_minidom,v - retrieving revision 1.12 - retrieving revision 1.13 - Merging differences between 1.12 and 1.13 into test_minidom - RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_scope,v - retrieving revision 1.6 - retrieving revision 1.8 - Merging differences between 1.6 and 1.8 into test_scope - U mergedescr/dist/src/Lib/test/output/test_unicode_file - RCS file: /cvsroot/python/python/dist/src/Lib/xml/dom/minidom.py,v - retrieving revision 1.32 - retrieving revision 1.34 - Merging differences between 1.32 and 1.34 into minidom.py - RCS file: /cvsroot/python/python/dist/src/Lib/xml/sax/expatreader.py,v - retrieving revision 1.22 - retrieving revision 1.23 - Merging differences between 1.22 and 1.23 into expatreader.py - RCS file: /cvsroot/python/python/dist/src/Lib/xml/sax/xmlreader.py,v - retrieving revision 1.14 - retrieving revision 1.16 - Merging differences between 1.14 and 1.16 into xmlreader.py - RCS file: /cvsroot/python/python/dist/src/Modules/_codecsmodule.c,v - retrieving revision 2.6 - retrieving revision 2.8 - Merging differences between 2.6 and 2.8 into _codecsmodule.c - RCS file: /cvsroot/python/python/dist/src/Modules/_cursesmodule.c,v - retrieving revision 2.51 - retrieving revision 2.52 - Merging differences between 2.51 and 2.52 into _cursesmodule.c - RCS file: /cvsroot/python/python/dist/src/Modules/_sre.c,v - retrieving revision 2.55 - retrieving revision 2.60 - Merging differences between 2.55 and 2.60 into _sre.c - RCS file: /cvsroot/python/python/dist/src/Modules/_testcapimodule.c,v - retrieving revision 1.3 - retrieving revision 1.9 - Merging differences between 1.3 and 1.9 into _testcapimodule.c - RCS file: /cvsroot/python/python/dist/src/Modules/_tkinter.c,v - retrieving revision 1.115 - retrieving revision 1.116 - Merging differences between 1.115 and 1.116 into _tkinter.c - RCS file: /cvsroot/python/python/dist/src/Modules/_weakref.c,v - retrieving revision 1.10 - retrieving revision 1.11 - Merging differences between 1.10 and 1.11 into _weakref.c - U mergedescr/dist/src/Modules/addrinfo.h - RCS file: /cvsroot/python/python/dist/src/Modules/arraymodule.c,v - retrieving revision 2.62 - retrieving revision 2.63 - Merging differences between 2.62 and 2.63 into arraymodule.c - RCS file: /cvsroot/python/python/dist/src/Modules/binascii.c,v - retrieving revision 2.28 - retrieving revision 2.29 - Merging differences between 2.28 and 2.29 into binascii.c - RCS file: /cvsroot/python/python/dist/src/Modules/fcntlmodule.c,v - retrieving revision 2.28 - retrieving revision 2.31 - Merging differences between 2.28 and 2.31 into fcntlmodule.c - U mergedescr/dist/src/Modules/getaddrinfo.c - U mergedescr/dist/src/Modules/getnameinfo.c - RCS file: /cvsroot/python/python/dist/src/Modules/main.c,v - retrieving revision 1.52 - retrieving revision 1.53 - Merging differences between 1.52 and 1.53 into main.c - RCS file: /cvsroot/python/python/dist/src/Modules/makesetup,v - retrieving revision 1.35 - retrieving revision 1.36 - Merging differences between 1.35 and 1.36 into makesetup - RCS file: /cvsroot/python/python/dist/src/Modules/mathmodule.c,v - retrieving revision 2.58 - retrieving revision 2.59 - Merging differences between 2.58 and 2.59 into mathmodule.c - RCS file: /cvsroot/python/python/dist/src/Modules/mmapmodule.c,v - retrieving revision 2.28 - retrieving revision 2.31 - Merging differences between 2.28 and 2.31 into mmapmodule.c - RCS file: /cvsroot/python/python/dist/src/Modules/parsermodule.c,v - retrieving revision 2.60 - retrieving revision 2.61 - Merging differences between 2.60 and 2.61 into parsermodule.c - RCS file: /cvsroot/python/python/dist/src/Modules/pcremodule.c,v - retrieving revision 2.25 - retrieving revision 2.26 - Merging differences between 2.25 and 2.26 into pcremodule.c - RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v - retrieving revision 2.187 - retrieving revision 2.190 - Merging differences between 2.187 and 2.190 into posixmodule.c - RCS file: /cvsroot/python/python/dist/src/Modules/regexpr.c,v - retrieving revision 1.33 - retrieving revision 1.34 - Merging differences between 1.33 and 1.34 into regexpr.c - RCS file: /cvsroot/python/python/dist/src/Modules/selectmodule.c,v - retrieving revision 2.50 - retrieving revision 2.51 - Merging differences between 2.50 and 2.51 into selectmodule.c - RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v - retrieving revision 1.141 - retrieving revision 1.149 - Merging differences between 1.141 and 1.149 into socketmodule.c - RCS file: /cvsroot/python/python/dist/src/Modules/sre.h,v - retrieving revision 2.18 - retrieving revision 2.21 - Merging differences between 2.18 and 2.21 into sre.h - RCS file: /cvsroot/python/python/dist/src/Modules/sre_constants.h,v - retrieving revision 2.12 - retrieving revision 2.13 - Merging differences between 2.12 and 2.13 into sre_constants.h - RCS file: /cvsroot/python/python/dist/src/Modules/stropmodule.c,v - retrieving revision 2.75 - retrieving revision 2.82 - Merging differences between 2.75 and 2.82 into stropmodule.c - RCS file: /cvsroot/python/python/dist/src/Modules/structmodule.c,v - retrieving revision 2.42 - retrieving revision 2.48 - Merging differences between 2.42 and 2.48 into structmodule.c - RCS file: /cvsroot/python/python/dist/src/Modules/termios.c,v - retrieving revision 2.24 - retrieving revision 2.31 - Merging differences between 2.24 and 2.31 into termios.c - U mergedescr/dist/src/Modules/testcapi_long.h - RCS file: /cvsroot/python/python/dist/src/Modules/timemodule.c,v - retrieving revision 2.110 - retrieving revision 2.111 - Merging differences between 2.110 and 2.111 into timemodule.c - RCS file: /cvsroot/python/python/dist/src/Modules/xreadlinesmodule.c,v - retrieving revision 1.5 - retrieving revision 1.6 - Merging differences between 1.5 and 1.6 into xreadlinesmodule.c - RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v - retrieving revision 2.60 - retrieving revision 2.69 - Merging differences between 2.60 and 2.69 into abstract.c - rcsmerge: warning: conflicts during merge - RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v - retrieving revision 2.127 - retrieving revision 2.132 - Merging differences between 2.127 and 2.132 into classobject.c - rcsmerge: warning: conflicts during merge - RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v - retrieving revision 2.112 - retrieving revision 2.113 - Merging differences between 2.112 and 2.113 into fileobject.c - RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v - retrieving revision 2.81 - retrieving revision 2.82 - Merging differences between 2.81 and 2.82 into floatobject.c - RCS file: /cvsroot/python/python/dist/src/Objects/funcobject.c,v - retrieving revision 2.37 - retrieving revision 2.38 - Merging differences between 2.37 and 2.38 into funcobject.c - rcsmerge: warning: conflicts during merge - RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v - retrieving revision 2.56 - retrieving revision 2.57 - Merging differences between 2.56 and 2.57 into intobject.c - RCS file: /cvsroot/python/python/dist/src/Objects/iterobject.c,v - retrieving revision 1.3 - retrieving revision 1.4 - Merging differences between 1.3 and 1.4 into iterobject.c - RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v - retrieving revision 2.92 - retrieving revision 2.96 - Merging differences between 2.92 and 2.96 into listobject.c - RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v - retrieving revision 1.71 - retrieving revision 1.83 - Merging differences between 1.71 and 1.83 into longobject.c - rcsmerge: warning: conflicts during merge - RCS file: /cvsroot/python/python/dist/src/Objects/moduleobject.c,v - retrieving revision 2.31 - retrieving revision 2.33 - Merging differences between 2.31 and 2.33 into moduleobject.c - rcsmerge: warning: conflicts during merge - RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v - retrieving revision 2.124 - retrieving revision 2.132 - Merging differences between 2.124 and 2.132 into object.c - rcsmerge: warning: conflicts during merge - RCS file: /cvsroot/python/python/dist/src/Objects/rangeobject.c,v - retrieving revision 2.24 - retrieving revision 2.25 - Merging differences between 2.24 and 2.25 into rangeobject.c - rcsmerge: warning: conflicts during merge - RCS file: /cvsroot/python/python/dist/src/Objects/tupleobject.c,v - retrieving revision 2.48 - retrieving revision 2.53 - Merging differences between 2.48 and 2.53 into tupleobject.c - RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v - retrieving revision 2.16 - retrieving revision 2.18 - Merging differences between 2.16 and 2.18 into typeobject.c - rcsmerge: warning: conflicts during merge - RCS file: /cvsroot/python/python/dist/src/Objects/unicodectype.c,v - retrieving revision 2.7 - retrieving revision 2.11 - Merging differences between 2.7 and 2.11 into unicodectype.c - RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v - retrieving revision 2.87 - retrieving revision 2.101 - Merging differences between 2.87 and 2.101 into unicodeobject.c - rcsmerge: warning: conflicts during merge - RCS file: /cvsroot/python/python/dist/src/PC/WinMain.c,v - retrieving revision 1.6 - retrieving revision 1.7 - Merging differences between 1.6 and 1.7 into WinMain.c - RCS file: /cvsroot/python/python/dist/src/PC/config.h,v - retrieving revision 1.51 - retrieving revision 1.55 - Merging differences between 1.51 and 1.55 into config.h - RCS file: /cvsroot/python/python/dist/src/PCbuild/BUILDno.txt,v - retrieving revision 1.12 - retrieving revision 1.15 - Merging differences between 1.12 and 1.15 into BUILDno.txt - cvs server: nonmergeable file needs merge - cvs server: revision 1.16 from repository is now in mergedescr/dist/src/PCbuild/pythoncore.dsp - cvs server: file from working directory is now in .#pythoncore.dsp.1.15.2.3 - C mergedescr/dist/src/PCbuild/pythoncore.dsp - RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v - retrieving revision 2.198 - retrieving revision 2.215 - Merging differences between 2.198 and 2.215 into bltinmodule.c - rcsmerge: warning: conflicts during merge - RCS file: /cvsroot/python/python/dist/src/Python/dynload_win.c,v - retrieving revision 2.7 - retrieving revision 2.8 - Merging differences between 2.7 and 2.8 into dynload_win.c - RCS file: /cvsroot/python/python/dist/src/Python/errors.c,v - retrieving revision 2.62 - retrieving revision 2.63 - Merging differences between 2.62 and 2.63 into errors.c - RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v - retrieving revision 2.54 - retrieving revision 2.60 - Merging differences between 2.54 and 2.60 into getargs.c - rcsmerge: warning: conflicts during merge - RCS file: /cvsroot/python/python/dist/src/Python/import.c,v - retrieving revision 2.176 - retrieving revision 2.178 - Merging differences between 2.176 and 2.178 into import.c - RCS file: /cvsroot/python/python/dist/src/Python/marshal.c,v - retrieving revision 1.62 - retrieving revision 1.64 - Merging differences between 1.62 and 1.64 into marshal.c - RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v - retrieving revision 2.133 - retrieving revision 2.134 - Merging differences between 2.133 and 2.134 into pythonrun.c - RCS file: /cvsroot/python/python/dist/src/Python/sysmodule.c,v - retrieving revision 2.85 - retrieving revision 2.88 - Merging differences between 2.85 and 2.88 into sysmodule.c ------------------------------------------------------------------ 2001-07-06 --- 269,272 ---- Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/README,v retrieving revision 1.123 retrieving revision 1.123.2.1 diff -C2 -r1.123 -r1.123.2.1 *** README 2001/04/18 04:37:57 1.123 --- README 2001/07/07 22:55:27 1.123.2.1 *************** *** 387,400 **** future release. ! Mac OS X: You need to add the "-traditional-cpp" option to the ! compiler command line for the Mac OS X Public Beta. This is ! appearantly a bug in the default pre-processor, and is ! expected not to be a problem with future versions. Run ! configure with "OPT='-g -traditional-cpp' ./configure ! --with-suffix=.exe --with-dyld" to add this ! option. One of the regular expression tests fails due to the ! small stack size used by default (how to change this?), and ! the test_largefile test is only expected to work on a Unix UFS ! filesystem (how to check for this on Mac OS X?). Cygwin: Cygwin Python builds OOTB when configured as follows: --- 387,400 ---- future release. ! Mac OS X 10.0: Run configure with "OPT='-no-cpp-precomp' ./configure ! --with-suffix=.exe --with-dyld". This generates executable ! file: 'python.exe' (it cannot be named 'python' on an HFS or ! HFS+ disk as the file name clashes with directory 'Python'). ! The '-no-cpp-precomp' option prevents a large number of ! compilation warnings. One of the regular expression tests ! fails with a SEGV due to the small stack size used by default ! (how to change this?), and the test_largefile test is only ! expected to work on a Unix UFS filesystem (how to check for ! this on Mac OS X?). Cygwin: Cygwin Python builds OOTB when configured as follows: Index: acconfig.h =================================================================== RCS file: /cvsroot/python/python/dist/src/acconfig.h,v retrieving revision 1.46 retrieving revision 1.46.4.1 diff -C2 -r1.46 -r1.46.4.1 *** acconfig.h 2001/03/20 13:09:13 1.46 --- acconfig.h 2001/07/07 22:55:27 1.46.4.1 *************** *** 36,39 **** --- 36,51 ---- #undef HAVE_ALTZONE + /* Define if --enable-ipv6 is specified */ + #undef ENABLE_IPV6 + + /* Define if sockaddr has sa_len member */ + #undef HAVE_SOCKADDR_SA_LEN + + /* struct addrinfo (netdb.h) */ + #undef HAVE_ADDRINFO + + /* struct sockaddr_storage (sys/socket.h) */ + #undef HAVE_SOCKADDR_STORAGE + /* Defined when any dynamic module loading is enabled */ #undef HAVE_DYNAMIC_LOADING *************** *** 93,96 **** --- 105,117 ---- #undef HAVE_WCHAR_H + /* Define if you want to have a Unicode type. */ + #undef Py_USING_UNICODE + + /* Define as the integral type used for Unicode representation. */ + #undef PY_UNICODE_TYPE + + /* Define as the size of the unicode type. */ + #undef Py_UNICODE_SIZE + /* Define if malloc(0) returns a NULL pointer */ #undef MALLOC_ZERO_RETURNS_NULL *************** *** 182,185 **** --- 203,209 ---- (shared library plus accessory files). */ #undef WITH_NEXT_FRAMEWORK + + /* Define if you want to use MacPython modules on MacOSX in unix-Python */ + #undef USE_TOOLBOX_OBJECT_GLUE /* Define if you want to use SGI (IRIX 4) dynamic linking. Index: config.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/config.h.in,v retrieving revision 2.92 retrieving revision 2.92.2.1 diff -C2 -r2.92 -r2.92.2.1 *** config.h.in 2001/04/18 04:37:57 2.92 --- config.h.in 2001/07/07 22:55:27 2.92.2.1 *************** *** 101,104 **** --- 101,116 ---- #undef HAVE_ALTZONE + /* Define if --enable-ipv6 is specified */ + #undef ENABLE_IPV6 + + /* Define if sockaddr has sa_len member */ + #undef HAVE_SOCKADDR_SA_LEN + + /* struct addrinfo (netdb.h) */ + #undef HAVE_ADDRINFO + + /* struct sockaddr_storage (sys/socket.h) */ + #undef HAVE_SOCKADDR_STORAGE + /* Defined when any dynamic module loading is enabled */ #undef HAVE_DYNAMIC_LOADING *************** *** 152,155 **** --- 164,176 ---- #undef HAVE_WCHAR_H + /* Define if you want to have a Unicode type. */ + #undef Py_USING_UNICODE + + /* Define as the integral type used for Unicode representation. */ + #undef PY_UNICODE_TYPE + + /* Define as the size of the unicode type. */ + #undef Py_UNICODE_SIZE + /* Define if malloc(0) returns a NULL pointer */ #undef MALLOC_ZERO_RETURNS_NULL *************** *** 230,233 **** --- 251,257 ---- #undef WITH_NEXT_FRAMEWORK + /* Define if you want to use MacPython modules on MacOSX in unix-Python */ + #undef USE_TOOLBOX_OBJECT_GLUE + /* Define if you want to use SGI (IRIX 4) dynamic linking. This requires the "dl" library by Jack Jansen, *************** *** 270,273 **** --- 294,300 ---- #undef SIZEOF_VOID_P + /* The number of bytes in a wchar_t. */ + #undef SIZEOF_WCHAR_T + /* Define if you have the _getpty function. */ #undef HAVE__GETPTY *************** *** 339,342 **** --- 366,372 ---- #undef HAVE_FTRUNCATE + /* Define if you have the getaddrinfo function. */ + #undef HAVE_GETADDRINFO + /* Define if you have the getcwd function. */ #undef HAVE_GETCWD *************** *** 351,354 **** --- 381,387 ---- #undef HAVE_GETLOGIN + /* Define if you have the getnameinfo function. */ + #undef HAVE_GETNAMEINFO + /* Define if you have the getpeername function. */ #undef HAVE_GETPEERNAME *************** *** 372,375 **** --- 405,411 ---- #undef HAVE_HYPOT + /* Define if you have the inet_pton function. */ + #undef HAVE_INET_PTON + /* Define if you have the kill function. */ #undef HAVE_KILL *************** *** 590,593 **** --- 626,632 ---- /* Define if you have the header file. */ #undef HAVE_SYS_LOCK_H + + /* Define if you have the header file. */ + #undef HAVE_SYS_MODEM_H /* Define if you have the header file. */ Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.209 retrieving revision 1.209.2.1 diff -C2 -r1.209 -r1.209.2.1 *** configure 2001/04/21 17:41:16 1.209 --- configure 2001/07/07 22:55:27 1.209.2.1 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.216 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.222 [...4942 lines suppressed...] *** 6223,6227 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6226: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then --- 6877,6881 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6880: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then *************** *** 6399,6402 **** --- 7053,7057 ---- s%@DLINCLDIR@%$DLINCLDIR%g s%@DYNLOADFILE@%$DYNLOADFILE%g + s%@MACHDEP_OBJS@%$MACHDEP_OBJS%g s%@LIBOBJS@%$LIBOBJS%g s%@HAVE_GETHOSTBYNAME_R_6_ARG@%$HAVE_GETHOSTBYNAME_R_6_ARG%g Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.217 retrieving revision 1.217.2.1 diff -C2 -r1.217 -r1.217.2.1 *** configure.in 2001/04/21 17:41:16 1.217 --- configure.in 2001/07/07 22:55:27 1.217.2.1 *************** *** 369,372 **** --- 369,517 ---- fi + # Check for enable-ipv6 + OPT="$OPT -Dss_family=__ss_family -Dss_len=__ss_len" + AC_MSG_CHECKING([whether to enable ipv6]) + AC_ARG_ENABLE(ipv6, + [ --enable-ipv6 Enable ipv6 (with ipv4) support + --disable-ipv6 Disable ipv6 support], + [ case "$enableval" in + no) + AC_MSG_RESULT(no) + ipv6=no + ;; + *) AC_MSG_RESULT(yes) + AC_DEFINE(ENABLE_IPV6) + ipv6=yes + ;; + esac ], + + AC_TRY_RUN([ /* AF_INET6 avalable check */ + #include + #include + main() + { + if (socket(AF_INET6, SOCK_STREAM, 0) < 0) + exit(1); + else + exit(0); + } + ], + AC_MSG_RESULT(yes) + AC_DEFINE(ENABLE_IPV6) + ipv6=yes, + AC_MSG_RESULT(no) + ipv6=no, + AC_MSG_RESULT(no) + ipv6=no + )) + + ipv6type=unknown + ipv6lib=none + ipv6trylibc=no + + if test "$ipv6" = "yes"; then + AC_MSG_CHECKING([ipv6 stack type]) + for i in inria kame linux-glibc linux-inet6 toshiba v6d zeta; do + case $i in + inria) + dnl http://www.kame.net/ + AC_EGREP_CPP(yes, [dnl + #include + #ifdef IPV6_INRIA_VERSION + yes + #endif], + [ipv6type=$i; + OPT="-DINET6 $OPT"]) + ;; + kame) + dnl http://www.kame.net/ + AC_EGREP_CPP(yes, [dnl + #include + #ifdef __KAME__ + yes + #endif], + [ipv6type=$i; + ipv6lib=inet6 + ipv6libdir=/usr/local/v6/lib + ipv6trylibc=yes + OPT="-DINET6 $OPT"]) + ;; + linux-glibc) + dnl http://www.v6.linux.or.jp/ + AC_EGREP_CPP(yes, [dnl + #include + #if defined(__GLIBC__) && ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2)) + yes + #endif], + [ipv6type=$i; + ipv6trylibc=yes + OPT="-DINET6 $OPT"]) + ;; + linux-inet6) + dnl http://www.v6.linux.or.jp/ + if test -d /usr/inet6; then + ipv6type=$i + ipv6lib=inet6 + ipv6libdir=/usr/inet6/lib + OPT="-DINET6 -I/usr/inet6/include $OPT" + fi + ;; + toshiba) + AC_EGREP_CPP(yes, [dnl + #include + #ifdef _TOSHIBA_INET6 + yes + #endif], + [ipv6type=$i; + ipv6lib=inet6; + ipv6libdir=/usr/local/v6/lib; + OPT="-DINET6 $OPT"]) + ;; + v6d) + AC_EGREP_CPP(yes, [dnl + #include + #ifdef __V6D__ + yes + #endif], + [ipv6type=$i; + ipv6lib=v6; + ipv6libdir=/usr/local/v6/lib; + OPT="-I/usr/local/v6/include $OPT"]) + ;; + zeta) + AC_EGREP_CPP(yes, [dnl + #include + #ifdef _ZETA_MINAMI_INET6 + yes + #endif], + [ipv6type=$i; + ipv6lib=inet6; + ipv6libdir=/usr/local/v6/lib; + OPT="-DINET6 $OPT"]) + ;; + esac + if test "$ipv6type" != "unknown"; then + break + fi + done + AC_MSG_RESULT($ipv6type) + fi + + if test "$ipv6" = "yes" -a "$ipv6lib" != "none"; then + if test -d $ipv6libdir -a -f $ipv6libdir/lib$ipv6lib.a; then + LIBS="-L$ipv6libdir -l$ipv6lib $LIBS" + echo "using lib$ipv6lib" + else + if test $ipv6trylibc = "yes"; then + echo "using libc" + else + echo 'Fatal: no $ipv6lib library found. cannot continue.' + echo "You need to fetch lib$ipv6lib.a from appropriate" + echo 'ipv6 kit and compile beforehand.' + exit 1 + fi + fi + fi + dnl # check for ANSI or K&R ("traditional") preprocessor dnl AC_MSG_CHECKING(for C preprocessor type) *************** *** 382,386 **** AC_CHECK_HEADERS(dlfcn.h fcntl.h limits.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 db_185.h db.h \ sys/param.h sys/select.h sys/socket.h sys/time.h sys/times.h \ sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ --- 527,531 ---- AC_CHECK_HEADERS(dlfcn.h fcntl.h limits.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/modem.h db_185.h db.h \ sys/param.h sys/select.h sys/socket.h sys/time.h sys/times.h \ sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ *************** *** 678,682 **** # loading of any modules which reference it in System.framework next/4*|next/5*) LINKFORSHARED="-u __dummy -framework System" ;; ! Darwin/*) LINKFORSHARED="-u __dummy -framework System -framework Foundation" ;; UnixWare*) LINKFORSHARED="-dy -Bdynamic -Wl,-Bexport";; SCO_SV*) LINKFORSHARED="-Bdynamic -dy -Wl,-Bexport";; --- 823,827 ---- # loading of any modules which reference it in System.framework next/4*|next/5*) LINKFORSHARED="-u __dummy -framework System" ;; ! Darwin/*) LINKFORSHARED="-u __dummy -u _PyMac_Error -framework System -framework Foundation -framework Carbon" ;; UnixWare*) LINKFORSHARED="-dy -Bdynamic -Wl,-Bexport";; SCO_SV*) LINKFORSHARED="-Bdynamic -dy -Wl,-Bexport";; *************** *** 998,1006 **** fi # checks for library functions AC_CHECK_FUNCS(alarm chown clock confstr ctermid ctermid_r execv \ flock fork fsync fdatasync fpathconf ftime ftruncate \ getgroups getlogin getpeername getpid getpwent getwd \ ! kill link lstat mkfifo mktime mremap \ nice pathconf pause plock poll pthread_init \ putenv readlink \ --- 1143,1167 ---- fi + # MACHDEP_OBJS can be set to platform-specific object files needed by Python + + AC_SUBST(MACHDEP_OBJS) + AC_MSG_CHECKING(MACHDEP_OBJS) + if test -z "$MACHDEP_OBJS" + then + case $ac_sys_system/$ac_sys_release in + Darwin/*) + MACHDEP_OBJS="Mac/Python/macglue.o" + AC_DEFINE(USE_TOOLBOX_OBJECT_GLUE) + ;; + *) MACHDEP_OBJS="";; + esac + fi + AC_MSG_RESULT($DYNLOADFILE) + # checks for library functions AC_CHECK_FUNCS(alarm chown clock confstr ctermid ctermid_r execv \ flock fork fsync fdatasync fpathconf ftime ftruncate \ getgroups getlogin getpeername getpid getpwent getwd \ ! inet_pton kill link lstat mkfifo mktime mremap \ nice pathconf pause plock poll pthread_init \ putenv readlink \ *************** *** 1024,1027 **** --- 1185,1292 ---- AC_CHECK_FUNCS(gettimeofday, AC_TRY_COMPILE([#include ], [gettimeofday((struct timeval*)0,(struct timezone*)0);], ,AC_DEFINE(GETTIMEOFDAY_NO_TZ))) + AC_CHECK_FUNCS(getaddrinfo, [dnl + AC_MSG_CHECKING(getaddrinfo bug) + AC_TRY_RUN([ + #include + #include + #include + #include + #include + + main() + { + int passive, gaierr, inet4 = 0, inet6 = 0; + struct addrinfo hints, *ai, *aitop; + char straddr[INET6_ADDRSTRLEN], strport[16]; + + for (passive = 0; passive <= 1; passive++) { + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_flags = passive ? AI_PASSIVE : 0; + hints.ai_socktype = SOCK_STREAM; + if ((gaierr = getaddrinfo(NULL, "54321", &hints, &aitop)) != 0) { + (void)gai_strerror(gaierr); + goto bad; + } + for (ai = aitop; ai; ai = ai->ai_next) { + if (ai->ai_addr == NULL || + ai->ai_addrlen == 0 || + getnameinfo(ai->ai_addr, ai->ai_addrlen, + straddr, sizeof(straddr), strport, sizeof(strport), + NI_NUMERICHOST|NI_NUMERICSERV) != 0) { + goto bad; + } + switch (ai->ai_family) { + case AF_INET: + if (strcmp(strport, "54321") != 0) { + goto bad; + } + if (passive) { + if (strcmp(straddr, "0.0.0.0") != 0) { + goto bad; + } + } else { + if (strcmp(straddr, "127.0.0.1") != 0) { + goto bad; + } + } + inet4++; + break; + case AF_INET6: + if (strcmp(strport, "54321") != 0) { + goto bad; + } + if (passive) { + if (strcmp(straddr, "::") != 0) { + goto bad; + } + } else { + if (strcmp(straddr, "::1") != 0) { + goto bad; + } + } + inet6++; + break; + case AF_UNSPEC: + goto bad; + break; + default: + /* another family support? */ + break; + } + } + } + + if (!(inet4 == 0 || inet4 == 2)) + goto bad; + if (!(inet6 == 0 || inet6 == 2)) + goto bad; + + if (aitop) + freeaddrinfo(aitop); + exit(0); + + bad: + if (aitop) + freeaddrinfo(aitop); + exit(1); + } + ], + AC_MSG_RESULT(good) + buggygetaddrinfo=no, + AC_MSG_RESULT(buggy) + buggygetaddrinfo=yes, + AC_MSG_RESULT(buggy) + buggygetaddrinfo=yes)], [buggygetaddrinfo=yes]) + + if test "$buggygetaddrinfo" = "yes"; then + if test "$ipv6" = "yes"; then + echo 'Fatal: You must get working getaddrinfo() function.' + echo ' or you can specify "--disable-ipv6"'. + exit 1 + fi + fi + AC_CHECK_FUNCS(getaddrinfo getnameinfo) + # checks for structures AC_HEADER_TIME *************** *** 1048,1051 **** --- 1313,1341 ---- AC_MSG_RESULT($was_it_defined) + AC_MSG_CHECKING(for addrinfo) + AC_CACHE_VAL(ac_cv_struct_addrinfo, + AC_TRY_COMPILE([ + # include ], + [struct addrinfo a], + ac_cv_struct_addrinfo=yes, + ac_cv_struct_addrinfo=no)) + AC_MSG_RESULT($ac_cv_struct_addrinfo) + if test $ac_cv_struct_addrinfo = yes; then + AC_DEFINE(HAVE_ADDRINFO) + fi + + AC_MSG_CHECKING(for sockaddr_storage) + AC_CACHE_VAL(ac_cv_struct_sockaddr_storage, + AC_TRY_COMPILE([ + # include + # include ], + [struct sockaddr_storage s], + ac_cv_struct_sockaddr_storage=yes, + ac_cv_struct_sockaddr_storage=no)) + AC_MSG_RESULT($ac_cv_struct_sockaddr_storage) + if test $ac_cv_struct_sockaddr_storage = yes; then + AC_DEFINE(HAVE_SOCKADDR_STORAGE) + fi + # checks for compiler characteristics *************** *** 1093,1096 **** --- 1383,1396 ---- fi + # check if sockaddr has sa_len member + AC_MSG_CHECKING(if sockaddr has sa_len member) + AC_TRY_COMPILE([#include + #include ], + [struct sockaddr x; + x.sa_len = 0;], + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SOCKADDR_SA_LEN), + AC_MSG_RESULT(no)) + bad_forward=no AC_MSG_CHECKING(for bad static forward) *************** *** 1279,1299 **** ) ! # check for usable wchar_t ! usable_wchar_t="unkown" ! AC_MSG_CHECKING(for usable wchar_t) ! AC_TRY_RUN([ ! #include "wchar.h" ! #include "wctype.h" ! main() { ! wchar_t s; ! if (sizeof(s) == 2) ! exit(0); ! else ! exit(1); ! } ! ], ! AC_DEFINE(HAVE_USABLE_WCHAR_T) usable_wchar_t="yes", ! usable_wchar_t="no") ! AC_MSG_RESULT($usable_wchar_t) # check for endianness --- 1579,1630 ---- ) ! # determine wchar_t size ! if test "$wchar_h" = yes ! then ! AC_CHECK_SIZEOF(wchar_t) ! fi ! ! AC_MSG_CHECKING(what type to use for unicode) ! AC_ARG_ENABLE(unicode, ! [ --enable-unicode[=ucs2,ucs4] Enable Unicode strings (default is yes)],,enable_unicode=yes) ! ! if test $enable_unicode = yes ! then ! # Without any arguments, Py_UNICODE defaults to two-byte mode ! enable_unicode="ucs2" ! fi ! ! case "$enable_unicode" in ! ucs2) unicode_size="2" ! AC_DEFINE(Py_UNICODE_SIZE,2) ! ;; ! ucs4) unicode_size="4" ! AC_DEFINE(Py_UNICODE_SIZE,4) ! ;; ! esac ! ! if test "$enable_unicode" = "no" ! then ! AC_MSG_RESULT(not used) ! else ! AC_DEFINE(Py_USING_UNICODE) ! if test "$unicode_size" = "$ac_cv_sizeof_wchar_t" ! then ! PY_UNICODE_TYPE="wchar_t" ! AC_DEFINE(HAVE_USABLE_WCHAR_T) ! AC_DEFINE(PY_UNICODE_TYPE,wchar_t) ! elif test "$ac_cv_sizeof_short" = "$unicode_size" ! then ! PY_UNICODE_TYPE="unsigned short" ! AC_DEFINE(PY_UNICODE_TYPE,unsigned short) ! elif test "$ac_cv_sizeof_long" = "$unicode_size" ! then ! PY_UNICODE_TYPE="unsigned long" ! AC_DEFINE(PY_UNICODE_TYPE,unsigned long) ! else ! PY_UNICODE_TYPE="no type found" ! fi ! AC_MSG_RESULT($PY_UNICODE_TYPE) ! fi # check for endianness Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.38 retrieving revision 1.38.4.1 diff -C2 -r1.38 -r1.38.4.1 *** setup.py 2001/04/15 15:16:12 1.38 --- setup.py 2001/07/07 22:55:27 1.38.4.1 *************** *** 1,7 **** # Autodetecting setup.py script for building the Python extensions # - # To be fixed: - # Implement --disable-modules setting - # __version__ = "$Revision$" --- 1,4 ---- *************** *** 13,16 **** --- 10,14 ---- from distutils.core import Extension, setup from distutils.command.build_ext import build_ext + from distutils.command.install import install # This global variable is used to hold the list of modules to be disabled. *************** *** 133,136 **** --- 131,145 ---- self.announce('WARNING: building of extension "%s" failed: %s' % (ext.name, sys.exc_info()[1])) + return + try: + __import__(ext.name) + except ImportError: + self.announce('WARNING: removing "%s" since importing it failed' % + ext.name) + assert not self.inplace + fullname = self.get_ext_fullname(ext.name) + ext_filename = os.path.join(self.build_lib, + self.get_ext_filename(fullname)) + os.remove(ext_filename) def get_platform (self): *************** *** 388,394 **** exts.append( Extension('resource', ['resource.c']) ) - # Generic dynamic loading module - #exts.append( Extension('dl', ['dlmodule.c']) ) - # Sun yellow pages. Some systems have the functions in libc. if platform not in ['cygwin']: --- 397,400 ---- *************** *** 599,606 **** # -lGL -lGLU -lXext -lXmu \ def main(): setup(name = 'Python standard library', version = '%d.%d' % sys.version_info[:2], ! cmdclass = {'build_ext':PyBuildExt}, # The struct module is defined here, because build_ext won't be # called unless there's at least one extension module defined. --- 605,623 ---- # -lGL -lGLU -lXext -lXmu \ + class PyBuildInstall(install): + # Suppress the warning about installation into the lib_dynload + # directory, which is not in sys.path when running Python during + # installation: + def initialize_options (self): + install.initialize_options(self) + self.warn_dir=0 + def main(): + # turn off warnings when deprecated modules are imported + import warnings + warnings.filterwarnings("ignore",category=DeprecationWarning) setup(name = 'Python standard library', version = '%d.%d' % sys.version_info[:2], ! cmdclass = {'build_ext':PyBuildExt, 'install':PyBuildInstall}, # The struct module is defined here, because build_ext won't be # called unless there's at least one extension module defined. From tim_one@users.sourceforge.net Sat Jul 7 23:56:00 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 15:56:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/distutils mwerkscompiler.py,1.1,1.1.6.1 sysconfig.py,1.34,1.34.6.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils In directory usw-pr-cvs1:/tmp/cvs-serv24450/mergedescr/dist/src/Lib/distutils Modified Files: Tag: descr-branch mwerkscompiler.py sysconfig.py Log Message: Merge of trunk tag date2001-07-06 into descr-branch. Index: mwerkscompiler.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/mwerkscompiler.py,v retrieving revision 1.1 retrieving revision 1.1.6.1 diff -C2 -r1.1 -r1.1.6.1 *** mwerkscompiler.py 2001/01/15 16:09:35 1.1 --- mwerkscompiler.py 2001/07/07 22:55:28 1.1.6.1 *************** *** 63,70 **** --- 63,73 ---- extra_preargs=None, extra_postargs=None): + (output_dir, macros, include_dirs) = \ + self._fix_compile_args (output_dir, macros, include_dirs) self.__sources = sources self.__macros = macros self.__include_dirs = include_dirs # Don't need extra_preargs and extra_postargs for CW + return [] def link (self, *************** *** 81,84 **** --- 84,92 ---- extra_postargs=None, build_temp=None): + # First fixup. + (objects, output_dir) = self._fix_object_args (objects, output_dir) + (libraries, library_dirs, runtime_library_dirs) = \ + self._fix_lib_args (libraries, library_dirs, runtime_library_dirs) + # First examine a couple of options for things that aren't implemented yet if not target_desc in (self.SHARED_LIBRARY, self.SHARED_OBJECT): *************** *** 115,118 **** --- 123,128 ---- if output_filename[-8:] == '.ppc.slb': basename = output_filename[:-8] + elif output_filename[-11:] == '.carbon.slb': + basename = output_filename[:-11] else: basename = os.path.strip(output_filename)[0] *************** *** 163,167 **** fp.write('#define %s\n'%name) else: ! fp.write('#define %s "%s"\n'%(name, value)) fp.close() settings['prefixname'] = prefixname --- 173,177 ---- fp.write('#define %s\n'%name) else: ! fp.write('#define %s %s\n'%(name, value)) fp.close() settings['prefixname'] = prefixname *************** *** 199,203 **** curdir = os.getcwd() filename = os.path.join(curdir, filename) ! return filename --- 209,218 ---- curdir = os.getcwd() filename = os.path.join(curdir, filename) ! # Finally remove .. components ! components = string.split(filename, ':') ! for i in range(1, len(components)): ! if components[i] == '..': ! components[i] = '' ! return string.join(components, ':') Index: sysconfig.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/sysconfig.py,v retrieving revision 1.34 retrieving revision 1.34.6.1 diff -C2 -r1.34 -r1.34.6.1 *** sysconfig.py 2001/02/28 19:40:27 1.34 --- sysconfig.py 2001/07/07 22:55:28 1.34.6.1 *************** *** 340,344 **** g['INCLUDEPY'] = get_python_inc(plat_specific=0) ! g['SO'] = '.ppc.slb' # XXX are these used anywhere? --- 340,348 ---- g['INCLUDEPY'] = get_python_inc(plat_specific=0) ! import MacOS ! if not hasattr(MacOS, 'runtimemodel'): ! g['SO'] = '.ppc.slb' ! else: ! g['SO'] = '.%s.slb' % MacOS.runtimemodel # XXX are these used anywhere? From tim_one@users.sourceforge.net Sat Jul 7 23:56:00 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 15:56:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/lib-old lockfile.py,1.1,1.1.12.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/lib-old In directory usw-pr-cvs1:/tmp/cvs-serv24450/mergedescr/dist/src/Lib/lib-old Modified Files: Tag: descr-branch lockfile.py Log Message: Merge of trunk tag date2001-07-06 into descr-branch. Index: lockfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/lib-old/lockfile.py,v retrieving revision 1.1 retrieving revision 1.1.12.1 diff -C2 -r1.1 -r1.1.12.1 *** lockfile.py 1994/05/03 14:46:18 1.1 --- lockfile.py 2001/07/07 22:55:28 1.1.12.1 *************** *** 1,15 **** ! import struct, fcntl, FCNTL def writelock(f): ! _lock(f, FCNTL.F_WRLCK) def readlock(f): ! _lock(f, FCNTL.F_RDLCK) def unlock(f): ! _lock(f, FCNTL.F_UNLCK) def _lock(f, op): ! dummy = fcntl.fcntl(f.fileno(), FCNTL.F_SETLKW, struct.pack('2h8l', op, 0, 0, 0, 0, 0, 0, 0, 0, 0)) --- 1,15 ---- ! import struct, fcntl def writelock(f): ! _lock(f, fcntl.F_WRLCK) def readlock(f): ! _lock(f, fcntl.F_RDLCK) def unlock(f): ! _lock(f, fcntl.F_UNLCK) def _lock(f, op): ! dummy = fcntl.fcntl(f.fileno(), fcntl.F_SETLKW, struct.pack('2h8l', op, 0, 0, 0, 0, 0, 0, 0, 0, 0)) From tim_one@users.sourceforge.net Sat Jul 7 23:56:00 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 15:56:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/distutils/command bdist_rpm.py,1.23,1.23.8.1 bdist_wininst.py,1.21,1.21.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils/command In directory usw-pr-cvs1:/tmp/cvs-serv24450/mergedescr/dist/src/Lib/distutils/command Modified Files: Tag: descr-branch bdist_rpm.py bdist_wininst.py Log Message: Merge of trunk tag date2001-07-06 into descr-branch. Index: bdist_rpm.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/command/bdist_rpm.py,v retrieving revision 1.23 retrieving revision 1.23.8.1 diff -C2 -r1.23 -r1.23.8.1 *** bdist_rpm.py 2000/09/30 18:27:54 1.23 --- bdist_rpm.py 2001/07/07 22:55:28 1.23.8.1 *************** *** 190,194 **** for readme in ('README', 'README.txt'): if os.path.exists(readme) and readme not in self.doc_files: ! self.doc.append(readme) self.ensure_string('release', "1") --- 190,194 ---- for readme in ('README', 'README.txt'): if os.path.exists(readme) and readme not in self.doc_files: ! self.doc_files.append(readme) self.ensure_string('release', "1") Index: bdist_wininst.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/command/bdist_wininst.py,v retrieving revision 1.21 retrieving revision 1.21.4.1 diff -C2 -r1.21 -r1.21.4.1 *** bdist_wininst.py 2001/04/10 18:57:07 1.21 --- bdist_wininst.py 2001/07/07 22:55:28 1.21.4.1 *************** *** 217,221 **** import base64 return base64.decodestring(EXEDATA) - # class bdist_wininst --- 217,220 ---- From tim_one@users.sourceforge.net Sat Jul 7 23:56:01 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 15:56:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib Cookie.py,1.8,1.8.4.1 UserDict.py,1.12,1.12.2.1 UserList.py,1.16,1.16.6.1 UserString.py,1.9,1.9.6.1 anydbm.py,1.10,1.10.6.1 asyncore.py,1.11,1.11.2.1 base64.py,1.11,1.11.6.1 bdb.py,1.31,1.31.4.1 calendar.py,1.21,1.21.6.1 cgi.py,1.63,1.63.4.1 chunk.py,1.10,1.10.4.1 code.py,1.15,1.15.6.1 dbhash.py,1.5,1.5.6.1 dis.py,1.34,1.34.2.1 doctest.py,1.10,1.10.4.1 dumbdbm.py,1.10,1.10.6.1 fnmatch.py,1.11,1.11.4.1 formatter.py,1.17,1.17.6.1 glob.py,1.9,1.9.6.1 htmllib.py,1.17,1.17.6.1 httplib.py,1.34,1.34.4.1 imaplib.py,1.27,1.27.6.1 keyword.py,1.10,1.10.6.1 linecache.py,1.7,1.7.6.1 mailbox.py,1.30,1.30.4.1 mailcap.py,1.9,1.9.6.1 mhlib.py,1.26,1.26.6.1 mimetypes.py,1.13,1.13.6.1 mimify.py,1.20,1.20.4.1 ntpath.py,1.34,1.34.6.1 pipes.py,1.8,1.8.6.1 posixfile.py,1.20,1.20.4.1 pprint.py,1.12,1.12.6.1 pre.py,1.9,1.9.6.1 profile.py,1.27,1.27.4.1 pstats.py,1.15,1.15.4.1 pty.py,1.7,1.7.6.1 pydoc.py,1.38,1.38.4.1 quopri.py,1.11,1.11.4.1 rexec.py,1.28,1.28.6.1 rfc822.py,1.54,1.54.6.1 sgmllib.py,1.30,1.30.4.1 site.py,1.26,1.26.4.1 sre_compile.py,1.37,1.37.4.1 sre_constants.py,1.28,1.28.4.1 tabnanny.py,1.13,1.13.4.1 tokenize.py,1.22,1.22.4.1 traceback.py,1.25,1.25.4.1 types.py,1.14.10.5,1.14.10.6 unittest.py,1.7,1.7.4.1 urllib.py,1.126,1.126.4.1 urllib2.py,1.13,1.13.4.1 weakref.py,1.9,1.9.2.1 zipfile.py,1.13,1.13.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv24450/mergedescr/dist/src/Lib Modified Files: Tag: descr-branch Cookie.py UserDict.py UserList.py UserString.py anydbm.py asyncore.py base64.py bdb.py calendar.py cgi.py chunk.py code.py dbhash.py dis.py doctest.py dumbdbm.py fnmatch.py formatter.py glob.py htmllib.py httplib.py imaplib.py keyword.py linecache.py mailbox.py mailcap.py mhlib.py mimetypes.py mimify.py ntpath.py pipes.py posixfile.py pprint.py pre.py profile.py pstats.py pty.py pydoc.py quopri.py rexec.py rfc822.py sgmllib.py site.py sre_compile.py sre_constants.py tabnanny.py tokenize.py traceback.py types.py unittest.py urllib.py urllib2.py weakref.py zipfile.py Log Message: Merge of trunk tag date2001-07-06 into descr-branch. Index: Cookie.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/Cookie.py,v retrieving revision 1.8 retrieving revision 1.8.4.1 diff -C2 -r1.8 -r1.8.4.1 *** Cookie.py 2001/04/06 19:39:11 1.8 --- Cookie.py 2001/07/07 22:55:27 1.8.4.1 *************** *** 71,76 **** >>> C["sugar"] = "wafer" >>> print C - Set-Cookie: sugar=wafer; Set-Cookie: fig=newton; Notice that the printable representation of a Cookie is the --- 71,76 ---- >>> C["sugar"] = "wafer" >>> print C Set-Cookie: fig=newton; + Set-Cookie: sugar=wafer; Notice that the printable representation of a Cookie is the *************** *** 94,99 **** >>> C.load("chips=ahoy; vienna=finger") >>> print C - Set-Cookie: vienna=finger; Set-Cookie: chips=ahoy; The load() method is darn-tootin smart about identifying cookies --- 94,99 ---- >>> C.load("chips=ahoy; vienna=finger") >>> print C Set-Cookie: chips=ahoy; + Set-Cookie: vienna=finger; The load() method is darn-tootin smart about identifying cookies *************** *** 494,498 **** if attrs is None: attrs = self._reserved_keys ! for K,V in self.items(): if V == "": continue if K not in attrs: continue --- 494,500 ---- if attrs is None: attrs = self._reserved_keys ! items = self.items() ! items.sort() ! for K,V in items: if V == "": continue if K not in attrs: continue *************** *** 587,591 **** """Return a string suitable for HTTP.""" result = [] ! for K,V in self.items(): result.append( V.output(attrs, header) ) return string.join(result, sep) --- 589,595 ---- """Return a string suitable for HTTP.""" result = [] ! items = self.items() ! items.sort() ! for K,V in items: result.append( V.output(attrs, header) ) return string.join(result, sep) *************** *** 596,600 **** def __repr__(self): L = [] ! for K,V in self.items(): L.append( '%s=%s' % (K,repr(V.value) ) ) return '<%s: %s>' % (self.__class__.__name__, string.join(L)) --- 600,606 ---- def __repr__(self): L = [] ! items = self.items() ! items.sort() ! for K,V in items: L.append( '%s=%s' % (K,repr(V.value) ) ) return '<%s: %s>' % (self.__class__.__name__, string.join(L)) *************** *** 603,607 **** """Return a string suitable for JavaScript.""" result = [] ! for K,V in self.items(): result.append( V.js_output(attrs) ) return string.join(result, "") --- 609,615 ---- """Return a string suitable for JavaScript.""" result = [] ! items = self.items() ! items.sort() ! for K,V in items: result.append( V.js_output(attrs) ) return string.join(result, "") Index: UserDict.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/UserDict.py,v retrieving revision 1.12 retrieving revision 1.12.2.1 diff -C2 -r1.12 -r1.12.2.1 *** UserDict.py 2001/04/21 09:13:15 1.12 --- UserDict.py 2001/07/07 22:55:27 1.12.2.1 *************** *** 23,26 **** --- 23,29 ---- def keys(self): return self.data.keys() def items(self): return self.data.items() + def iteritems(self): return self.data.iteritems() + def iterkeys(self): return self.data.iterkeys() + def itervalues(self): return self.data.itervalues() def values(self): return self.data.values() def has_key(self, key): return self.data.has_key(key) *************** *** 32,42 **** else: for k, v in dict.items(): ! self.data[k] = v def get(self, key, failobj=None): ! return self.data.get(key, failobj) def setdefault(self, key, failobj=None): ! if not self.data.has_key(key): ! self.data[key] = failobj ! return self.data[key] def popitem(self): return self.data.popitem() --- 35,47 ---- else: for k, v in dict.items(): ! self[k] = v def get(self, key, failobj=None): ! if not self.has_key(key): ! return failobj ! return self[key] def setdefault(self, key, failobj=None): ! if not self.has_key(key): ! self[key] = failobj ! return self[key] def popitem(self): return self.data.popitem() Index: UserList.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/UserList.py,v retrieving revision 1.16 retrieving revision 1.16.6.1 diff -C2 -r1.16 -r1.16.6.1 *** UserList.py 2001/02/18 03:30:53 1.16 --- UserList.py 2001/07/07 22:55:27 1.16.6.1 *************** *** 23,27 **** else: return other def __cmp__(self, other): ! raise RuntimeError, "UserList.__cmp__() is obsolete" def __contains__(self, item): return item in self.data def __len__(self): return len(self.data) --- 23,27 ---- else: return other def __cmp__(self, other): ! return cmp(self.data, self.__cast(other)) def __contains__(self, item): return item in self.data def __len__(self): return len(self.data) Index: UserString.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/UserString.py,v retrieving revision 1.9 retrieving revision 1.9.6.1 diff -C2 -r1.9 -r1.9.6.1 *** UserString.py 2001/01/20 19:54:20 1.9 --- UserString.py 2001/07/07 22:55:27 1.9.6.1 *************** *** 73,76 **** --- 73,84 ---- def count(self, sub, start=0, end=sys.maxint): return self.data.count(sub, start, end) + def decode(self, encoding=None, errors=None): # XXX improve this? + if encoding: + if errors: + return self.__class__(self.data.decode(encoding, errors)) + else: + return self.__class__(self.data.decode(encoding)) + else: + return self.__class__(self.data.decode()) def encode(self, encoding=None, errors=None): # XXX improve this? if encoding: Index: anydbm.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/anydbm.py,v retrieving revision 1.10 retrieving revision 1.10.6.1 diff -C2 -r1.10 -r1.10.6.1 *** anydbm.py 2001/02/18 03:30:53 1.10 --- anydbm.py 2001/07/07 22:55:27 1.10.6.1 *************** *** 46,50 **** class error(Exception): pass ! except: error = "anydbm.error" --- 46,50 ---- class error(Exception): pass ! except (NameError, TypeError): error = "anydbm.error" Index: asyncore.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/asyncore.py,v retrieving revision 1.11 retrieving revision 1.11.2.1 diff -C2 -r1.11 -r1.11.2.1 *** asyncore.py 2001/04/20 19:04:55 1.11 --- asyncore.py 2001/07/07 22:55:27 1.11.2.1 *************** *** 225,229 **** except: pass ! try: ar = repr (self.addr) --- 225,229 ---- except: pass ! try: ar = repr (self.addr) *************** *** 267,271 **** self.socket.getsockopt (socket.SOL_SOCKET, socket.SO_REUSEADDR) | 1 ) ! except: pass --- 267,271 ---- self.socket.getsockopt (socket.SOL_SOCKET, socket.SO_REUSEADDR) | 1 ) ! except socket.error: pass *************** *** 511,515 **** if os.name == 'posix': import fcntl - import FCNTL class file_wrapper: --- 511,514 ---- *************** *** 539,545 **** self.connected = 1 # set it to non-blocking mode ! flags = fcntl.fcntl (fd, FCNTL.F_GETFL, 0) ! flags = flags | FCNTL.O_NONBLOCK ! fcntl.fcntl (fd, FCNTL.F_SETFL, flags) self.set_file (fd) --- 538,544 ---- self.connected = 1 # set it to non-blocking mode ! flags = fcntl.fcntl (fd, fcntl.F_GETFL, 0) ! flags = flags | os.O_NONBLOCK ! fcntl.fcntl (fd, fcntl.F_SETFL, flags) self.set_file (fd) Index: base64.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/base64.py,v retrieving revision 1.11 retrieving revision 1.11.6.1 diff -C2 -r1.11 -r1.11.6.1 *** base64.py 2001/01/20 19:54:20 1.11 --- base64.py 2001/07/07 22:55:27 1.11.6.1 *************** *** 34,50 **** def encodestring(s): """Encode a string.""" ! import StringIO ! f = StringIO.StringIO(s) ! g = StringIO.StringIO() ! encode(f, g) ! return g.getvalue() def decodestring(s): """Decode a string.""" ! import StringIO ! f = StringIO.StringIO(s) ! g = StringIO.StringIO() ! decode(f, g) ! return g.getvalue() def test(): --- 34,46 ---- def encodestring(s): """Encode a string.""" ! pieces = [] ! for i in range(0, len(s), MAXBINSIZE): ! chunk = s[i : i + MAXBINSIZE] ! pieces.append(binascii.b2a_base64(chunk)) ! return "".join(pieces) def decodestring(s): """Decode a string.""" ! return binascii.a2b_base64(s) def test(): Index: bdb.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bdb.py,v retrieving revision 1.31 retrieving revision 1.31.4.1 diff -C2 -r1.31 -r1.31.4.1 *** bdb.py 2001/04/08 15:05:16 1.31 --- bdb.py 2001/07/07 22:55:27 1.31.4.1 *************** *** 75,78 **** --- 75,79 ---- self.user_return(frame, arg) if self.quitting: raise BdbQuit + return self.trace_dispatch def dispatch_exception(self, frame, arg): Index: calendar.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/calendar.py,v retrieving revision 1.21 retrieving revision 1.21.6.1 diff -C2 -r1.21 -r1.21.6.1 *** calendar.py 2001/01/20 19:54:20 1.21 --- calendar.py 2001/07/07 22:55:27 1.21.6.1 *************** *** 9,13 **** # Import functions and variables from time module ! from time import localtime, mktime __all__ = ["error","setfirstweekday","firstweekday","isleap", --- 9,13 ---- # Import functions and variables from time module ! from time import localtime, mktime, strftime __all__ = ["error","setfirstweekday","firstweekday","isleap", *************** *** 25,39 **** mdays = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] # Full and abbreviated names of weekdays ! day_name = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', ! 'Friday', 'Saturday', 'Sunday'] ! day_abbr = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] # Full and abbreviated names of months (1-based arrays!!!) ! month_name = ['', 'January', 'February', 'March', 'April', ! 'May', 'June', 'July', 'August', ! 'September', 'October', 'November', 'December'] ! month_abbr = [' ', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', ! 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] # Constants for weekdays --- 25,41 ---- mdays = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] + class _localized_name: + def __init__(self, format): + self.format = format + def __getitem__(self, item): + return strftime(self.format, (item,)*9).capitalize() + # Full and abbreviated names of weekdays ! day_name = _localized_name('%A') ! day_abbr = _localized_name('%a') # Full and abbreviated names of months (1-based arrays!!!) ! month_name = _localized_name('%B') ! month_abbr = _localized_name('%b') # Constants for weekdays Index: cgi.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/cgi.py,v retrieving revision 1.63 retrieving revision 1.63.4.1 diff -C2 -r1.63 -r1.63.4.1 *** cgi.py 2001/03/19 13:40:44 1.63 --- cgi.py 2001/07/07 22:55:27 1.63.4.1 *************** *** 29,33 **** # ! __version__ = "2.5" --- 29,33 ---- # ! __version__ = "2.6" *************** *** 634,638 **** def read_lines(self): """Internal: read lines until EOF or outerboundary.""" ! self.file = self.make_file('') if self.outerboundary: self.read_lines_to_outerboundary() --- 634,638 ---- def read_lines(self): """Internal: read lines until EOF or outerboundary.""" ! self.file = self.__file = StringIO() if self.outerboundary: self.read_lines_to_outerboundary() *************** *** 640,643 **** --- 640,651 ---- self.read_lines_to_eof() + def __write(self, line): + if self.__file is not None: + if self.__file.tell() + len(line) > 1000: + self.file = self.make_file('') + self.file.write(self.__file.getvalue()) + self.__file = None + self.file.write(line) + def read_lines_to_eof(self): """Internal: read lines until EOF.""" *************** *** 647,651 **** self.done = -1 break ! self.file.write(line) def read_lines_to_outerboundary(self): --- 655,659 ---- self.done = -1 break ! self.__write(line) def read_lines_to_outerboundary(self): *************** *** 675,679 **** else: delim = "" ! self.file.write(odelim + line) def skip_lines(self): --- 683,687 ---- else: delim = "" ! self.__write(odelim + line) def skip_lines(self): Index: chunk.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/chunk.py,v retrieving revision 1.10 retrieving revision 1.10.4.1 diff -C2 -r1.10 -r1.10.4.1 *** chunk.py 2001/04/15 12:40:13 1.10 --- chunk.py 2001/07/07 22:55:27 1.10.4.1 *************** *** 71,75 **** try: self.offset = self.file.tell() ! except: self.seekable = 0 else: --- 71,75 ---- try: self.offset = self.file.tell() ! except (AttributeError, IOError): self.seekable = 0 else: *************** *** 159,163 **** self.size_read = self.size_read + n return ! except: pass while self.size_read < self.chunksize: --- 159,163 ---- self.size_read = self.size_read + n return ! except IOError: pass while self.size_read < self.chunksize: Index: code.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/code.py,v retrieving revision 1.15 retrieving revision 1.15.6.1 diff -C2 -r1.15 -r1.15.6.1 *** code.py 2001/02/09 08:56:30 1.15 --- code.py 2001/07/07 22:55:27 1.15.6.1 *************** *** 138,141 **** --- 138,142 ---- # If that failed, assume SyntaxError is a string value = msg, (filename, lineno, offset, line) + sys.last_value = value list = traceback.format_exception_only(type, value) map(self.write, list) Index: dbhash.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/dbhash.py,v retrieving revision 1.5 retrieving revision 1.5.6.1 diff -C2 -r1.5 -r1.5.6.1 *** dbhash.py 2001/01/25 13:47:00 1.5 --- dbhash.py 2001/07/07 22:55:27 1.5.6.1 *************** *** 13,16 **** error = bsddb.error # Exported for anydbm ! def open(file, flag, mode=0666): return bsddb.hashopen(file, flag, mode) --- 13,16 ---- error = bsddb.error # Exported for anydbm ! def open(file, flag = 'r', mode=0666): return bsddb.hashopen(file, flag, mode) Index: dis.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/dis.py,v retrieving revision 1.34 retrieving revision 1.34.2.1 diff -C2 -r1.34 -r1.34.2.1 *** dis.py 2001/04/20 19:13:01 1.34 --- dis.py 2001/07/07 22:55:27 1.34.2.1 *************** *** 224,227 **** --- 224,228 ---- def_op('IMPORT_STAR', 84) def_op('EXEC_STMT', 85) + def_op('YIELD_STMT', 86) def_op('POP_BLOCK', 87) Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.10 retrieving revision 1.10.4.1 diff -C2 -r1.10 -r1.10.4.1 *** doctest.py 2001/03/21 23:07:59 1.10 --- doctest.py 2001/07/07 22:55:27 1.10.4.1 *************** *** 501,506 **** # the traceback isn't necessary. want = want.split('\n')[-2] + '\n' ! exc_type, exc_val, exc_tb = sys.exc_info() ! got = traceback.format_exception_only(exc_type, exc_val)[0] state = OK else: --- 501,506 ---- # the traceback isn't necessary. want = want.split('\n')[-2] + '\n' ! exc_type, exc_val = sys.exc_info()[:2] ! got = traceback.format_exception_only(exc_type, exc_val)[-1] state = OK else: *************** *** 530,538 **** return failures, len(examples) ! # Run list of examples, in context globs. Return (#failures, #tries). def _run_examples(examples, globs, verbose, name): import sys saveout = sys.stdout try: sys.stdout = fakeout = _SpoofOut() --- 530,540 ---- return failures, len(examples) ! # Run list of examples, in a shallow copy of context (dict) globs. ! # Return (#failures, #tries). def _run_examples(examples, globs, verbose, name): import sys saveout = sys.stdout + globs = globs.copy() try: sys.stdout = fakeout = _SpoofOut() *************** *** 541,544 **** --- 543,555 ---- finally: sys.stdout = saveout + # While Python gc can clean up most cycles on its own, it doesn't + # chase frame objects. This is especially irksome when running + # generator tests that raise exceptions, because a named generator- + # iterator gets an entry in globs, and the generator-iterator + # object's frame's traceback info points back to globs. This is + # easy to break just by clearing the namespace. This can also + # help to break other kinds of cycles, and even for cycles that + # gc can break itself it's better to break them ASAP. + globs.clear() return x *************** *** 546,550 **** """f, globs, verbose=0, name="NoName" -> run examples from f.__doc__. ! Use dict globs as the globals for execution. Return (#failures, #tries). --- 557,561 ---- """f, globs, verbose=0, name="NoName" -> run examples from f.__doc__. ! Use (a shallow copy of) dict globs as the globals for execution. Return (#failures, #tries). *************** *** 736,740 **** e = _extract_examples(s) if e: ! f, t = _run_examples(e, self.globs.copy(), self.verbose, name) if self.verbose: print f, "of", t, "examples failed in string", name --- 747,751 ---- e = _extract_examples(s) if e: ! f, t = _run_examples(e, self.globs, self.verbose, name) if self.verbose: print f, "of", t, "examples failed in string", name *************** *** 774,779 **** if self.verbose: print "Running", name + ".__doc__" ! f, t = run_docstring_examples(object, self.globs.copy(), ! self.verbose, name) if self.verbose: print f, "of", t, "examples failed in", name + ".__doc__" --- 785,789 ---- if self.verbose: print "Running", name + ".__doc__" ! f, t = run_docstring_examples(object, self.globs, self.verbose, name) if self.verbose: print f, "of", t, "examples failed in", name + ".__doc__" Index: dumbdbm.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/dumbdbm.py,v retrieving revision 1.10 retrieving revision 1.10.6.1 diff -C2 -r1.10 -r1.10.6.1 *** dumbdbm.py 2001/03/02 06:43:49 1.10 --- dumbdbm.py 2001/07/07 22:55:27 1.10.6.1 *************** *** 136,139 **** --- 136,146 ---- return self._index.has_key(key) + def __contains__(self, key): + return self._index.has_key(key) + + def iterkeys(self): + return self._index.iterkeys() + __iter__ = iterkeys + def __len__(self): return len(self._index) *************** *** 144,148 **** ! def open(file, flag = None, mode = None): # flag, mode arguments are currently ignored return _Database(file) --- 151,155 ---- ! def open(file, flag=None, mode=None): # flag, mode arguments are currently ignored return _Database(file) Index: fnmatch.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/fnmatch.py,v retrieving revision 1.11 retrieving revision 1.11.4.1 diff -C2 -r1.11 -r1.11.4.1 *** fnmatch.py 2001/03/21 18:05:48 1.11 --- fnmatch.py 2001/07/07 22:55:27 1.11.4.1 *************** *** 38,41 **** --- 38,61 ---- return fnmatchcase(name, pat) + def filter(names, pat): + """Return the subset of the list NAMES that match PAT""" + import os,posixpath + result=[] + pat=os.path.normcase(pat) + if not _cache.has_key(pat): + res = translate(pat) + _cache[pat] = re.compile(res) + match=_cache[pat].match + if os.path is posixpath: + # normcase on posix is NOP. Optimize it away from the loop. + for name in names: + if match(name): + result.append(name) + else: + for name in names: + if match(os.path.normcase(name)): + result.append(name) + return result + def fnmatchcase(name, pat): """Test whether FILENAME matches PATTERN, including case. Index: formatter.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/formatter.py,v retrieving revision 1.17 retrieving revision 1.17.6.1 diff -C2 -r1.17 -r1.17.6.1 *** formatter.py 2001/02/09 10:58:30 1.17 --- formatter.py 2001/07/07 22:55:27 1.17.6.1 *************** *** 114,129 **** label = '' for c in format: ! try: ! if c == '1': ! label = label + ('%d' % counter) ! elif c in 'aA': ! if counter > 0: ! label = label + self.format_letter(c, counter) ! elif c in 'iI': ! if counter > 0: ! label = label + self.format_roman(c, counter) ! else: ! label = label + c ! except: label = label + c return label --- 114,126 ---- label = '' for c in format: ! if c == '1': ! label = label + ('%d' % counter) ! elif c in 'aA': ! if counter > 0: ! label = label + self.format_letter(c, counter) ! elif c in 'iI': ! if counter > 0: ! label = label + self.format_roman(c, counter) ! else: label = label + c return label *************** *** 133,136 **** --- 130,136 ---- while counter > 0: counter, x = divmod(counter-1, 26) + # This makes a strong assumption that lowercase letters + # and uppercase letters form two contiguous blocks, with + # letters in order! s = chr(ord(case) + x) label = s + label Index: glob.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/glob.py,v retrieving revision 1.9 retrieving revision 1.9.6.1 diff -C2 -r1.9 -r1.9.6.1 *** glob.py 2001/01/20 23:34:12 1.9 --- glob.py 2001/07/07 22:55:27 1.9.6.1 *************** *** 19,23 **** return [] dirname, basename = os.path.split(pathname) ! if has_magic(dirname): list = glob(dirname) else: --- 19,25 ---- return [] dirname, basename = os.path.split(pathname) ! if not dirname: ! return glob1(os.curdir, basename) ! elif has_magic(dirname): list = glob(dirname) else: *************** *** 44,53 **** except os.error: return [] ! result = [] ! for name in names: ! if name[0] != '.' or pattern[0] == '.': ! if fnmatch.fnmatch(name, pattern): ! result.append(name) ! return result --- 46,52 ---- except os.error: return [] ! if pattern[0]!='.': ! names=filter(lambda x: x[0]!='.',names) ! return fnmatch.filter(names,pattern) Index: htmllib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/htmllib.py,v retrieving revision 1.17 retrieving revision 1.17.6.1 diff -C2 -r1.17 -r1.17.6.1 *** htmllib.py 2001/02/09 08:21:17 1.17 --- htmllib.py 2001/07/07 22:55:27 1.17.6.1 *************** *** 363,370 **** if attrname == 'width': try: width = int(value) ! except: pass if attrname == 'height': try: height = int(value) ! except: pass self.handle_image(src, alt, ismap, align, width, height) --- 363,370 ---- if attrname == 'width': try: width = int(value) ! except ValueError: pass if attrname == 'height': try: height = int(value) ! except ValueError: pass self.handle_image(src, alt, ismap, align, width, height) Index: httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/httplib.py,v retrieving revision 1.34 retrieving revision 1.34.4.1 diff -C2 -r1.34 -r1.34.4.1 *** httplib.py 2001/04/13 14:57:08 1.34 --- httplib.py 2001/07/07 22:55:27 1.34.4.1 *************** *** 75,79 **** from StringIO import StringIO ! __all__ = ["HTTP"] HTTP_PORT = 80 --- 75,84 ---- from StringIO import StringIO ! __all__ = ["HTTP", "HTTPResponse", "HTTPConnection", "HTTPSConnection", ! "HTTPException", "NotConnected", "UnknownProtocol", ! "UnknownTransferEncoding", "IllegalKeywordArgument", ! "UnimplementedFileMode", "IncompleteRead", ! "ImproperConnectionState", "CannotSendRequest", "CannotSendHeader", ! "ResponseNotReady", "BadStatusLine", "error"] HTTP_PORT = 80 Index: imaplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/imaplib.py,v retrieving revision 1.27 retrieving revision 1.27.6.1 diff -C2 -r1.27 -r1.27.6.1 *** imaplib.py 2001/02/22 13:24:27 1.27 --- imaplib.py 2001/07/07 22:55:27 1.27.6.1 *************** *** 59,62 **** --- 59,63 ---- 'UID': ('SELECTED',), 'UNSUBSCRIBE': ('AUTH', 'SELECTED'), + 'NAMESPACE': ('AUTH', 'SELECTED'), } *************** *** 572,575 **** --- 573,582 ---- return apply(self._simple_command, (name,) + args) + def namespace(self): + """ Returns IMAP namespaces ala rfc2342 + """ + name = 'NAMESPACE' + typ, dat = self._simple_command(name) + return self._untagged_response(typ, dat, name) Index: keyword.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/keyword.py,v retrieving revision 1.10 retrieving revision 1.10.6.1 diff -C2 -r1.10 -r1.10.6.1 *** keyword.py 2001/02/09 09:10:35 1.10 --- keyword.py 2001/07/07 22:55:27 1.10.6.1 *************** *** 43,46 **** --- 43,47 ---- 'try', 'while', + 'yield', #--end keywords-- ] Index: linecache.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/linecache.py,v retrieving revision 1.7 retrieving revision 1.7.6.1 diff -C2 -r1.7 -r1.7.6.1 *** linecache.py 2001/01/24 06:27:27 1.7 --- linecache.py 2001/07/07 22:55:27 1.7.6.1 *************** *** 70,82 **** stat = os.stat(fullname) except os.error, msg: ! # Try looking through the module search path basename = os.path.split(filename)[1] for dirname in sys.path: ! fullname = os.path.join(dirname, basename) try: ! stat = os.stat(fullname) ! break ! except os.error: pass else: # No luck --- 70,89 ---- stat = os.stat(fullname) except os.error, msg: ! # Try looking through the module search path. basename = os.path.split(filename)[1] for dirname in sys.path: ! # When using imputil, sys.path may contain things other than ! # strings; ignore them when it happens. try: ! fullname = os.path.join(dirname, basename) ! except (TypeError, AttributeError): ! # Not sufficiently string-like to do anything useful with. pass + else: + try: + stat = os.stat(fullname) + break + except os.error: + pass else: # No luck Index: mailbox.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/mailbox.py,v retrieving revision 1.30 retrieving revision 1.30.4.1 diff -C2 -r1.30 -r1.30.4.1 *** mailbox.py 2001/04/15 13:32:27 1.30 --- mailbox.py 2001/07/07 22:55:27 1.30.4.1 *************** *** 15,18 **** --- 15,21 ---- self.factory = factory + def __iter__(self): + return self + def next(self): while 1: *************** *** 192,195 **** --- 195,201 ---- self.factory = factory + def __iter__(self): + return self + def next(self): if not self.boxes: *************** *** 219,222 **** --- 225,231 ---- self.boxes = boxes + + def __iter__(self): + return self def next(self): Index: mailcap.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/mailcap.py,v retrieving revision 1.9 retrieving revision 1.9.6.1 diff -C2 -r1.9 -r1.9.6.1 *** mailcap.py 2001/02/09 10:23:55 1.9 --- mailcap.py 2001/07/07 22:55:27 1.9.6.1 *************** *** 21,25 **** try: fp = open(mailcap, 'r') ! except: continue morecaps = readmailcapfile(fp) --- 21,25 ---- try: fp = open(mailcap, 'r') ! except IOError: continue morecaps = readmailcapfile(fp) Index: mhlib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/mhlib.py,v retrieving revision 1.26 retrieving revision 1.26.6.1 diff -C2 -r1.26 -r1.26.6.1 *** mhlib.py 2001/02/10 00:11:08 1.26 --- mhlib.py 2001/07/07 22:55:27 1.26.6.1 *************** *** 531,535 **** toseq = tosequences[name] new = 0 ! except: toseq = [] new = 1 --- 531,535 ---- toseq = tosequences[name] new = 0 ! except KeyError: toseq = [] new = 1 Index: mimetypes.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/mimetypes.py,v retrieving revision 1.13 retrieving revision 1.13.6.1 diff -C2 -r1.13 -r1.13.6.1 *** mimetypes.py 2001/02/09 09:44:47 1.13 --- mimetypes.py 2001/07/07 22:55:28 1.13.6.1 *************** *** 198,204 **** '.png': 'image/png', '.ppm': 'image/x-portable-pixmap', '.py': 'text/x-python', '.pyc': 'application/x-python-code', ! '.ps': 'application/postscript', '.qt': 'video/quicktime', '.ras': 'image/x-cmu-raster', --- 198,205 ---- '.png': 'image/png', '.ppm': 'image/x-portable-pixmap', + '.ps': 'application/postscript', '.py': 'text/x-python', '.pyc': 'application/x-python-code', ! '.pyo': 'application/x-python-code', '.qt': 'video/quicktime', '.ras': 'image/x-cmu-raster', Index: mimify.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/mimify.py,v retrieving revision 1.20 retrieving revision 1.20.4.1 diff -C2 -r1.20 -r1.20.4.1 *** mimify.py 2001/04/10 15:42:02 1.20 --- mimify.py 2001/07/07 22:55:28 1.20.4.1 *************** *** 254,258 **** return newline + line ! mime_header = re.compile('([ \t(]|^)([-a-zA-Z0-9_+]*[\177-\377][-a-zA-Z0-9_+\177-\377]*)([ \t)]|\n)') def mime_encode_header(line): --- 254,258 ---- return newline + line ! mime_header = re.compile('([ \t(]|^)([-a-zA-Z0-9_+]*[\177-\377][-a-zA-Z0-9_+\177-\377]*)(?=[ \t)]|\n)') def mime_encode_header(line): *************** *** 264,270 **** if res is None: break ! newline = '%s%s%s=?%s?Q?%s?=%s' % \ (newline, line[pos:res.start(0)], res.group(1), ! CHARSET, mime_encode(res.group(2), 1), res.group(3)) pos = res.end(0) return newline + line[pos:] --- 264,270 ---- if res is None: break ! newline = '%s%s%s=?%s?Q?%s?=' % \ (newline, line[pos:res.start(0)], res.group(1), ! CHARSET, mime_encode(res.group(2), 1)) pos = res.end(0) return newline + line[pos:] Index: ntpath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/ntpath.py,v retrieving revision 1.34 retrieving revision 1.34.6.1 diff -C2 -r1.34 -r1.34.6.1 *** ntpath.py 2001/02/06 01:07:01 1.34 --- ntpath.py 2001/07/07 22:55:28 1.34.6.1 *************** *** 405,422 **** def abspath(path): """Return the absolute version of a path""" - try: - import win32api - except ImportError: - global abspath - def _abspath(path): - if not isabs(path): - path = join(os.getcwd(), path) - return normpath(path) - abspath = _abspath - return _abspath(path) if path: # Empty path must return current working directory. try: ! path = win32api.GetFullPathName(path) ! except win32api.error: pass # Bad path - return unchanged. else: --- 405,413 ---- def abspath(path): """Return the absolute version of a path""" if path: # Empty path must return current working directory. + from nt import _getfullpathname try: ! path = _getfullpathname(path) ! except WindowsError: pass # Bad path - return unchanged. else: Index: pipes.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pipes.py,v retrieving revision 1.8 retrieving revision 1.8.6.1 diff -C2 -r1.8 -r1.8.6.1 *** pipes.py 2001/02/07 23:14:30 1.8 --- pipes.py 2001/07/07 22:55:28 1.8.6.1 *************** *** 124,131 **** raise ValueError, \ 'Template.append: already ends with SINK' ! if kind[0] == 'f' and not re.search('\$IN\b', cmd): raise ValueError, \ 'Template.append: missing $IN in cmd' ! if kind[1] == 'f' and not re.search('\$OUT\b', cmd): raise ValueError, \ 'Template.append: missing $OUT in cmd' --- 124,131 ---- raise ValueError, \ 'Template.append: already ends with SINK' ! if kind[0] == 'f' and not re.search(r'\$IN\b', cmd): raise ValueError, \ 'Template.append: missing $IN in cmd' ! if kind[1] == 'f' and not re.search(r'\$OUT\b', cmd): raise ValueError, \ 'Template.append: missing $OUT in cmd' *************** *** 146,153 **** raise ValueError, \ 'Template.prepend: already begins with SOURCE' ! if kind[0] == 'f' and not re.search('\$IN\b', cmd): raise ValueError, \ 'Template.prepend: missing $IN in cmd' ! if kind[1] == 'f' and not re.search('\$OUT\b', cmd): raise ValueError, \ 'Template.prepend: missing $OUT in cmd' --- 146,153 ---- raise ValueError, \ 'Template.prepend: already begins with SOURCE' ! if kind[0] == 'f' and not re.search(r'\$IN\b', cmd): raise ValueError, \ 'Template.prepend: missing $IN in cmd' ! if kind[1] == 'f' and not re.search(r'\$OUT\b', cmd): raise ValueError, \ 'Template.prepend: missing $OUT in cmd' Index: posixfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/posixfile.py,v retrieving revision 1.20 retrieving revision 1.20.4.1 diff -C2 -r1.20 -r1.20.4.1 *** posixfile.py 2001/04/10 15:44:33 1.20 --- posixfile.py 2001/07/07 22:55:28 1.20.4.1 *************** *** 108,112 **** def flags(self, *which): ! import fcntl, FCNTL if which: --- 108,112 ---- def flags(self, *which): ! import fcntl if which: *************** *** 117,158 **** l_flags = 0 ! if 'n' in which: l_flags = l_flags | FCNTL.O_NDELAY ! if 'a' in which: l_flags = l_flags | FCNTL.O_APPEND ! if 's' in which: l_flags = l_flags | FCNTL.O_SYNC file = self._file_ if '=' not in which: ! cur_fl = fcntl.fcntl(file.fileno(), FCNTL.F_GETFL, 0) if '!' in which: l_flags = cur_fl & ~ l_flags else: l_flags = cur_fl | l_flags ! l_flags = fcntl.fcntl(file.fileno(), FCNTL.F_SETFL, l_flags) if 'c' in which: arg = ('!' not in which) # 0 is don't, 1 is do close on exec ! l_flags = fcntl.fcntl(file.fileno(), FCNTL.F_SETFD, arg) if '?' in which: which = '' # Return current flags ! l_flags = fcntl.fcntl(file.fileno(), FCNTL.F_GETFL, 0) ! if FCNTL.O_APPEND & l_flags: which = which + 'a' ! if fcntl.fcntl(file.fileno(), FCNTL.F_GETFD, 0) & 1: which = which + 'c' ! if FCNTL.O_NDELAY & l_flags: which = which + 'n' ! if FCNTL.O_SYNC & l_flags: which = which + 's' return which def lock(self, how, *args): ! import struct, fcntl, FCNTL ! if 'w' in how: l_type = FCNTL.F_WRLCK ! elif 'r' in how: l_type = FCNTL.F_RDLCK ! elif 'u' in how: l_type = FCNTL.F_UNLCK else: raise TypeError, 'no type of lock specified' ! if '|' in how: cmd = FCNTL.F_SETLKW ! elif '?' in how: cmd = FCNTL.F_GETLK ! else: cmd = FCNTL.F_SETLK l_whence = 0 --- 117,158 ---- l_flags = 0 ! if 'n' in which: l_flags = l_flags | os.O_NDELAY ! if 'a' in which: l_flags = l_flags | os.O_APPEND ! if 's' in which: l_flags = l_flags | os.O_SYNC file = self._file_ if '=' not in which: ! cur_fl = fcntl.fcntl(file.fileno(), fcntl.F_GETFL, 0) if '!' in which: l_flags = cur_fl & ~ l_flags else: l_flags = cur_fl | l_flags ! l_flags = fcntl.fcntl(file.fileno(), fcntl.F_SETFL, l_flags) if 'c' in which: arg = ('!' not in which) # 0 is don't, 1 is do close on exec ! l_flags = fcntl.fcntl(file.fileno(), fcntl.F_SETFD, arg) if '?' in which: which = '' # Return current flags ! l_flags = fcntl.fcntl(file.fileno(), fcntl.F_GETFL, 0) ! if os.O_APPEND & l_flags: which = which + 'a' ! if fcntl.fcntl(file.fileno(), fcntl.F_GETFD, 0) & 1: which = which + 'c' ! if os.O_NDELAY & l_flags: which = which + 'n' ! if os.O_SYNC & l_flags: which = which + 's' return which def lock(self, how, *args): ! import struct, fcntl ! if 'w' in how: l_type = fcntl.F_WRLCK ! elif 'r' in how: l_type = fcntl.F_RDLCK ! elif 'u' in how: l_type = fcntl.F_UNLCK else: raise TypeError, 'no type of lock specified' ! if '|' in how: cmd = fcntl.F_SETLKW ! elif '?' in how: cmd = fcntl.F_GETLK ! else: cmd = fcntl.F_SETLK l_whence = 0 *************** *** 204,209 **** struct.unpack('hhllhh', flock) ! if l_type != FCNTL.F_UNLCK: ! if l_type == FCNTL.F_RDLCK: return 'r', l_len, l_start, l_whence, l_pid else: --- 204,209 ---- struct.unpack('hhllhh', flock) ! if l_type != fcntl.F_UNLCK: ! if l_type == fcntl.F_RDLCK: return 'r', l_len, l_start, l_whence, l_pid else: Index: pprint.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pprint.py,v retrieving revision 1.12 retrieving revision 1.12.6.1 diff -C2 -r1.12 -r1.12.6.1 *** pprint.py 2001/02/12 02:00:42 1.12 --- pprint.py 2001/07/07 22:55:28 1.12.6.1 *************** *** 50,74 **** printer.pprint(object) - def pformat(object): """Format a Python object into a pretty-printed representation.""" return PrettyPrinter().pformat(object) def isreadable(object): """Determine if saferepr(object) is readable by eval().""" ! return PrettyPrinter().isreadable(object) ! def isrecursive(object): """Determine if object requires a recursive representation.""" ! return PrettyPrinter().isrecursive(object) ! ! ! def saferepr(object): ! """Version of repr() which can handle recursive data structures.""" ! return _safe_repr(object, {})[0] - class PrettyPrinter: def __init__(self, indent=1, width=80, depth=None, stream=None): --- 50,69 ---- printer.pprint(object) def pformat(object): """Format a Python object into a pretty-printed representation.""" return PrettyPrinter().pformat(object) + def saferepr(object): + """Version of repr() which can handle recursive data structures.""" + return _safe_repr(object, {})[0] def isreadable(object): """Determine if saferepr(object) is readable by eval().""" ! return _safe_repr(object, {})[1] def isrecursive(object): """Determine if object requires a recursive representation.""" ! return _safe_repr(object, {})[2] class PrettyPrinter: def __init__(self, indent=1, width=80, depth=None, stream=None): *************** *** 93,97 **** width = int(width) assert indent >= 0 ! assert (not depth) or depth > 0, "depth may not be negative" assert width self.__depth = depth --- 88,92 ---- width = int(width) assert indent >= 0 ! assert depth is None or depth > 0, "depth must be > 0" assert width self.__depth = depth *************** *** 183,243 **** def __repr(self, object, context, level): ! repr, readable = _safe_repr(object, context, self.__depth, level) if not readable: self.__readable = 0 return repr def _safe_repr(object, context, maxlevels=None, level=0): ! level = level + 1 typ = type(object) if not (typ in (DictType, ListType, TupleType) and object): rep = `object` ! return rep, (rep and (rep[0] != '<')) if context.has_key(id(object)): ! return `_Recursion(object)`, 0 objid = id(object) context[objid] = 1 readable = 1 ! if typ is DictType: ! if maxlevels and level >= maxlevels: ! s = "{...}" ! readable = 0 ! else: ! items = object.items() ! k, v = items[0] ! krepr, kreadable = _safe_repr(k, context, maxlevels, level) ! vrepr, vreadable = _safe_repr(v, context, maxlevels, level) readable = readable and kreadable and vreadable ! s = "{%s: %s" % (krepr, vrepr) ! for k, v in items[1:]: ! krepr, kreadable = _safe_repr(k, context, maxlevels, level) ! vrepr, vreadable = _safe_repr(v, context, maxlevels, level) ! readable = readable and kreadable and vreadable ! s = "%s, %s: %s" % (s, krepr, vrepr) ! s = s + "}" ! else: ! s, term = (typ is ListType) and ('[', ']') or ('(', ')') ! if maxlevels and level >= maxlevels: ! s = s + "..." ! readable = 0 ! else: ! subrepr, subreadable = _safe_repr( ! object[0], context, maxlevels, level) readable = readable and subreadable ! s = s + subrepr ! tail = object[1:] ! if not tail: ! if typ is TupleType: ! s = s + ',' ! for ent in tail: ! subrepr, subreadable = _safe_repr( ! ent, context, maxlevels, level) ! readable = readable and subreadable ! s = "%s, %s" % (s, subrepr) ! s = s + term ! del context[objid] ! return s, readable class _Recursion: --- 178,240 ---- def __repr(self, object, context, level): ! repr, readable, recursive = _safe_repr(object, context, ! self.__depth, level) if not readable: self.__readable = 0 + if recursive: + self.__recursive = 1 return repr + # Return triple (repr_string, isreadable, isrecursive). def _safe_repr(object, context, maxlevels=None, level=0): ! level += 1 typ = type(object) if not (typ in (DictType, ListType, TupleType) and object): rep = `object` ! return rep, (rep and (rep[0] != '<')), 0 ! if context.has_key(id(object)): ! return `_Recursion(object)`, 0, 1 objid = id(object) context[objid] = 1 + readable = 1 ! recursive = 0 ! startchar, endchar = {ListType: "[]", ! TupleType: "()", ! DictType: "{}"}[typ] ! if maxlevels and level > maxlevels: ! with_commas = "..." ! readable = 0 ! ! elif typ is DictType: ! components = [] ! for k, v in object.iteritems(): ! krepr, kreadable, krecur = _safe_repr(k, context, maxlevels, ! level) ! vrepr, vreadable, vrecur = _safe_repr(v, context, maxlevels, ! level) ! components.append("%s: %s" % (krepr, vrepr)) readable = readable and kreadable and vreadable ! recursive = recursive or krecur or vrecur ! with_commas = ", ".join(components) ! ! else: # list or tuple ! assert typ in (ListType, TupleType) ! components = [] ! for element in object: ! subrepr, subreadable, subrecur = _safe_repr( ! element, context, maxlevels, level) ! components.append(subrepr) readable = readable and subreadable ! recursive = recursive or subrecur ! if len(components) == 1 and typ is TupleType: ! components[0] += "," ! with_commas = ", ".join(components) + s = "%s%s%s" % (startchar, with_commas, endchar) + del context[objid] + return s, readable and not recursive, recursive class _Recursion: Index: pre.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pre.py,v retrieving revision 1.9 retrieving revision 1.9.6.1 diff -C2 -r1.9 -r1.9.6.1 *** pre.py 2001/03/10 09:33:14 1.9 --- pre.py 2001/07/07 22:55:28 1.9.6.1 *************** *** 365,369 **** try: repl = pcre_expand(_Dummy, repl) ! except: m = MatchObject(self, source, 0, end, []) repl = lambda m, repl=repl, expand=pcre_expand: expand(m, repl) --- 365,369 ---- try: repl = pcre_expand(_Dummy, repl) ! except error: m = MatchObject(self, source, 0, end, []) repl = lambda m, repl=repl, expand=pcre_expand: expand(m, repl) Index: profile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/profile.py,v retrieving revision 1.27 retrieving revision 1.27.4.1 diff -C2 -r1.27 -r1.27.4.1 *** profile.py 2001/03/14 20:01:19 1.27 --- profile.py 2001/07/07 22:55:28 1.27.4.1 *************** *** 90,93 **** --- 90,104 ---- + if os.name == "mac": + import MacOS + def _get_time_mac(timer=MacOS.GetTicks): + return timer() / 60.0 + + if hasattr(os, "times"): + def _get_time_times(timer=os.times): + t = timer() + return t[0] + t[1] + + class Profile: """Profiler class. *************** *** 133,142 **** self.cmd = "" - self.dispatch = { \ - 'call' : self.trace_dispatch_call, \ - 'return' : self.trace_dispatch_return, \ - 'exception': self.trace_dispatch_exception, \ - } - if not timer: if os.name == 'mac': --- 144,147 ---- *************** *** 144,156 **** self.timer = MacOS.GetTicks self.dispatcher = self.trace_dispatch_mac ! self.get_time = self.get_time_mac elif hasattr(time, 'clock'): ! self.timer = time.clock self.dispatcher = self.trace_dispatch_i elif hasattr(os, 'times'): self.timer = os.times self.dispatcher = self.trace_dispatch else: ! self.timer = time.time self.dispatcher = self.trace_dispatch_i else: --- 149,162 ---- self.timer = MacOS.GetTicks self.dispatcher = self.trace_dispatch_mac ! self.get_time = _get_time_mac elif hasattr(time, 'clock'): ! self.timer = self.get_time = time.clock self.dispatcher = self.trace_dispatch_i elif hasattr(os, 'times'): self.timer = os.times self.dispatcher = self.trace_dispatch + self.get_time = _get_time_times else: ! self.timer = self.get_time = time.time self.dispatcher = self.trace_dispatch_i else: *************** *** 158,192 **** t = self.timer() # test out timer function try: ! if len(t) == 2: self.dispatcher = self.trace_dispatch else: self.dispatcher = self.trace_dispatch_l ! except TypeError: ! self.dispatcher = self.trace_dispatch_i self.t = self.get_time() self.simulate_call('profiler') - - def get_time(self): # slow simulation of method to acquire time - t = self.timer() - if type(t) == type(()) or type(t) == type([]): - t = reduce(lambda x,y: x+y, t, 0) - return t - - def get_time_mac(self): - return self.timer()/60.0 - # Heavily optimized dispatch routine for os.times() timer def trace_dispatch(self, frame, event, arg): ! t = self.timer() t = t[0] + t[1] - self.t # No Calibration constant # t = t[0] + t[1] - self.t - .00053 # Calibration constant ! if self.dispatch[event](frame,t): ! t = self.timer() self.t = t[0] + t[1] else: ! r = self.timer() self.t = r[0] + r[1] - t # put back unrecorded delta return --- 164,201 ---- t = self.timer() # test out timer function try: ! length = len(t) ! except TypeError: ! self.get_time = timer ! self.dispatcher = self.trace_dispatch_i ! else: ! if length == 2: self.dispatcher = self.trace_dispatch else: self.dispatcher = self.trace_dispatch_l ! # This get_time() implementation needs to be defined ! # here to capture the passed-in timer in the parameter ! # list (for performance). Note that we can't assume ! # the timer() result contains two values in all ! # cases. ! def get_time_timer(timer=timer, ! reduce=reduce, reducer=operator.add): ! return reduce(reducer, timer(), 0) ! self.get_time = get_time_timer self.t = self.get_time() self.simulate_call('profiler') # Heavily optimized dispatch routine for os.times() timer def trace_dispatch(self, frame, event, arg): ! timer = self.timer ! t = timer() t = t[0] + t[1] - self.t # No Calibration constant # t = t[0] + t[1] - self.t - .00053 # Calibration constant ! if self.dispatch[event](self, frame,t): ! t = timer() self.t = t[0] + t[1] else: ! r = timer() self.t = r[0] + r[1] - t # put back unrecorded delta return *************** *** 197,215 **** def trace_dispatch_i(self, frame, event, arg): ! t = self.timer() - self.t # - 1 # Integer calibration constant ! if self.dispatch[event](frame,t): ! self.t = self.timer() else: ! self.t = self.timer() - t # put back unrecorded delta return ! # Dispatch routine for macintosh (timer returns time in ticks of 1/60th second) def trace_dispatch_mac(self, frame, event, arg): ! t = self.timer()/60.0 - self.t # - 1 # Integer calibration constant ! if self.dispatch[event](frame,t): ! self.t = self.timer()/60.0 else: ! self.t = self.timer()/60.0 - t # put back unrecorded delta return --- 206,227 ---- def trace_dispatch_i(self, frame, event, arg): ! timer = self.timer ! t = timer() - self.t # - 1 # Integer calibration constant ! if self.dispatch[event](self, frame,t): ! self.t = timer() else: ! self.t = timer() - t # put back unrecorded delta return ! # Dispatch routine for macintosh (timer returns time in ticks of ! # 1/60th second) def trace_dispatch_mac(self, frame, event, arg): ! timer = self.timer ! t = timer()/60.0 - self.t # - 1 # Integer calibration constant ! if self.dispatch[event](self, frame,t): ! self.t = timer()/60.0 else: ! self.t = timer()/60.0 - t # put back unrecorded delta return *************** *** 218,227 **** def trace_dispatch_l(self, frame, event, arg): ! t = self.get_time() - self.t ! if self.dispatch[event](frame,t): ! self.t = self.get_time() else: ! self.t = self.get_time()-t # put back unrecorded delta return --- 230,240 ---- def trace_dispatch_l(self, frame, event, arg): ! get_time = self.get_time ! t = get_time() - self.t ! if self.dispatch[event](self, frame,t): ! self.t = get_time() else: ! self.t = get_time() - t # put back unrecorded delta return *************** *** 238,246 **** fn = (fcode.co_filename, fcode.co_firstlineno, fcode.co_name) self.cur = (t, 0, 0, fn, frame, self.cur) ! if self.timings.has_key(fn): ! cc, ns, tt, ct, callers = self.timings[fn] ! self.timings[fn] = cc, ns + 1, tt, ct, callers else: ! self.timings[fn] = 0, 0, 0, 0, {} return 1 --- 251,260 ---- fn = (fcode.co_filename, fcode.co_firstlineno, fcode.co_name) self.cur = (t, 0, 0, fn, frame, self.cur) ! timings = self.timings ! if timings.has_key(fn): ! cc, ns, tt, ct, callers = timings[fn] ! timings[fn] = cc, ns + 1, tt, ct, callers else: ! timings[fn] = 0, 0, 0, 0, {} return 1 *************** *** 258,262 **** self.cur = pt, ptt+rt, pct+sft, pfn, pframe, pcur ! cc, ns, tt, ct, callers = self.timings[rfn] if not ns: ct = ct + sft --- 272,277 ---- self.cur = pt, ptt+rt, pct+sft, pfn, pframe, pcur ! timings = self.timings ! cc, ns, tt, ct, callers = timings[rfn] if not ns: ct = ct + sft *************** *** 269,276 **** else: callers[pfn] = 1 ! self.timings[rfn] = cc, ns - 1, tt+rtt, ct, callers return 1 # The next few function play with self.cmd. By carefully preloading # our parallel stack, we can force the profiled result to include --- 284,299 ---- else: callers[pfn] = 1 ! timings[rfn] = cc, ns - 1, tt+rtt, ct, callers return 1 + + dispatch = { + "call": trace_dispatch_call, + "exception": trace_dispatch_exception, + "return": trace_dispatch_return, + } + + # The next few function play with self.cmd. By carefully preloading # our parallel stack, we can force the profiled result to include *************** *** 306,310 **** pframe = None frame = self.fake_frame(code, pframe) ! a = self.dispatch['call'](frame, 0) return --- 329,333 ---- pframe = None frame = self.fake_frame(code, pframe) ! a = self.dispatch['call'](self, frame, 0) return *************** *** 313,323 **** def simulate_cmd_complete(self): ! t = self.get_time() - self.t while self.cur[-1]: # We *can* cause assertion errors here if # dispatch_trace_return checks for a frame match! ! a = self.dispatch['return'](self.cur[-2], t) t = 0 ! self.t = self.get_time() - t --- 336,347 ---- def simulate_cmd_complete(self): ! get_time = self.get_time ! t = get_time() - self.t while self.cur[-1]: # We *can* cause assertion errors here if # dispatch_trace_return checks for a frame match! ! a = self.dispatch['return'](self, self.cur[-2], t) t = 0 ! self.t = get_time() - t *************** *** 366,374 **** # This method is more useful to profile a single function call. ! def runcall(self, func, *args): self.set_cmd(`func`) sys.setprofile(self.dispatcher) try: ! return apply(func, args) finally: sys.setprofile(None) --- 390,398 ---- # This method is more useful to profile a single function call. ! def runcall(self, func, *args, **kw): self.set_cmd(`func`) sys.setprofile(self.dispatcher) try: ! return apply(func, args, kw) finally: sys.setprofile(None) *************** *** 420,438 **** def calibrate(self, m): # Modified by Tim Peters n = m ! s = self.get_time() while n: self.simple() n = n - 1 ! f = self.get_time() my_simple = f - s #print "Simple =", my_simple, n = m ! s = self.get_time() while n: self.instrumented() n = n - 1 ! f = self.get_time() my_inst = f - s # print "Instrumented =", my_inst --- 444,463 ---- def calibrate(self, m): # Modified by Tim Peters + get_time = self.get_time n = m ! s = get_time() while n: self.simple() n = n - 1 ! f = get_time() my_simple = f - s #print "Simple =", my_simple, n = m ! s = get_time() while n: self.instrumented() n = n - 1 ! f = get_time() my_inst = f - s # print "Instrumented =", my_inst *************** *** 504,507 **** --- 529,539 ---- + dispatch = { + "call": trace_dispatch_call, + "exception": trace_dispatch_exception, + "return": trace_dispatch_return, + } + + def snapshot_stats(self): self.stats = {} *************** *** 550,553 **** --- 582,592 ---- + dispatch = { + "call": trace_dispatch_call, + "exception": trace_dispatch_exception, + "return": trace_dispatch_return, + } + + def snapshot_stats(self): self.stats = {} *************** *** 565,570 **** # When invoked as main program, invoke the profiler on a script if __name__ == '__main__': - import sys - import os if not sys.argv[1:]: print "usage: profile.py scriptfile [arg] ..." --- 604,607 ---- Index: pstats.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pstats.py,v retrieving revision 1.15 retrieving revision 1.15.4.1 diff -C2 -r1.15 -r1.15.4.1 *** pstats.py 2001/04/14 15:16:05 1.15 --- pstats.py 2001/07/07 22:55:28 1.15.4.1 *************** *** 534,538 **** try: import readline ! except: pass --- 534,538 ---- try: import readline ! except ImportError: pass *************** *** 569,572 **** --- 569,579 ---- print "No statistics object is loaded." return 0 + def generic_help(self): + print "Arguments may be:" + print "* An integer maximum number of entries to print." + print "* A decimal fractional number between 0 and 1, controlling" + print " what fraction of selected entries to print." + print "* A regular expression; only entries with function names" + print " that match it are printed." def do_add(self, line): *************** *** 574,578 **** return 0 def help_add(self): ! print "Add profile info from given file to current stastics object." def do_callees(self, line): --- 581,585 ---- return 0 def help_add(self): ! print "Add profile info from given file to current statistics object." def do_callees(self, line): *************** *** 580,583 **** --- 587,591 ---- def help_callees(self): print "Print callees statistics from the current stat object." + self.generic_help() def do_callers(self, line): *************** *** 585,588 **** --- 593,597 ---- def help_callers(self): print "Print callers statistics from the current stat object." + self.generic_help() def do_EOF(self, line): *************** *** 605,609 **** return self.prompt = line + "% " ! elif len(self.prompt > 2): line = self.prompt[-2:] else: --- 614,618 ---- return self.prompt = line + "% " ! elif len(self.prompt) > 2: line = self.prompt[-2:] else: *************** *** 620,627 **** def do_sort(self, line): ! apply(self.stats.sort_stats, line.split()) return 0 def help_sort(self): print "Sort profile data according to specified keys." def do_stats(self, line): --- 629,643 ---- def do_sort(self, line): ! abbrevs = self.stats.get_sort_arg_defs().keys() ! if line and not filter(lambda x,a=abbrevs: x not in a,line.split()): ! apply(self.stats.sort_stats, line.split()) ! else: ! print "Valid sort keys (unique prefixes are accepted):" ! for (key, value) in Stats.sort_arg_dict_default.items(): ! print "%s -- %s" % (key, value[1]) return 0 def help_sort(self): print "Sort profile data according to specified keys." + print "(Typing `sort' without arguments lists valid keys.)" def do_stats(self, line): *************** *** 629,632 **** --- 645,649 ---- def help_stats(self): print "Print statistics from the current stat object." + self.generic_help() def do_strip(self, line): Index: pty.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pty.py,v retrieving revision 1.7 retrieving revision 1.7.6.1 diff -C2 -r1.7 -r1.7.6.1 *** pty.py 2001/02/12 02:00:42 1.7 --- pty.py 2001/07/07 22:55:28 1.7.6.1 *************** *** 8,12 **** from select import select ! import os, FCNTL import tty --- 8,23 ---- from select import select ! import os ! ! # Absurd: import termios and then delete it. This is to force an attempt ! # to import pty to raise an ImportError on platforms that lack termios. ! # Without this explicit import of termios here, some other module may ! # import tty first, which in turn imports termios and dies with an ! # ImportError then. But since tty *does* exist across platforms, that ! # leaves a damaged module object for tty in sys.modules, and the import ! # of tty here then appears to work despite that the tty imported is junk. ! import termios ! del termios ! import tty *************** *** 56,60 **** else: try: ! tty_name, master_fd = sgi._getpty(FCNTL.O_RDWR, 0666, 0) except IOError, msg: raise os.error, msg --- 67,71 ---- else: try: ! tty_name, master_fd = sgi._getpty(os.O_RDWR, 0666, 0) except IOError, msg: raise os.error, msg *************** *** 64,68 **** pty_name = '/dev/pty' + x + y try: ! fd = os.open(pty_name, FCNTL.O_RDWR) except os.error: continue --- 75,79 ---- pty_name = '/dev/pty' + x + y try: ! fd = os.open(pty_name, os.O_RDWR) except os.error: continue *************** *** 76,80 **** Deprecated, use openpty() instead.""" ! return os.open(tty_name, FCNTL.O_RDWR) def fork(): --- 87,91 ---- Deprecated, use openpty() instead.""" ! return os.open(tty_name, os.O_RDWR) def fork(): *************** *** 148,151 **** try: _copy(master_fd, master_read, stdin_read) ! except: tty.tcsetattr(STDIN_FILENO, tty.TCSAFLUSH, mode) --- 159,162 ---- try: _copy(master_fd, master_read, stdin_read) ! except IOError: tty.tcsetattr(STDIN_FILENO, tty.TCSAFLUSH, mode) Index: pydoc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pydoc.py,v retrieving revision 1.38 retrieving revision 1.38.4.1 diff -C2 -r1.38 -r1.38.4.1 *** pydoc.py 2001/04/13 15:04:32 1.38 --- pydoc.py 2001/07/07 22:55:28 1.38.4.1 *************** *** 1285,1289 **** self.interact() self.output.write(''' ! You're now leaving help and returning to the Python interpreter. If you want to ask for help on a particular object directly from the interpreter, you can type "help(object)". Executing "help('string')" --- 1285,1289 ---- self.interact() self.output.write(''' ! You are now leaving help and returning to the Python interpreter. If you want to ask for help on a particular object directly from the interpreter, you can type "help(object)". Executing "help('string')" Index: quopri.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/quopri.py,v retrieving revision 1.11 retrieving revision 1.11.4.1 diff -C2 -r1.11 -r1.11.4.1 *** quopri.py 2001/03/22 22:30:21 1.11 --- quopri.py 2001/07/07 22:55:28 1.11.4.1 *************** *** 1,21 **** #! /usr/bin/env python ! """Conversions to/from quoted-printable transport encoding as per RFC-1521.""" # (Dec 1991 version). ! __all__ = ["encode","decode"] ESCAPE = '=' MAXLINESIZE = 76 HEX = '0123456789ABCDEF' def needsquoting(c, quotetabs): """Decide whether a particular character needs to be quoted. ! The 'quotetabs' flag indicates whether tabs should be quoted.""" ! if c == '\t': ! return not quotetabs ! return c == ESCAPE or not(' ' <= c <= '~') def quote(c): --- 1,27 ---- #! /usr/bin/env python ! """Conversions to/from quoted-printable transport encoding as per RFC 1521.""" # (Dec 1991 version). ! __all__ = ["encode", "decode", "encodestring", "decodestring"] ESCAPE = '=' MAXLINESIZE = 76 HEX = '0123456789ABCDEF' + EMPTYSTRING = '' + + def needsquoting(c, quotetabs): """Decide whether a particular character needs to be quoted. ! The 'quotetabs' flag indicates whether embedded tabs and spaces should be ! quoted. Note that line-ending tabs and spaces are always encoded, as per ! RFC 1521. ! """ ! if c in ' \t': ! return quotetabs ! return c == ESCAPE or not (' ' <= c <= '~') def quote(c): *************** *** 24,57 **** return ESCAPE + HEX[i/16] + HEX[i%16] def encode(input, output, quotetabs): """Read 'input', apply quoted-printable encoding, and write to 'output'. 'input' and 'output' are files with readline() and write() methods. ! The 'quotetabs' flag indicates whether tabs should be quoted. ! """ while 1: line = input.readline() if not line: break ! new = '' ! last = line[-1:] ! if last == '\n': line = line[:-1] ! else: ! last = '' ! prev = '' for c in line: if needsquoting(c, quotetabs): c = quote(c) ! if len(new) + len(c) >= MAXLINESIZE: ! output.write(new + ESCAPE + '\n') ! new = '' ! new = new + c ! prev = c ! if prev in (' ', '\t'): ! output.write(new + ESCAPE + '\n\n') ! else: ! output.write(new + '\n') def decode(input, output): """Read 'input', apply quoted-printable decoding, and write to 'output'. --- 30,93 ---- return ESCAPE + HEX[i/16] + HEX[i%16] + + def encode(input, output, quotetabs): """Read 'input', apply quoted-printable encoding, and write to 'output'. 'input' and 'output' are files with readline() and write() methods. ! The 'quotetabs' flag indicates whether embedded tabs and spaces should be ! quoted. Note that line-ending tabs and spaces are always encoded, as per ! RFC 1521. ! """ ! def write(s, output=output, lineEnd='\n'): ! # RFC 1521 requires that the line ending in a space or tab must have ! # that trailing character encoded. ! if s and s[-1:] in ' \t': ! output.write(s[:-1] + quote(s[-1]) + lineEnd) ! else: ! output.write(s + lineEnd) ! ! prevline = None while 1: line = input.readline() if not line: break ! outline = [] ! # Strip off any readline induced trailing newline ! stripped = '' ! if line[-1:] == '\n': line = line[:-1] ! stripped = '\n' ! # Calculate the un-length-limited encoded line for c in line: if needsquoting(c, quotetabs): c = quote(c) ! outline.append(c) ! # First, write out the previous line ! if prevline is not None: ! write(prevline) ! # Now see if we need any soft line breaks because of RFC-imposed ! # length limitations. Then do the thisline->prevline dance. ! thisline = EMPTYSTRING.join(outline) ! while len(thisline) > MAXLINESIZE: ! # Don't forget to include the soft line break `=' sign in the ! # length calculation! ! write(thisline[:MAXLINESIZE-1], lineEnd='=\n') ! thisline = thisline[MAXLINESIZE-1:] ! # Write out the current line ! prevline = thisline ! # Write out the last line, without a trailing newline ! if prevline is not None: ! write(prevline, lineEnd=stripped) ! ! def encodestring(s, quotetabs=0): ! from cStringIO import StringIO ! infp = StringIO(s) ! outfp = StringIO() ! encode(infp, outfp, quotetabs) ! return outfp.getvalue() + + def decode(input, output): """Read 'input', apply quoted-printable decoding, and write to 'output'. *************** *** 88,91 **** --- 124,137 ---- output.write(new) + def decodestring(s): + from cStringIO import StringIO + infp = StringIO(s) + outfp = StringIO() + decode(infp, outfp) + return outfp.getvalue() + + + + # Other helper functions def ishex(c): """Return true if the character 'c' is a hexadecimal digit.""" *************** *** 107,111 **** return bits ! def test(): import sys import getopt --- 153,159 ---- return bits ! ! ! def main(): import sys import getopt *************** *** 149,152 **** sys.exit(sts) if __name__ == '__main__': ! test() --- 197,202 ---- sys.exit(sts) + + if __name__ == '__main__': ! main() Index: rexec.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/rexec.py,v retrieving revision 1.28 retrieving revision 1.28.6.1 diff -C2 -r1.28 -r1.28.6.1 *** rexec.py 2001/02/15 22:15:13 1.28 --- rexec.py 2001/07/07 22:55:28 1.28.6.1 *************** *** 124,128 **** 'marshal', 'math', 'md5', 'operator', 'parser', 'regex', 'pcre', 'rotor', 'select', ! 'strop', 'struct', 'time') ok_posix_names = ('error', 'fstat', 'listdir', 'lstat', 'readlink', --- 124,128 ---- 'marshal', 'math', 'md5', 'operator', 'parser', 'regex', 'pcre', 'rotor', 'select', ! 'sha', '_sre', 'strop', 'struct', 'time') ok_posix_names = ('error', 'fstat', 'listdir', 'lstat', 'readlink', *************** *** 333,354 **** finally: self.restore_files() def s_exec(self, *args): ! self.s_apply(self.r_exec, args) def s_eval(self, *args): ! self.s_apply(self.r_eval, args) def s_execfile(self, *args): ! self.s_apply(self.r_execfile, args) def s_import(self, *args): ! self.s_apply(self.r_import, args) def s_reload(self, *args): ! self.s_apply(self.r_reload, args) def s_unload(self, *args): ! self.s_apply(self.r_unload, args) # Restricted open(...) --- 333,355 ---- finally: self.restore_files() + return r def s_exec(self, *args): ! return self.s_apply(self.r_exec, args) def s_eval(self, *args): ! return self.s_apply(self.r_eval, args) def s_execfile(self, *args): ! return self.s_apply(self.r_execfile, args) def s_import(self, *args): ! return self.s_apply(self.r_import, args) def s_reload(self, *args): ! return self.s_apply(self.r_reload, args) def s_unload(self, *args): ! return self.s_apply(self.r_unload, args) # Restricted open(...) Index: rfc822.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/rfc822.py,v retrieving revision 1.54 retrieving revision 1.54.6.1 diff -C2 -r1.54 -r1.54.6.1 *** rfc822.py 2001/02/15 22:15:13 1.54 --- rfc822.py 2001/07/07 22:55:28 1.54.6.1 *************** *** 75,79 **** try: fp.tell() ! except: seekable = 0 else: --- 75,79 ---- try: fp.tell() ! except (AttributeError, IOError): seekable = 0 else: *************** *** 421,424 **** --- 421,443 ---- for i in list: del self.headers[i] + + def get(self, name, default=""): + name = name.lower() + if self.dict.has_key(name): + return self.dict[name] + else: + return default + + def setdefault(self, name, default=""): + lowername = name.lower() + if self.dict.has_key(lowername): + return self.dict[lowername] + else: + text = name + ": " + default + lines = text.split("\n") + for line in lines: + self.headers.append(line + "\n") + self.dict[lowername] = default + return default def has_key(self, name): Index: sgmllib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sgmllib.py,v retrieving revision 1.30 retrieving revision 1.30.4.1 diff -C2 -r1.30 -r1.30.4.1 *** sgmllib.py 2001/04/15 13:01:41 1.30 --- sgmllib.py 2001/07/07 22:55:28 1.30.4.1 *************** *** 35,44 **** commentopen = re.compile(' sample text """, [ ("data", "\n"), ("decl", "DOCTYPE html PUBLIC 'foo'"), ("data", "\n"), ("starttag", "html", []), ("entityref", "entity"), ("charref", "32"), ("data", "\n"), ("comment", "comment1a\n-><", [ ("starttag", "a", []), ("starttag", "b", []), ("endtag", "a"), ("endtag", "b"), ]) def check_attr_syntax(self): output = [ ("starttag", "a", [("b", "v"), ("c", "v"), ("d", "v"), ("e", None)]) ] self._run_check("""""", output) self._run_check("""""", output) self._run_check("""""", output) self._run_check("""""", output) def check_attr_values(self): self._run_check("""""", [("starttag", "a", [("b", "xxx\n\txxx"), ("c", "yyy\t\nyyy"), ("d", "\txyz\n")]) ]) self._run_check("""""", [ ("starttag", "a", [("b", ""), ("c", "")]), ]) def check_attr_entity_replacement(self): self._run_check("""""", [ ("starttag", "a", [("b", "&><\"'")]), ]) def check_attr_funky_names(self): self._run_check("""""", [ ("starttag", "a", [("a.b", "v"), ("c:d", "v"), ("e-f", "v")]), ]) def check_starttag_end_boundary(self): self._run_check("""""", [("starttag", "a", [("b", "<")])]) self._run_check("""""", [("starttag", "a", [("b", ">")])]) def check_buffer_artefacts(self): output = [("starttag", "a", [("b", "<")])] self._run_check([""], output) self._run_check([""], output) self._run_check([""], output) self._run_check([""], output) self._run_check([""], output) self._run_check([""], output) output = [("starttag", "a", [("b", ">")])] self._run_check([""], output) self._run_check([""], output) self._run_check([""], output) self._run_check(["'>"], output) self._run_check([""], output) self._run_check([""], output) def check_starttag_junk_chars(self): self._parse_error("<") self._parse_error("<>") self._parse_error("") self._parse_error("") self._parse_error("") self._parse_error("") self._parse_error("<$") self._parse_error("<$>") self._parse_error("") self._parse_error("'") self._parse_error("

", [ ("starttag", "p", []), ("startendtag", "img", [("src", "foo")]), ("endtag", "p"), ]) def check_get_starttag_text(self): s = """""" self._run_check_extra(s, [ ("starttag", "foo:bar", [("one", "1"), ("two", "2")]), ("starttag_text", s)]) def check_cdata_content(self): s = """""" self._run_check(s, [ ("starttag", "script", []), ("data", " ¬-an-entity-ref; "), ("endtag", "script"), ]) s = """""" self._run_check(s, [ ("starttag", "script", []), ("data", " "), ("endtag", "script"), ]) test_support.run_unittest(HTMLParserTestCase) --- NEW FILE: test_mutants.py --- from test_support import verbose, TESTFN import random import os # From SF bug #422121: Insecurities in dict comparison. # Safety of code doing comparisons has been an historical Python weak spot. # The problem is that comparison of structures written in C *naturally* # wants to hold on to things like the size of the container, or "the # biggest" containee so far, across a traversal of the container; but # code to do containee comparisons can call back into Python and mutate # the container in arbitrary ways while the C loop is in midstream. If the # C code isn't extremely paranoid about digging things out of memory on # each trip, and artificially boosting refcounts for the duration, anything # from infinite loops to OS crashes can result (yes, I use Windows ). # # The other problem is that code designed to provoke a weakness is usually # white-box code, and so catches only the particular vulnerabilities the # author knew to protect against. For example, Python's list.sort() code # went thru many iterations as one "new" vulnerability after another was # discovered. # # So the dict comparison test here uses a black-box approach instead, # generating dicts of various sizes at random, and performing random # mutations on them at random times. This proved very effective, # triggering at least six distinct failure modes the first 20 times I # ran it. Indeed, at the start, the driver never got beyond 6 iterations # before the test died. # The dicts are global to make it easy to mutate tham from within functions. dict1 = {} dict2 = {} # The current set of keys in dict1 and dict2. These are materialized as # lists to make it easy to pick a dict key at random. dict1keys = [] dict2keys = [] # Global flag telling maybe_mutate() wether to *consider* mutating. mutate = 0 # If global mutate is true, consider mutating a dict. May or may not # mutate a dict even if mutate is true. If it does decide to mutate a # dict, it picks one of {dict1, dict2} at random, and deletes a random # entry from it; or, more rarely, adds a random element. def maybe_mutate(): global mutate if not mutate: return if random.random() < 0.5: return if random.random() < 0.5: target, keys = dict1, dict1keys else: target, keys = dict2, dict2keys if random.random() < 0.2: # Insert a new key. mutate = 0 # disable mutation until key inserted while 1: newkey = Horrid(random.randrange(100)) if newkey not in target: break target[newkey] = Horrid(random.randrange(100)) keys.append(newkey) mutate = 1 elif keys: # Delete a key at random. i = random.randrange(len(keys)) key = keys[i] del target[key] # CAUTION: don't use keys.remove(key) here. Or do . The # point is that .remove() would trigger more comparisons, and so # also more calls to this routine. We're mutating often enough # without that. del keys[i] # A horrid class that triggers random mutations of dict1 and dict2 when # instances are compared. class Horrid: def __init__(self, i): # Comparison outcomes are determined by the value of i. self.i = i # An artificial hashcode is selected at random so that we don't # have any systematic relationship between comparison outcomes # (based on self.i and other.i) and relative position within the # hash vector (based on hashcode). self.hashcode = random.randrange(1000000000) def __hash__(self): return self.hashcode def __cmp__(self, other): maybe_mutate() # The point of the test. return cmp(self.i, other.i) def __repr__(self): return "Horrid(%d)" % self.i # Fill dict d with numentries (Horrid(i), Horrid(j)) key-value pairs, # where i and j are selected at random from the candidates list. # Return d.keys() after filling. def fill_dict(d, candidates, numentries): d.clear() for i in xrange(numentries): d[Horrid(random.choice(candidates))] = \ Horrid(random.choice(candidates)) return d.keys() # Test one pair of randomly generated dicts, each with n entries. # Note that dict comparison is trivial if they don't have the same number # of entires (then the "shorter" dict is instantly considered to be the # smaller one, without even looking at the entries). def test_one(n): global mutate, dict1, dict2, dict1keys, dict2keys # Fill the dicts without mutating them. mutate = 0 dict1keys = fill_dict(dict1, range(n), n) dict2keys = fill_dict(dict2, range(n), n) # Enable mutation, then compare the dicts so long as they have the # same size. mutate = 1 if verbose: print "trying w/ lengths", len(dict1), len(dict2), while dict1 and len(dict1) == len(dict2): if verbose: print ".", c = cmp(dict1, dict2) if verbose: print # Run test_one n times. At the start (before the bugs were fixed), 20 # consecutive runs of this test each blew up on or before the sixth time # test_one was run. So n doesn't have to be large to get an interesting # test. # OTOH, calling with large n is also interesting, to ensure that the fixed # code doesn't hold on to refcounts *too* long (in which case memory would # leak). def test(n): for i in xrange(n): test_one(random.randrange(1, 100)) # See last comment block for clues about good values for n. test(100) ########################################################################## # Another segfault bug, distilled by Michael Hudson from a c.l.py post. class Child: def __init__(self, parent): self.__dict__['parent'] = parent def __getattr__(self, attr): self.parent.a = 1 self.parent.b = 1 self.parent.c = 1 self.parent.d = 1 self.parent.e = 1 self.parent.f = 1 self.parent.g = 1 self.parent.h = 1 self.parent.i = 1 return getattr(self.parent, attr) class Parent: def __init__(self): self.a = Child(self) # Hard to say what this will print! May vary from time to time. But # we're specifically trying to test the tp_print slot here, and this is # the clearest way to do it. We print the result to a temp file so that # the expected-output file doesn't need to change. f = open(TESTFN, "w") print >> f, Parent().__dict__ f.close() os.unlink(TESTFN) ########################################################################## # And another core-dumper from Michael Hudson. dict = {} # Force dict to malloc its table. for i in range(1, 10): dict[i] = i f = open(TESTFN, "w") class Machiavelli: def __repr__(self): dict.clear() # Michael sez: "doesn't crash without this. don't know why." # Tim sez: "luck of the draw; crashes with or without for me." print >> f return `"machiavelli"` def __hash__(self): return 0 dict[Machiavelli()] = Machiavelli() print >> f, str(dict) f.close() os.unlink(TESTFN) del f, dict ########################################################################## # And another core-dumper from Michael Hudson. dict = {} # let's force dict to malloc its table for i in range(1, 10): dict[i] = i class Machiavelli2: def __eq__(self, other): dict.clear() return 1 def __hash__(self): return 0 dict[Machiavelli2()] = Machiavelli2() try: dict[Machiavelli2()] except KeyError: pass del dict ########################################################################## # And another core-dumper from Michael Hudson. dict = {} # let's force dict to malloc its table for i in range(1, 10): dict[i] = i class Machiavelli3: def __init__(self, id): self.id = id def __eq__(self, other): if self.id == other.id: dict.clear() return 1 else: return 0 def __repr__(self): return "%s(%s)"%(self.__class__.__name__, self.id) def __hash__(self): return 0 dict[Machiavelli3(1)] = Machiavelli3(0) dict[Machiavelli3(2)] = Machiavelli3(0) f = open(TESTFN, "w") try: try: print >> f, dict[Machiavelli3(2)] except KeyError: pass finally: f.close() os.unlink(TESTFN) del dict --- NEW FILE: test_pprint.py --- import pprint import unittest import test_support class QueryTestCase(unittest.TestCase): def setUp(self): self.a = range(100) self.b = range(200) self.a[-12] = self.b def test_basic(self): """Verify .isrecursive() and .isreadable() w/o recursion.""" verify = self.assert_ for safe in (2, 2.0, 2j, "abc", [3], (2,2), {3: 3}, u"yaddayadda", self.a, self.b): verify(not pprint.isrecursive(safe), "expected not isrecursive for " + `safe`) verify(pprint.isreadable(safe), "expected isreadable for " + `safe`) def test_knotted(self): """Verify .isrecursive() and .isreadable() w/ recursion.""" # Tie a knot. self.b[67] = self.a # Messy dict. self.d = {} self.d[0] = self.d[1] = self.d[2] = self.d verify = self.assert_ for icky in self.a, self.b, self.d, (self.d, self.d): verify(pprint.isrecursive(icky), "expected isrecursive") verify(not pprint.isreadable(icky), "expected not isreadable") # Break the cycles. self.d.clear() del self.a[:] del self.b[:] for safe in self.a, self.b, self.d, (self.d, self.d): verify(not pprint.isrecursive(safe), "expected not isrecursive for " + `safe`) verify(pprint.isreadable(safe), "expected isreadable for " + `safe`) def test_unreadable(self): """Not recursive but not readable anyway.""" verify = self.assert_ for unreadable in type(3), pprint, pprint.isrecursive: verify(not pprint.isrecursive(unreadable), "expected not isrecursive for " + `unreadable`) verify(not pprint.isreadable(unreadable), "expected not isreadable for " + `unreadable`) def test_same_as_repr(self): "Simple objects and small containers that should be same as repr()." verify = self.assert_ for simple in (0, 0L, 0+0j, 0.0, "", u"", (), [], {}, verify, pprint, -6, -6L, -6-6j, -1.5, "x", u"x", (3,), [3], {3: 6}, (1,2), [3,4], {5: 6, 7: 8}, {"xy\tab\n": (3,), 5: [[]], (): {}}, range(10, -11, -1) ): native = repr(simple) for function in "pformat", "saferepr": f = getattr(pprint, function) got = f(simple) verify(native == got, "expected %s got %s from pprint.%s" % (native, got, function)) test_support.run_unittest(QueryTestCase) --- NEW FILE: test_quopri.py --- import test_support import unittest from cStringIO import StringIO from quopri import * ENCSAMPLE = """\ Here's a bunch of special=20 =A1=A2=A3=A4=A5=A6=A7=A8=A9 =AA=AB=AC=AD=AE=AF=B0=B1=B2=B3 =B4=B5=B6=B7=B8=B9=BA=BB=BC=BD=BE =BF=C0=C1=C2=C3=C4=C5=C6 =C7=C8=C9=CA=CB=CC=CD=CE=CF =D0=D1=D2=D3=D4=D5=D6=D7 =D8=D9=DA=DB=DC=DD=DE=DF =E0=E1=E2=E3=E4=E5=E6=E7 =E8=E9=EA=EB=EC=ED=EE=EF =F0=F1=F2=F3=F4=F5=F6=F7 =F8=F9=FA=FB=FC=FD=FE=FF characters... have fun! """ # First line ends with a space DECSAMPLE = """\ Here's a bunch of special ¡¢£¤¥¦§¨© ª«¬­®¯°±²³ ´µ¶·¸¹º»¼½¾ ¿ÀÁÂÃÄÅÆ ÇÈÉÊËÌÍÎÏ ÐÑÒÓÔÕÖ× ØÙÚÛÜÝÞß àáâãäåæç èéêëìíîï ðñòóôõö÷ øùúûüýþÿ characters... have fun! """ class QuopriTestCase(unittest.TestCase): # Each entry is a tuple of (plaintext, encoded string). These strings are # used in the "quotetabs=0" tests. STRINGS = ( # Some normal strings ('hello', 'hello'), ('''hello there world''', '''hello there world'''), ('''hello there world ''', '''hello there world '''), ('\201\202\203', '=81=82=83'), # Add some trailing MUST QUOTE strings ('hello ', 'hello=20'), ('hello\t', 'hello=09'), # Some long lines. First, a single line of 108 characters ('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxØÙÚÛÜÝÞßxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '''xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=D8=D9=DA=DB=DC=DD=DE=DFx= xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'''), # A line of exactly 76 characters, no soft line break should be needed ('yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy', 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'), # A line of 77 characters, forcing a soft line break at position 75, # and a second line of exactly 2 characters (because the soft line # break `=' sign counts against the line length limit). ('zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz', '''zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz= zz'''), # A line of 151 characters, forcing a soft line break at position 75, # with a second line of exactly 76 characters and no trailing = ('zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz', '''zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz= zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'''), # A string containing a hard line break, but which the first line is # 151 characters and the second line is exactly 76 characters. This # should leave us with three lines, the first which has a soft line # break, and which the second and third do not. ('''yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz''', '''yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy= yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'''), # Now some really complex stuff ;) (DECSAMPLE, ENCSAMPLE), ) # These are used in the "quotetabs=1" tests. ESTRINGS = ( ('hello world', 'hello=20world'), ('hello\tworld', 'hello=09world'), ) def test_encodestring(self): for p, e in self.STRINGS: self.assert_(encodestring(p) == e) def test_decodestring(self): for p, e in self.STRINGS: self.assert_(decodestring(e) == p) def test_idempotent_string(self): for p, e in self.STRINGS: self.assert_(decodestring(encodestring(e)) == e) def test_encode(self): for p, e in self.STRINGS: infp = StringIO(p) outfp = StringIO() encode(infp, outfp, quotetabs=0) self.assert_(outfp.getvalue() == e) def test_decode(self): for p, e in self.STRINGS: infp = StringIO(e) outfp = StringIO() decode(infp, outfp) self.assert_(outfp.getvalue() == p) def test_embedded_ws(self): for p, e in self.ESTRINGS: self.assert_(encodestring(p, quotetabs=1) == e) self.assert_(decodestring(e) == p) test_support.run_unittest(QuopriTestCase) --- NEW FILE: test_unicode_file.py --- # Test some Unicode file name semantics # We dont test many operations on files other than # that their names can be used with Unicode characters. import os from test_support import verify, TestSkipped, TESTFN_UNICODE try: from test_support import TESTFN_ENCODING except ImportError: raise TestSkipped("No Unicode filesystem semantics on this platform.") TESTFN_ENCODED = TESTFN_UNICODE.encode(TESTFN_ENCODING) # Check with creation as Unicode string. f = open(TESTFN_UNICODE, 'wb') if not os.path.isfile(TESTFN_UNICODE): print "File doesn't exist after creating it" if not os.path.isfile(TESTFN_ENCODED): print "File doesn't exist (encoded string) after creating it" f.close() # Test stat and chmod if os.stat(TESTFN_ENCODED) != os.stat(TESTFN_UNICODE): print "os.stat() did not agree on the 2 filenames" os.chmod(TESTFN_ENCODED, 0777) os.chmod(TESTFN_UNICODE, 0777) # Test rename os.rename(TESTFN_ENCODED, TESTFN_ENCODED + ".new") os.rename(TESTFN_UNICODE+".new", TESTFN_ENCODED) os.unlink(TESTFN_ENCODED) if os.path.isfile(TESTFN_ENCODED) or \ os.path.isfile(TESTFN_UNICODE): print "File exists after deleting it" # Check with creation as encoded string. f = open(TESTFN_ENCODED, 'wb') if not os.path.isfile(TESTFN_UNICODE) or \ not os.path.isfile(TESTFN_ENCODED): print "File doesn't exist after creating it" path, base = os.path.split(os.path.abspath(TESTFN_ENCODED)) if base not in os.listdir(path): print "Filename did not appear in os.listdir()" f.close() os.unlink(TESTFN_UNICODE) if os.path.isfile(TESTFN_ENCODED) or \ os.path.isfile(TESTFN_UNICODE): print "File exists after deleting it" # test os.open f = os.open(TESTFN_ENCODED, os.O_CREAT) if not os.path.isfile(TESTFN_UNICODE) or \ not os.path.isfile(TESTFN_ENCODED): print "File doesn't exist after creating it" os.close(f) os.unlink(TESTFN_UNICODE) # Test directories etc cwd = os.getcwd() abs_encoded = os.path.abspath(TESTFN_ENCODED) + ".dir" abs_unicode = os.path.abspath(TESTFN_UNICODE) + ".dir" os.mkdir(abs_encoded) try: os.chdir(abs_encoded) os.chdir(abs_unicode) finally: os.chdir(cwd) os.rmdir(abs_unicode) os.mkdir(abs_unicode) try: os.chdir(abs_encoded) os.chdir(abs_unicode) finally: os.chdir(cwd) os.rmdir(abs_encoded) print "All the Unicode tests appeared to work" --- NEW FILE: test_urllib2.py --- from test_support import verify import urllib2 # A couple trivial tests try: urllib2.urlopen('bogus url') except ValueError: pass else: verify(0) file_url = "file://%s" % urllib2.__file__ f = urllib2.urlopen(file_url) buf = f.read() f.close() Index: re_tests.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/re_tests.py,v retrieving revision 1.28 retrieving revision 1.28.4.1 diff -C2 -r1.28 -r1.28.4.1 *** re_tests.py 2001/03/22 15:50:10 1.28 --- re_tests.py 2001/07/07 22:55:28 1.28.4.1 *************** *** 639,642 **** --- 639,644 ---- # bug 130748: ^* should be an error (nothing to repeat) (r'^*', '', SYNTAX_ERROR), + # bug 133283: minimizing repeat bug + (r'"(?:\\"|[^"])*?"', r'"\""', SUCCEED, 'found', r'"\"'), ] Index: string_tests.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/string_tests.py,v retrieving revision 1.7 retrieving revision 1.7.6.1 diff -C2 -r1.7 -r1.7.6.1 *** string_tests.py 2001/02/09 11:43:35 1.7 --- string_tests.py 2001/07/07 22:55:28 1.7.6.1 *************** *** 2,5 **** --- 2,6 ---- import string + from test_support import verify, verbose, TestFailed transtable = '\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`xyzdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377' *************** *** 178,181 **** --- 179,188 ---- test('replace', 'one!two!three!', 'one!two!three!', 'x', '@') test('replace', 'one!two!three!', 'one!two!three!', 'x', '@', 2) + # Next three for SF bug 422088: [OSF1 alpha] string.replace(); died with + # MemoryError due to empty result (platform malloc issue when requesting + # 0 bytes). + test('replace', '123', '', '123', '') + test('replace', '123123', '', '123', '') + test('replace', '123x123', 'x', '123', '') test('startswith', 'hello', 1, 'he') *************** *** 207,208 **** --- 214,233 ---- test('endswith', 'ab', 0, 'ab', 0, 1) test('endswith', 'ab', 0, 'ab', 0, 0) + + # Encoding/decoding + codecs = [('rot13', 'uryyb jbeyq'), + ('base64', 'aGVsbG8gd29ybGQ=\n'), + ('hex', '68656c6c6f20776f726c64'), + ('uu', 'begin 666 \n+:&5L;&\\@=V]R;&0 \n \nend\n')] + for encoding, data in codecs: + test('encode', 'hello world', data, encoding) + test('decode', data, 'hello world', encoding) + # zlib is optional, so we make the test optional too... + try: + import zlib + except ImportError: + pass + else: + data = 'x\x9c\xcbH\xcd\xc9\xc9W(\xcf/\xcaI\x01\x00\x1a\x0b\x04]' + verify('hello world'.encode('zlib') == data) + verify(data.decode('zlib') == 'hello world') Index: test_b1.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_b1.py,v retrieving revision 1.34 retrieving revision 1.34.6.1 diff -C2 -r1.34 -r1.34.6.1 *** test_b1.py 2001/01/22 19:30:07 1.34 --- test_b1.py 2001/07/07 22:55:28 1.34.6.1 *************** *** 368,371 **** --- 368,378 ---- raise TestFailed, "int(%s)" % `s[1:]` + " should raise ValueError" + # SF bug 434186: 0x80000000/2 != 0x80000000>>1. + # Worked by accident in Windows release build, but failed in debug build. + # Failed in all Linux builds. + x = -1-sys.maxint + if x >> 1 != x/2: + raise TestFailed("x >> 1 != x/2 when x == -1-sys.maxint") + print 'isinstance' class C: Index: test_b2.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_b2.py,v retrieving revision 1.24 retrieving revision 1.24.6.1 diff -C2 -r1.24 -r1.24.6.1 *** test_b2.py 2001/01/19 21:57:52 1.24 --- test_b2.py 2001/07/07 22:55:28 1.24.6.1 *************** *** 255,272 **** if tuple(xrange(0,10,2)) != tuple(range(0,10,2)): raise TestFailed, 'xrange(0,10,2)' - # regression tests for SourceForge bug #121695 - def _range_test(r): - verify(r.start != r.stop, 'Test not valid for passed-in xrange object.') - if r.stop in r: - raise TestFailed, 'r.stop in ' + `r` - if r.stop-r.step not in r: - raise TestFailed, 'r.stop-r.step not in ' + `r` - if r.start not in r: - raise TestFailed, 'r.start not in ' + `r` - if r.stop+r.step in r: - raise TestFailed, 'r.stop+r.step in ' + `r` - _range_test(xrange(10)) - _range_test(xrange(9, -1, -1)) - _range_test(xrange(0, 10, 2)) print 'zip' --- 255,258 ---- *************** *** 310,314 **** try: zip(a, G()) ! except AttributeError: exc = 1 except: --- 296,300 ---- try: zip(a, G()) ! except TypeError: exc = 1 except: *************** *** 316,320 **** raise TestFailed, 'zip(a, b) - b instance w/o __getitem__' if not exc: ! raise TestFailed, 'zip(a, b) - missing expected AttributeError' --- 302,306 ---- raise TestFailed, 'zip(a, b) - b instance w/o __getitem__' if not exc: ! raise TestFailed, 'zip(a, b) - missing expected TypeError' Index: test_binhex.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_binhex.py,v retrieving revision 1.10 retrieving revision 1.10.6.1 diff -C2 -r1.10 -r1.10.6.1 *** test_binhex.py 2001/01/17 21:51:36 1.10 --- test_binhex.py 2001/07/07 22:55:28 1.10.6.1 *************** *** 3,47 **** Uses the mechanism of the python binhex module ! Roger E. Masse """ import binhex import tempfile ! from test_support import verbose, TestSkipped - def test(): ! try: ! fname1 = tempfile.mktemp() ! fname2 = tempfile.mktemp() ! f = open(fname1, 'w') ! except: ! raise TestSkipped, "Cannot test binhex without a temp file" ! ! start = 'Jack is my hero' ! f.write(start) ! f.close() ! ! binhex.binhex(fname1, fname2) ! if verbose: ! print 'binhex' ! ! binhex.hexbin(fname2, fname1) ! if verbose: ! print 'hexbin' ! ! f = open(fname1, 'r') ! finish = f.readline() ! f.close() # on Windows an open file cannot be unlinked ! ! if start != finish: ! print 'Error: binhex != hexbin' ! elif verbose: ! print 'binhex == hexbin' ! ! try: ! import os ! os.unlink(fname1) ! os.unlink(fname2) ! except: ! pass ! test() --- 3,45 ---- Uses the mechanism of the python binhex module ! Based on an original test by Roger E. Masse. """ import binhex + import os import tempfile ! import test_support ! import unittest ! class BinHexTestCase(unittest.TestCase): ! ! def setUp(self): ! self.fname1 = tempfile.mktemp() ! self.fname2 = tempfile.mktemp() ! ! def tearDown(self): ! try: os.unlink(self.fname1) ! except OSError: pass ! ! try: os.unlink(self.fname2) ! except OSError: pass ! ! DATA = 'Jack is my hero' ! ! def test_binhex(self): ! f = open(self.fname1, 'w') ! f.write(self.DATA) ! f.close() ! ! binhex.binhex(self.fname1, self.fname2) ! ! binhex.hexbin(self.fname2, self.fname1) ! ! f = open(self.fname1, 'r') ! finish = f.readline() ! f.close() ! ! self.assertEqual(self.DATA, finish) ! ! ! test_support.run_unittest(BinHexTestCase) Index: test_complex.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_complex.py,v retrieving revision 1.1 retrieving revision 1.1.4.1 diff -C2 -r1.1 -r1.1.4.1 *** test_complex.py 2001/03/18 08:21:56 1.1 --- test_complex.py 2001/07/07 22:55:28 1.1.4.1 *************** *** 6,10 **** nerrors = 0 ! def check_close_real(x, y, eps=1e-12): """Return true iff floats x and y "are close\"""" # put the one with larger magnitude second --- 6,10 ---- nerrors = 0 ! def check_close_real(x, y, eps=1e-9): """Return true iff floats x and y "are close\"""" # put the one with larger magnitude second *************** *** 18,22 **** return abs((x-y)/y) < eps ! def check_close(x, y, eps=1e-12): """Return true iff complexes x and y "are close\"""" return check_close_real(x.real, y.real, eps) and \ --- 18,22 ---- return abs((x-y)/y) < eps ! def check_close(x, y, eps=1e-9): """Return true iff complexes x and y "are close\"""" return check_close_real(x.real, y.real, eps) and \ *************** *** 31,40 **** if not check_close(q, y): nerrors += 1 ! print `z`, "/", `x`, "==", `q`, "but expected", `y` if y != 0: q = z / y if not check_close(q, x): nerrors += 1 ! print `z`, "/", `y`, "==", `q`, "but expected", `x` simple_real = [float(i) for i in range(-5, 6)] --- 31,40 ---- if not check_close(q, y): nerrors += 1 ! print "%r / %r == %r but expected %r" % (z, x, q, y) if y != 0: q = z / y if not check_close(q, x): nerrors += 1 ! print "%r / %r == %r but expected %r" % (z, y, q, x) simple_real = [float(i) for i in range(-5, 6)] Index: test_contains.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_contains.py,v retrieving revision 1.6 retrieving revision 1.6.6.1 diff -C2 -r1.6 -r1.6.6.1 *** test_contains.py 2000/10/23 17:22:07 1.6 --- test_contains.py 2001/07/07 22:55:28 1.6.6.1 *************** *** 32,36 **** 1 in a check(0, "in base_set did not raise error") ! except AttributeError: pass --- 32,36 ---- 1 in a check(0, "in base_set did not raise error") ! except TypeError: pass *************** *** 38,42 **** 1 not in a check(0, "not in base_set did not raise error") ! except AttributeError: pass --- 38,42 ---- 1 not in a check(0, "not in base_set did not raise error") ! except TypeError: pass Index: test_cookie.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_cookie.py,v retrieving revision 1.9 retrieving revision 1.9.4.1 diff -C2 -r1.9 -r1.9.4.1 *** test_cookie.py 2001/04/06 21:20:58 1.9 --- test_cookie.py 2001/07/07 22:55:28 1.9.4.1 *************** *** 21,25 **** print repr(C) print str(C) ! for k, v in dict.items(): print ' ', k, repr( C[k].value ), repr(v) verify(C[k].value == v) --- 21,27 ---- print repr(C) print str(C) ! items = dict.items() ! items.sort() ! for k, v in items: print ' ', k, repr( C[k].value ), repr(v) verify(C[k].value == v) Index: test_copy_reg.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_copy_reg.py,v retrieving revision 1.1 retrieving revision 1.1.8.1 diff -C2 -r1.1 -r1.1.8.1 *** test_copy_reg.py 2000/10/11 22:17:35 1.1 --- test_copy_reg.py 2001/07/07 22:55:28 1.1.8.1 *************** *** 1,35 **** import copy_reg class C: pass ! try: ! copy_reg.pickle(C, None, None) ! except TypeError, e: ! print "Caught expected TypeError:" ! print e ! else: ! print "Failed to catch expected TypeError when registering a class type." ! ! ! print ! try: ! copy_reg.pickle(type(1), "not a callable") ! except TypeError, e: ! print "Caught expected TypeError:" ! print e ! else: ! print "Failed to catch TypeError " \ ! "when registering a non-callable reduction function." ! ! ! print ! try: ! copy_reg.pickle(type(1), int, "not a callable") ! except TypeError, e: ! print "Caught expected TypeError:" ! print e ! else: ! print "Failed to catch TypeError " \ ! "when registering a non-callable constructor." --- 1,25 ---- import copy_reg + import test_support + import unittest + class C: pass + + class CopyRegTestCase(unittest.TestCase): + + def test_class(self): + self.assertRaises(TypeError, copy_reg.pickle, + C, None, None) + + def test_noncallable_reduce(self): + self.assertRaises(TypeError, copy_reg.pickle, + type(1), "not a callable") + + def test_noncallable_constructor(self): + self.assertRaises(TypeError, copy_reg.pickle, + type(1), int, "not a callable") + ! test_support.run_unittest(CopyRegTestCase) Index: test_difflib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_difflib.py,v retrieving revision 1.1 retrieving revision 1.1.6.1 diff -C2 -r1.1 -r1.1.6.1 *** test_difflib.py 2001/02/10 08:00:53 1.1 --- test_difflib.py 2001/07/07 22:55:28 1.1.6.1 *************** *** 1,2 **** import doctest, difflib ! doctest.testmod(difflib, verbose=1) --- 1,3 ---- + from test_support import verbose import doctest, difflib ! doctest.testmod(difflib, verbose=verbose) Index: test_doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_doctest.py,v retrieving revision 1.1 retrieving revision 1.1.6.1 diff -C2 -r1.1 -r1.1.6.1 *** test_doctest.py 2001/02/10 01:36:47 1.1 --- test_doctest.py 2001/07/07 22:55:28 1.1.6.1 *************** *** 1,2 **** import doctest ! doctest.testmod(doctest, verbose=1) --- 1,3 ---- + from test_support import verbose import doctest ! doctest.testmod(doctest, verbose=verbose) Index: test_dospath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_dospath.py,v retrieving revision 1.3 retrieving revision 1.3.6.1 diff -C2 -r1.3 -r1.3.6.1 *** test_dospath.py 2001/02/09 11:44:24 1.3 --- test_dospath.py 2001/07/07 22:55:28 1.3.6.1 *************** *** 1,47 **** import dospath ! import os - errors = 0 ! def tester(fn, wantResult): ! fn = fn.replace("\\", "\\\\") ! gotResult = eval(fn) ! if wantResult != gotResult: ! print "error!" ! print "evaluated: " + str(fn) ! print "should be: " + str(wantResult) ! print " returned: " + str(gotResult) ! print "" ! global errors ! errors = errors + 1 ! ! tester('dospath.splitdrive("c:\\foo\\bar")', ('c:', '\\foo\\bar')) ! tester('dospath.splitdrive("c:/foo/bar")', ('c:', '/foo/bar')) ! ! tester('dospath.split("c:\\foo\\bar")', ('c:\\foo', 'bar')) ! tester('dospath.split("\\\\conky\\mountpoint\\foo\\bar")', ('\\\\conky\\mountpoint\\foo', 'bar')) ! ! tester('dospath.split("c:\\")', ('c:\\', '')) ! tester('dospath.split("\\\\conky\\mountpoint\\")', ('\\\\conky\\mountpoint', '')) ! ! tester('dospath.split("c:/")', ('c:/', '')) ! tester('dospath.split("//conky/mountpoint/")', ('//conky/mountpoint', '')) ! ! tester('dospath.isabs("c:\\")', 1) ! tester('dospath.isabs("\\\\conky\\mountpoint\\")', 1) ! tester('dospath.isabs("\\foo")', 1) ! tester('dospath.isabs("\\foo\\bar")', 1) ! ! tester('dospath.abspath("C:\\")', "C:\\") ! ! tester('dospath.commonprefix(["/home/swenson/spam", "/home/swen/spam"])', ! "/home/swen") ! tester('dospath.commonprefix(["\\home\\swen\\spam", "\\home\\swen\\eggs"])', ! "\\home\\swen\\") ! tester('dospath.commonprefix(["/home/swen/spam", "/home/swen/spam"])', ! "/home/swen/spam") ! ! if errors: ! print str(errors) + " errors." ! else: ! print "No errors. Thank your lucky stars." --- 1,56 ---- import dospath ! import test_support ! import unittest ! class DOSPathTestCase(unittest.TestCase): ! ! def test_abspath(self): ! self.assert_(dospath.abspath("C:\\") == "C:\\") ! ! def test_isabs(self): ! isabs = dospath.isabs ! self.assert_(isabs("c:\\")) ! self.assert_(isabs("\\\\conky\\mountpoint\\")) ! self.assert_(isabs("\\foo")) ! self.assert_(isabs("\\foo\\bar")) ! self.failIf(isabs("foo")) ! self.failIf(isabs("foo\\")) ! self.failIf(isabs("foo\\bar")) ! self.failIf(isabs("c:foo")) ! self.failIf(isabs("c:foo\\")) ! self.failIf(isabs("c:foo\\bar")) ! ! def test_commonprefix(self): ! commonprefix = dospath.commonprefix ! self.assert_(commonprefix(["/home/swenson/spam", "/home/swen/spam"]) ! == "/home/swen") ! self.assert_(commonprefix(["\\home\\swen\\spam", "\\home\\swen\\eggs"]) ! == "\\home\\swen\\") ! self.assert_(commonprefix(["/home/swen/spam", "/home/swen/spam"]) ! == "/home/swen/spam") ! ! def test_split(self): ! split = dospath.split ! self.assertEquals(split("c:\\foo\\bar"), ! ('c:\\foo', 'bar')) ! self.assertEquals(split("\\\\conky\\mountpoint\\foo\\bar"), ! ('\\\\conky\\mountpoint\\foo', 'bar')) ! ! self.assertEquals(split("c:\\"), ('c:\\', '')) ! self.assertEquals(split("\\\\conky\\mountpoint\\"), ! ('\\\\conky\\mountpoint', '')) ! ! self.assertEquals(split("c:/"), ('c:/', '')) ! self.assertEquals(split("//conky/mountpoint/"), ! ('//conky/mountpoint', '')) ! ! def test_splitdrive(self): ! splitdrive = dospath.splitdrive ! self.assertEquals(splitdrive("c:\\foo\\bar"), ('c:', '\\foo\\bar')) ! self.assertEquals(splitdrive("c:/foo/bar"), ('c:', '/foo/bar')) ! self.assertEquals(splitdrive("foo\\bar"), ('', 'foo\\bar')) ! self.assertEquals(splitdrive("c:"), ('c:', '')) ! ! ! test_support.run_unittest(DOSPathTestCase) Index: test_extcall.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_extcall.py,v retrieving revision 1.14 retrieving revision 1.14.4.1 diff -C2 -r1.14 -r1.14.4.1 *** test_extcall.py 2001/04/11 13:53:35 1.14 --- test_extcall.py 2001/07/07 22:55:28 1.14.4.1 *************** *** 1,13 **** ! from test_support import verify, verbose, TestFailed from UserList import UserList - def sortdict(d): - keys = d.keys() - keys.sort() - lst = [] - for k in keys: - lst.append("%r: %r" % (k, d[k])) - return "{%s}" % ", ".join(lst) - def f(*a, **k): print a, sortdict(k) --- 1,5 ---- ! from test_support import verify, verbose, TestFailed, sortdict from UserList import UserList def f(*a, **k): print a, sortdict(k) *************** *** 59,66 **** try: g(*Nothing()) ! except AttributeError, attr: pass else: ! print "should raise AttributeError: __len__" class Nothing: --- 51,58 ---- try: g(*Nothing()) ! except TypeError, attr: pass else: ! print "should raise TypeError" class Nothing: *************** *** 69,76 **** try: g(*Nothing()) ! except AttributeError, attr: pass else: ! print "should raise AttributeError: __getitem__" class Nothing: --- 61,68 ---- try: g(*Nothing()) ! except TypeError, attr: pass else: ! print "should raise TypeError" class Nothing: *************** *** 229,234 **** if vararg: arglist.append('*' + vararg) if kwarg: arglist.append('**' + kwarg) ! decl = 'def %s(%s): print "ok %s", a, b, d, e, v, k' % ( ! name, ', '.join(arglist), name) exec(decl) func = eval(name) --- 221,227 ---- if vararg: arglist.append('*' + vararg) if kwarg: arglist.append('**' + kwarg) ! decl = (('def %s(%s): print "ok %s", a, b, d, e, v, ' + ! 'type(k) is type ("") and k or sortdict(k)') ! % (name, ', '.join(arglist), name)) exec(decl) func = eval(name) Index: test_fcntl.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_fcntl.py,v retrieving revision 1.17 retrieving revision 1.17.4.1 diff -C2 -r1.17 -r1.17.4.1 *** test_fcntl.py 2001/04/11 20:58:20 1.17 --- test_fcntl.py 2001/07/07 22:55:28 1.17.4.1 *************** *** 5,9 **** import struct import fcntl - import FCNTL import os, sys from test_support import verbose, TESTFN --- 5,8 ---- *************** *** 11,35 **** filename = TESTFN - # the example from the library docs - f = open(filename, 'w') - rv = fcntl.fcntl(f.fileno(), FCNTL.F_SETFL, os.O_NONBLOCK) - if verbose: - print 'Status from fnctl with O_NONBLOCK: ', rv - if sys.platform in ('netbsd1', 'Darwin1.2', 'darwin1', 'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5', 'bsdos2', 'bsdos3', 'bsdos4', 'openbsd', 'openbsd2'): ! lockdata = struct.pack('lxxxxlxxxxlhh', 0, 0, 0, FCNTL.F_WRLCK, 0) elif sys.platform in ['aix3', 'aix4', 'hp-uxB', 'unixware7']: ! lockdata = struct.pack('hhlllii', FCNTL.F_WRLCK, 0, 0, 0, 0, 0, 0) else: ! lockdata = struct.pack('hhllhh', FCNTL.F_WRLCK, 0, 0, 0, 0, 0) if verbose: print 'struct.pack: ', `lockdata` ! rv = fcntl.fcntl(f.fileno(), FCNTL.F_SETLKW, lockdata) if verbose: print 'String from fcntl with F_SETLKW: ', `rv` f.close() --- 10,45 ---- filename = TESTFN if sys.platform in ('netbsd1', 'Darwin1.2', 'darwin1', 'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5', 'bsdos2', 'bsdos3', 'bsdos4', 'openbsd', 'openbsd2'): ! lockdata = struct.pack('lxxxxlxxxxlhh', 0, 0, 0, fcntl.F_WRLCK, 0) elif sys.platform in ['aix3', 'aix4', 'hp-uxB', 'unixware7']: ! lockdata = struct.pack('hhlllii', fcntl.F_WRLCK, 0, 0, 0, 0, 0, 0) else: ! lockdata = struct.pack('hhllhh', fcntl.F_WRLCK, 0, 0, 0, 0, 0) if verbose: print 'struct.pack: ', `lockdata` + + + # the example from the library docs + f = open(filename, 'w') + rv = fcntl.fcntl(f.fileno(), fcntl.F_SETFL, os.O_NONBLOCK) + if verbose: + print 'Status from fnctl with O_NONBLOCK: ', rv ! rv = fcntl.fcntl(f.fileno(), fcntl.F_SETLKW, lockdata) if verbose: print 'String from fcntl with F_SETLKW: ', `rv` + + f.close() + os.unlink(filename) + + + # Again, but pass the file rather than numeric descriptor: + f = open(filename, 'w') + rv = fcntl.fcntl(f, fcntl.F_SETFL, os.O_NONBLOCK) + + rv = fcntl.fcntl(f, fcntl.F_SETLKW, lockdata) f.close() Index: test_fnmatch.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_fnmatch.py,v retrieving revision 1.1 retrieving revision 1.1.4.1 diff -C2 -r1.1 -r1.1.4.1 *** test_fnmatch.py 2001/03/21 18:29:24 1.1 --- test_fnmatch.py 2001/07/07 22:55:28 1.1.4.1 *************** *** 1,5 **** """Test cases for the fnmatch module.""" - import re import test_support import unittest --- 1,4 ---- Index: test_grp.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_grp.py,v retrieving revision 1.7 retrieving revision 1.7.6.1 diff -C2 -r1.7 -r1.7.6.1 *** test_grp.py 2001/01/17 21:51:35 1.7 --- test_grp.py 2001/07/07 22:55:28 1.7.6.1 *************** *** 1,25 **** ! #! /usr/bin/env python ! """Test script for the grp module ! Roger E. Masse ! """ import grp ! from test_support import verbose ! groups = grp.getgrall() ! if verbose: ! print 'Groups:' ! for group in groups: ! print group ! ! if not groups: ! if verbose: ! print "Empty Group Database -- no further tests of grp module possible" ! else: ! group = grp.getgrgid(groups[0][2]) ! if verbose: ! print 'Group Entry for GID %d: %s' % (groups[0][2], group) ! ! group = grp.getgrnam(groups[0][0]) ! if verbose: ! print 'Group Entry for group %s: %s' % (groups[0][0], group) --- 1,22 ---- ! """Test script for the grp module.""" + # XXX This really needs some work, but what are the expected invariants? + import grp ! import test_support ! import unittest ! ! ! class GroupDatabaseTestCase(unittest.TestCase): ! ! def setUp(self): ! self.groups = grp.getgrall() ! ! def test_getgrgid(self): ! entry = grp.getgrgid(self.groups[0][2]) ! ! def test_getgrnam(self): ! entry = grp.getgrnam(self.groups[0][0]) ! ! test_support.run_unittest(GroupDatabaseTestCase) Index: test_hash.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_hash.py,v retrieving revision 1.2 retrieving revision 1.2.6.1 diff -C2 -r1.2 -r1.2.6.1 *** test_hash.py 2000/10/23 17:22:07 1.2 --- test_hash.py 2001/07/07 22:55:28 1.2.6.1 *************** *** 4,23 **** import test_support ! def same_hash(*objlist): ! # hash each object given an raise TestFailed if ! # the hash values are not all the same ! hashed = map(hash, objlist) ! for h in hashed[1:]: ! if h != hashed[0]: ! raise TestFailed, "hashed values differ: %s" % `objlist` ! same_hash(1, 1L, 1.0, 1.0+0.0j) ! same_hash(int(1), long(1), float(1), complex(1)) ! same_hash(long(1.23e300), float(1.23e300)) ! same_hash(float(0.5), complex(0.5, 0.0)) --- 4,31 ---- import test_support + import unittest ! class HashEqualityTestCase(unittest.TestCase): + def same_hash(self, *objlist): + # Hash each object given and fail if + # the hash values are not all the same. + hashed = map(hash, objlist) + for h in hashed[1:]: + if h != hashed[0]: + self.fail("hashed values differ: %s" % `objlist`) + def test_numeric_literals(self): + self.same_hash(1, 1L, 1.0, 1.0+0.0j) ! def test_coerced_integers(self): ! self.same_hash(int(1), long(1), float(1), complex(1), ! int('1'), float('1.0')) ! def test_coerced_floats(self): ! self.same_hash(long(1.23e300), float(1.23e300)) ! self.same_hash(float(0.5), complex(0.5, 0.0)) ! ! test_support.run_unittest(HashEqualityTestCase) Index: test_import.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_import.py,v retrieving revision 1.3 retrieving revision 1.3.4.1 diff -C2 -r1.3 -r1.3.4.1 *** test_import.py 2001/03/21 03:58:16 1.3 --- test_import.py 2001/07/07 22:55:28 1.3.4.1 *************** *** 14,17 **** --- 14,20 ---- raise TestFailed("import of RAnDoM should have failed (case mismatch)") + # Another brief digression to test the accuracy of manifest float constants. + import double_const # don't blink -- that *was* the test + sys.path.insert(0, os.curdir) Index: test_iter.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_iter.py,v retrieving revision 1.2.2.1 retrieving revision 1.2.2.2 diff -C2 -r1.2.2.1 -r1.2.2.2 *** test_iter.py 2001/06/11 19:05:28 1.2.2.1 --- test_iter.py 2001/07/07 22:55:28 1.2.2.2 *************** *** 276,278 **** --- 276,650 ---- pass + # Test tuples()'s use of iterators. + def test_builtin_tuple(self): + self.assertEqual(tuple(SequenceClass(5)), (0, 1, 2, 3, 4)) + self.assertEqual(tuple(SequenceClass(0)), ()) + self.assertEqual(tuple([]), ()) + self.assertEqual(tuple(()), ()) + self.assertEqual(tuple("abc"), ("a", "b", "c")) + + d = {"one": 1, "two": 2, "three": 3} + self.assertEqual(tuple(d), tuple(d.keys())) + + self.assertRaises(TypeError, tuple, list) + self.assertRaises(TypeError, tuple, 42) + + f = open(TESTFN, "w") + try: + for i in range(5): + f.write("%d\n" % i) + finally: + f.close() + f = open(TESTFN, "r") + try: + self.assertEqual(tuple(f), ("0\n", "1\n", "2\n", "3\n", "4\n")) + f.seek(0, 0) + self.assertEqual(tuple(f.xreadlines()), + ("0\n", "1\n", "2\n", "3\n", "4\n")) + finally: + f.close() + try: + unlink(TESTFN) + except OSError: + pass + + # Test filter()'s use of iterators. + def test_builtin_filter(self): + self.assertEqual(filter(None, SequenceClass(5)), range(1, 5)) + self.assertEqual(filter(None, SequenceClass(0)), []) + self.assertEqual(filter(None, ()), ()) + self.assertEqual(filter(None, "abc"), "abc") + + d = {"one": 1, "two": 2, "three": 3} + self.assertEqual(filter(None, d), d.keys()) + + self.assertRaises(TypeError, filter, None, list) + self.assertRaises(TypeError, filter, None, 42) + + class Boolean: + def __init__(self, truth): + self.truth = truth + def __nonzero__(self): + return self.truth + True = Boolean(1) + False = Boolean(0) + + class Seq: + def __init__(self, *args): + self.vals = args + def __iter__(self): + class SeqIter: + def __init__(self, vals): + self.vals = vals + self.i = 0 + def __iter__(self): + return self + def next(self): + i = self.i + self.i = i + 1 + if i < len(self.vals): + return self.vals[i] + else: + raise StopIteration + return SeqIter(self.vals) + + seq = Seq(*([True, False] * 25)) + self.assertEqual(filter(lambda x: not x, seq), [False]*25) + self.assertEqual(filter(lambda x: not x, iter(seq)), [False]*25) + + # Test max() and min()'s use of iterators. + def test_builtin_max_min(self): + self.assertEqual(max(SequenceClass(5)), 4) + self.assertEqual(min(SequenceClass(5)), 0) + self.assertEqual(max(8, -1), 8) + self.assertEqual(min(8, -1), -1) + + d = {"one": 1, "two": 2, "three": 3} + self.assertEqual(max(d), "two") + self.assertEqual(min(d), "one") + self.assertEqual(max(d.itervalues()), 3) + self.assertEqual(min(iter(d.itervalues())), 1) + + f = open(TESTFN, "w") + try: + f.write("medium line\n") + f.write("xtra large line\n") + f.write("itty-bitty line\n") + finally: + f.close() + f = open(TESTFN, "r") + try: + self.assertEqual(min(f), "itty-bitty line\n") + f.seek(0, 0) + self.assertEqual(max(f), "xtra large line\n") + finally: + f.close() + try: + unlink(TESTFN) + except OSError: + pass + + # Test map()'s use of iterators. + def test_builtin_map(self): + self.assertEqual(map(None, SequenceClass(5)), range(5)) + self.assertEqual(map(lambda x: x+1, SequenceClass(5)), range(1, 6)) + + d = {"one": 1, "two": 2, "three": 3} + self.assertEqual(map(None, d), d.keys()) + self.assertEqual(map(lambda k, d=d: (k, d[k]), d), d.items()) + dkeys = d.keys() + expected = [(i < len(d) and dkeys[i] or None, + i, + i < len(d) and dkeys[i] or None) + for i in range(5)] + self.assertEqual(map(None, d, + SequenceClass(5), + iter(d.iterkeys())), + expected) + + f = open(TESTFN, "w") + try: + for i in range(10): + f.write("xy" * i + "\n") # line i has len 2*i+1 + finally: + f.close() + f = open(TESTFN, "r") + try: + self.assertEqual(map(len, f), range(1, 21, 2)) + finally: + f.close() + try: + unlink(TESTFN) + except OSError: + pass + + # Test zip()'s use of iterators. + def test_builtin_zip(self): + self.assertRaises(TypeError, zip) + self.assertRaises(TypeError, zip, None) + self.assertRaises(TypeError, zip, range(10), 42) + self.assertRaises(TypeError, zip, range(10), zip) + + self.assertEqual(zip(IteratingSequenceClass(3)), + [(0,), (1,), (2,)]) + self.assertEqual(zip(SequenceClass(3)), + [(0,), (1,), (2,)]) + + d = {"one": 1, "two": 2, "three": 3} + self.assertEqual(d.items(), zip(d, d.itervalues())) + + # Generate all ints starting at constructor arg. + class IntsFrom: + def __init__(self, start): + self.i = start + + def __iter__(self): + return self + + def next(self): + i = self.i + self.i = i+1 + return i + + f = open(TESTFN, "w") + try: + f.write("a\n" "bbb\n" "cc\n") + finally: + f.close() + f = open(TESTFN, "r") + try: + self.assertEqual(zip(IntsFrom(0), f, IntsFrom(-100)), + [(0, "a\n", -100), + (1, "bbb\n", -99), + (2, "cc\n", -98)]) + finally: + f.close() + try: + unlink(TESTFN) + except OSError: + pass + + # Test reduces()'s use of iterators. + def test_builtin_reduce(self): + from operator import add + self.assertEqual(reduce(add, SequenceClass(5)), 10) + self.assertEqual(reduce(add, SequenceClass(5), 42), 52) + self.assertRaises(TypeError, reduce, add, SequenceClass(0)) + self.assertEqual(reduce(add, SequenceClass(0), 42), 42) + self.assertEqual(reduce(add, SequenceClass(1)), 0) + self.assertEqual(reduce(add, SequenceClass(1), 42), 42) + + d = {"one": 1, "two": 2, "three": 3} + self.assertEqual(reduce(add, d), "".join(d.keys())) + + def test_unicode_join_endcase(self): + + # This class inserts a Unicode object into its argument's natural + # iteration, in the 3rd position. + class OhPhooey: + def __init__(self, seq): + self.it = iter(seq) + self.i = 0 + + def __iter__(self): + return self + + def next(self): + i = self.i + self.i = i+1 + if i == 2: + return u"fooled you!" + return self.it.next() + + f = open(TESTFN, "w") + try: + f.write("a\n" + "b\n" + "c\n") + finally: + f.close() + + f = open(TESTFN, "r") + # Nasty: string.join(s) can't know whether unicode.join() is needed + # until it's seen all of s's elements. But in this case, f's + # iterator cannot be restarted. So what we're testing here is + # whether string.join() can manage to remember everything it's seen + # and pass that on to unicode.join(). + try: + got = " - ".join(OhPhooey(f)) + self.assertEqual(got, u"a\n - b\n - fooled you! - c\n") + finally: + f.close() + try: + unlink(TESTFN) + except OSError: + pass + + # Test iterators with 'x in y' and 'x not in y'. + def test_in_and_not_in(self): + for sc5 in IteratingSequenceClass(5), SequenceClass(5): + for i in range(5): + self.assert_(i in sc5) + for i in "abc", -1, 5, 42.42, (3, 4), [], {1: 1}, 3-12j, sc5: + self.assert_(i not in sc5) + + self.assertRaises(TypeError, lambda: 3 in 12) + self.assertRaises(TypeError, lambda: 3 not in map) + + d = {"one": 1, "two": 2, "three": 3, 1j: 2j} + for k in d: + self.assert_(k in d) + self.assert_(k not in d.itervalues()) + for v in d.values(): + self.assert_(v in d.itervalues()) + self.assert_(v not in d) + for k, v in d.iteritems(): + self.assert_((k, v) in d.iteritems()) + self.assert_((v, k) not in d.iteritems()) + + f = open(TESTFN, "w") + try: + f.write("a\n" "b\n" "c\n") + finally: + f.close() + f = open(TESTFN, "r") + try: + for chunk in "abc": + f.seek(0, 0) + self.assert_(chunk not in f) + f.seek(0, 0) + self.assert_((chunk + "\n") in f) + finally: + f.close() + try: + unlink(TESTFN) + except OSError: + pass + + # Test iterators with operator.countOf (PySequence_Count). + def test_countOf(self): + from operator import countOf + self.assertEqual(countOf([1,2,2,3,2,5], 2), 3) + self.assertEqual(countOf((1,2,2,3,2,5), 2), 3) + self.assertEqual(countOf("122325", "2"), 3) + self.assertEqual(countOf("122325", "6"), 0) + + self.assertRaises(TypeError, countOf, 42, 1) + self.assertRaises(TypeError, countOf, countOf, countOf) + + d = {"one": 3, "two": 3, "three": 3, 1j: 2j} + for k in d: + self.assertEqual(countOf(d, k), 1) + self.assertEqual(countOf(d.itervalues(), 3), 3) + self.assertEqual(countOf(d.itervalues(), 2j), 1) + self.assertEqual(countOf(d.itervalues(), 1j), 0) + + f = open(TESTFN, "w") + try: + f.write("a\n" "b\n" "c\n" "b\n") + finally: + f.close() + f = open(TESTFN, "r") + try: + for letter, count in ("a", 1), ("b", 2), ("c", 1), ("d", 0): + f.seek(0, 0) + self.assertEqual(countOf(f, letter + "\n"), count) + finally: + f.close() + try: + unlink(TESTFN) + except OSError: + pass + + # Test iterators on RHS of unpacking assignments. + def test_unpack_iter(self): + a, b = 1, 2 + self.assertEqual((a, b), (1, 2)) + + a, b, c = IteratingSequenceClass(3) + self.assertEqual((a, b, c), (0, 1, 2)) + + try: # too many values + a, b = IteratingSequenceClass(3) + except ValueError: + pass + else: + self.fail("should have raised ValueError") + + try: # not enough values + a, b, c = IteratingSequenceClass(2) + except ValueError: + pass + else: + self.fail("should have raised ValueError") + + try: # not iterable + a, b, c = len + except TypeError: + pass + else: + self.fail("should have raised TypeError") + + a, b, c = {1: 42, 2: 42, 3: 42}.itervalues() + self.assertEqual((a, b, c), (42, 42, 42)) + + f = open(TESTFN, "w") + lines = ("a\n", "bb\n", "ccc\n") + try: + for line in lines: + f.write(line) + finally: + f.close() + f = open(TESTFN, "r") + try: + a, b, c = f + self.assertEqual((a, b, c), lines) + finally: + f.close() + try: + unlink(TESTFN) + except OSError: + pass + + (a, b), (c,) = IteratingSequenceClass(2), {42: 24} + self.assertEqual((a, b, c), (0, 1, 42)) + run_unittest(TestCase) Index: test_locale.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_locale.py,v retrieving revision 1.2 retrieving revision 1.2.4.1 diff -C2 -r1.2 -r1.2.4.1 *** test_locale.py 2001/04/15 13:15:56 1.2 --- test_locale.py 2001/07/07 22:55:29 1.2.4.1 *************** *** 37,42 **** testformat("%+f", -42, grouping=1, output='-42.000000') testformat("%20.f", -42, grouping=1, output=' -42') ! testformat("%+10.f", -4200, grouping=1, output=' -4,200') ! testformat("%-10.f", 4200, grouping=1, output='4,200 ') finally: locale.setlocale(locale.LC_NUMERIC, oldlocale) --- 37,42 ---- testformat("%+f", -42, grouping=1, output='-42.000000') testformat("%20.f", -42, grouping=1, output=' -42') ! testformat("%+10.f", -4200, grouping=1, output=' -4,200') ! testformat("%-10.f", 4200, grouping=1, output='4,200 ') finally: locale.setlocale(locale.LC_NUMERIC, oldlocale) Index: test_mailbox.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_mailbox.py,v retrieving revision 1.3 retrieving revision 1.3.4.1 diff -C2 -r1.3 -r1.3.4.1 *** test_mailbox.py 2001/04/10 15:01:20 1.3 --- test_mailbox.py 2001/07/07 22:55:29 1.3.4.1 *************** *** 2,7 **** import os import test_support ! # cleanup try: os.unlink(test_support.TESTFN) --- 2,9 ---- import os import test_support + import time + import unittest ! # cleanup earlier tests try: os.unlink(test_support.TESTFN) *************** *** 9,34 **** pass - # create a new maildir mailbox to work with: - curdir = os.path.join(test_support.TESTFN, "cur") - newdir = os.path.join(test_support.TESTFN, "new") - try: - os.mkdir(test_support.TESTFN) - os.mkdir(curdir) - os.mkdir(newdir) - - # Test for regression on bug #117490: - # http://sourceforge.net/bugs/?func=detailbug&bug_id=117490&group_id=5470 - # Make sure the boxes attribute actually gets set. - mbox = mailbox.Maildir(test_support.TESTFN) - mbox.boxes - print "newly created maildir contains", len(mbox.boxes), "messages" # XXX We still need more tests! ! finally: ! try: os.rmdir(newdir) ! except os.error: pass ! try: os.rmdir(curdir) ! except os.error: pass ! try: os.rmdir(test_support.TESTFN) ! except os.error: pass --- 11,99 ---- pass + DUMMY_MESSAGE = """\ + From: some.body@dummy.domain + To: me@my.domain + + This is a dummy message. + """ + + + class MaildirTestCase(unittest.TestCase): + + def setUp(self): + # create a new maildir mailbox to work with: + self._dir = test_support.TESTFN + os.mkdir(self._dir) + os.mkdir(os.path.join(self._dir, "cur")) + os.mkdir(os.path.join(self._dir, "tmp")) + os.mkdir(os.path.join(self._dir, "new")) + self._counter = 1 + self._msgfiles = [] + + def tearDown(self): + map(os.unlink, self._msgfiles) + os.rmdir(os.path.join(self._dir, "cur")) + os.rmdir(os.path.join(self._dir, "tmp")) + os.rmdir(os.path.join(self._dir, "new")) + os.rmdir(self._dir) + + def createMessage(self, dir): + t = int(time.time() % 1000000) + pid = self._counter + self._counter += 1 + filename = "%s.%s.myhostname.mydomain" % (t, pid) + tmpname = os.path.join(self._dir, "tmp", filename) + newname = os.path.join(self._dir, dir, filename) + fp = open(tmpname, "w") + self._msgfiles.append(tmpname) + fp.write(DUMMY_MESSAGE) + fp.close() + if hasattr(os, "link"): + os.link(tmpname, newname) + else: + fp = open(newname, "w") + fp.write(DUMMY_MESSAGE) + fp.close() + self._msgfiles.append(newname) + + def test_empty_maildir(self): + """Test an empty maildir mailbox""" + # Test for regression on bug #117490: + # Make sure the boxes attribute actually gets set. + self.mbox = mailbox.Maildir(test_support.TESTFN) + self.assert_(hasattr(self.mbox, "boxes")) + self.assert_(len(self.mbox.boxes) == 0) + self.assert_(self.mbox.next() is None) + self.assert_(self.mbox.next() is None) + + def test_nonempty_maildir_cur(self): + self.createMessage("cur") + self.mbox = mailbox.Maildir(test_support.TESTFN) + self.assert_(len(self.mbox.boxes) == 1) + self.assert_(self.mbox.next() is not None) + self.assert_(self.mbox.next() is None) + self.assert_(self.mbox.next() is None) + + def test_nonempty_maildir_new(self): + self.createMessage("new") + self.mbox = mailbox.Maildir(test_support.TESTFN) + self.assert_(len(self.mbox.boxes) == 1) + self.assert_(self.mbox.next() is not None) + self.assert_(self.mbox.next() is None) + self.assert_(self.mbox.next() is None) + + def test_nonempty_maildir_both(self): + self.createMessage("cur") + self.createMessage("new") + self.mbox = mailbox.Maildir(test_support.TESTFN) + self.assert_(len(self.mbox.boxes) == 2) + self.assert_(self.mbox.next() is not None) + self.assert_(self.mbox.next() is not None) + self.assert_(self.mbox.next() is None) + self.assert_(self.mbox.next() is None) + # XXX We still need more tests! + ! test_support.run_unittest(MaildirTestCase) Index: test_minidom.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_minidom.py,v retrieving revision 1.26 retrieving revision 1.26.6.1 diff -C2 -r1.26 -r1.26.6.1 *** test_minidom.py 2001/02/21 07:29:48 1.26 --- test_minidom.py 2001/07/07 22:55:29 1.26.6.1 *************** *** 240,244 **** def testGetAttributeNode(): pass ! def testGetElementsByTagNameNS(): pass def testGetEmptyNodeListFromElementsByTagNameNS(): pass --- 240,251 ---- def testGetAttributeNode(): pass ! def testGetElementsByTagNameNS(): ! d=""" ! ! """ ! dom = parseString(d) ! elem = dom.getElementsByTagNameNS("http://pyxml.sf.net/minidom","myelem") ! confirm(len(elem) == 1) ! dom.unlink() def testGetEmptyNodeListFromElementsByTagNameNS(): pass Index: test_mmap.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_mmap.py,v retrieving revision 1.15 retrieving revision 1.15.6.1 diff -C2 -r1.15 -r1.15.6.1 *** test_mmap.py 2001/02/09 11:49:24 1.15 --- test_mmap.py 2001/07/07 22:55:29 1.15.6.1 *************** *** 1,5 **** ! from test_support import verify import mmap ! import os, re, sys PAGESIZE = mmap.PAGESIZE --- 1,5 ---- ! from test_support import verify, TESTFN import mmap ! import os, re PAGESIZE = mmap.PAGESIZE *************** *** 8,123 **** "Test mmap module on Unix systems and Windows" ! # Create an mmap'ed file ! f = open('foo', 'w+') ! # Write 2 pages worth of data to the file ! f.write('\0'* PAGESIZE) ! f.write('foo') ! f.write('\0'* (PAGESIZE-3) ) ! ! m = mmap.mmap(f.fileno(), 2 * PAGESIZE) ! f.close() ! ! # Simple sanity checks ! ! print type(m) # SF bug 128713: segfaulted on Linux ! print ' Position of foo:', m.find('foo') / float(PAGESIZE), 'pages' ! verify(m.find('foo') == PAGESIZE) ! ! print ' Length of file:', len(m) / float(PAGESIZE), 'pages' ! verify(len(m) == 2*PAGESIZE) ! ! print ' Contents of byte 0:', repr(m[0]) ! verify(m[0] == '\0') ! print ' Contents of first 3 bytes:', repr(m[0:3]) ! verify(m[0:3] == '\0\0\0') ! ! # Modify the file's content ! print "\n Modifying file's content..." ! m[0] = '3' ! m[PAGESIZE +3: PAGESIZE +3+3]='bar' ! ! # Check that the modification worked ! print ' Contents of byte 0:', repr(m[0]) ! verify(m[0] == '3') ! print ' Contents of first 3 bytes:', repr(m[0:3]) ! verify(m[0:3] == '3\0\0') ! print ' Contents of second page:', repr(m[PAGESIZE-1 : PAGESIZE + 7]) ! verify(m[PAGESIZE-1 : PAGESIZE + 7] == '\0foobar\0') ! ! m.flush() ! ! # Test doing a regular expression match in an mmap'ed file ! match=re.search('[A-Za-z]+', m) ! if match is None: ! print ' ERROR: regex match on mmap failed!' ! else: ! start, end = match.span(0) ! length = end - start ! ! print ' Regex match on mmap (page start, length of match):', ! print start / float(PAGESIZE), length ! ! verify(start == PAGESIZE) ! verify(end == PAGESIZE + 6) ! ! # test seeking around (try to overflow the seek implementation) ! m.seek(0,0) ! print ' Seek to zeroth byte' ! verify(m.tell() == 0) ! m.seek(42,1) ! print ' Seek to 42nd byte' ! verify(m.tell() == 42) ! m.seek(0,2) ! print ' Seek to last byte' ! verify(m.tell() == len(m)) ! ! print ' Try to seek to negative position...' ! try: ! m.seek(-1) ! except ValueError: ! pass ! else: ! verify(0, 'expected a ValueError but did not get it') ! ! print ' Try to seek beyond end of mmap...' ! try: ! m.seek(1,2) ! except ValueError: ! pass ! else: ! verify(0, 'expected a ValueError but did not get it') ! ! print ' Try to seek to negative position...' ! try: ! m.seek(-len(m)-1,2) ! except ValueError: ! pass ! else: ! verify(0, 'expected a ValueError but did not get it') ! ! # Try resizing map ! print ' Attempting resize()' ! try: ! m.resize( 512 ) ! except SystemError: ! # resize() not supported ! # No messages are printed, since the output of this test suite ! # would then be different across platforms. ! pass ! else: ! # resize() is supported ! verify(len(m) == 512, ! "len(m) is %d, but expecting 512" % (len(m),) ) ! # Check that we can no longer seek beyond the new size. try: ! m.seek(513,0) except ValueError: pass else: ! verify(0, 'Could seek beyond the new size') - m.close() - os.unlink("foo") print ' Test passed' --- 8,136 ---- "Test mmap module on Unix systems and Windows" ! # Create a file to be mmap'ed. ! if os.path.exists(TESTFN): ! os.unlink(TESTFN) ! f = open(TESTFN, 'w+') ! ! try: # unlink TESTFN no matter what ! # Write 2 pages worth of data to the file ! f.write('\0'* PAGESIZE) ! f.write('foo') ! f.write('\0'* (PAGESIZE-3) ) ! ! m = mmap.mmap(f.fileno(), 2 * PAGESIZE) ! f.close() ! ! # Simple sanity checks ! ! print type(m) # SF bug 128713: segfaulted on Linux ! print ' Position of foo:', m.find('foo') / float(PAGESIZE), 'pages' ! verify(m.find('foo') == PAGESIZE) ! ! print ' Length of file:', len(m) / float(PAGESIZE), 'pages' ! verify(len(m) == 2*PAGESIZE) ! ! print ' Contents of byte 0:', repr(m[0]) ! verify(m[0] == '\0') ! print ' Contents of first 3 bytes:', repr(m[0:3]) ! verify(m[0:3] == '\0\0\0') ! ! # Modify the file's content ! print "\n Modifying file's content..." ! m[0] = '3' ! m[PAGESIZE +3: PAGESIZE +3+3] = 'bar' ! ! # Check that the modification worked ! print ' Contents of byte 0:', repr(m[0]) ! verify(m[0] == '3') ! print ' Contents of first 3 bytes:', repr(m[0:3]) ! verify(m[0:3] == '3\0\0') ! print ' Contents of second page:', repr(m[PAGESIZE-1 : PAGESIZE + 7]) ! verify(m[PAGESIZE-1 : PAGESIZE + 7] == '\0foobar\0') ! ! m.flush() ! ! # Test doing a regular expression match in an mmap'ed file ! match = re.search('[A-Za-z]+', m) ! if match is None: ! print ' ERROR: regex match on mmap failed!' ! else: ! start, end = match.span(0) ! length = end - start ! ! print ' Regex match on mmap (page start, length of match):', ! print start / float(PAGESIZE), length ! ! verify(start == PAGESIZE) ! verify(end == PAGESIZE + 6) ! ! # test seeking around (try to overflow the seek implementation) ! m.seek(0,0) ! print ' Seek to zeroth byte' ! verify(m.tell() == 0) ! m.seek(42,1) ! print ' Seek to 42nd byte' ! verify(m.tell() == 42) ! m.seek(0,2) ! print ' Seek to last byte' ! verify(m.tell() == len(m)) ! ! print ' Try to seek to negative position...' ! try: ! m.seek(-1) ! except ValueError: ! pass ! else: ! verify(0, 'expected a ValueError but did not get it') ! ! print ' Try to seek beyond end of mmap...' ! try: ! m.seek(1,2) ! except ValueError: ! pass ! else: ! verify(0, 'expected a ValueError but did not get it') ! print ' Try to seek to negative position...' try: ! m.seek(-len(m)-1,2) except ValueError: pass + else: + verify(0, 'expected a ValueError but did not get it') + + # Try resizing map + print ' Attempting resize()' + try: + m.resize( 512 ) + except SystemError: + # resize() not supported + # No messages are printed, since the output of this test suite + # would then be different across platforms. + pass else: ! # resize() is supported ! verify(len(m) == 512, ! "len(m) is %d, but expecting 512" % (len(m),) ) ! # Check that we can no longer seek beyond the new size. ! try: ! m.seek(513,0) ! except ValueError: ! pass ! else: ! verify(0, 'Could seek beyond the new size') ! ! m.close() ! ! finally: ! try: ! f.close() ! except OSError: ! pass ! try: ! os.unlink(TESTFN) ! except OSError: ! pass print ' Test passed' Index: test_operations.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_operations.py,v retrieving revision 1.3 retrieving revision 1.3.6.1 diff -C2 -r1.3 -r1.3.6.1 *** test_operations.py 2000/10/23 17:22:07 1.3 --- test_operations.py 2001/07/07 22:55:29 1.3.6.1 *************** *** 12,15 **** --- 12,17 ---- class BadDictKey: + already_printed_raising_error = 0 + def __hash__(self): return hash(self.__class__) *************** *** 17,21 **** def __cmp__(self, other): if isinstance(other, self.__class__): ! print "raising error" raise RuntimeError, "gotcha" return other --- 19,30 ---- def __cmp__(self, other): if isinstance(other, self.__class__): ! if not BadDictKey.already_printed_raising_error: ! # How many times __cmp__ gets called depends on the hash ! # code and the internals of the dict implementation; we ! # know it will be called at least once, but that's it. ! # already_printed_raising_error makes sure the expected- ! # output file prints the msg at most once. ! BadDictKey.already_printed_raising_error = 1 ! print "raising error" raise RuntimeError, "gotcha" return other *************** *** 27,28 **** --- 36,52 ---- d[x2] = 2 print "No exception passed through." + + # Dict resizing bug, found by Jack Jansen in 2.2 CVS development. + # This version got an assert failure in debug build, infinite loop in + # release build. Unfortunately, provoking this kind of stuff requires + # a mix of inserts and deletes hitting exactly the right hash codes in + # exactly the right order, and I can't think of a randomized approach + # that would be *likely* to hit a failing case in reasonable time. + + d = {} + for i in range(5): + d[i] = i + for i in range(5): + del d[i] + for i in range(5, 9): # i==8 was the problem + d[i] = i Index: test_parser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_parser.py,v retrieving revision 1.6 retrieving revision 1.6.6.1 diff -C2 -r1.6 -r1.6.6.1 *** test_parser.py 2001/01/17 21:51:36 1.6 --- test_parser.py 2001/07/07 22:55:29 1.6.6.1 *************** *** 1,9 **** - import os.path import parser ! import pprint ! import sys - from test_support import TestFailed - # # First, we test that we can generate trees from valid source fragments, --- 1,6 ---- import parser ! import test_support ! import unittest # # First, we test that we can generate trees from valid source fragments, *************** *** 12,124 **** # ! def roundtrip(f, s): ! st1 = f(s) ! t = st1.totuple() ! try: ! st2 = parser.sequence2ast(t) ! except parser.ParserError: ! raise TestFailed, s ! ! def roundtrip_fromfile(filename): ! roundtrip(parser.suite, open(filename).read()) ! ! def test_expr(s): ! print "expr:", s ! roundtrip(parser.expr, s) ! ! def test_suite(s): ! print "suite:", s ! roundtrip(parser.suite, s) ! ! ! print "Expressions:" ! ! test_expr("foo(1)") ! test_expr("[1, 2, 3]") ! test_expr("[x**3 for x in range(20)]") ! test_expr("[x**3 for x in range(20) if x % 3]") ! test_expr("foo(*args)") ! test_expr("foo(*args, **kw)") ! test_expr("foo(**kw)") ! test_expr("foo(key=value)") ! test_expr("foo(key=value, *args)") ! test_expr("foo(key=value, *args, **kw)") ! test_expr("foo(key=value, **kw)") ! test_expr("foo(a, b, c, *args)") ! test_expr("foo(a, b, c, *args, **kw)") ! test_expr("foo(a, b, c, **kw)") ! test_expr("foo + bar") ! test_expr("lambda: 0") ! test_expr("lambda x: 0") ! test_expr("lambda *y: 0") ! test_expr("lambda *y, **z: 0") ! test_expr("lambda **z: 0") ! test_expr("lambda x, y: 0") ! test_expr("lambda foo=bar: 0") ! test_expr("lambda foo=bar, spaz=nifty+spit: 0") ! test_expr("lambda foo=bar, **z: 0") ! test_expr("lambda foo=bar, blaz=blat+2, **z: 0") ! test_expr("lambda foo=bar, blaz=blat+2, *y, **z: 0") ! test_expr("lambda x, *y, **z: 0") ! ! print ! print "Statements:" ! test_suite("print") ! test_suite("print 1") ! test_suite("print 1,") ! test_suite("print >>fp") ! test_suite("print >>fp, 1") ! test_suite("print >>fp, 1,") ! ! # expr_stmt ! test_suite("a") ! test_suite("a = b") ! test_suite("a = b = c = d = e") ! test_suite("a += b") ! test_suite("a -= b") ! test_suite("a *= b") ! test_suite("a /= b") ! test_suite("a %= b") ! test_suite("a &= b") ! test_suite("a |= b") ! test_suite("a ^= b") ! test_suite("a <<= b") ! test_suite("a >>= b") ! test_suite("a **= b") ! ! test_suite("def f(): pass") ! test_suite("def f(*args): pass") ! test_suite("def f(*args, **kw): pass") ! test_suite("def f(**kw): pass") ! test_suite("def f(foo=bar): pass") ! test_suite("def f(foo=bar, *args): pass") ! test_suite("def f(foo=bar, *args, **kw): pass") ! test_suite("def f(foo=bar, **kw): pass") ! ! test_suite("def f(a, b): pass") ! test_suite("def f(a, b, *args): pass") ! test_suite("def f(a, b, *args, **kw): pass") ! test_suite("def f(a, b, **kw): pass") ! test_suite("def f(a, b, foo=bar): pass") ! test_suite("def f(a, b, foo=bar, *args): pass") ! test_suite("def f(a, b, foo=bar, *args, **kw): pass") ! test_suite("def f(a, b, foo=bar, **kw): pass") ! ! test_suite("from sys.path import *") ! test_suite("from sys.path import dirname") ! test_suite("from sys.path import dirname as my_dirname") ! test_suite("from sys.path import dirname, basename") ! test_suite("from sys.path import dirname as my_dirname, basename") ! test_suite("from sys.path import dirname, basename as my_basename") ! ! test_suite("import sys") ! test_suite("import sys as system") ! test_suite("import sys, math") ! test_suite("import sys as system, math") ! test_suite("import sys, math as my_math") ! ! #d = os.path.dirname(os.__file__) ! #roundtrip_fromfile(os.path.join(d, "os.py")) ! #roundtrip_fromfile(os.path.join(d, "test", "test_parser.py")) # --- 9,123 ---- # ! class RoundtripLegalSyntaxTestCase(unittest.TestCase): ! def roundtrip(self, f, s): ! st1 = f(s) ! t = st1.totuple() ! try: ! st2 = parser.sequence2ast(t) ! except parser.ParserError: ! self.fail("could not roundtrip %r" % s) ! ! self.assertEquals(t, st2.totuple(), ! "could not re-generate syntax tree") ! ! def check_expr(self, s): ! self.roundtrip(parser.expr, s) ! ! def check_suite(self, s): ! self.roundtrip(parser.suite, s) ! ! def test_expressions(self): ! self.check_expr("foo(1)") ! self.check_expr("[1, 2, 3]") ! self.check_expr("[x**3 for x in range(20)]") ! self.check_expr("[x**3 for x in range(20) if x % 3]") ! self.check_expr("foo(*args)") ! self.check_expr("foo(*args, **kw)") ! self.check_expr("foo(**kw)") ! self.check_expr("foo(key=value)") ! self.check_expr("foo(key=value, *args)") ! self.check_expr("foo(key=value, *args, **kw)") ! self.check_expr("foo(key=value, **kw)") ! self.check_expr("foo(a, b, c, *args)") ! self.check_expr("foo(a, b, c, *args, **kw)") ! self.check_expr("foo(a, b, c, **kw)") ! self.check_expr("foo + bar") ! self.check_expr("lambda: 0") ! self.check_expr("lambda x: 0") ! self.check_expr("lambda *y: 0") ! self.check_expr("lambda *y, **z: 0") ! self.check_expr("lambda **z: 0") ! self.check_expr("lambda x, y: 0") ! self.check_expr("lambda foo=bar: 0") ! self.check_expr("lambda foo=bar, spaz=nifty+spit: 0") ! self.check_expr("lambda foo=bar, **z: 0") ! self.check_expr("lambda foo=bar, blaz=blat+2, **z: 0") ! self.check_expr("lambda foo=bar, blaz=blat+2, *y, **z: 0") ! self.check_expr("lambda x, *y, **z: 0") ! ! def test_print(self): ! self.check_suite("print") ! self.check_suite("print 1") ! self.check_suite("print 1,") ! self.check_suite("print >>fp") ! self.check_suite("print >>fp, 1") ! self.check_suite("print >>fp, 1,") ! ! def test_simple_expression(self): ! # expr_stmt ! self.check_suite("a") ! ! def test_simple_assignments(self): ! self.check_suite("a = b") ! self.check_suite("a = b = c = d = e") ! ! def test_simple_augmented_assignments(self): ! 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") ! 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") ! self.check_suite("a **= b") ! ! def test_function_defs(self): ! self.check_suite("def f(): pass") ! self.check_suite("def f(*args): pass") ! self.check_suite("def f(*args, **kw): pass") ! self.check_suite("def f(**kw): pass") ! self.check_suite("def f(foo=bar): pass") ! self.check_suite("def f(foo=bar, *args): pass") ! self.check_suite("def f(foo=bar, *args, **kw): pass") ! self.check_suite("def f(foo=bar, **kw): pass") ! ! self.check_suite("def f(a, b): pass") ! self.check_suite("def f(a, b, *args): pass") ! self.check_suite("def f(a, b, *args, **kw): pass") ! self.check_suite("def f(a, b, **kw): pass") ! self.check_suite("def f(a, b, foo=bar): pass") ! self.check_suite("def f(a, b, foo=bar, *args): pass") ! self.check_suite("def f(a, b, foo=bar, *args, **kw): pass") ! self.check_suite("def f(a, b, foo=bar, **kw): pass") ! ! def test_import_from_statement(self): ! self.check_suite("from sys.path import *") ! self.check_suite("from sys.path import dirname") ! self.check_suite("from sys.path import dirname as my_dirname") ! self.check_suite("from sys.path import dirname, basename") ! self.check_suite( ! "from sys.path import dirname as my_dirname, basename") ! self.check_suite( ! "from sys.path import dirname, basename as my_basename") ! ! def test_basic_import_statement(self): ! self.check_suite("import sys") ! self.check_suite("import sys as system") ! self.check_suite("import sys, math") ! self.check_suite("import sys as system, math") ! self.check_suite("import sys, math as my_math") # *************** *** 127,222 **** # ! print ! print "Invalid parse trees:" - def check_bad_tree(tree, label): - print - print label - try: - parser.sequence2ast(tree) - except parser.ParserError: - print "caught expected exception for invalid tree" - else: - print "test failed: did not properly detect invalid tree:" - pprint.pprint(tree) - - - # not even remotely valid: - check_bad_tree((1, 2, 3), "") - - # print >>fp, - tree = \ - (257, - (264, - (265, - (266, - (268, - (1, 'print'), - (35, '>>'), - (290, - (291, - (292, - (293, - (295, - (296, - (297, - (298, (299, (300, (301, (302, (303, (1, 'fp')))))))))))))), - (12, ','))), - (4, ''))), - (0, '')) - - check_bad_tree(tree, "print >>fp,") - - # a,,c - tree = \ - (258, - (311, - (290, - (291, - (292, - (293, - (295, - (296, (297, (298, (299, (300, (301, (302, (303, (1, 'a')))))))))))))), - (12, ','), - (12, ','), - (290, - (291, - (292, - (293, - (295, - (296, (297, (298, (299, (300, (301, (302, (303, (1, 'c'))))))))))))))), - (4, ''), - (0, '')) - - check_bad_tree(tree, "a,,c") - - # a $= b - tree = \ - (257, - (264, - (265, - (266, - (267, - (312, - (291, - (292, - (293, - (294, - (296, - (297, - (298, - (299, (300, (301, (302, (303, (304, (1, 'a'))))))))))))))), - (268, (37, '$=')), - (312, - (291, - (292, - (293, - (294, - (296, - (297, - (298, - (299, (300, (301, (302, (303, (304, (1, 'b'))))))))))))))))), - (4, ''))), - (0, '')) ! check_bad_tree(tree, "a $= b") --- 126,226 ---- # ! class IllegalSyntaxTestCase(unittest.TestCase): ! def check_bad_tree(self, tree, label): ! try: ! parser.sequence2ast(tree) ! except parser.ParserError: ! pass ! else: ! self.fail("did not detect invalid tree for %r" % label) ! ! def test_junk(self): ! # not even remotely valid: ! self.check_bad_tree((1, 2, 3), "") ! ! def test_print_chevron_comma(self): ! "Illegal input: print >>fp,""" ! tree = \ ! (257, ! (264, ! (265, ! (266, ! (268, ! (1, 'print'), ! (35, '>>'), ! (290, ! (291, ! (292, ! (293, ! (295, ! (296, ! (297, ! (298, (299, (300, (301, (302, (303, (1, 'fp')))))))))))))), ! (12, ','))), ! (4, ''))), ! (0, '')) ! self.check_bad_tree(tree, "print >>fp,") ! ! def test_a_comma_comma_c(self): ! """Illegal input: a,,c""" ! tree = \ ! (258, ! (311, ! (290, ! (291, ! (292, ! (293, ! (295, ! (296, ! (297, ! (298, (299, (300, (301, (302, (303, (1, 'a')))))))))))))), ! (12, ','), ! (12, ','), ! (290, ! (291, ! (292, ! (293, ! (295, ! (296, ! (297, ! (298, (299, (300, (301, (302, (303, (1, 'c'))))))))))))))), ! (4, ''), ! (0, '')) ! self.check_bad_tree(tree, "a,,c") ! ! def test_illegal_operator(self): ! """Illegal input: a $= b""" ! tree = \ ! (257, ! (264, ! (265, ! (266, ! (267, ! (312, ! (291, ! (292, ! (293, ! (294, ! (296, ! (297, ! (298, ! (299, ! (300, (301, (302, (303, (304, (1, 'a'))))))))))))))), ! (268, (37, '$=')), ! (312, ! (291, ! (292, ! (293, ! (294, ! (296, ! (297, ! (298, ! (299, ! (300, (301, (302, (303, (304, (1, 'b'))))))))))))))))), ! (4, ''))), ! (0, '')) ! self.check_bad_tree(tree, "a $= b") ! test_support.run_unittest(RoundtripLegalSyntaxTestCase) ! test_support.run_unittest(IllegalSyntaxTestCase) Index: test_pyexpat.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pyexpat.py,v retrieving revision 1.7 retrieving revision 1.7.6.1 diff -C2 -r1.7 -r1.7.6.1 *** test_pyexpat.py 2000/12/23 22:12:07 1.7 --- test_pyexpat.py 2001/07/07 22:55:29 1.7.6.1 *************** *** 6,12 **** from xml.parsers import expat class Outputter: def StartElementHandler(self, name, attrs): ! print 'Start element:\n\t', repr(name), attrs def EndElementHandler(self, name): --- 6,14 ---- from xml.parsers import expat + from test_support import sortdict + class Outputter: def StartElementHandler(self, name, attrs): ! print 'Start element:\n\t', repr(name), sortdict(attrs) def EndElementHandler(self, name): *************** *** 76,79 **** --- 78,93 ---- parser.returns_unicode = 0; confirm(parser.returns_unicode == 0) + # Test getting/setting ordered_attributes + parser.ordered_attributes = 0; confirm(parser.ordered_attributes == 0) + parser.ordered_attributes = 1; confirm(parser.ordered_attributes == 1) + parser.ordered_attributes = 2; confirm(parser.ordered_attributes == 1) + parser.ordered_attributes = 0; confirm(parser.ordered_attributes == 0) + + # Test getting/setting specified_attributes + parser.specified_attributes = 0; confirm(parser.specified_attributes == 0) + parser.specified_attributes = 1; confirm(parser.specified_attributes == 1) + parser.specified_attributes = 2; confirm(parser.specified_attributes == 1) + parser.specified_attributes = 0; confirm(parser.specified_attributes == 0) + HANDLER_NAMES = [ 'StartElementHandler', 'EndElementHandler', *************** *** 168,171 **** --- 182,186 ---- else: print "Failed to catch expected TypeError." + try: expat.ParserCreate(namespace_separator='too long') *************** *** 174,183 **** print e else: - print "Failed to catch expected ValueError." - try: - expat.ParserCreate(namespace_separator='') # too short - except ValueError, e: - print "Caught expected ValueError:" - print e - else: print "Failed to catch expected ValueError." --- 189,201 ---- print e else: print "Failed to catch expected ValueError." + + # ParserCreate() needs to accept a namespace_separator of zero length + # to satisfy the requirements of RDF applications that are required + # to simply glue together the namespace URI and the localname. Though + # considered a wart of the RDF specifications, it needs to be supported. + # + # See XML-SIG mailing list thread starting with + # http://mail.python.org/pipermail/xml-sig/2001-April/005202.html + # + expat.ParserCreate(namespace_separator='') # too short Index: test_regex.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_regex.py,v retrieving revision 1.9 retrieving revision 1.9.6.1 diff -C2 -r1.9 -r1.9.6.1 *** test_regex.py 2001/01/17 21:51:36 1.9 --- test_regex.py 2001/07/07 22:55:29 1.9.6.1 *************** *** 1,3 **** ! from test_support import verbose import warnings warnings.filterwarnings("ignore", "the regex module is deprecated", --- 1,3 ---- ! from test_support import verbose, sortdict import warnings warnings.filterwarnings("ignore", "the regex module is deprecated", *************** *** 41,45 **** print cre.group('one', 'two') print 'realpat:', cre.realpat ! print 'groupindex:', cre.groupindex re = 'world' --- 41,45 ---- print cre.group('one', 'two') print 'realpat:', cre.realpat ! print 'groupindex:', sortdict(cre.groupindex) re = 'world' Index: test_rfc822.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_rfc822.py,v retrieving revision 1.9 retrieving revision 1.9.6.1 diff -C2 -r1.9 -r1.9.6.1 *** test_rfc822.py 2001/01/17 21:51:36 1.9 --- test_rfc822.py 2001/07/07 22:55:29 1.9.6.1 *************** *** 1,4 **** ! from test_support import verbose ! import rfc822, sys try: from cStringIO import StringIO --- 1,7 ---- ! import rfc822 ! import sys ! import test_support ! import unittest ! try: from cStringIO import StringIO *************** *** 6,126 **** from StringIO import StringIO - def test(msg, results): - fp = StringIO() - fp.write(msg) - fp.seek(0) - m = rfc822.Message(fp) - i = 0 - - for n, a in m.getaddrlist('to') + m.getaddrlist('cc'): - if verbose: - print 'name:', repr(n), 'addr:', repr(a) - try: - mn, ma = results[i][0], results[i][1] - except IndexError: - print 'extra parsed address:', repr(n), repr(a) - continue - i = i + 1 - if mn == n and ma == a: - if verbose: - print ' [matched]' - else: - if verbose: - print ' [no match]' - print 'not found:', repr(n), repr(a) - - out = m.getdate('date') - if out: - if verbose: - print 'Date:', m.getheader('date') - if out == (1999, 1, 13, 23, 57, 35, 0, 0, 0): - if verbose: - print ' [matched]' - else: - if verbose: - print ' [no match]' - print 'Date conversion failed:', out - - # Note: all test cases must have the same date (in various formats), - # or no date! - - test('''Date: Wed, 13 Jan 1999 23:57:35 -0500 - From: Guido van Rossum - To: "Guido van - \t : Rossum" - Subject: test2 - - test2 - ''', [('Guido van\n\t : Rossum', 'guido@python.org')]) - - test('''From: Barry - Date: 13-Jan-1999 23:57:35 EST - - test''', [('Guido: the Barbarian', 'guido@python.org'), - ('Guido: the Madman', 'guido@python.org') - ]) - - test('''To: "The monster with - the very long name: Guido" - Date: Wed, 13 Jan 1999 23:57:35 -0500 - - test''', [('The monster with\n the very long name: Guido', - 'guido@python.org')]) - - test('''To: "Amit J. Patel" - CC: Mike Fletcher , - "'string-sig@python.org'" - Cc: fooz@bat.com, bart@toof.com - Cc: goit@lip.com - Date: Wed, 13 Jan 1999 23:57:35 -0500 - - test''', [('Amit J. Patel', 'amitp@Theory.Stanford.EDU'), - ('Mike Fletcher', 'mfletch@vrtelecom.com'), - ("'string-sig@python.org'", 'string-sig@python.org'), - ('', 'fooz@bat.com'), - ('', 'bart@toof.com'), - ('', 'goit@lip.com'), - ]) - - # This one is just twisted. I don't know what the proper result should be, - # but it shouldn't be to infloop, which is what used to happen! - test('''To: <[smtp:dd47@mail.xxx.edu]_at_hmhq@hdq-mdm1-imgout.companay.com> - Date: Wed, 13 Jan 1999 23:57:35 -0500 - - test''', [('', ''), - ('', 'dd47@mail.xxx.edu'), - ('', '_at_hmhq@hdq-mdm1-imgout.companay.com') - ]) - - # This exercises the old commas-in-a-full-name bug, which should be doing the - # right thing in recent versions of the module. - test('''To: "last, first" - - test''', [('last, first', 'userid@foo.net'), - ]) - - test('''To: (Comment stuff) "Quoted name"@somewhere.com - - test''', [('Comment stuff', '"Quoted name"@somewhere.com'), - ]) - - test('''To: : - Cc: goit@lip.com - Date: Wed, 13 Jan 1999 23:57:35 -0500 - - test''', [('', 'goit@lip.com')]) - test('''To: guido@[132.151.1.21] ! foo''', [('', 'guido@[132.151.1.21]')]) --- 9,168 ---- from StringIO import StringIO + class MessageTestCase(unittest.TestCase): + def create_message(self, msg): + return rfc822.Message(StringIO(msg)) + + def test_get(self): + msg = self.create_message( + 'To: "last, first" \n\ntest\n') + self.assert_(msg.get("to") == '"last, first" ') + self.assert_(msg.get("TO") == '"last, first" ') + self.assert_(msg.get("No-Such-Header") == "") + self.assert_(msg.get("No-Such-Header", "No-Such-Value") + == "No-Such-Value") + + def test_setdefault(self): + msg = self.create_message( + 'To: "last, first" \n\ntest\n') + self.assert_(not msg.has_key("New-Header")) + self.assert_(msg.setdefault("New-Header", "New-Value") == "New-Value") + self.assert_(msg.setdefault("New-Header", "Different-Value") + == "New-Value") + self.assert_(msg["new-header"] == "New-Value") + + self.assert_(msg.setdefault("Another-Header") == "") + self.assert_(msg["another-header"] == "") + + def check(self, msg, results): + """Check addresses and the date.""" + m = self.create_message(msg) + i = 0 + for n, a in m.getaddrlist('to') + m.getaddrlist('cc'): + try: + mn, ma = results[i][0], results[i][1] + except IndexError: + print 'extra parsed address:', repr(n), repr(a) + continue + i = i + 1 + if mn == n and ma == a: + pass + else: + print 'not found:', repr(n), repr(a) + + out = m.getdate('date') + if out: + self.assertEqual(out, + (1999, 1, 13, 23, 57, 35, 0, 0, 0), + "date conversion failed") + + + # Note: all test cases must have the same date (in various formats), + # or no date! + + def test_basic(self): + self.check( + 'Date: Wed, 13 Jan 1999 23:57:35 -0500\n' + 'From: Guido van Rossum \n' + 'To: "Guido van\n' + '\t : Rossum" \n' + 'Subject: test2\n' + '\n' + 'test2\n', + [('Guido van\n\t : Rossum', 'guido@python.org')]) + + self.check( + 'From: Barry \n' + 'Date: 13-Jan-1999 23:57:35 EST\n' + '\n' + 'test', + [('Guido: the Barbarian', 'guido@python.org'), + ('Guido: the Madman', 'guido@python.org') + ]) + + self.check( + 'To: "The monster with\n' + ' the very long name: Guido" \n' + 'Date: Wed, 13 Jan 1999 23:57:35 -0500\n' + '\n' + 'test', + [('The monster with\n the very long name: Guido', + 'guido@python.org')]) + + self.check( + 'To: "Amit J. Patel" \n' + 'CC: Mike Fletcher ,\n' + ' "\'string-sig@python.org\'" \n' + 'Cc: fooz@bat.com, bart@toof.com\n' + 'Cc: goit@lip.com\n' + 'Date: Wed, 13 Jan 1999 23:57:35 -0500\n' + '\n' + 'test', + [('Amit J. Patel', 'amitp@Theory.Stanford.EDU'), + ('Mike Fletcher', 'mfletch@vrtelecom.com'), + ("'string-sig@python.org'", 'string-sig@python.org'), + ('', 'fooz@bat.com'), + ('', 'bart@toof.com'), + ('', 'goit@lip.com'), + ]) + + def test_twisted(self): + # This one is just twisted. I don't know what the proper + # result should be, but it shouldn't be to infloop, which is + # what used to happen! + self.check( + 'To: <[smtp:dd47@mail.xxx.edu]_at_hmhq@hdq-mdm1-imgout.companay.com>\n' + 'Date: Wed, 13 Jan 1999 23:57:35 -0500\n' + '\n' + 'test', + [('', ''), + ('', 'dd47@mail.xxx.edu'), + ('', '_at_hmhq@hdq-mdm1-imgout.companay.com'), + ]) + + def test_commas_in_full_name(self): + # This exercises the old commas-in-a-full-name bug, which + # should be doing the right thing in recent versions of the + # module. + self.check( + 'To: "last, first" \n' + '\n' + 'test', + [('last, first', 'userid@foo.net')]) + + def test_quoted_name(self): + self.check( + 'To: (Comment stuff) "Quoted name"@somewhere.com\n' + '\n' + 'test', + [('Comment stuff', '"Quoted name"@somewhere.com')]) + + def test_bogus_to_header(self): + self.check( + 'To: :\n' + 'Cc: goit@lip.com\n' + 'Date: Wed, 13 Jan 1999 23:57:35 -0500\n' + '\n' + 'test', + [('', 'goit@lip.com')]) + + def test_addr_ipquad(self): + self.check( + 'To: guido@[132.151.1.21]\n' + '\n' + 'foo', + [('', 'guido@[132.151.1.21]')]) ! test_support.run_unittest(MessageTestCase) Index: test_richcmp.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_richcmp.py,v retrieving revision 1.5 retrieving revision 1.5.6.1 diff -C2 -r1.5 -r1.5.6.1 *** test_richcmp.py 2001/01/19 06:12:17 1.5 --- test_richcmp.py 2001/07/07 22:55:29 1.5.6.1 *************** *** 222,225 **** --- 222,252 ---- if verbose: print "recursion tests ok" + def dicts(): + # Verify that __eq__ and __ne__ work for dicts even if the keys and + # values don't support anything other than __eq__ and __ne__. Complex + # numbers are a fine example of that. + import random + imag1a = {} + for i in range(50): + imag1a[random.randrange(100)*1j] = random.randrange(100)*1j + items = imag1a.items() + random.shuffle(items) + imag1b = {} + for k, v in items: + imag1b[k] = v + imag2 = imag1b.copy() + imag2[k] = v + 1.0 + verify(imag1a == imag1a, "imag1a == imag1a should have worked") + verify(imag1a == imag1b, "imag1a == imag1b should have worked") + verify(imag2 == imag2, "imag2 == imag2 should have worked") + verify(imag1a != imag2, "imag1a != imag2 should have worked") + for op in "<", "<=", ">", ">=": + try: + eval("imag1a %s imag2" % op) + except TypeError: + pass + else: + raise TestFailed("expected TypeError from imag1a %s imag2" % op) + def main(): basic() *************** *** 230,233 **** --- 257,261 ---- misbehavin() recursion() + dicts() main() Index: test_scope.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_scope.py,v retrieving revision 1.14 retrieving revision 1.14.4.1 diff -C2 -r1.14 -r1.14.4.1 *** test_scope.py 2001/04/13 16:51:46 1.14 --- test_scope.py 2001/07/07 22:55:29 1.14.4.1 *************** *** 437,438 **** --- 437,469 ---- verify(d == {'x': 2, 'y': 7, 'w': 6}) + print "19. var is bound and free in class" + + def f(x): + class C: + def m(self): + return x + a = x + return C + + inst = f(3)() + verify(inst.a == inst.m()) + + print "20. interaction with trace function" + + import sys + def tracer(a,b,c): + return tracer + + def adaptgetter(name, klass, getter): + kind, des = getter + if kind == 1: # AV happens when stepping from this line to next + if des == "": + des = "_%s__%s" % (klass.__name__, name) + return lambda obj: getattr(obj, des) + + class TestClass: + pass + + sys.settrace(tracer) + adaptgetter("foo", TestClass, (1, "")) + sys.settrace(None) Index: test_sha.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sha.py,v retrieving revision 1.1 retrieving revision 1.1.12.1 diff -C2 -r1.1 -r1.1.12.1 *** test_sha.py 1999/03/24 19:04:29 1.1 --- test_sha.py 2001/07/07 22:55:29 1.1.12.1 *************** *** 1,28 **** # Testing sha module (NIST's Secure Hash Algorithm) - import sha - # use the three examples from Federal Information Processing Standards # Publication 180-1, Secure Hash Standard, 1995 April 17 # http://www.itl.nist.gov/div897/pubs/fip180-1.htm ! s = [''] * 3 ! d = [''] * 3 ! s[0] = 'abc' ! d[0] = 'a9993e364706816aba3e25717850c26c9cd0d89d' - s[1] = 'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq' - d[1] = '84983e441c3bd26ebaae4aa1f95129e5e54670f1' ! s[2] = 'a' * 1000000 ! d[2] = '34aa973cd4c4daa4f61eeb2bdbad27316534016f' ! ! for i in range(3): ! test = sha.new(s[i]).hexdigest() ! if test == d[i]: ! print "test %d ok" % i ! else: ! print "test %d failed" % i ! print "expected", d[i] ! print "computed", test --- 1,30 ---- # Testing sha module (NIST's Secure Hash Algorithm) # use the three examples from Federal Information Processing Standards # Publication 180-1, Secure Hash Standard, 1995 April 17 # http://www.itl.nist.gov/div897/pubs/fip180-1.htm + + import sha + import test_support + import unittest + + + class SHATestCase(unittest.TestCase): + def check(self, data, digest): + computed = sha.new(data).hexdigest() + self.assert_(computed == digest) + + def test_case_1(self): + self.check("abc", + "a9993e364706816aba3e25717850c26c9cd0d89d") ! def test_case_2(self): ! self.check("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", ! "84983e441c3bd26ebaae4aa1f95129e5e54670f1") ! def test_case_3(self): ! self.check("a" * 1000000, ! "34aa973cd4c4daa4f61eeb2bdbad27316534016f") ! test_support.run_unittest(SHATestCase) Index: test_sre.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sre.py,v retrieving revision 1.24 retrieving revision 1.24.4.1 diff -C2 -r1.24 -r1.24.4.1 *** test_sre.py 2001/03/22 23:48:28 1.24 --- test_sre.py 2001/07/07 22:55:29 1.24.4.1 *************** *** 246,250 **** test("sre.match('(x)*', 50000*'x').span()", (0, 50000), RuntimeError) test("sre.match(r'(x)*y', 50000*'x'+'y').span()", (0, 50001), RuntimeError) ! test("sre.match(r'(x)*?y', 50000*'x'+'y').span()", (0, 50001), RuntimeError) from re_tests import * --- 246,250 ---- test("sre.match('(x)*', 50000*'x').span()", (0, 50000), RuntimeError) test("sre.match(r'(x)*y', 50000*'x'+'y').span()", (0, 50001), RuntimeError) ! test("sre.match(r'(x)*?y', 50000*'x'+'y').span()", (0, 50001)) from re_tests import * Index: test_strop.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_strop.py,v retrieving revision 1.10 retrieving revision 1.10.6.1 diff -C2 -r1.10 -r1.10.6.1 *** test_strop.py 2001/01/17 21:51:36 1.10 --- test_strop.py 2001/07/07 22:55:29 1.10.6.1 *************** *** 1,87 **** ! from test_support import verbose ! import strop, sys - def test(name, input, output, *args): - if verbose: - print 'string.%s%s =? %s... ' % (name, (input,) + args, output), - f = getattr(strop, name) - try: - value = apply(f, (input,) + args) - except: - value = sys.exc_type - if value != output: - if verbose: - print 'no' - print f, `input`, `output`, `value` - else: - if verbose: - print 'yes' - - test('atoi', " 1 ", 1) - test('atoi', " 1x", ValueError) - test('atoi', " x1 ", ValueError) - test('atol', " 1 ", 1L) - test('atol', " 1x ", ValueError) - test('atol', " x1 ", ValueError) - test('atof', " 1 ", 1.0) - test('atof', " 1x ", ValueError) - test('atof', " x1 ", ValueError) - - test('capitalize', ' hello ', ' hello ') - test('capitalize', 'hello ', 'Hello ') - test('find', 'abcdefghiabc', 0, 'abc') - test('find', 'abcdefghiabc', 9, 'abc', 1) - test('find', 'abcdefghiabc', -1, 'def', 4) - test('rfind', 'abcdefghiabc', 9, 'abc') - test('lower', 'HeLLo', 'hello') - test('upper', 'HeLLo', 'HELLO') transtable = '\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`xyzdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377' - test('maketrans', 'abc', transtable, 'xyz') - test('maketrans', 'abc', ValueError, 'xyzq') ! test('split', 'this is the split function', ! ['this', 'is', 'the', 'split', 'function']) ! test('split', 'a|b|c|d', ['a', 'b', 'c', 'd'], '|') ! test('split', 'a|b|c|d', ['a', 'b', 'c|d'], '|', 2) ! test('split', 'a b c d', ['a', 'b c d'], None, 1) ! test('split', 'a b c d', ['a', 'b', 'c d'], None, 2) ! test('split', 'a b c d', ['a', 'b', 'c', 'd'], None, 3) ! test('split', 'a b c d', ['a', 'b', 'c', 'd'], None, 4) ! test('split', 'a b c d', ['a', 'b', 'c', 'd'], None, 0) ! test('split', 'a b c d', ['a', 'b', 'c d'], None, 2) ! ! # join now works with any sequence type class Sequence: def __init__(self): self.seq = 'wxyz' def __len__(self): return len(self.seq) def __getitem__(self, i): return self.seq[i] ! test('join', ['a', 'b', 'c', 'd'], 'a b c d') ! test('join', ('a', 'b', 'c', 'd'), 'abcd', '') ! test('join', Sequence(), 'w x y z') ! ! # try a few long ones ! print strop.join(['x' * 100] * 100, ':') ! print strop.join(('x' * 100,) * 100, ':') ! ! test('strip', ' hello ', 'hello') ! test('lstrip', ' hello ', 'hello ') ! test('rstrip', ' hello ', ' hello') ! ! test('swapcase', 'HeLLo cOmpUteRs', 'hEllO CoMPuTErS') ! test('translate', 'xyzabcdef', 'xyzxyz', transtable, 'def') ! ! test('replace', 'one!two!three!', 'one@two!three!', '!', '@', 1) ! test('replace', 'one!two!three!', 'one@two@three!', '!', '@', 2) ! test('replace', 'one!two!three!', 'one@two@three@', '!', '@', 3) ! test('replace', 'one!two!three!', 'one@two@three@', '!', '@', 4) ! test('replace', 'one!two!three!', 'one@two@three@', '!', '@', 0) ! test('replace', 'one!two!three!', 'one@two@three@', '!', '@') ! test('replace', 'one!two!three!', 'one!two!three!', 'x', '@') ! test('replace', 'one!two!three!', 'one!two!three!', 'x', '@', 2) ! ! strop.whitespace ! strop.lowercase ! strop.uppercase --- 1,128 ---- ! import warnings ! warnings.filterwarnings("ignore", "", DeprecationWarning, __name__) ! warnings.filterwarnings("ignore", "", DeprecationWarning, "unittest") ! import strop ! import test_support ! import unittest ! ! ! class StropFunctionTestCase(unittest.TestCase): ! ! def test_atoi(self): ! self.assert_(strop.atoi(" 1 ") == 1) ! self.assertRaises(ValueError, strop.atoi, " 1x") ! self.assertRaises(ValueError, strop.atoi, " x1 ") ! ! def test_atol(self): ! self.assert_(strop.atol(" 1 ") == 1L) ! self.assertRaises(ValueError, strop.atol, " 1x") ! self.assertRaises(ValueError, strop.atol, " x1 ") ! ! def test_atof(self): ! self.assert_(strop.atof(" 1 ") == 1.0) ! self.assertRaises(ValueError, strop.atof, " 1x") ! self.assertRaises(ValueError, strop.atof, " x1 ") ! ! def test_capitalize(self): ! self.assert_(strop.capitalize(" hello ") == " hello ") ! self.assert_(strop.capitalize("hello ") == "Hello ") ! ! def test_find(self): ! self.assert_(strop.find("abcdefghiabc", "abc") == 0) ! self.assert_(strop.find("abcdefghiabc", "abc", 1) == 9) ! self.assert_(strop.find("abcdefghiabc", "def", 4) == -1) ! ! def test_rfind(self): ! self.assert_(strop.rfind("abcdefghiabc", "abc") == 9) ! ! def test_lower(self): ! self.assert_(strop.lower("HeLLo") == "hello") ! ! def test_upper(self): ! self.assert_(strop.upper("HeLLo") == "HELLO") ! ! def test_swapcase(self): ! self.assert_(strop.swapcase("HeLLo cOmpUteRs") == "hEllO CoMPuTErS") ! ! def test_strip(self): ! self.assert_(strop.strip(" \t\n hello \t\n ") == "hello") ! ! def test_lstrip(self): ! self.assert_(strop.lstrip(" \t\n hello \t\n ") == "hello \t\n ") ! ! def test_rstrip(self): ! self.assert_(strop.rstrip(" \t\n hello \t\n ") == " \t\n hello") ! ! def test_replace(self): ! replace = strop.replace ! self.assert_(replace("one!two!three!", '!', '@', 1) ! == "one@two!three!") ! self.assert_(replace("one!two!three!", '!', '@', 2) ! == "one@two@three!") ! self.assert_(replace("one!two!three!", '!', '@', 3) ! == "one@two@three@") ! self.assert_(replace("one!two!three!", '!', '@', 4) ! == "one@two@three@") ! ! # CAUTION: a replace count of 0 means infinity only to strop, ! # not to the string .replace() method or to the ! # string.replace() function. ! ! self.assert_(replace("one!two!three!", '!', '@', 0) ! == "one@two@three@") ! self.assert_(replace("one!two!three!", '!', '@') ! == "one@two@three@") ! self.assert_(replace("one!two!three!", 'x', '@') ! == "one!two!three!") ! self.assert_(replace("one!two!three!", 'x', '@', 2) ! == "one!two!three!") ! ! def test_split(self): ! split = strop.split ! self.assert_(split("this is the split function") ! == ['this', 'is', 'the', 'split', 'function']) ! self.assert_(split("a|b|c|d", '|') == ['a', 'b', 'c', 'd']) ! self.assert_(split("a|b|c|d", '|', 2) == ['a', 'b', 'c|d']) ! self.assert_(split("a b c d", None, 1) == ['a', 'b c d']) ! self.assert_(split("a b c d", None, 2) == ['a', 'b', 'c d']) ! self.assert_(split("a b c d", None, 3) == ['a', 'b', 'c', 'd']) ! self.assert_(split("a b c d", None, 4) == ['a', 'b', 'c', 'd']) ! self.assert_(split("a b c d", None, 0) == ['a', 'b', 'c', 'd']) ! self.assert_(split("a b c d", None, 2) == ['a', 'b', 'c d']) ! ! def test_join(self): ! self.assert_(strop.join(['a', 'b', 'c', 'd']) == 'a b c d') ! self.assert_(strop.join(('a', 'b', 'c', 'd'), '') == 'abcd') ! self.assert_(strop.join(Sequence()) == 'w x y z') ! ! # try a few long ones ! self.assert_(strop.join(['x' * 100] * 100, ':') ! == (('x' * 100) + ":") * 99 + "x" * 100) ! self.assert_(strop.join(('x' * 100,) * 100, ':') ! == (('x' * 100) + ":") * 99 + "x" * 100) ! ! def test_maketrans(self): ! self.assert_(strop.maketrans("abc", "xyz") == transtable) ! self.assertRaises(ValueError, strop.maketrans, "abc", "xyzq") ! ! def test_translate(self): ! self.assert_(strop.translate("xyzabcdef", transtable, "def") ! == "xyzxyz") ! ! def test_data_attributes(self): ! strop.lowercase ! strop.uppercase ! strop.whitespace transtable = '\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`xyzdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377' ! # join() now works with any sequence type. class Sequence: def __init__(self): self.seq = 'wxyz' def __len__(self): return len(self.seq) def __getitem__(self, i): return self.seq[i] + ! test_support.run_unittest(StropFunctionTestCase) Index: test_struct.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_struct.py,v retrieving revision 1.7 retrieving revision 1.7.6.1 diff -C2 -r1.7 -r1.7.6.1 *** test_struct.py 2000/12/12 23:11:42 1.7 --- test_struct.py 2001/07/07 22:55:29 1.7.6.1 *************** *** 1,6 **** ! from test_support import TestFailed, verbose import struct ## import pdb def simple_err(func, *args): try: --- 1,23 ---- ! from test_support import TestFailed, verbose, verify import struct ## import pdb + import sys + ISBIGENDIAN = sys.byteorder == "big" + del sys + verify((struct.pack('=i', 1)[0] == chr(0)) == ISBIGENDIAN, + "bigendian determination appears wrong") + + def string_reverse(s): + chars = list(s) + chars.reverse() + return "".join(chars) + + def bigendian_to_native(value): + if ISBIGENDIAN: + return value + else: + return string_reverse(value) + def simple_err(func, *args): try: *************** *** 12,18 **** func.__name__, args) ## pdb.set_trace() - simple_err(struct.calcsize, 'Q') sz = struct.calcsize('i') if sz * 3 != struct.calcsize('iii'): --- 29,46 ---- func.__name__, args) ## pdb.set_trace() + + def any_err(func, *args): + try: + apply(func, args) + except (struct.error, OverflowError, TypeError): + pass + else: + raise TestFailed, "%s%s did not raise error" % ( + func.__name__, args) + ## pdb.set_trace() + simple_err(struct.calcsize, 'Z') + sz = struct.calcsize('i') if sz * 3 != struct.calcsize('iii'): *************** *** 94,111 **** ] - def badpack(fmt, arg, got, exp): - return - - def badunpack(fmt, arg, got, exp): - return "unpack(%s, %s) -> (%s,) # expected (%s,)" % ( - `fmt`, `arg`, `got`, `exp`) - - isbigendian = struct.pack('=h', 1) == '\0\1' - for fmt, arg, big, lil, asy in tests: if verbose: print `fmt`, `arg`, `big`, `lil` for (xfmt, exp) in [('>'+fmt, big), ('!'+fmt, big), ('<'+fmt, lil), ! ('='+fmt, isbigendian and big or lil)]: res = struct.pack(xfmt, arg) if res != exp: --- 122,130 ---- ] for fmt, arg, big, lil, asy in tests: if verbose: print `fmt`, `arg`, `big`, `lil` for (xfmt, exp) in [('>'+fmt, big), ('!'+fmt, big), ('<'+fmt, lil), ! ('='+fmt, ISBIGENDIAN and big or lil)]: res = struct.pack(xfmt, arg) if res != exp: *************** *** 120,121 **** --- 139,370 ---- raise TestFailed, "unpack(%s, %s) -> (%s,) # expected (%s,)" % ( `fmt`, `res`, `rev`, `arg`) + + ########################################################################### + # Simple native q/Q tests. + + has_native_qQ = 1 + try: + struct.pack("q", 5) + except struct.error: + has_native_qQ = 0 + + if verbose: + print "Platform has native q/Q?", has_native_qQ and "Yes." or "No." + + any_err(struct.pack, "Q", -1) # can't pack -1 as unsigned regardless + simple_err(struct.pack, "q", "a") # can't pack string as 'q' regardless + simple_err(struct.pack, "Q", "a") # ditto, but 'Q' + + def test_native_qQ(): + bytes = struct.calcsize('q') + # The expected values here are in big-endian format, primarily because + # I'm on a little-endian machine and so this is the clearest way (for + # me) to force the code to get exercised. + for format, input, expected in ( + ('q', -1, '\xff' * bytes), + ('q', 0, '\x00' * bytes), + ('Q', 0, '\x00' * bytes), + ('q', 1L, '\x00' * (bytes-1) + '\x01'), + ('Q', (1L << (8*bytes))-1, '\xff' * bytes), + ('q', (1L << (8*bytes-1))-1, '\x7f' + '\xff' * (bytes - 1))): + got = struct.pack(format, input) + native_expected = bigendian_to_native(expected) + verify(got == native_expected, + "%r-pack of %r gave %r, not %r" % + (format, input, got, native_expected)) + retrieved = struct.unpack(format, got)[0] + verify(retrieved == input, + "%r-unpack of %r gave %r, not %r" % + (format, got, retrieved, input)) + + if has_native_qQ: + test_native_qQ() + + ########################################################################### + # Standard integer tests (bBhHiIlLqQ). + + import binascii + + class IntTester: + + # XXX Most std integer modes fail to test for out-of-range. + # The "i" and "l" codes appear to range-check OK on 32-bit boxes, but + # fail to check correctly on some 64-bit ones (Tru64 Unix + Compaq C + # reported by Mark Favas). + BUGGY_RANGE_CHECK = "bBhHiIlL" + + def __init__(self, formatpair, bytesize): + assert len(formatpair) == 2 + self.formatpair = formatpair + for direction in "<>!=": + for code in formatpair: + format = direction + code + verify(struct.calcsize(format) == bytesize) + self.bytesize = bytesize + self.bitsize = bytesize * 8 + self.signed_code, self.unsigned_code = formatpair + self.unsigned_min = 0 + self.unsigned_max = 2L**self.bitsize - 1 + self.signed_min = -(2L**(self.bitsize-1)) + self.signed_max = 2L**(self.bitsize-1) - 1 + + def test_one(self, x, pack=struct.pack, + unpack=struct.unpack, + unhexlify=binascii.unhexlify): + if verbose: + print "trying std", self.formatpair, "on", x, "==", hex(x) + + # Try signed. + code = self.signed_code + if self.signed_min <= x <= self.signed_max: + # Try big-endian. + expected = long(x) + if x < 0: + expected += 1L << self.bitsize + assert expected > 0 + expected = hex(expected)[2:-1] # chop "0x" and trailing 'L' + if len(expected) & 1: + expected = "0" + expected + expected = unhexlify(expected) + expected = "\x00" * (self.bytesize - len(expected)) + expected + + # Pack work? + format = ">" + code + got = pack(format, x) + verify(got == expected, + "'%s'-pack of %r gave %r, not %r" % + (format, x, got, expected)) + + # Unpack work? + retrieved = unpack(format, got)[0] + verify(x == retrieved, + "'%s'-unpack of %r gave %r, not %r" % + (format, got, retrieved, x)) + + # Adding any byte should cause a "too big" error. + any_err(unpack, format, '\x01' + got) + + # Try little-endian. + format = "<" + code + expected = string_reverse(expected) + + # Pack work? + got = pack(format, x) + verify(got == expected, + "'%s'-pack of %r gave %r, not %r" % + (format, x, got, expected)) + + # Unpack work? + retrieved = unpack(format, got)[0] + verify(x == retrieved, + "'%s'-unpack of %r gave %r, not %r" % + (format, got, retrieved, x)) + + # Adding any byte should cause a "too big" error. + any_err(unpack, format, '\x01' + got) + + else: + # x is out of range -- verify pack realizes that. + if code in self.BUGGY_RANGE_CHECK: + if verbose: + print "Skipping buggy range check for code", code + else: + any_err(pack, ">" + code, x) + any_err(pack, "<" + code, x) + + # Much the same for unsigned. + code = self.unsigned_code + if self.unsigned_min <= x <= self.unsigned_max: + # Try big-endian. + format = ">" + code + expected = long(x) + expected = hex(expected)[2:-1] # chop "0x" and trailing 'L' + if len(expected) & 1: + expected = "0" + expected + expected = unhexlify(expected) + expected = "\x00" * (self.bytesize - len(expected)) + expected + + # Pack work? + got = pack(format, x) + verify(got == expected, + "'%s'-pack of %r gave %r, not %r" % + (format, x, got, expected)) + + # Unpack work? + retrieved = unpack(format, got)[0] + verify(x == retrieved, + "'%s'-unpack of %r gave %r, not %r" % + (format, got, retrieved, x)) + + # Adding any byte should cause a "too big" error. + any_err(unpack, format, '\x01' + got) + + # Try little-endian. + format = "<" + code + expected = string_reverse(expected) + + # Pack work? + got = pack(format, x) + verify(got == expected, + "'%s'-pack of %r gave %r, not %r" % + (format, x, got, expected)) + + # Unpack work? + retrieved = unpack(format, got)[0] + verify(x == retrieved, + "'%s'-unpack of %r gave %r, not %r" % + (format, got, retrieved, x)) + + # Adding any byte should cause a "too big" error. + any_err(unpack, format, '\x01' + got) + + else: + # x is out of range -- verify pack realizes that. + if code in self.BUGGY_RANGE_CHECK: + if verbose: + print "Skipping buggy range check for code", code + else: + any_err(pack, ">" + code, x) + any_err(pack, "<" + code, x) + + def run(self): + from random import randrange + + # Create all interesting powers of 2. + values = [] + for exp in range(self.bitsize + 3): + values.append(1L << exp) + + # Add some random values. + for i in range(self.bitsize): + val = 0L + for j in range(self.bytesize): + val = (val << 8) | randrange(256) + values.append(val) + + # Try all those, and their negations, and +-1 from them. Note + # that this tests all power-of-2 boundaries in range, and a few out + # of range, plus +-(2**n +- 1). + for base in values: + for val in -base, base: + for incr in -1, 0, 1: + x = val + incr + try: + x = int(x) + except OverflowError: + pass + self.test_one(x) + + # Some error cases. + for direction in "<>": + for code in self.formatpair: + for badobject in "a string", 3+42j, randrange: + any_err(struct.pack, direction + code, badobject) + + for args in [("bB", 1), + ("hH", 2), + ("iI", 4), + ("lL", 4), + ("qQ", 8)]: + t = IntTester(*args) + t.run() Index: test_time.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_time.py,v retrieving revision 1.6 retrieving revision 1.6.6.1 diff -C2 -r1.6 -r1.6.6.1 *** test_time.py 2000/12/12 23:11:42 1.6 --- test_time.py 2001/07/07 22:55:29 1.6.6.1 *************** *** 1,39 **** import time ! time.altzone ! time.clock() ! t = time.time() ! time.asctime(time.gmtime(t)) ! if time.ctime(t) != time.asctime(time.localtime(t)): ! print 'time.ctime(t) != time.asctime(time.localtime(t))' ! ! time.daylight ! if long(time.mktime(time.localtime(t))) != long(t): ! print 'time.mktime(time.localtime(t)) != t' ! ! time.sleep(1.2) ! tt = time.gmtime(t) ! for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'H', 'I', ! 'j', 'm', 'M', 'p', 'S', ! 'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'): ! format = ' %' + directive ! try: ! time.strftime(format, tt) ! except ValueError: ! print 'conversion specifier:', format, ' failed.' ! ! time.timezone ! time.tzname ! ! # expected errors ! try: ! time.asctime(0) ! except TypeError: ! pass ! ! try: ! time.mktime((999999, 999999, 999999, 999999, ! 999999, 999999, 999999, 999999, ! 999999)) ! except OverflowError: ! pass --- 1,51 ---- + import test_support import time + import unittest ! ! class TimeTestCase(unittest.TestCase): ! ! def setUp(self): ! self.t = time.time() ! ! def test_data_attributes(self): ! time.altzone ! time.daylight ! time.timezone ! time.tzname ! ! def test_clock(self): ! time.clock() ! ! def test_conversions(self): ! self.assert_(time.ctime(self.t) ! == time.asctime(time.localtime(self.t))) ! self.assert_(long(time.mktime(time.localtime(self.t))) ! == long(self.t)) ! ! def test_sleep(self): ! time.sleep(1.2) ! ! def test_strftime(self): ! tt = time.gmtime(self.t) ! for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'H', 'I', ! 'j', 'm', 'M', 'p', 'S', ! 'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'): ! format = ' %' + directive ! try: ! time.strftime(format, tt) ! except ValueError: ! self.fail('conversion specifier: %r failed.' % format) ! ! def test_asctime(self): ! time.asctime(time.gmtime(self.t)) ! self.assertRaises(TypeError, time.asctime, 0) ! ! def test_mktime(self): ! self.assertRaises(OverflowError, ! time.mktime, (999999, 999999, 999999, 999999, ! 999999, 999999, 999999, 999999, ! 999999)) ! ! ! test_support.run_unittest(TimeTestCase) Index: test_types.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_types.py,v retrieving revision 1.20 retrieving revision 1.20.2.1 diff -C2 -r1.20 -r1.20.2.1 *** test_types.py 2001/04/20 16:50:40 1.20 --- test_types.py 2001/07/07 22:55:29 1.20.2.1 *************** *** 240,250 **** --- 240,320 ---- del d['b'] if d != {'a': 4, 'c': 3}: raise TestFailed, 'dict item deletion' + # dict.clear() d = {1:1, 2:2, 3:3} d.clear() if d != {}: raise TestFailed, 'dict clear' + # dict.update() d.update({1:100}) d.update({2:20}) d.update({1:1, 2:2, 3:3}) if d != {1:1, 2:2, 3:3}: raise TestFailed, 'dict update' + d.clear() + try: d.update(None) + except AttributeError: pass + else: raise TestFailed, 'dict.update(None), AttributeError expected' + class SimpleUserDict: + def __init__(self): + self.d = {1:1, 2:2, 3:3} + def keys(self): + return self.d.keys() + def __getitem__(self, i): + return self.d[i] + d.update(SimpleUserDict()) + if d != {1:1, 2:2, 3:3}: raise TestFailed, 'dict.update(instance)' + d.clear() + class FailingUserDict: + def keys(self): + raise ValueError + try: d.update(FailingUserDict()) + except ValueError: pass + else: raise TestFailed, 'dict.keys() expected ValueError' + class FailingUserDict: + def keys(self): + class BogonIter: + def __iter__(self): + raise ValueError + return BogonIter() + try: d.update(FailingUserDict()) + except ValueError: pass + else: raise TestFailed, 'iter(dict.keys()) expected ValueError' + class FailingUserDict: + def keys(self): + class BogonIter: + def __init__(self): + self.i = 1 + def __iter__(self): + return self + def next(self): + if self.i: + self.i = 0 + return 'a' + raise ValueError + return BogonIter() + def __getitem__(self, key): + return key + try: d.update(FailingUserDict()) + except ValueError: pass + else: raise TestFailed, 'iter(dict.keys()).next() expected ValueError' + class FailingUserDict: + def keys(self): + class BogonIter: + def __init__(self): + self.i = ord('a') + def __iter__(self): + return self + def next(self): + if self.i <= ord('z'): + rtn = chr(self.i) + self.i += 1 + return rtn + raise StopIteration + return BogonIter() + def __getitem__(self, key): + raise ValueError + try: d.update(FailingUserDict()) + except ValueError: pass + else: raise TestFailed, 'dict.update(), __getitem__ expected ValueError' + # dict.copy() + d = {1:1, 2:2, 3:3} if d.copy() != {1:1, 2:2, 3:3}: raise TestFailed, 'dict copy' if {}.copy() != {}: raise TestFailed, 'empty dict copy' Index: test_weakref.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_weakref.py,v retrieving revision 1.7 retrieving revision 1.7.4.1 diff -C2 -r1.7 -r1.7.4.1 *** test_weakref.py 2001/04/16 17:37:27 1.7 --- test_weakref.py 2001/07/07 22:55:29 1.7.4.1 *************** *** 230,238 **** def test_weak_values(self): ! dict = weakref.WeakValueDictionary() ! objects = map(Object, range(self.COUNT)) ! for o in objects: ! dict[o.arg] = o ! for o in objects: self.assert_(weakref.getweakrefcount(o) == 1, --- 230,237 ---- def test_weak_values(self): ! # ! # This exercises d.copy(), d.items(), d[], del d[], len(d). ! # ! dict, objects = self.make_weak_valued_dict() for o in objects: self.assert_(weakref.getweakrefcount(o) == 1, *************** *** 256,265 **** def test_weak_keys(self): ! dict = weakref.WeakKeyDictionary() ! objects = map(Object, range(self.COUNT)) for o in objects: - dict[o] = o.arg - - for o in objects: self.assert_(weakref.getweakrefcount(o) == 1, "wrong number of weak references to %r!" % o) --- 255,264 ---- def test_weak_keys(self): ! # ! # This exercises d.copy(), d.items(), d[] = v, d[], del d[], ! # len(d). ! # ! dict, objects = self.make_weak_keyed_dict() for o in objects: self.assert_(weakref.getweakrefcount(o) == 1, "wrong number of weak references to %r!" % o) *************** *** 281,285 **** --- 280,386 ---- "deleting the keys did not clear the dictionary") + def test_weak_keyed_iters(self): + dict, objects = self.make_weak_keyed_dict() + self.check_iters(dict) + + def test_weak_valued_iters(self): + dict, objects = self.make_weak_valued_dict() + self.check_iters(dict) + + def check_iters(self, dict): + # item iterator: + items = dict.items() + for item in dict.iteritems(): + items.remove(item) + self.assert_(len(items) == 0, "iteritems() did not touch all items") + + # key iterator, via __iter__(): + keys = dict.keys() + for k in dict: + keys.remove(k) + self.assert_(len(keys) == 0, "__iter__() did not touch all keys") + + # key iterator, via iterkeys(): + keys = dict.keys() + for k in dict.iterkeys(): + keys.remove(k) + self.assert_(len(keys) == 0, "iterkeys() did not touch all keys") + + # value iterator: + values = dict.values() + for v in dict.itervalues(): + values.remove(v) + self.assert_(len(values) == 0, "itervalues() did not touch all values") + + def make_weak_keyed_dict(self): + dict = weakref.WeakKeyDictionary() + objects = map(Object, range(self.COUNT)) + for o in objects: + dict[o] = o.arg + return dict, objects + + def make_weak_valued_dict(self): + dict = weakref.WeakValueDictionary() + objects = map(Object, range(self.COUNT)) + for o in objects: + dict[o.arg] = o + return dict, objects + + def check_popitem(self, klass, key1, value1, key2, value2): + weakdict = klass() + weakdict[key1] = value1 + weakdict[key2] = value2 + self.assert_(len(weakdict) == 2) + k, v = weakdict.popitem() + self.assert_(len(weakdict) == 1) + if k is key1: + self.assert_(v is value1) + else: + self.assert_(v is value2) + k, v = weakdict.popitem() + self.assert_(len(weakdict) == 0) + if k is key1: + self.assert_(v is value1) + else: + self.assert_(v is value2) + + def test_weak_valued_dict_popitem(self): + self.check_popitem(weakref.WeakValueDictionary, + "key1", C(), "key2", C()) + + def test_weak_keyed_dict_popitem(self): + self.check_popitem(weakref.WeakKeyDictionary, + C(), "value 1", C(), "value 2") + + def check_setdefault(self, klass, key, value1, value2): + self.assert_(value1 is not value2, + "invalid test" + " -- value parameters must be distinct objects") + weakdict = klass() + o = weakdict.setdefault(key, value1) + self.assert_(o is value1) + self.assert_(weakdict.has_key(key)) + self.assert_(weakdict.get(key) is value1) + self.assert_(weakdict[key] is value1) + + o = weakdict.setdefault(key, value2) + self.assert_(o is value1) + self.assert_(weakdict.has_key(key)) + self.assert_(weakdict.get(key) is value1) + self.assert_(weakdict[key] is value1) + + def test_weak_valued_dict_setdefault(self): + self.check_setdefault(weakref.WeakValueDictionary, + "key", C(), C()) + + def test_weak_keyed_dict_setdefault(self): + self.check_setdefault(weakref.WeakKeyDictionary, + C(), "value 1", "value 2") + def check_update(self, klass, dict): + # + # This exercises d.update(), len(d), d.keys(), d.has_key(), + # d.get(), d[]. + # weakdict = klass() weakdict.update(dict) Index: test_xmllib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_xmllib.py,v retrieving revision 1.4 retrieving revision 1.4.6.1 diff -C2 -r1.4 -r1.4.6.1 *** test_xmllib.py 2001/01/17 21:51:36 1.4 --- test_xmllib.py 2001/07/07 22:55:29 1.4.6.1 *************** *** 3,12 **** ''' - from test_support import verbose - testdoc = """\ --- 3,11 ---- ''' testdoc = """\ + *************** *** 15,25 **** """ import xmllib ! if verbose: ! parser = xmllib.TestXMLParser() ! else: ! parser = xmllib.XMLParser() ! ! for c in testdoc: ! parser.feed(c) ! parser.close() --- 14,30 ---- """ + import test_support + import unittest import xmllib ! ! ! class XMLParserTestCase(unittest.TestCase): ! ! def test_simple(self): ! parser = xmllib.XMLParser() ! for c in testdoc: ! parser.feed(c) ! parser.close() ! ! ! test_support.run_unittest(XMLParserTestCase) From tim_one@users.sourceforge.net Sun Jul 8 02:39:01 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 18:39:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.1.2.30,1.1.2.31 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv24943/descr/dist/src/Lib/test Modified Files: Tag: descr-branch test_descr.py Log Message: Fixed two shallow errors in test_descr.py. This leaves us with the first "real error" due to the merge (a memory fault; see PLAN.txt). Explained the test_generators.py failure; generators work fine; it's a change in the way errors get reported when attempting to set an attribute on an object that doesn't have a setattr slot; see PLAN.txt. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_descr.py,v retrieving revision 1.1.2.30 retrieving revision 1.1.2.31 diff -C2 -r1.1.2.30 -r1.1.2.31 *** test_descr.py 2001/07/06 18:53:47 1.1.2.30 --- test_descr.py 2001/07/08 01:38:59 1.1.2.31 *************** *** 120,124 **** verify(l == l1) testunop({1:2,3:4}, 2, "len(a)", "__len__") ! testunop({1:2,3:4}, "{3: 4, 1: 2}", "repr(a)", "__repr__") testset2op({1:2,3:4}, 2, 3, {1:2,2:3,3:4}, "a[b]=c", "__setitem__") --- 120,124 ---- verify(l == l1) testunop({1:2,3:4}, 2, "len(a)", "__len__") ! testunop({1:2,3:4}, "{1: 2, 3: 4}", "repr(a)", "__repr__") testset2op({1:2,3:4}, 2, 3, {1:2,2:3,3:4}, "a[b]=c", "__setitem__") *************** *** 281,285 **** verify(l == l1) testunop(spamdict({1:2,3:4}), 2, "len(a)", "__len__") ! testunop(spamdict({1:2,3:4}), "{3: 4, 1: 2}", "repr(a)", "__repr__") testset2op(spamdict({1:2,3:4}), 2, 3, spamdict({1:2,2:3,3:4}), "a[b]=c", "__setitem__") --- 281,285 ---- verify(l == l1) testunop(spamdict({1:2,3:4}), 2, "len(a)", "__len__") ! testunop(spamdict({1:2,3:4}), "{1: 2, 3: 4}", "repr(a)", "__repr__") testset2op(spamdict({1:2,3:4}), 2, 3, spamdict({1:2,2:3,3:4}), "a[b]=c", "__setitem__") From tim_one@users.sourceforge.net Sun Jul 8 02:39:01 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 18:39:01 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.1.2.17,1.1.2.18 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv24943/descr/dist/src Modified Files: Tag: descr-branch PLAN.txt Log Message: Fixed two shallow errors in test_descr.py. This leaves us with the first "real error" due to the merge (a memory fault; see PLAN.txt). Explained the test_generators.py failure; generators work fine; it's a change in the way errors get reported when attempting to set an attribute on an object that doesn't have a setattr slot; see PLAN.txt. Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Attic/PLAN.txt,v retrieving revision 1.1.2.17 retrieving revision 1.1.2.18 diff -C2 -r1.1.2.17 -r1.1.2.18 *** PLAN.txt 2001/07/07 22:55:27 1.1.2.17 --- PLAN.txt 2001/07/08 01:38:59 1.1.2.18 *************** *** 263,268 **** --- 263,283 ---- + New std test failures (again on Windows): + test_descr.py + Two shallow test errors were fixed (relying on exact order of + dict traversal -- for that matter, it still does, but now the + correct exact order ). + Now dies with a memory error right after + Testing Python subclass of dict... + I expect this is a merge glitch that slipped past me. + test_generators.py + All of the computational tests pass. + It's failing because attempting to assign to the .gi_running attr + of a generator-iterator object was expected to raise + TypeError: object has read-only attributes + but is now raising + AttributeError: 'generator' object has no attribute 'gi_running' + How generator-iterators define attributes should be reworked. + If some non-Windows test has an expected-output file in descr-branch From tim_one@users.sourceforge.net Sun Jul 8 03:07:11 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 19:07:11 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.1.2.18,1.1.2.19 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv30509/descr/dist/src Modified Files: Tag: descr-branch PLAN.txt Log Message: Added editorial about merge frequency. Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Attic/PLAN.txt,v retrieving revision 1.1.2.18 retrieving revision 1.1.2.19 diff -C2 -r1.1.2.18 -r1.1.2.19 *** PLAN.txt 2001/07/08 01:38:59 1.1.2.18 --- PLAN.txt 2001/07/08 02:07:09 1.1.2.19 *************** *** 197,200 **** --- 197,214 ---- later. + Note from Tim: We should never again wait until literally 100s of files + are out of synch. I don't care how often I need to do this, provided only + that it's a tractable task each time. Once per week sounds like a good + idea. As is, even the trunk change to rangeobject.c created more than its + proper share of merge headaches, because it confused all the other reasons + include file merges were getting conflicts (the more changes there are, the + worse diff does; indeed, I came up with the ndiff algorithm in the 80s + precisely because the source-control diff program Cray used at the time + produced minimal but *senseless* diffs, thus creating artificial conflicts; + paying unbounded attention to context does a much better job of putting + changes where they make semantic sense too; but we're stuck with Unix diff + here, and it isn't robust in this sense; if we don't keep its job simple, + it will make my job hell). + Done: To undo or rename before final merge: Modules/spam.c has worked its From tim_one@users.sourceforge.net Sun Jul 8 05:30:31 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 21:30:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.63,2.16.8.64 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv20230/descr/dist/src/Objects Modified Files: Tag: descr-branch typeobject.c Log Message: test_generators.py Passes again. ceval.c Redid genobject type object to use PyObject_GenericGetAttr; got rid of genobject's custom getattr routine. typeobject.c Improved the docstring wrapperbase tab_next uses for .next(). PLAN.txt Added note about major (IMO) lost dir() functionality (one of the reasons test_generators.py failed is that dir(object) usually returns an empty list now). Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.63 retrieving revision 2.16.8.64 diff -C2 -r2.16.8.63 -r2.16.8.64 *** typeobject.c 2001/07/07 22:55:30 2.16.8.63 --- typeobject.c 2001/07/08 04:30:29 2.16.8.64 *************** *** 1734,1738 **** static struct wrapperbase tab_next[] = { ! {"next", (wrapperfunc)wrap_next, "x.next() -> next value"}, {0} }; --- 1734,1739 ---- static struct wrapperbase tab_next[] = { ! {"next", (wrapperfunc)wrap_next, ! "x.next() -> get the next value, or raise StopIteration"}, {0} }; From tim_one@users.sourceforge.net Sun Jul 8 05:30:31 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 21:30:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,1.17.2.1,1.17.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv20230/descr/dist/src/Lib/test Modified Files: Tag: descr-branch test_generators.py Log Message: test_generators.py Passes again. ceval.c Redid genobject type object to use PyObject_GenericGetAttr; got rid of genobject's custom getattr routine. typeobject.c Improved the docstring wrapperbase tab_next uses for .next(). PLAN.txt Added note about major (IMO) lost dir() functionality (one of the reasons test_generators.py failed is that dir(object) usually returns an empty list now). Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.17.2.1 retrieving revision 1.17.2.2 diff -C2 -r1.17.2.1 -r1.17.2.2 *** test_generators.py 2001/07/07 22:55:28 1.17.2.1 --- test_generators.py 2001/07/08 04:30:29 1.17.2.2 *************** *** 381,388 **** >>> type(i) >>> dir(i) ['gi_frame', 'gi_running', 'next'] >>> print i.next.__doc__ ! next() -- get the next value, or raise StopIteration >>> iter(i) is i 1 --- 381,394 ---- >>> type(i) + + XXX dir(object) *generally* doesn't return useful stuff in descr-branch. >>> dir(i) + [] + + Was hoping to see this instead: ['gi_frame', 'gi_running', 'next'] + >>> print i.next.__doc__ ! x.next() -> get the next value, or raise StopIteration >>> iter(i) is i 1 *************** *** 400,404 **** Traceback (most recent call last): ... ! TypeError: object has read-only attributes >>> def g(): ... yield me.gi_running --- 406,410 ---- Traceback (most recent call last): ... ! TypeError: readonly attribute >>> def g(): ... yield me.gi_running From tim_one@users.sourceforge.net Sun Jul 8 05:30:31 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 21:30:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.241.2.5,2.241.2.6 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv20230/descr/dist/src/Python Modified Files: Tag: descr-branch ceval.c Log Message: test_generators.py Passes again. ceval.c Redid genobject type object to use PyObject_GenericGetAttr; got rid of genobject's custom getattr routine. typeobject.c Improved the docstring wrapperbase tab_next uses for .next(). PLAN.txt Added note about major (IMO) lost dir() functionality (one of the reasons test_generators.py failed is that dir(object) usually returns an empty list now). Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.241.2.5 retrieving revision 2.241.2.6 diff -C2 -r2.241.2.5 -r2.241.2.6 *** ceval.c 2001/07/07 22:55:30 2.241.2.5 --- ceval.c 2001/07/08 04:30:29 2.241.2.6 *************** *** 14,17 **** --- 14,18 ---- #include "eval.h" #include "opcode.h" + #include "structmember.h" #ifdef macintosh *************** *** 194,226 **** }; ! static PyObject * ! gen_getattr(genobject *gen, char *name) ! { ! PyObject *result; ! ! if (strcmp(name, "gi_frame") == 0) { ! result = (PyObject *)gen->gi_frame; ! assert(result != NULL); ! Py_INCREF(result); ! } ! else if (strcmp(name, "gi_running") == 0) ! result = (PyObject *)PyInt_FromLong((long)gen->gi_running); ! else if (strcmp(name, "__members__") == 0) ! result = Py_BuildValue("[ss]", "gi_frame", "gi_running"); ! else ! result = Py_FindMethod(gen_methods, (PyObject *)gen, name); ! return result; ! } statichere PyTypeObject gentype = { PyObject_HEAD_INIT(&PyType_Type) ! 0, /* ob_size */ ! "generator", /* tp_name */ ! sizeof(genobject), /* tp_basicsize */ ! 0, /* tp_itemsize */ ! /* methods */ ! (destructor)gen_dealloc, /* tp_dealloc */ 0, /* tp_print */ ! (getattrfunc)gen_getattr, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ --- 195,213 ---- }; ! static struct memberlist gen_memberlist[] = { ! {"gi_frame", T_OBJECT, offsetof(genobject, gi_frame), RO}, ! {"gi_running", T_INT, offsetof(genobject, gi_running), RO}, ! {NULL} /* Sentinel */ ! }; statichere PyTypeObject gentype = { PyObject_HEAD_INIT(&PyType_Type) ! 0, /* Number of items for varobject */ ! "generator", /* Name of this type */ ! sizeof(genobject), /* Basic object size */ ! 0, /* Item size for varobject */ ! (destructor)gen_dealloc, /* tp_dealloc */ 0, /* tp_print */ ! 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ *************** *** 232,246 **** 0, /* tp_call */ 0, /* tp_str */ ! 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ ! 0, /* tp_doc */ ! 0, /* tp_traverse */ ! 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ (getiterfunc)gen_getiter, /* tp_iter */ (iternextfunc)gen_iternext, /* tp_iternext */ }; --- 219,238 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ ! 0, /* tp_doc */ ! 0, /* tp_traverse */ ! 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ (getiterfunc)gen_getiter, /* tp_iter */ (iternextfunc)gen_iternext, /* tp_iternext */ + gen_methods, /* tp_methods */ + gen_memberlist, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ }; From tim_one@users.sourceforge.net Sun Jul 8 05:30:31 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 21:30:31 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.1.2.19,1.1.2.20 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv20230/descr/dist/src Modified Files: Tag: descr-branch PLAN.txt Log Message: test_generators.py Passes again. ceval.c Redid genobject type object to use PyObject_GenericGetAttr; got rid of genobject's custom getattr routine. typeobject.c Improved the docstring wrapperbase tab_next uses for .next(). PLAN.txt Added note about major (IMO) lost dir() functionality (one of the reasons test_generators.py failed is that dir(object) usually returns an empty list now). Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Attic/PLAN.txt,v retrieving revision 1.1.2.19 retrieving revision 1.1.2.20 diff -C2 -r1.1.2.19 -r1.1.2.20 *** PLAN.txt 2001/07/08 02:07:09 1.1.2.19 --- PLAN.txt 2001/07/08 04:30:29 1.1.2.20 *************** *** 159,163 **** These are currently not present (conformant to PEP 252, which proposes to drop them) but we may have to add them back. This can be done in a ! generic way with not too much effort. Another area: going all the way with classes and instances means that --- 159,166 ---- These are currently not present (conformant to PEP 252, which proposes to drop them) but we may have to add them back. This can be done in a ! generic way with not too much effort. Tim adds: Perhaps that dir(object) ! rarely returns anything but [] now is a consequence of this. I'm very ! used to doing, e.g., dir([]) or dir("") in an interactive shell to jog my ! memory; also one of the reasons test_generators failed. Another area: going all the way with classes and instances means that *************** *** 285,298 **** Testing Python subclass of dict... I expect this is a merge glitch that slipped past me. ! ! test_generators.py ! All of the computational tests pass. ! It's failing because attempting to assign to the .gi_running attr ! of a generator-iterator object was expected to raise ! TypeError: object has read-only attributes ! but is now raising ! AttributeError: 'generator' object has no attribute 'gi_running' ! How generator-iterators define attributes should be reworked. ! + If some non-Windows test has an expected-output file in descr-branch that has been removed on the trunk since descr-fork, it will probably --- 288,292 ---- Testing Python subclass of dict... I expect this is a merge glitch that slipped past me. ! + If some non-Windows test has an expected-output file in descr-branch that has been removed on the trunk since descr-fork, it will probably From tim_one@users.sourceforge.net Sun Jul 8 06:50:16 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 22:50:16 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.1.2.20,1.1.2.21 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv7428/descr/dist/src Modified Files: Tag: descr-branch PLAN.txt Log Message: Added info about the test_descr memory error: small test case and "the cause" (an uninitialized dict). I haven't found anything in the mechanics of merging that could plausibly account for this, so maybe it's deeper than that. Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Attic/PLAN.txt,v retrieving revision 1.1.2.20 retrieving revision 1.1.2.21 diff -C2 -r1.1.2.20 -r1.1.2.21 *** PLAN.txt 2001/07/08 04:30:29 1.1.2.20 --- PLAN.txt 2001/07/08 05:50:14 1.1.2.21 *************** *** 285,292 **** dict traversal -- for that matter, it still does, but now the correct exact order ). Now dies with a memory error right after Testing Python subclass of dict... I expect this is a merge glitch that slipped past me. ! + If some non-Windows test has an expected-output file in descr-branch that has been removed on the trunk since descr-fork, it will probably --- 285,306 ---- dict traversal -- for that matter, it still does, but now the correct exact order ). + Now dies with a memory error right after Testing Python subclass of dict... I expect this is a merge glitch that slipped past me. ! ! Small program that reproduces the problem: ! class C(dictionary): ! def __init__(self): ! self['a'] = 1 ! ! a = C() ! ! Gross cause: The dictionary has not been initialized, i.e. ! mp->ma_table is NULL when we get into lookdict_string. But ! mp->ma_table must never be NULL after the trunk dict rewrite (any ! legit way of creating the dict will leave ma_table pointing to ! ma_smalltable). ! + If some non-Windows test has an expected-output file in descr-branch that has been removed on the trunk since descr-fork, it will probably From tim_one@users.sourceforge.net Sun Jul 8 07:53:06 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 07 Jul 2001 23:53:06 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.1.2.21,1.1.2.22 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv18078/descr/dist/src Modified Files: Tag: descr-branch PLAN.txt Log Message: More info about the test_descr.py failure: cause understood. Guido added code to insertdict() in descr-branch 2.80.2.6 of dictobject.c that appears to be trying to get away with adding items to uninitialized dicts. Besides being disgusting , more to the point that can't work anymore -- since dicts grew the ma_smalltable member, dict initialization is no longer a nop, and *lots* of the small dict speedups rely on that ma_table is never ever NULL (so we got to remove the endlessly repeated old "ma_table == NULL?" tests+branches on critical paths). Don't know how to fix it, but it's not simply a merge glitch -- 'tis deep. Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Attic/PLAN.txt,v retrieving revision 1.1.2.21 retrieving revision 1.1.2.22 diff -C2 -r1.1.2.21 -r1.1.2.22 *** PLAN.txt 2001/07/08 05:50:14 1.1.2.21 --- PLAN.txt 2001/07/08 06:53:04 1.1.2.22 *************** *** 288,292 **** Now dies with a memory error right after Testing Python subclass of dict... - I expect this is a merge glitch that slipped past me. Small program that reproduces the problem: --- 288,291 ---- *************** *** 301,305 **** mp->ma_table must never be NULL after the trunk dict rewrite (any legit way of creating the dict will leave ma_table pointing to ! ma_smalltable). + If some non-Windows test has an expected-output file in descr-branch --- 300,316 ---- mp->ma_table must never be NULL after the trunk dict rewrite (any legit way of creating the dict will leave ma_table pointing to ! the ma_smalltable member). ! ! Note: We get into lookdict_string because insertdict forces ! mp->ma_lookup to lookdict_string if mp->ma_lookup is NULL. It ! is in this case. But that again says this object never went thru ! dict initialization: insertdict should really be asserting that ! mp->ma_lookup is not NULL on entry! The trunk version simply ! assumes it's not NULL (it's impossible to create a dict object ! with it NULL). ! ! Looks like Guido added this in descr-branch rev 2.80.2.6 ! of dictobject.c; but this form of casting cheat doesn't work ! anymore on dicts. + If some non-Windows test has an expected-output file in descr-branch From tim_one@users.sourceforge.net Sun Jul 8 08:47:08 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 08 Jul 2001 00:47:08 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.1.2.22,1.1.2.23 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv935/descr/dist/src Modified Files: Tag: descr-branch PLAN.txt Log Message: Remove all remaining useless expected-output test files. Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Attic/PLAN.txt,v retrieving revision 1.1.2.22 retrieving revision 1.1.2.23 diff -C2 -r1.1.2.22 -r1.1.2.23 *** PLAN.txt 2001/07/08 06:53:04 1.1.2.22 --- PLAN.txt 2001/07/08 07:47:05 1.1.2.23 *************** *** 313,320 **** of dictobject.c; but this form of casting cheat doesn't work anymore on dicts. - - + If some non-Windows test has an expected-output file in descr-branch - that has been removed on the trunk since descr-fork, it will probably - fail. The cure is to remove the expected-output file in descr-branch too. ------------------------------------------------------------------ 2001-07-06 --- 313,316 ---- From tim_one@users.sourceforge.net Sun Jul 8 08:47:08 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 08 Jul 2001 00:47:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test___all__,1.1,NONE test___future__,1.1,NONE test_al,1.1,NONE test_array,1.1,NONE test_audioop,1.1,NONE test_binhex,1.1,NONE test_bisect,1.1,NONE test_bsddb,1.1,NONE test_bufio,1.1,NONE test_capi,1.1,NONE test_cd,1.1,NONE test_cl,1.1,NONE test_cmath,1.1,NONE test_complex,1.1,NONE test_contains,1.1,NONE test_crypt,1.2,NONE test_dbm,1.1,NONE test_dl,1.1,NONE test_dumbdbm,1.1,NONE test_errno,1.1,NONE test_fcntl,1.1,NONE test_file,1.1,NONE test_fnmatch,1.1,NONE test_fork1,1.1,NONE test_format,1.1,NONE test_funcattrs,1.1,NONE test_gc,1.2,NONE test_gdbm,1.1,NONE test_getopt,1.2,NONE test_gl,1.1,NONE test_grp,1.1,NONE test_gzip,1.1,NONE test_hash,1.1,NONE test_imageop,1.1,NONE test_imgfile,1.1,NONE test_import,1.1,NONE test_inspect,1.1,NONE test_iter,1.2,NONE test_largefile,1.1,NONE test_locale,1.1,NONE test_rfc822,1.1,NONE test_select,1.2,NONE test_sre,1.12,NONE test_strftime,1.2,NONE test_struct,1.2,NONE test_sunaudiodev,1.1,NONE test_sundry,1.1,NONE test_symtable,1.1,NONE test_time,1.1,NONE test_timing,1.1,NONE test_traceback,1.1,NONE test_unpack,1.1,NONE test_urllib,1.1,NONE test_userdict,1.1,NONE test_userlist,1.1,NONE test_userstring,1.3,NONE test_wave,1.1,NONE test_weakref,1.3,NONE test_xmllib,1.1,NONE test_zipfile,1.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv935/descr/dist/src/Lib/test/output Removed Files: Tag: descr-branch test___all__ test___future__ test_al test_array test_audioop test_binhex test_bisect test_bsddb test_bufio test_capi test_cd test_cl test_cmath test_complex test_contains test_crypt test_dbm test_dl test_dumbdbm test_errno test_fcntl test_file test_fnmatch test_fork1 test_format test_funcattrs test_gc test_gdbm test_getopt test_gl test_grp test_gzip test_hash test_imageop test_imgfile test_import test_inspect test_iter test_largefile test_locale test_rfc822 test_select test_sre test_strftime test_struct test_sunaudiodev test_sundry test_symtable test_time test_timing test_traceback test_unpack test_urllib test_userdict test_userlist test_userstring test_wave test_weakref test_xmllib test_zipfile Log Message: Remove all remaining useless expected-output test files. --- test___all__ DELETED --- --- test___future__ DELETED --- --- test_al DELETED --- --- test_array DELETED --- --- test_audioop DELETED --- --- test_binhex DELETED --- --- test_bisect DELETED --- --- test_bsddb DELETED --- --- test_bufio DELETED --- --- test_capi DELETED --- --- test_cd DELETED --- --- test_cl DELETED --- --- test_cmath DELETED --- --- test_complex DELETED --- --- test_contains DELETED --- --- test_crypt DELETED --- --- test_dbm DELETED --- --- test_dl DELETED --- --- test_dumbdbm DELETED --- --- test_errno DELETED --- --- test_fcntl DELETED --- --- test_file DELETED --- --- test_fnmatch DELETED --- --- test_fork1 DELETED --- --- test_format DELETED --- --- test_funcattrs DELETED --- --- test_gc DELETED --- --- test_gdbm DELETED --- --- test_getopt DELETED --- --- test_gl DELETED --- --- test_grp DELETED --- --- test_gzip DELETED --- --- test_hash DELETED --- --- test_imageop DELETED --- --- test_imgfile DELETED --- --- test_import DELETED --- --- test_inspect DELETED --- --- test_iter DELETED --- --- test_largefile DELETED --- --- test_locale DELETED --- --- test_rfc822 DELETED --- --- test_select DELETED --- --- test_sre DELETED --- --- test_strftime DELETED --- --- test_struct DELETED --- --- test_sunaudiodev DELETED --- --- test_sundry DELETED --- --- test_symtable DELETED --- --- test_time DELETED --- --- test_timing DELETED --- --- test_traceback DELETED --- --- test_unpack DELETED --- --- test_urllib DELETED --- --- test_userdict DELETED --- --- test_userlist DELETED --- --- test_userstring DELETED --- --- test_wave DELETED --- --- test_weakref DELETED --- --- test_xmllib DELETED --- --- test_zipfile DELETED --- From gvanrossum@users.sourceforge.net Sun Jul 8 12:51:57 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 08 Jul 2001 04:51:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.241.2.6,2.241.2.7 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv3727 Modified Files: Tag: descr-branch ceval.c Log Message: Add a feature: if a global variable __metaclass__ exists, use that as the default metaclass, rather than &PyClass_Type. This makes it possible to write modules where all classes are new-style classes without having to add "__metaclass__ = type" (or a base class 'object') to each class. This serves as a future statement for the default metaclass. Classes derived from classic classes defined in other modules are exempt; the default metaclass is only used when there are no base classes, otherwise the metaclass of the first base class is used. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.241.2.6 retrieving revision 2.241.2.7 diff -C2 -r2.241.2.6 -r2.241.2.7 *** ceval.c 2001/07/08 04:30:29 2.241.2.6 --- ceval.c 2001/07/08 11:51:54 2.241.2.7 *************** *** 3605,3610 **** metaclass = (PyObject *) PyTuple_GET_ITEM(bases, 0)->ob_type; ! else ! metaclass = (PyObject *) &PyClass_Type; } return PyObject_CallFunction(metaclass, "OOO", name, bases, methods); --- 3605,3616 ---- metaclass = (PyObject *) PyTuple_GET_ITEM(bases, 0)->ob_type; ! else { ! PyObject *g = PyEval_GetGlobals(); ! if (g != NULL && PyDict_Check(g)) ! metaclass = PyDict_GetItemString( ! g, "__metaclass__"); ! if (metaclass == NULL) ! metaclass = (PyObject *) &PyClass_Type; ! } } return PyObject_CallFunction(metaclass, "OOO", name, bases, methods); From effbot@users.sourceforge.net Sun Jul 8 14:26:59 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Sun, 08 Jul 2001 06:26:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _sre.c,2.60,2.61 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv27901/Modules Modified Files: _sre.c Log Message: map re.sub() to string.replace(), when possible Index: _sre.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_sre.c,v retrieving revision 2.60 retrieving revision 2.61 diff -C2 -r2.60 -r2.61 *** _sre.c 2001/07/03 20:32:36 2.60 --- _sre.c 2001/07/08 13:26:57 2.61 *************** *** 1956,1959 **** --- 1956,1981 ---- } + static PyObject* + pattern_isliteral(PatternObject* self, PyObject* args) + { + /* internal: return true if pattern consists of literal text only */ + + SRE_CODE* code; + PyObject* isliteral; + + if (!PyArg_ParseTuple(args, ":_isliteral")) + return NULL; + + code = PatternObject_GetCode(self); + + if (code[0] == SRE_OP_INFO && code[2] & SRE_INFO_LITERAL) + isliteral = Py_True; + else + isliteral = Py_False; + + Py_INCREF(isliteral); + return isliteral; + } + static PyMethodDef pattern_methods[] = { {"match", (PyCFunction) pattern_match, METH_VARARGS|METH_KEYWORDS}, *************** *** 1966,1969 **** --- 1988,1992 ---- {"__copy__", (PyCFunction) pattern_copy, METH_VARARGS}, {"__deepcopy__", (PyCFunction) pattern_deepcopy, METH_VARARGS}, + {"_isliteral", (PyCFunction) pattern_isliteral, METH_VARARGS}, {NULL, NULL} }; From effbot@users.sourceforge.net Sun Jul 8 14:26:59 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Sun, 08 Jul 2001 06:26:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib sre.py,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv27901/Lib Modified Files: sre.py Log Message: map re.sub() to string.replace(), when possible Index: sre.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre.py,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -r1.32 -r1.33 *** sre.py 2001/07/06 20:56:10 1.32 --- sre.py 2001/07/08 13:26:57 1.33 *************** *** 160,168 **** return sre_parse.expand_template(template, match) ! def _sub(pattern, template, string, count=0): # internal: pattern.sub implementation hook ! return _subn(pattern, template, string, count)[0] ! def _subn(pattern, template, string, count=0): # internal: pattern.subn implementation hook if callable(template): --- 160,168 ---- return sre_parse.expand_template(template, match) ! def _sub(pattern, template, text, count=0): # internal: pattern.sub implementation hook ! return _subn(pattern, template, text, count, 1)[0] ! def _subn(pattern, template, text, count=0, sub=0): # internal: pattern.subn implementation hook if callable(template): *************** *** 170,173 **** --- 170,178 ---- else: template = _compile_repl(template, pattern) + literals = template[1] + if (sub and not count and pattern._isliteral() and + len(literals) == 1 and literals[0]): + # shortcut: both pattern and string are literals + return string.replace(text, pattern.pattern, literals[0]), 0 def filter(match, template=template): return sre_parse.expand_template(template, match) *************** *** 175,179 **** s = [] append = s.append ! c = pattern.scanner(string) while not count or n < count: m = c.search() --- 180,184 ---- s = [] append = s.append ! c = pattern.scanner(text) while not count or n < count: m = c.search() *************** *** 182,193 **** b, e = m.span() if i < b: ! append(string[i:b]) append(filter(m)) i = e n = n + 1 ! append(string[i:]) ! return _join(s, string[:0]), n ! def _split(pattern, string, maxsplit=0): # internal: pattern.split implementation hook n = i = 0 --- 187,198 ---- b, e = m.span() if i < b: ! append(text[i:b]) append(filter(m)) i = e n = n + 1 ! append(text[i:]) ! return _join(s, text[:0]), n ! def _split(pattern, text, maxsplit=0): # internal: pattern.split implementation hook n = i = 0 *************** *** 195,199 **** append = s.append extend = s.extend ! c = pattern.scanner(string) g = pattern.groups while not maxsplit or n < maxsplit: --- 200,204 ---- append = s.append extend = s.extend ! c = pattern.scanner(text) g = pattern.groups while not maxsplit or n < maxsplit: *************** *** 203,215 **** b, e = m.span() if b == e: ! if i >= len(string): break continue ! append(string[i:b]) if g and b != e: extend(list(m.groups())) i = e n = n + 1 ! append(string[i:]) return s --- 208,220 ---- b, e = m.span() if b == e: ! if i >= len(text): break continue ! append(text[i:b]) if g and b != e: extend(list(m.groups())) i = e n = n + 1 ! append(text[i:]) return s From tim_one@users.sourceforge.net Sun Jul 8 20:16:32 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 08 Jul 2001 12:16:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.80.2.15,2.80.2.16 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv7970/descr/dist/src/Objects Modified Files: Tag: descr-branch dictobject.c Log Message: Add a "real" tp_new slot to dicts, in order to get dicts initialized before use. I'm certain I didn't do it correctly, but don't understand what "correctly" entails, exactly. See PLAN.txt for more details. test_descr.py doesn't core dump anymore, but fails one line later with a verify() failure. Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.80.2.15 retrieving revision 2.80.2.16 diff -C2 -r2.80.2.15 -r2.80.2.16 *** dictobject.c 2001/07/07 22:55:30 2.80.2.15 --- dictobject.c 2001/07/08 19:16:30 2.80.2.16 *************** *** 160,163 **** --- 160,169 ---- } + static PyObject * + dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + return PyDict_New(); + } + /* The basic lookup function used by all operations. *************** *** 1732,1736 **** (initproc)dict_init, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ ! PyType_GenericNew, /* tp_new */ }; --- 1738,1742 ---- (initproc)dict_init, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ ! dict_new, /* tp_new */ }; From tim_one@users.sourceforge.net Sun Jul 8 20:16:32 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 08 Jul 2001 12:16:32 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.1.2.23,1.1.2.24 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv7970/descr/dist/src Modified Files: Tag: descr-branch PLAN.txt Log Message: Add a "real" tp_new slot to dicts, in order to get dicts initialized before use. I'm certain I didn't do it correctly, but don't understand what "correctly" entails, exactly. See PLAN.txt for more details. test_descr.py doesn't core dump anymore, but fails one line later with a verify() failure. Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Attic/PLAN.txt,v retrieving revision 1.1.2.23 retrieving revision 1.1.2.24 diff -C2 -r1.1.2.23 -r1.1.2.24 *** PLAN.txt 2001/07/08 07:47:05 1.1.2.23 --- PLAN.txt 2001/07/08 19:16:30 1.1.2.24 *************** *** 268,272 **** he dies of frustration while wrestling with CVS <0.9 wink>). ! ------------------------------------------------------------------ 2001-07-07 --- 268,272 ---- he dies of frustration while wrestling with CVS <0.9 wink>). ! ---------------------------------------------------------------------------- 2001-07-07 *************** *** 286,317 **** correct exact order ). ! Now dies with a memory error right after ! Testing Python subclass of dict... ! Small program that reproduces the problem: ! class C(dictionary): ! def __init__(self): ! self['a'] = 1 ! ! a = C() ! ! Gross cause: The dictionary has not been initialized, i.e. ! mp->ma_table is NULL when we get into lookdict_string. But ! mp->ma_table must never be NULL after the trunk dict rewrite (any ! legit way of creating the dict will leave ma_table pointing to ! the ma_smalltable member). ! ! Note: We get into lookdict_string because insertdict forces ! mp->ma_lookup to lookdict_string if mp->ma_lookup is NULL. It ! is in this case. But that again says this object never went thru ! dict initialization: insertdict should really be asserting that ! mp->ma_lookup is not NULL on entry! The trunk version simply ! assumes it's not NULL (it's impossible to create a dict object ! with it NULL). ! ! Looks like Guido added this in descr-branch rev 2.80.2.6 ! of dictobject.c; but this form of casting cheat doesn't work ! anymore on dicts. ! ------------------------------------------------------------------ 2001-07-06 --- 286,317 ---- correct exact order ). ! A core dump was "fixed" (unsure about that!) via adding a ! tp_new slot to dict objects, to ensure that they're initialized ! before being used. ! ! Now dies with ! File "../lib/test\test_descr.py", line 325, in pydicts ! verify(a1.state == 12) ! AttributeError: 'dictionary' object has no attribute 'state' ! ! I don't understand what tp_new is supposed to do for dicts, ! exactly. PEP 253 says ! ! - If the base type defines tp_init as well as tp_new, its tp_new ! should be inheritable: it should call the tp_alloc and the ! tp_init of the type passed in as its first argument. ! ! The tp_new I added doesn't do that, mostly because I couldn't find ! any code that already does that in order to fill in the fine ! points. PEP 253 also says tp_alloc has signature: ! ! PyObject *tp_alloc(PyTypeObject *type, ! PyObject *args, ! PyObject *kwds) ! but in reality it appears to be this instead: ! ! typedef PyObject *(*allocfunc)(struct _typeobject *, int); ! ---------------------------------------------------------------------------- 2001-07-06 From tim_one@users.sourceforge.net Sun Jul 8 21:11:25 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 08 Jul 2001 13:11:25 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.1.2.24,1.1.2.25 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv21236/descr/dist/src Modified Files: Tag: descr-branch PLAN.txt Log Message: dict_new(): Try to be more realistic. Guido, please check! I have many more questions (written up as XXX comments) than answers here. insertdict(): Removed code attempting to allow use of uninitialized dicts. test_descr gets beyond the spamdict tests now, but fails in a new place instead (see PLAN.txt). Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Attic/PLAN.txt,v retrieving revision 1.1.2.24 retrieving revision 1.1.2.25 diff -C2 -r1.1.2.24 -r1.1.2.25 *** PLAN.txt 2001/07/08 19:16:30 1.1.2.24 --- PLAN.txt 2001/07/08 20:11:23 1.1.2.25 *************** *** 290,294 **** before being used. ! Now dies with File "../lib/test\test_descr.py", line 325, in pydicts verify(a1.state == 12) --- 290,294 ---- before being used. ! Then it died with File "../lib/test\test_descr.py", line 325, in pydicts verify(a1.state == 12) *************** *** 313,316 **** --- 313,323 ---- typedef PyObject *(*allocfunc)(struct _typeobject *, int); + + After lots of guesswork, made a tp_new that got beyond that. + + Now it dies with + + Testing errors... + test test_descr failed -- __slots__ = {} should be illegal ---------------------------------------------------------------------------- 2001-07-06 From tim_one@users.sourceforge.net Sun Jul 8 21:11:25 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 08 Jul 2001 13:11:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.80.2.16,2.80.2.17 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv21236/descr/dist/src/Objects Modified Files: Tag: descr-branch dictobject.c Log Message: dict_new(): Try to be more realistic. Guido, please check! I have many more questions (written up as XXX comments) than answers here. insertdict(): Removed code attempting to allow use of uninitialized dicts. test_descr gets beyond the spamdict tests now, but fails in a new place instead (see PLAN.txt). Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.80.2.16 retrieving revision 2.80.2.17 diff -C2 -r2.80.2.16 -r2.80.2.17 *** dictobject.c 2001/07/08 19:16:30 2.80.2.16 --- dictobject.c 2001/07/08 20:11:23 2.80.2.17 *************** *** 160,169 **** } - static PyObject * - dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds) - { - return PyDict_New(); - } - /* The basic lookup function used by all operations. --- 160,163 ---- *************** *** 357,366 **** register dictentry *ep; typedef PyDictEntry *(*lookupfunc)(PyDictObject *, PyObject *, long); - register lookupfunc lookup; ! lookup = mp->ma_lookup; ! if (lookup == NULL) ! mp->ma_lookup = lookup = lookdict_string; ! ep = lookup(mp, key, hash); if (ep->me_value != NULL) { old_value = ep->me_value; --- 351,357 ---- register dictentry *ep; typedef PyDictEntry *(*lookupfunc)(PyDictObject *, PyObject *, long); ! assert(mp->ma_lookup != NULL); ! ep = mp->ma_lookup(mp, key, hash); if (ep->me_value != NULL) { old_value = ep->me_value; *************** *** 1690,1693 **** --- 1681,1734 ---- #endif return 0; + } + + /* XXX This is wrong, but if I knew *how* it was wrong I would fix + * XXX it instead of typing this comment <0.5 wink>. + */ + static PyObject * + dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + PyObject *self; + + /* XXX Is it legit to insist these all be non-NULL? */ + if (!(type && type->tp_alloc && type->tp_init)) { + PyErr_BadInternalCall(); + return NULL; + } + + /* XXX I'm not sure what the 2nd tp_alloc arg is for, and wholly + * unsure what to pass if 0 isn't appropriate in this specific case. + * XXX Will tp_alloc set up GC correctly for dict objects? + * If not, how to tell? If so, how to verify? Dare not add the + * object *twice* to the GC list. + */ + self = type->tp_alloc(type, 0); + if (self == NULL) + return NULL; + /* XXX Safe to assume Py_DECREF(self) is OK hereafter? */ + + /* XXX This appears to be necessary (core dumps without it). But I + * would have guessed that, if type is a subclass, it's part of + * type->tp_init()'s job to call all base class tp_init slots, "bottom + * up". Apparently not(?). + */ + if (dict_init((PyDictObject *)self, args, kwds) < 0) { + Py_DECREF(self); + return NULL; + } + + /* XXX If type is PyDictObject, we end up calling dict_init twice. + * Should that be special-cased? It's a little inefficient, and + * "created* will get incremented twice. But if type is a subclass, + * and calls dict_init directly (see last blob of confusions), that's + * going to happen anyway. + */ + if (type->tp_init(self, args, kwds) < 0) { + Py_DECREF(self); + return NULL; + } + + /* This line I feel confident about . */ + return self; } From jackjansen@users.sourceforge.net Sun Jul 8 23:07:15 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sun, 08 Jul 2001 15:07:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules macfsmodule.c,1.36,1.37 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules In directory usw-pr-cvs1:/tmp/cvs-serv17020/Python/Mac/Modules Modified Files: macfsmodule.c Log Message: Implemented minimal FSRef support, plus conversion between FSRefs, FSSpecs and pathnames where applicable. PyMac_GetFSSpec and PyMac_BuildFSSpec have moved to macfsmodule from macglue. These mods are untested on OSX. Index: macfsmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/macfsmodule.c,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -r1.36 -r1.37 *** macfsmodule.c 2001/05/19 12:34:59 1.36 --- macfsmodule.c 2001/07/08 22:07:13 1.37 *************** *** 39,44 **** #include "getapplbycreator.h" - /* Should this be in macglue.h? */ - extern FSSpec *mfs_GetFSSpecFSSpec(PyObject *); static PyObject *ErrorObject; --- 39,42 ---- *************** *** 68,72 **** --- 66,82 ---- #define is_mfssobject(v) ((v)->ob_type == &Mfsstype) + /* ---------------------------------------------------------------- */ + /* Declarations for objects of type FSRef */ + + typedef struct { + PyObject_HEAD + FSRef fsref; + } mfsrobject; + + staticforward PyTypeObject Mfsrtype; + #define is_mfsrobject(v) ((v)->ob_type == &Mfsrtype) + + /* ---------------------------------------------------------------- */ /* Declarations for objects of type FInfo */ *************** *** 82,86 **** ! mfssobject *newmfssobject(FSSpec *fss); /* Forward */ /* ---------------------------------------------------------------- */ --- 92,97 ---- ! staticforward mfssobject *newmfssobject(FSSpec *fss); /* Forward */ ! staticforward mfsrobject *newmfsrobject(FSRef *fsr); /* Forward */ /* ---------------------------------------------------------------- */ *************** *** 337,351 **** /* ! ** Helper routine for other modules: return an FSSpec * if the ! ** object is a python fsspec object, else NULL */ ! FSSpec * ! mfs_GetFSSpecFSSpec(PyObject *self) { ! if ( is_mfssobject(self) ) ! return &((mfssobject *)self)->fsspec; ! return NULL; } /* ** Two generally useful routines --- 348,403 ---- /* ! ** Helper routines for the FSRef and FSSpec creators in macglue.c ! ** They return an FSSpec/FSRef if the Python object encapsulating ! ** either is passed. They return a boolean success indicator. ! ** Note that they do not set an exception on failure, they're only ! ** helper routines. */ ! static int ! _mfs_GetFSSpecFromFSSpec(PyObject *self, FSSpec *fssp) ! { ! if ( is_mfssobject(self) ) { ! *fssp = ((mfssobject *)self)->fsspec; ! return 1; ! } ! return 0; ! } ! ! /* Return an FSSpec if this is an FSref */ ! static int ! _mfs_GetFSSpecFromFSRef(PyObject *self, FSSpec *fssp) { ! static FSRef *fsrp; ! ! if ( is_mfsrobject(self) ) { ! fsrp = &((mfsrobject *)self)->fsref; ! if ( FSGetCatalogInfo(&((mfsrobject *)self)->fsref, kFSCatInfoNone, NULL, NULL, fssp, NULL) == noErr ) ! return 1; ! } ! return 0; } + /* Return an FSRef if this is an FSRef */ + static int + _mfs_GetFSRefFromFSRef(PyObject *self, FSRef *fsrp) + { + if ( is_mfsrobject(self) ) { + *fsrp = ((mfsrobject *)self)->fsref; + return 1; + } + return 0; + } + + /* Return an FSRef if this is an FSSpec */ + static int + _mfs_GetFSRefFromFSSpec(PyObject *self, FSRef *fsrp) + { + if ( is_mfssobject(self) ) { + if ( FSpMakeFSRef(&((mfssobject *)self)->fsspec, fsrp) == noErr ) + return 1; + } + return 0; + } + /* ** Two generally useful routines *************** *** 468,471 **** --- 520,541 ---- } + static PyObject * + mfss_FSpMakeFSRef(self, args) + mfssobject *self; + PyObject *args; + { + OSErr err; + FSRef fsref; + + if (!PyArg_ParseTuple(args, "")) + return NULL; + err = FSpMakeFSRef(&self->fsspec, &fsref); + if ( err ) { + PyErr_Mac(ErrorObject, err); + return NULL; + } + return (PyObject *)newmfsrobject(&fsref); + } + /* XXXX These routines should be replaced by a wrapper to the *FInfo routines */ static PyObject * *************** *** 597,600 **** --- 667,672 ---- {"as_pathname", (PyCFunction)mfss_as_pathname, 1}, {"as_tuple", (PyCFunction)mfss_as_tuple, 1}, + {"as_fsref", (PyCFunction)mfss_FSpMakeFSRef, 1}, + {"FSpMakeFSRef", (PyCFunction)mfss_FSpMakeFSRef, 1}, {"NewAlias", (PyCFunction)mfss_NewAlias, 1}, {"NewAliasMinimal", (PyCFunction)mfss_NewAliasMinimal, 1}, *************** *** 697,700 **** --- 769,878 ---- static PyObject * + mfsr_as_fsspec(self, args) + mfsrobject *self; + PyObject *args; + { + OSErr err; + FSSpec fss; + + if (!PyArg_ParseTuple(args, "")) + return NULL; + err = FSGetCatalogInfo(&self->fsref, kFSCatInfoNone, NULL, NULL, &fss, NULL); + if ( err ) { + PyErr_Mac(ErrorObject, err); + return NULL; + } + Py_INCREF(Py_None); + return (PyObject *)newmfssobject(&fss); + } + + static struct PyMethodDef mfsr_methods[] = { + {"as_fsspec", (PyCFunction)mfsr_as_fsspec, 1}, + #if 0 + {"as_pathname", (PyCFunction)mfss_as_pathname, 1}, + {"as_tuple", (PyCFunction)mfss_as_tuple, 1}, + {"NewAlias", (PyCFunction)mfss_NewAlias, 1}, + {"NewAliasMinimal", (PyCFunction)mfss_NewAliasMinimal, 1}, + {"GetCreatorType", (PyCFunction)mfss_GetCreatorType, 1}, + {"SetCreatorType", (PyCFunction)mfss_SetCreatorType, 1}, + {"GetFInfo", (PyCFunction)mfss_GetFInfo, 1}, + {"SetFInfo", (PyCFunction)mfss_SetFInfo, 1}, + {"GetDates", (PyCFunction)mfss_GetDates, 1}, + {"SetDates", (PyCFunction)mfss_SetDates, 1}, + #endif + + {NULL, NULL} /* sentinel */ + }; + + /* ---------- */ + + static PyObject * + mfsr_getattr(self, name) + mfsrobject *self; + char *name; + { + if ( strcmp(name, "data") == 0) + return PyString_FromStringAndSize((char *)&self->fsref, sizeof(FSRef)); + return Py_FindMethod(mfsr_methods, (PyObject *)self, name); + } + + mfsrobject * + newmfsrobject(fsr) + FSRef *fsr; + { + mfsrobject *self; + + self = PyObject_NEW(mfsrobject, &Mfsrtype); + if (self == NULL) + return NULL; + self->fsref = *fsr; + return self; + } + + static int + mfsr_compare(v, w) + mfsrobject *v, *w; + { + OSErr err; + + if ( v == w ) return 0; + err = FSCompareFSRefs(&v->fsref, &w->fsref); + if ( err == 0 ) + return 0; + if (v < w ) + return -1; + return 1; + } + + static void + mfsr_dealloc(self) + mfsrobject *self; + { + PyMem_DEL(self); + } + + statichere PyTypeObject Mfsrtype = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*ob_size*/ + "FSRef", /*tp_name*/ + sizeof(mfsrobject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)mfsr_dealloc, /*tp_dealloc*/ + (printfunc)0, /*tp_print*/ + (getattrfunc)mfsr_getattr, /*tp_getattr*/ + (setattrfunc)0, /*tp_setattr*/ + (cmpfunc)mfsr_compare, /*tp_compare*/ + (reprfunc)0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + (hashfunc)0, /*tp_hash*/ + }; + + /* End of code for FSRef objects */ + /* -------------------------------------------------------- */ + + static PyObject * mfs_ResolveAliasFile(self, args) PyObject *self; /* Not used */ *************** *** 821,824 **** --- 999,1014 ---- static PyObject * + mfs_FSRef(self, args) + PyObject *self; /* Not used */ + PyObject *args; + { + FSRef fsr; + + if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSRef, &fsr)) + return NULL; + return (PyObject *)newmfsrobject(&fsr); + } + + static PyObject * mfs_RawFSSpec(self, args) PyObject *self; /* Not used */ *************** *** 964,967 **** --- 1154,1158 ---- #endif {"FSSpec", mfs_FSSpec, 1}, + {"FSRef", mfs_FSRef, 1}, {"RawFSSpec", mfs_RawFSSpec, 1}, {"RawAlias", mfs_RawAlias, 1}, *************** *** 974,977 **** --- 1165,1241 ---- }; + /* + ** Convert a Python object to an FSSpec. + ** The object may either be a full pathname, an FSSpec, an FSRef or a triple + ** (vrefnum, dirid, path). + */ + int + PyMac_GetFSRef(PyObject *v, FSRef *fsr) + { + OSErr err; + + /* If it's an FSRef we're also okay. */ + if (_mfs_GetFSRefFromFSRef(v, fsr)) + return 1; + /* first check whether it already is an FSSpec */ + if ( _mfs_GetFSRefFromFSSpec(v, fsr) ) + return 1; + if ( PyString_Check(v) ) { + PyErr_SetString(PyExc_NotImplementedError, "Cannot create an FSRef from a pathname on this platform"); + return 0; + } + PyErr_SetString(PyExc_TypeError, "FSRef argument should be existing FSRef, FSSpec or (OSX only) pathname"); + return 0; + } + + /* Convert FSSpec to PyObject */ + PyObject *PyMac_BuildFSRef(FSRef *v) + { + return (PyObject *)newmfsrobject(v); + } + + /* + ** Convert a Python object to an FSRef. + ** The object may either be a full pathname (OSX only), an FSSpec or an FSRef. + */ + int + PyMac_GetFSSpec(PyObject *v, FSSpec *fs) + { + Str255 path; + short refnum; + long parid; + OSErr err; + + /* first check whether it already is an FSSpec */ + if ( _mfs_GetFSSpecFromFSSpec(v, fs) ) + return 1; + /* If it's an FSRef we're also okay. */ + if (_mfs_GetFSSpecFromFSRef(v, fs)) + return 1; + if ( PyString_Check(v) ) { + /* It's a pathname */ + if( !PyArg_Parse(v, "O&", PyMac_GetStr255, &path) ) + return 0; + refnum = 0; /* XXXX Should get CurWD here?? */ + parid = 0; + } else { + if( !PyArg_Parse(v, "(hlO&); FSSpec should be FSSpec, FSRef, fullpath or (vrefnum,dirid,path)", + &refnum, &parid, PyMac_GetStr255, &path)) { + return 0; + } + } + err = FSMakeFSSpec(refnum, parid, path, fs); + if ( err && err != fnfErr ) { + PyMac_Error(err); + return 0; + } + return 1; + } + + /* Convert FSSpec to PyObject */ + PyObject *PyMac_BuildFSSpec(FSSpec *v) + { + return (PyObject *)newmfssobject(v); + } /* Initialization function for the module (*must* be called initmacfs) */ From jackjansen@users.sourceforge.net Sun Jul 8 23:07:20 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sun, 08 Jul 2001 15:07:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Include macglue.h,1.54,1.55 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Include In directory usw-pr-cvs1:/tmp/cvs-serv17063/Python/Mac/Include Modified Files: macglue.h Log Message: Implemented minimal FSRef support, plus conversion between FSRefs, FSSpecs and pathnames where applicable. PyMac_GetFSSpec and PyMac_BuildFSSpec have moved to macfsmodule from macglue. These mods are untested on OSX. Index: macglue.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Include/macglue.h,v retrieving revision 1.54 retrieving revision 1.55 diff -C2 -r1.54 -r1.55 *** macglue.h 2001/05/12 22:46:35 1.54 --- macglue.h 2001/07/08 22:07:18 1.55 *************** *** 107,113 **** PyObject *PyMac_BuildOptStr255(Str255); /* Convert Str255 to PyObject, NULL to None */ - int PyMac_GetFSSpec(PyObject *, FSSpec *); /* argument parser for FSSpec */ - PyObject *PyMac_BuildFSSpec(FSSpec *); /* Convert FSSpec to PyObject */ - int PyMac_GetRect(PyObject *, Rect *); /* argument parser for Rect */ PyObject *PyMac_BuildRect(Rect *); /* Convert Rect to PyObject */ --- 107,110 ---- *************** *** 129,132 **** --- 126,137 ---- short PyMac_OpenPrefFile(void); /* From macgetpath.c, open and return preference file */ #endif + + /* from macfsmodule.c: */ + int PyMac_GetFSSpec(PyObject *, FSSpec *); /* argument parser for FSSpec */ + PyObject *PyMac_BuildFSSpec(FSSpec *); /* Convert FSSpec to PyObject */ + + int PyMac_GetFSRef(PyObject *, FSRef *); /* argument parser for FSRef */ + PyObject *PyMac_BuildFSRef(FSRef *); /* Convert FSRef to PyObject */ + /* From macfiletype.c: */ From jackjansen@users.sourceforge.net Sun Jul 8 23:07:25 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sun, 08 Jul 2001 15:07:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Python macglue.c,1.95,1.96 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Python In directory usw-pr-cvs1:/tmp/cvs-serv17090/Python/Mac/Python Modified Files: macglue.c Log Message: Implemented minimal FSRef support, plus conversion between FSRefs, FSSpecs and pathnames where applicable. PyMac_GetFSSpec and PyMac_BuildFSSpec have moved to macfsmodule from macglue. These mods are untested on OSX. Index: macglue.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Python/macglue.c,v retrieving revision 1.95 retrieving revision 1.96 diff -C2 -r1.95 -r1.96 *** macglue.c 2001/07/04 22:36:27 1.95 --- macglue.c 2001/07/08 22:07:23 1.96 *************** *** 131,138 **** #define fnfErr -43 - /* Declared in macfsmodule.c: */ - extern FSSpec *mfs_GetFSSpecFSSpec(PyObject *); - extern PyObject *newmfssobject(FSSpec *); - /* Interrupt code variables: */ static int interrupted; /* Set to true when cmd-. seen */ --- 131,134 ---- *************** *** 1045,1105 **** - /* - ** Convert a Python object to an FSSpec. - ** The object may either be a full pathname or a triple - ** (vrefnum, dirid, path). - ** NOTE: This routine will fail on pre-sys7 machines. - ** The caller is responsible for not calling this routine - ** in those cases (which is fine, since everyone calling - ** this is probably sys7 dependent anyway). - */ - int - PyMac_GetFSSpec(PyObject *v, FSSpec *fs) - { - Str255 path; - short refnum; - long parid; - OSErr err; - FSSpec *fs2; - - #if !TARGET_API_MAC_OSX - /* XXX This #if is temporary */ - /* first check whether it already is an FSSpec */ - fs2 = mfs_GetFSSpecFSSpec(v); - if ( fs2 ) { - (void)FSMakeFSSpec(fs2->vRefNum, fs2->parID, fs2->name, fs); - return 1; - } - #endif - if ( PyString_Check(v) ) { - /* It's a pathname */ - if( !PyArg_Parse(v, "O&", PyMac_GetStr255, &path) ) - return 0; - refnum = 0; /* XXXX Should get CurWD here?? */ - parid = 0; - } else { - if( !PyArg_Parse(v, "(hlO&); FSSpec should be fullpath or (vrefnum,dirid,path)", - &refnum, &parid, PyMac_GetStr255, &path)) { - return 0; - } - } - err = FSMakeFSSpec(refnum, parid, path, fs); - if ( err && err != fnfErr ) { - PyMac_Error(err); - return 0; - } - return 1; - } - - /* Convert FSSpec to PyObject */ - PyObject *PyMac_BuildFSSpec(FSSpec *v) - { - #if TARGET_API_MAC_OSX - PyErr_SetString(PyExc_NotImplementedError, "FSSpec not yet done for OSX"); - return NULL; - #else - return newmfssobject(v); - #endif - } /* Convert a Python object to a Rect. --- 1041,1044 ---- From gvanrossum@users.sourceforge.net Mon Jul 9 02:19:05 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 08 Jul 2001 18:19:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules xxsubtype.c,1.1.2.1,1.1.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv16061 Modified Files: Tag: descr-branch xxsubtype.c Log Message: Shouldn't specify PyType_Generic{Alloc,New} in the tp_{alloc,new} slots -- these should inherit the slots from the base types. Index: xxsubtype.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/Attic/xxsubtype.c,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -r1.1.2.1 -r1.1.2.2 *** xxsubtype.c 2001/07/06 18:53:47 1.1.2.1 --- xxsubtype.c 2001/07/09 01:19:03 1.1.2.2 *************** *** 67,71 **** 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 67,71 ---- 0, /* tp_call */ 0, /* tp_str */ ! 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ *************** *** 87,92 **** 0, /* tp_dictoffset */ (initproc)spamlist_init, /* tp_init */ ! PyType_GenericAlloc, /* tp_alloc */ ! PyType_GenericNew, /* tp_new */ }; --- 87,92 ---- 0, /* tp_dictoffset */ (initproc)spamlist_init, /* tp_init */ ! 0, /* tp_alloc */ ! 0, /* tp_new */ }; *************** *** 155,159 **** 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 155,159 ---- 0, /* tp_call */ 0, /* tp_str */ ! 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ *************** *** 175,180 **** 0, /* tp_dictoffset */ (initproc)spamdict_init, /* tp_init */ ! PyType_GenericAlloc, /* tp_alloc */ ! PyType_GenericNew, /* tp_new */ }; --- 175,180 ---- 0, /* tp_dictoffset */ (initproc)spamdict_init, /* tp_init */ ! 0, /* tp_alloc */ ! 0, /* tp_new */ }; From gvanrossum@users.sourceforge.net Mon Jul 9 02:26:21 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 08 Jul 2001 18:26:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.1.2.31,1.1.2.32 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv17438 Modified Files: Tag: descr-branch test_descr.py Log Message: After the merge, this test was failing on a test that insisted that class C(object): __slots__ = {} be an error. Well, because of the way it was written (slots was converted to a tuple using PySequence_Tuple()) and because of enhanced behavior of dictionaries (a dictionary in a sequence context behaves like a list of its keys) this is no longer an error. Rather than trying to make this an error, I propose to accept this defeat, and use a different non-sequence type in the test. If the __slots__ variable is a dictionary, the values are ignored. But they might be used by some future tool, e.g. as doc strings, or type specs, or whatever. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_descr.py,v retrieving revision 1.1.2.31 retrieving revision 1.1.2.32 diff -C2 -r1.1.2.31 -r1.1.2.32 *** test_descr.py 2001/07/08 01:38:59 1.1.2.31 --- test_descr.py 2001/07/09 01:26:19 1.1.2.32 *************** *** 606,614 **** try: class C(object): ! __slots__ = {} except TypeError: pass else: ! verify(0, "__slots__ = {} should be illegal") try: --- 606,614 ---- try: class C(object): ! __slots__ = 1 except TypeError: pass else: ! verify(0, "__slots__ = 1 should be illegal") try: From gvanrossum@users.sourceforge.net Mon Jul 9 02:27:55 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 08 Jul 2001 18:27:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.80.2.17,2.80.2.18 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv17748 Modified Files: Tag: descr-branch dictobject.c Log Message: Write dict_new() the way it should be done. Together with the change to Modules/xxsubtype.c, this makes the problems Tim was reporting go away. Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.80.2.17 retrieving revision 2.80.2.18 diff -C2 -r2.80.2.17 -r2.80.2.18 *** dictobject.c 2001/07/08 20:11:23 2.80.2.17 --- dictobject.c 2001/07/09 01:27:53 2.80.2.18 *************** *** 129,133 **** /* Set PyDictObject* mp to empty but w/ PyDict_MINSIZE slots, using ma_smalltable. */ ! #define empty_to_minsize(mp) do { \ memset((mp)->ma_smalltable, 0, sizeof((mp)->ma_smalltable)); \ (mp)->ma_table = (mp)->ma_smalltable; \ --- 129,133 ---- /* Set PyDictObject* mp to empty but w/ PyDict_MINSIZE slots, using ma_smalltable. */ ! #define EMPTY_TO_MINSIZE(mp) do { \ memset((mp)->ma_smalltable, 0, sizeof((mp)->ma_smalltable)); \ (mp)->ma_table = (mp)->ma_smalltable; \ *************** *** 151,155 **** if (mp == NULL) return NULL; ! empty_to_minsize(mp); mp->ma_lookup = lookdict_string; #ifdef SHOW_CONVERSION_COUNTS --- 151,155 ---- if (mp == NULL) return NULL; ! EMPTY_TO_MINSIZE(mp); mp->ma_lookup = lookdict_string; #ifdef SHOW_CONVERSION_COUNTS *************** *** 609,613 **** fill = mp->ma_fill; if (table_is_malloced) ! empty_to_minsize(mp); else if (fill > 0) { --- 609,613 ---- fill = mp->ma_fill; if (table_is_malloced) ! EMPTY_TO_MINSIZE(mp); else if (fill > 0) { *************** *** 618,622 **** memcpy(small_copy, table, sizeof(small_copy)); table = small_copy; ! empty_to_minsize(mp); } /* else it's a small table that's already empty */ --- 618,622 ---- memcpy(small_copy, table, sizeof(small_copy)); table = small_copy; ! EMPTY_TO_MINSIZE(mp); } /* else it's a small table that's already empty */ *************** *** 1672,1689 **** }; - static int - dict_init(PyDictObject *self, PyObject *args, PyObject *kw) - { - empty_to_minsize(self); - self->ma_lookup = lookdict_string; - #ifdef SHOW_CONVERSION_COUNTS - ++created; - #endif - return 0; - } - - /* XXX This is wrong, but if I knew *how* it was wrong I would fix - * XXX it instead of typing this comment <0.5 wink>. - */ static PyObject * dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds) --- 1672,1675 ---- *************** *** 1691,1733 **** PyObject *self; - /* XXX Is it legit to insist these all be non-NULL? */ - if (!(type && type->tp_alloc && type->tp_init)) { - PyErr_BadInternalCall(); - return NULL; - } - - /* XXX I'm not sure what the 2nd tp_alloc arg is for, and wholly - * unsure what to pass if 0 isn't appropriate in this specific case. - * XXX Will tp_alloc set up GC correctly for dict objects? - * If not, how to tell? If so, how to verify? Dare not add the - * object *twice* to the GC list. - */ self = type->tp_alloc(type, 0); ! if (self == NULL) ! return NULL; ! /* XXX Safe to assume Py_DECREF(self) is OK hereafter? */ ! ! /* XXX This appears to be necessary (core dumps without it). But I ! * would have guessed that, if type is a subclass, it's part of ! * type->tp_init()'s job to call all base class tp_init slots, "bottom ! * up". Apparently not(?). ! */ ! if (dict_init((PyDictObject *)self, args, kwds) < 0) { ! Py_DECREF(self); ! return NULL; ! } ! ! /* XXX If type is PyDictObject, we end up calling dict_init twice. ! * Should that be special-cased? It's a little inefficient, and ! * "created* will get incremented twice. But if type is a subclass, ! * and calls dict_init directly (see last blob of confusions), that's ! * going to happen anyway. ! */ ! if (type->tp_init(self, args, kwds) < 0) { ! Py_DECREF(self); ! return NULL; } - - /* This line I feel confident about . */ return self; } --- 1677,1689 ---- PyObject *self; self = type->tp_alloc(type, 0); ! if (self != NULL) { ! PyDictObject *d = (PyDictObject *)self; ! EMPTY_TO_MINSIZE(d); ! d->ma_lookup = lookdict_string; ! #ifdef SHOW_CONVERSION_COUNTS ! ++created; ! #endif } return self; } *************** *** 1777,1781 **** 0, /* tp_descr_set */ 0, /* tp_dictoffset */ ! (initproc)dict_init, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ dict_new, /* tp_new */ --- 1733,1737 ---- 0, /* tp_descr_set */ 0, /* tp_dictoffset */ ! 0, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ dict_new, /* tp_new */ From gvanrossum@users.sourceforge.net Mon Jul 9 02:32:30 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 08 Jul 2001 18:32:30 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.1.2.25,1.1.2.26 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv18604 Modified Files: Tag: descr-branch PLAN.txt Log Message: Noted that Tim's last remaining issues are resolved. The merged version now builds and tests fine on Linux and Windows. Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Attic/PLAN.txt,v retrieving revision 1.1.2.25 retrieving revision 1.1.2.26 diff -C2 -r1.1.2.25 -r1.1.2.26 *** PLAN.txt 2001/07/08 20:11:23 1.1.2.25 --- PLAN.txt 2001/07/09 01:32:28 1.1.2.26 *************** *** 277,323 **** Merge issues: ! + Tried only on Windows; Unix build may not even compile. ! ! + New std test failures (again on Windows): ! ! test_descr.py ! Two shallow test errors were fixed (relying on exact order of ! dict traversal -- for that matter, it still does, but now the ! correct exact order ). ! ! A core dump was "fixed" (unsure about that!) via adding a ! tp_new slot to dict objects, to ensure that they're initialized ! before being used. ! ! Then it died with ! File "../lib/test\test_descr.py", line 325, in pydicts ! verify(a1.state == 12) ! AttributeError: 'dictionary' object has no attribute 'state' ! ! I don't understand what tp_new is supposed to do for dicts, ! exactly. PEP 253 says ! ! - If the base type defines tp_init as well as tp_new, its tp_new ! should be inheritable: it should call the tp_alloc and the ! tp_init of the type passed in as its first argument. ! ! The tp_new I added doesn't do that, mostly because I couldn't find ! any code that already does that in order to fill in the fine ! points. PEP 253 also says tp_alloc has signature: ! ! PyObject *tp_alloc(PyTypeObject *type, ! PyObject *args, ! PyObject *kwds) ! ! but in reality it appears to be this instead: ! ! typedef PyObject *(*allocfunc)(struct _typeobject *, int); ! ! After lots of guesswork, made a tp_new that got beyond that. ! ! Now it dies with ! ! Testing errors... ! test test_descr failed -- __slots__ = {} should be illegal ---------------------------------------------------------------------------- 2001-07-06 --- 277,281 ---- Merge issues: ! (all resolved -- GvR) ---------------------------------------------------------------------------- 2001-07-06 From tim_one@users.sourceforge.net Mon Jul 9 04:28:38 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 08 Jul 2001 20:28:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.80.2.18,2.80.2.19 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv3925/descr/dist/src/Objects Modified Files: Tag: descr-branch dictobject.c Log Message: Restore some "ain't NULL" asserts. Maybe on Unix you don't care about core dumps, but I get very weary of rebooting Win98SE <0.4 wink>. Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.80.2.18 retrieving revision 2.80.2.19 diff -C2 -r2.80.2.18 -r2.80.2.19 *** dictobject.c 2001/07/09 01:27:53 2.80.2.18 --- dictobject.c 2001/07/09 03:28:36 2.80.2.19 *************** *** 1677,1680 **** --- 1677,1681 ---- PyObject *self; + assert(type != NULL && type->tp_alloc != NULL); self = type->tp_alloc(type, 0); if (self != NULL) { From akuchling@users.sourceforge.net Mon Jul 9 04:57:11 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Sun, 08 Jul 2001 20:57:11 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0247.txt,1.2,1.3 pep-0241.txt,1.8,1.9 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv8689 Modified Files: pep-0247.txt pep-0241.txt Log Message: Change my e-mail address Index: pep-0247.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0247.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** pep-0247.txt 2001/03/28 20:18:03 1.2 --- pep-0247.txt 2001/07/09 03:57:09 1.3 *************** *** 2,6 **** Title: API for Cryptographic Hash Functions Version: $Revision$ ! Author: amk1@bigfoot.com (A.M. Kuchling) Status: Draft Type: Informational --- 2,6 ---- Title: API for Cryptographic Hash Functions Version: $Revision$ ! Author: A.M. Kuchling Status: Draft Type: Informational Index: pep-0241.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0241.txt,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** pep-0241.txt 2001/03/20 15:48:10 1.8 --- pep-0241.txt 2001/07/09 03:57:09 1.9 *************** *** 2,6 **** Title: Metadata for Python Software Packages Version: $Revision$ ! Author: A.M. Kuchling Type: Standards Track Created: 12-Mar-2001 --- 2,6 ---- Title: Metadata for Python Software Packages Version: $Revision$ ! Author: A.M. Kuchling Type: Standards Track Created: 12-Mar-2001 From twouters@users.sourceforge.net Mon Jul 9 11:45:33 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Mon, 09 Jul 2001 03:45:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules regexmodule.c,1.42,1.43 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv11772/Modules Modified Files: regexmodule.c Log Message: initregex(): Check return value of PyErr_Warn() and propagate the exception (if any.) Index: regexmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/regexmodule.c,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -r1.42 -r1.43 *** regexmodule.c 2001/01/22 15:29:14 1.42 --- regexmodule.c 2001/07/09 10:45:31 1.43 *************** *** 661,666 **** d = PyModule_GetDict(m); ! PyErr_Warn(PyExc_DeprecationWarning, ! "the regex module is deprecated; please use the re module"); /* Initialize regex.error exception */ --- 661,668 ---- d = PyModule_GetDict(m); ! if (PyErr_Warn(PyExc_DeprecationWarning, ! "the regex module is deprecated; " ! "please use the re module") < 0) ! return NULL; /* Initialize regex.error exception */ From twouters@users.sourceforge.net Mon Jul 9 13:30:56 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Mon, 09 Jul 2001 05:30:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include rangeobject.h,2.17,2.18 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv758/Include Modified Files: rangeobject.h Log Message: Re-add 'advanced' xrange features, adding DeprecationWarnings as discussed on python-dev. The features will still vanish, however, just one release later. Index: rangeobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/rangeobject.h,v retrieving revision 2.17 retrieving revision 2.18 diff -C2 -r2.17 -r2.18 *** rangeobject.h 2001/07/05 13:24:44 2.17 --- rangeobject.h 2001/07/09 12:30:54 2.18 *************** *** 20,24 **** #define PyRange_Check(op) ((op)->ob_type == &PyRange_Type) ! extern DL_IMPORT(PyObject *) PyRange_New(long, long, long); #ifdef __cplusplus --- 20,24 ---- #define PyRange_Check(op) ((op)->ob_type == &PyRange_Type) ! extern DL_IMPORT(PyObject *) PyRange_New(long, long, long, int); #ifdef __cplusplus From twouters@users.sourceforge.net Mon Jul 9 13:30:56 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Mon, 09 Jul 2001 05:30:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.215,2.216 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv758/Python Modified Files: bltinmodule.c Log Message: Re-add 'advanced' xrange features, adding DeprecationWarnings as discussed on python-dev. The features will still vanish, however, just one release later. Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.215 retrieving revision 2.216 diff -C2 -r2.215 -r2.216 *** bltinmodule.c 2001/07/05 14:44:41 2.215 --- bltinmodule.c 2001/07/09 12:30:54 2.216 *************** *** 1764,1768 **** return NULL; } ! return PyRange_New(ilow, n, istep); } --- 1764,1768 ---- return NULL; } ! return PyRange_New(ilow, n, istep, 1); } From twouters@users.sourceforge.net Mon Jul 9 13:30:56 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Mon, 09 Jul 2001 05:30:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects rangeobject.c,2.25,2.26 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv758/Objects Modified Files: rangeobject.c Log Message: Re-add 'advanced' xrange features, adding DeprecationWarnings as discussed on python-dev. The features will still vanish, however, just one release later. Index: rangeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/rangeobject.c,v retrieving revision 2.25 retrieving revision 2.26 diff -C2 -r2.25 -r2.26 *** rangeobject.c 2001/07/05 13:26:49 2.25 --- rangeobject.c 2001/07/09 12:30:54 2.26 *************** *** 6,9 **** --- 6,12 ---- #include + #define WARN(msg) if (PyErr_Warn(PyExc_DeprecationWarning, msg) < 0) \ + return NULL; + typedef struct { PyObject_HEAD *************** *** 11,37 **** long step; long len; } rangeobject; PyObject * ! PyRange_New(long start, long len, long step) { rangeobject *obj = PyObject_NEW(rangeobject, &PyRange_Type); if (obj == NULL) return NULL; ! if (len == 0) { start = 0; len = 0; step = 1; } else { long last = start + (len - 1) * step; if ((step > 0) ? ! (last > (PyInt_GetMax() - step)) ! :(last < (-1 - PyInt_GetMax() - step))) { PyErr_SetString(PyExc_OverflowError, "integer addition"); return NULL; } } --- 14,87 ---- long step; long len; + int reps; + long totlen; } rangeobject; + static int + long_mul(long i, long j, long *kk) + { + PyObject *a; + PyObject *b; + PyObject *c; + + if ((a = PyInt_FromLong(i)) == NULL) + return 0; + + if ((b = PyInt_FromLong(j)) == NULL) + return 0; + + c = PyNumber_Multiply(a, b); + + Py_DECREF(a); + Py_DECREF(b); + + if (c == NULL) + return 0; + + *kk = PyInt_AS_LONG(c); + Py_DECREF(c); + + if (*kk > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "integer multiplication"); + return 0; + } + else + return 1; + } + PyObject * ! PyRange_New(long start, long len, long step, int reps) { + long totlen = -1; rangeobject *obj = PyObject_NEW(rangeobject, &PyRange_Type); if (obj == NULL) return NULL; + + if (reps != 1) + WARN("PyRange_New's 'repetitions' argument is deprecated"); ! if (len == 0 || reps <= 0) { start = 0; len = 0; step = 1; + reps = 1; + totlen = 0; } else { long last = start + (len - 1) * step; if ((step > 0) ? ! (last > (PyInt_GetMax() - step)) : ! (last < (-1 - PyInt_GetMax() - step))) { PyErr_SetString(PyExc_OverflowError, "integer addition"); return NULL; + } + if (! long_mul(len, (long) reps, &totlen)) { + if(!PyErr_ExceptionMatches(PyExc_OverflowError)) + return NULL; + PyErr_Clear(); + totlen = -1; } } *************** *** 40,43 **** --- 90,95 ---- obj->len = len; obj->step = step; + obj->reps = reps; + obj->totlen = totlen; return (PyObject *) obj; *************** *** 53,61 **** range_item(rangeobject *r, int i) { ! if (i < 0 || i >= r->len) { ! PyErr_SetString(PyExc_IndexError, "xrange object index out of range"); ! return NULL; ! } return PyInt_FromLong(r->start + (i % r->len) * r->step); --- 105,114 ---- range_item(rangeobject *r, int i) { ! if (i < 0 || i >= r->totlen) ! if (r->totlen!=-1) { ! PyErr_SetString(PyExc_IndexError, "xrange object index out of range"); ! return NULL; ! } return PyInt_FromLong(r->start + (i % r->len) * r->step); *************** *** 65,69 **** range_length(rangeobject *r) { ! return r->len; } --- 118,125 ---- range_length(rangeobject *r) { ! if (r->totlen == -1) ! PyErr_SetString(PyExc_OverflowError, ! "xrange object has too many items"); ! return r->totlen; } *************** *** 75,78 **** --- 131,135 ---- */ char buf1[250]; + char buf2[250]; if (r->start == 0 && r->step == 1) *************** *** 89,105 **** r->start + r->len * r->step, r->step); ! return PyString_FromString(buf1); } static PySequenceMethods range_as_sequence = { (inquiry)range_length, /*sq_length*/ 0, /*sq_concat*/ ! 0, /*sq_repeat*/ ! (intargfunc)range_item, /*sq_item*/ ! 0, /*sq_slice*/ 0, /*sq_ass_item*/ 0, /*sq_ass_slice*/ ! 0, /*sq_contains*/ }; --- 146,306 ---- r->start + r->len * r->step, r->step); + + if (r->reps != 1) + sprintf(buf2, "(%s * %d)", buf1, r->reps); + + return PyString_FromString(r->reps == 1 ? buf1 : buf2); + } + + static PyObject * + range_repeat(rangeobject *r, int n) + { + long lreps = 0; + + WARN("xrange object multiplication is deprecated; " + "convert to list instead"); + + if (n <= 0) + return (PyObject *) PyRange_New(0, 0, 1, 1); ! else if (n == 1) { ! Py_INCREF(r); ! return (PyObject *) r; ! } ! ! else if (! long_mul((long) r->reps, (long) n, &lreps)) ! return NULL; ! ! else ! return (PyObject *) PyRange_New( ! r->start, ! r->len, ! r->step, ! (int) lreps); } + static int + range_compare(rangeobject *r1, rangeobject *r2) + { + + if (PyErr_Warn(PyExc_DeprecationWarning, + "xrange object comparision is deprecated; " + "convert to list instead") < 0) + return -1; + + if (r1->start != r2->start) + return r1->start - r2->start; + + else if (r1->step != r2->step) + return r1->step - r2->step; + + else if (r1->len != r2->len) + return r1->len - r2->len; + + else + return r1->reps - r2->reps; + } + + static PyObject * + range_slice(rangeobject *r, int low, int high) + { + WARN("xrange object slicing is deprecated; " + "convert to list instead"); + + if (r->reps != 1) { + PyErr_SetString(PyExc_TypeError, + "cannot slice a replicated xrange"); + return NULL; + } + if (low < 0) + low = 0; + else if (low > r->len) + low = r->len; + if (high < 0) + high = 0; + if (high < low) + high = low; + else if (high > r->len) + high = r->len; + + if (low == 0 && high == r->len) { + Py_INCREF(r); + return (PyObject *) r; + } + + return (PyObject *) PyRange_New( + low * r->step + r->start, + high - low, + r->step, + 1); + } + + static PyObject * + range_tolist(rangeobject *self, PyObject *args) + { + PyObject *thelist; + int j; + + WARN("xrange.tolist() is deprecated; use list(xrange) instead"); + + if (! PyArg_ParseTuple(args, ":tolist")) + return NULL; + + if (self->totlen == -1) + return PyErr_NoMemory(); + + if ((thelist = PyList_New(self->totlen)) == NULL) + return NULL; + + for (j = 0; j < self->totlen; ++j) + if ((PyList_SetItem(thelist, j, (PyObject *) PyInt_FromLong( + self->start + (j % self->len) * self->step))) < 0) + return NULL; + + return thelist; + } + + static PyObject * + range_getattr(rangeobject *r, char *name) + { + PyObject *result; + + static PyMethodDef range_methods[] = { + {"tolist", (PyCFunction)range_tolist, METH_VARARGS, + "tolist() -> list\n" + "Return a list object with the same values.\n" + "(This method is deprecated; use list() instead.)"}, + {NULL, NULL} + }; + static struct memberlist range_members[] = { + {"step", T_LONG, offsetof(rangeobject, step), RO}, + {"start", T_LONG, offsetof(rangeobject, start), RO}, + {"stop", T_LONG, 0, RO}, + {NULL, 0, 0, 0} + }; + + result = Py_FindMethod(range_methods, (PyObject *) r, name); + if (result == NULL) { + PyErr_Clear(); + if (strcmp("stop", name) == 0) + result = PyInt_FromLong(r->start + (r->len * r->step)); + else + result = PyMember_Get((char *)r, range_members, name); + if (result) + WARN("xrange object's 'start', 'stop' and 'step' " + "attributes are deprecated"); + } + return result; + } + static PySequenceMethods range_as_sequence = { (inquiry)range_length, /*sq_length*/ 0, /*sq_concat*/ ! (intargfunc)range_repeat, /*sq_repeat*/ ! (intargfunc)range_item, /*sq_item*/ ! (intintargfunc)range_slice, /*sq_slice*/ 0, /*sq_ass_item*/ 0, /*sq_ass_slice*/ ! 0, /*sq_contains*/ }; *************** *** 112,118 **** (destructor)range_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ ! 0, /*tp_getattr*/ 0, /*tp_setattr*/ ! 0, /*tp_compare*/ (reprfunc)range_repr, /*tp_repr*/ 0, /*tp_as_number*/ --- 313,319 ---- (destructor)range_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ ! (getattrfunc)range_getattr, /*tp_getattr*/ 0, /*tp_setattr*/ ! (cmpfunc)range_compare, /*tp_compare*/ (reprfunc)range_repr, /*tp_repr*/ 0, /*tp_as_number*/ *************** *** 127,128 **** --- 328,331 ---- Py_TPFLAGS_DEFAULT, /*tp_flags*/ }; + + #undef WARN From akuchling@users.sourceforge.net Mon Jul 9 15:26:28 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Mon, 09 Jul 2001 07:26:28 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0262.txt,NONE,1.1 pep-0000.txt,1.105,1.106 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv26931 Modified Files: pep-0000.txt Added Files: pep-0262.txt Log Message: Add PEP 262, "A Database of Installed Python Packages". This is the same version that's just been sent to the Distutils SIG. --- NEW FILE: pep-0262.txt --- PEP: 262 Title: A Database of Installed Python Packages Version: $Revision: 1.1 $ Author: A.M. Kuchling Type: Standards Track Created: 08-Jul-2001 Status: Draft Post-History: Introduction This PEP describes a format for a database of Python packages installed on a system. Requirements We need a way to figure out what packages, and what versions of those packages, are installed on a system. We want to provide features similar to CPAN, APT, or RPM. Required use cases that should be supported are: * Is package X on a system? * What version of package X is installed? * Where can the new version of package X be found? XXX Does this mean "a home page where the user can go and find a download link", or "a place where a program can find the newest version?" Perhaps both... * What files did package X put on my system? * What package did the file x/y/z.py come from? * Has anyone modified x/y/z.py locally? Database Location The database lives in a bunch of files under /lib/python/install/. This location will be called INSTALLDB through the remainder of this PEP. XXX is that a good location? What effect does platform-dependent code vs. platform-independent code have on this? The structure of the database is deliberately kept simple; each file in this directory or its subdirectories (if any) describes a single package. The rationale for scanning subdirectories is that we can move to a directory-based indexing scheme if the package directory contains too many entries. That is, instead of INSTALLDB/Numeric, we could switch to INSTALLDB/N/Nu/Numeric or some similar scheme. XXX how much do we care about performance? Do we really need to use an anydbm file or something similar? XXX is the actual filename important? Let's say the installation data for PIL is in the file INSTALLDB/Numeric. Is this OK? When we want to figure out if Numeric is installed, do we want to open a single file, or have to scan them all? Note that for human-interface purposes, we'll often have to scan all the packages anyway, for a case-insensitive or keyword search. Database Contents Each file in INSTALLDB or its subdirectories describes a single package, and has the following contents: An initial line listing the sections in this file, separated by whitespace. Currently this will always be 'PKG-INFO FILES'. This is for future-proofing; if we add a new section, for example to list documentation files, then we'd add a DOCS section and list it in the contents. Sections are always separated by blank lines. XXX too simple? [PKG-INFO section] An initial set of RFC-822 headers containing the package information for a file, as described in PEP 241, "Metadata for Python Software Packages". A blank line indicating the end of the PKG-INFO section. An entry for each file installed by the package. XXX Are .pyc and .pyo files in this list? What about compiled .so files? AMK thinks "no" and "yes", respectively. Each file's entry is a single tab-delimited line that contains the following fields: XXX should each file entry be all on one line and tab-delimited? More RFC-822 headers? AMK thinks tab-delimited seems sufficent. * The file's size * XXX do we need to store permissions? The owner/group? * An MD5 digest of the file, written in hex. (XXX All 16 bytes of the digest seems unnecessary; first 8 bytes only, maybe? Is a zlib.crc32() hash sufficient?) * The file's full path, as installed on the system. (XXX should it be relative to sys.prefix, or sys.prefix + '/lib/python?' If so, full paths are still needed; consider a package that installs a startup script such as /etc/init.d/zope) * XXX some sort of type indicator, to indicate whether this is a Python module, binary module, documentation file, config file? Do we need this? A package that uses the Distutils for installation will automatically update the database. Packages that roll their own installation XXX what's the relationship between this database and the RPM or DPKG database? I'm tempted to make the Python database completely optional; a distributor can preserve the interface of the package management tool and replace it with their own wrapper on top of their own package manager. (XXX but how would the Distutils know that, and not bother to update the Python database?) Deliverables Patches to the Distutils that 1) implement a InstallationDatabase class, 2) Update the database when a new package is installed. 3) a simple package management tool, features to be added to this PEP. (Or a separate PEP?) References [1] Michael Muller's patch (posted to the Distutils-SIG around 28 Dec 1999) generates a list of installed files. Acknowledgements Ideas for this PEP originally came from postings by Greg Ward, Fred Drake, Mats Wichmann, and others. Many changes and rewrites to this document were suggested by the readers of the Distutils SIG. Copyright This document has been placed in the public domain. Local Variables: mode: indented-text indent-tabs-mode: nil End: Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.105 retrieving revision 1.106 diff -C2 -r1.105 -r1.106 *** pep-0000.txt 2001/07/07 18:35:10 1.105 --- pep-0000.txt 2001/07/09 14:26:26 1.106 *************** *** 65,68 **** --- 65,69 ---- S 260 pep-0260.txt Simplify xrange() van Rossum S 261 pep-0261.txt Support for "wide" Unicode characters Prescod + S 262 pep-0262.txt Database of Installed Python Packages Kuchling Py-in-the-sky PEPs (not ready; may become active yet) *************** *** 197,200 **** --- 198,202 ---- S 260 pep-0260.txt Simplify xrange() van Rossum S 261 pep-0261.txt Support for "wide" Unicode characters Prescod + S 262 pep-0262.txt Database of Installed Python Packages Kuchling Key From twouters@users.sourceforge.net Mon Jul 9 15:34:19 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Mon, 09 Jul 2001 07:34:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.117.2.6,1.117.2.7 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv28195/api Modified Files: Tag: release21-maint api.tex Log Message: Fix for SF bug #436525, reported by Greg Kochanski: The block/unblock thread macros are called 'Py_BLOCK_THREADS' and 'Py_UNBLOCK_THREADS', not 'Py_BEGIN_BLOCK_THREADS' and 'Py_BEGIN_UNBLOCK_THREADS'. Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.117.2.6 retrieving revision 1.117.2.7 diff -C2 -r1.117.2.6 -r1.117.2.7 *** api.tex 2001/06/21 18:56:49 1.117.2.6 --- api.tex 2001/07/09 14:34:16 1.117.2.7 *************** *** 4540,4544 **** \end{csimplemacrodesc} ! \begin{csimplemacrodesc}{Py_BEGIN_BLOCK_THREADS} This macro expands to \samp{PyEval_RestoreThread(_save);} i.e. it is equivalent to \code{Py_END_ALLOW_THREADS} without the closing --- 4540,4544 ---- \end{csimplemacrodesc} ! \begin{csimplemacrodesc}{Py_BLOCK_THREADS} This macro expands to \samp{PyEval_RestoreThread(_save);} i.e. it is equivalent to \code{Py_END_ALLOW_THREADS} without the closing *************** *** 4547,4551 **** \end{csimplemacrodesc} ! \begin{csimplemacrodesc}{Py_BEGIN_UNBLOCK_THREADS} This macro expands to \samp{_save = PyEval_SaveThread();} i.e. it is equivalent to \code{Py_BEGIN_ALLOW_THREADS} without the opening brace --- 4547,4551 ---- \end{csimplemacrodesc} ! \begin{csimplemacrodesc}{Py_UNBLOCK_THREADS} This macro expands to \samp{_save = PyEval_SaveThread();} i.e. it is equivalent to \code{Py_BEGIN_ALLOW_THREADS} without the opening brace From twouters@users.sourceforge.net Mon Jul 9 15:35:03 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Mon, 09 Jul 2001 07:35:03 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.127,1.128 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv28842/api Modified Files: api.tex Log Message: Fix for SF bug #436525, reported by Greg Kochanski: The block/unblock thread macros are called 'Py_BLOCK_THREADS' and 'Py_UNBLOCK_THREADS', not 'Py_BEGIN_BLOCK_THREADS' and 'Py_BEGIN_UNBLOCK_THREADS'. Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.127 retrieving revision 1.128 diff -C2 -r1.127 -r1.128 *** api.tex 2001/06/20 21:39:12 1.127 --- api.tex 2001/07/09 14:35:01 1.128 *************** *** 4599,4603 **** \end{csimplemacrodesc} ! \begin{csimplemacrodesc}{Py_BEGIN_BLOCK_THREADS} This macro expands to \samp{PyEval_RestoreThread(_save);} i.e. it is equivalent to \code{Py_END_ALLOW_THREADS} without the closing --- 4599,4603 ---- \end{csimplemacrodesc} ! \begin{csimplemacrodesc}{Py_BLOCK_THREADS} This macro expands to \samp{PyEval_RestoreThread(_save);} i.e. it is equivalent to \code{Py_END_ALLOW_THREADS} without the closing *************** *** 4606,4610 **** \end{csimplemacrodesc} ! \begin{csimplemacrodesc}{Py_BEGIN_UNBLOCK_THREADS} This macro expands to \samp{_save = PyEval_SaveThread();} i.e. it is equivalent to \code{Py_BEGIN_ALLOW_THREADS} without the opening brace --- 4606,4610 ---- \end{csimplemacrodesc} ! \begin{csimplemacrodesc}{Py_UNBLOCK_THREADS} This macro expands to \samp{_save = PyEval_SaveThread();} i.e. it is equivalent to \code{Py_BEGIN_ALLOW_THREADS} without the opening brace From fdrake@users.sourceforge.net Mon Jul 9 16:00:44 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 09 Jul 2001 08:00:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools/sgmlconv conversion.xml,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools/sgmlconv In directory usw-pr-cvs1:/tmp/cvs-serv2597/tools/sgmlconv Modified Files: conversion.xml Log Message: Add conversion information for the grammar production support (preliminary). Index: conversion.xml =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/sgmlconv/conversion.xml,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -r1.15 -r1.16 *** conversion.xml 2001/07/07 06:00:36 1.15 --- conversion.xml 2001/07/09 15:00:42 1.16 *************** *** 602,605 **** --- 602,621 ---- + + + + + + + + + + + + + + + + From fdrake@users.sourceforge.net Mon Jul 9 17:04:05 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 09 Jul 2001 09:04:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/doc doc.tex,1.43,1.44 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/doc In directory usw-pr-cvs1:/tmp/cvs-serv18568/doc Modified Files: doc.tex Log Message: Add a little bit more about the XML migration plan. This still needs a lot of work, but mostly it needs time spent doing the work to make the generated XML useful. Index: doc.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/doc/doc.tex,v retrieving revision 1.43 retrieving revision 1.44 diff -C2 -r1.43 -r1.44 *** doc.tex 2001/07/06 22:34:33 1.43 --- doc.tex 2001/07/09 16:04:03 1.44 *************** *** 1063,1067 **** the tools for Python documentation processing. In particular, the generated HTML looks good! There is also an advantage for the ! eventual conversion of the documentation to SGML (see section \ref{futures}, ``Future Directions''). --- 1063,1067 ---- the tools for Python documentation processing. In particular, the generated HTML looks good! There is also an advantage for the ! eventual conversion of the documentation to XML (see section \ref{futures}, ``Future Directions''). *************** *** 1586,1590 **** especially those using ordinary text editors. There are also additional abilities to define content models. A number of ! high-quality tools with demonstrated maturity is available, but most are not free; for those which are, portability issues remain a problem. --- 1586,1590 ---- especially those using ordinary text editors. There are also additional abilities to define content models. A number of ! high-quality tools with demonstrated maturity are available, but most are not free; for those which are, portability issues remain a problem. *************** *** 1598,1604 **** high-quality tools which support some of the most important related standards is not immediate. Many tools are likely to be ! free. ! XXX Eventual migration to SGML/XML. \subsection{Discussion Forums \label{discussion}} --- 1598,1623 ---- high-quality tools which support some of the most important related standards is not immediate. Many tools are likely to be ! free, and the portability issues of those which are, are not ! expected to be significant. ! It turns out that converting to an XML or SGML system holds ! promise for translators as well; how much can be done to ease the ! burden on translators remains to be seen, and may have some impact ! on the schema and specific technologies used. ! ! XXX Eventual migration to XML. ! ! The documentation will be moved to XML in the future, and tools ! are being written which will convert the documentation from the ! current format to something close to a finished version, to the ! extent that the desired information is already present in the ! documentation. Some XSLT stylesheets have been started for ! presenting a preliminary XML version as HTML, but the results are ! fairly rough.. ! ! The timeframe for the conversion is not clear since there doesn't ! seem to be much time available to work on this, but the appearant ! benefits are growing more substantial at a moderately rapid pace. ! \subsection{Discussion Forums \label{discussion}} From gvanrossum@users.sourceforge.net Mon Jul 9 19:11:58 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 09 Jul 2001 11:11:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include descrobject.h,1.1.2.6,1.1.2.7 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv18303/Include Modified Files: Tag: descr-branch descrobject.h Log Message: Total rewrite of the descriptor object implementation, to get rid of the discriminated union. The ultimate goal here was to make the definition of PyDescr_IsData() more reasonable: it not just tests whether the type has a __set__ method (i.e. a tp_descr_set slot). If it does, it's a data descriptor, otherwise it's not. This is important when an attribute is found in both the __dict__ of the class and the __dict__ of the instance: when the descriptor in the class is a data descriptor, it has precedence, but when it is a non-data (e.g. method) desscriptor, the instance __dict__ takes precedence. Previously, this function had to have special dispensation to look inside descriptor objects -- this is no longer necessary. Note that the presence of a __set__ method doesn't mean that the attribute can actually be assigned to: this is also used to make attributes deliberately read-only, by making the __set__ method always raise an exception. (Q: should it raise AttributeError or TypeError? Traditionally, this has raised TypeError!) Index: descrobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/Attic/descrobject.h,v retrieving revision 1.1.2.6 retrieving revision 1.1.2.7 diff -C2 -r1.1.2.6 -r1.1.2.7 *** descrobject.h 2001/05/01 21:04:21 1.1.2.6 --- descrobject.h 2001/07/09 18:11:56 1.1.2.7 *************** *** 1,3 **** ! /* XXX getter, setter, and struct getsetlist need 'Py'-prefixed names */ typedef PyObject *(*getter)(PyObject *, void *); --- 1,3 ---- ! /* XXX getter, setter, getsetlist and wrapperbase need 'Py'-prefixed names */ typedef PyObject *(*getter)(PyObject *, void *); *************** *** 11,15 **** }; ! typedef PyObject *(*wrapperfunc)(PyObject *self, PyObject *args, void *wrapped); struct wrapperbase { --- 11,16 ---- }; ! typedef PyObject *(*wrapperfunc)(PyObject *self, PyObject *args, ! void *wrapped); struct wrapperbase { *************** *** 19,28 **** }; - extern PyTypeObject PyDescr_Type; - - #define PyDescr_Check(d) ((d)->ob_type == &PyDescr_Type) - - typedef struct PyDescrObject PyDescrObject; - extern DL_IMPORT(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *); extern DL_IMPORT(PyObject *) PyDescr_NewMember(PyTypeObject *, --- 20,23 ---- *************** *** 32,38 **** extern DL_IMPORT(PyObject *) PyDescr_NewWrapper(PyTypeObject *, struct wrapperbase *, void *); - extern DL_IMPORT(int) PyDescr_IsMethod(PyObject *); extern DL_IMPORT(int) PyDescr_IsData(PyObject *); extern DL_IMPORT(PyObject *) PyDictProxy_New(PyObject *); ! extern DL_IMPORT(PyObject *) PyWrapper_New(PyDescrObject *, PyObject *); --- 27,32 ---- extern DL_IMPORT(PyObject *) PyDescr_NewWrapper(PyTypeObject *, struct wrapperbase *, void *); extern DL_IMPORT(int) PyDescr_IsData(PyObject *); extern DL_IMPORT(PyObject *) PyDictProxy_New(PyObject *); ! extern DL_IMPORT(PyObject *) PyWrapper_New(PyObject *, PyObject *); From gvanrossum@users.sourceforge.net Mon Jul 9 19:11:58 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 09 Jul 2001 11:11:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects descrobject.c,1.1.2.13,1.1.2.14 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv18303/Objects Modified Files: Tag: descr-branch descrobject.c Log Message: Total rewrite of the descriptor object implementation, to get rid of the discriminated union. The ultimate goal here was to make the definition of PyDescr_IsData() more reasonable: it not just tests whether the type has a __set__ method (i.e. a tp_descr_set slot). If it does, it's a data descriptor, otherwise it's not. This is important when an attribute is found in both the __dict__ of the class and the __dict__ of the instance: when the descriptor in the class is a data descriptor, it has precedence, but when it is a non-data (e.g. method) desscriptor, the instance __dict__ takes precedence. Previously, this function had to have special dispensation to look inside descriptor objects -- this is no longer necessary. Note that the presence of a __set__ method doesn't mean that the attribute can actually be assigned to: this is also used to make attributes deliberately read-only, by making the __set__ method always raise an exception. (Q: should it raise AttributeError or TypeError? Traditionally, this has raised TypeError!) Index: descrobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/Attic/descrobject.c,v retrieving revision 1.1.2.13 retrieving revision 1.1.2.14 diff -C2 -r1.1.2.13 -r1.1.2.14 *** descrobject.c 2001/07/03 09:24:39 1.1.2.13 --- descrobject.c 2001/07/09 18:11:56 1.1.2.14 *************** *** 4,35 **** #include "structmember.h" /* Why is this not included in Python.h? */ ! struct wrapperdescr { ! struct wrapperbase *base; ! void *wrapped; /* This can be any function pointer */ ! }; ! /* Descriptor object */ ! struct PyDescrObject { ! PyObject_HEAD [...1084 lines suppressed...] PyObject * ! PyWrapper_New(PyDescrObject *descr, PyObject *self) { wrapperobject *wp; ! assert(descr->d_flavor == DF_WRAPPER); assert(PyObject_IsInstance(self, (PyObject *)(descr->d_type))); --- 820,830 ---- PyObject * ! PyWrapper_New(PyObject *d, PyObject *self) { wrapperobject *wp; + PyWrapperDescrObject *descr; ! assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type)); ! descr = (PyWrapperDescrObject *)d; assert(PyObject_IsInstance(self, (PyObject *)(descr->d_type))); From tim_one@users.sourceforge.net Mon Jul 9 19:15:40 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 09 Jul 2001 11:15:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules regexmodule.c,1.43,1.44 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv20574/python/dist/src/Modules Modified Files: regexmodule.c Log Message: initregex(): this function is declared void, so the recent change to return NULL in an error case was itself an error. Index: regexmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/regexmodule.c,v retrieving revision 1.43 retrieving revision 1.44 diff -C2 -r1.43 -r1.44 *** regexmodule.c 2001/07/09 10:45:31 1.43 --- regexmodule.c 2001/07/09 18:15:38 1.44 *************** *** 664,668 **** "the regex module is deprecated; " "please use the re module") < 0) ! return NULL; /* Initialize regex.error exception */ --- 664,668 ---- "the regex module is deprecated; " "please use the re module") < 0) ! return; /* Initialize regex.error exception */ From gvanrossum@users.sourceforge.net Mon Jul 9 19:47:14 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 09 Jul 2001 11:47:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects descrobject.c,1.1.2.14,1.1.2.15 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv30009 Modified Files: Tag: descr-branch descrobject.c Log Message: Allow None as the first argument to the tp_descr_get slot (a.k.a. __get__). Index: descrobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/Attic/descrobject.c,v retrieving revision 1.1.2.14 retrieving revision 1.1.2.15 diff -C2 -r1.1.2.14 -r1.1.2.15 *** descrobject.c 2001/07/09 18:11:56 1.1.2.14 --- descrobject.c 2001/07/09 18:47:12 1.1.2.15 *************** *** 94,98 **** PyObject **pres) { ! if (obj == NULL) { Py_INCREF(descr); *pres = (PyObject *)descr; --- 94,98 ---- PyObject **pres) { ! if (obj == NULL || obj == Py_None) { Py_INCREF(descr); *pres = (PyObject *)descr; From gvanrossum@users.sourceforge.net Mon Jul 9 20:05:41 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 09 Jul 2001 12:05:41 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0252.txt,1.10,1.11 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv3443 Modified Files: pep-0252.txt Log Message: Simplify the attribute descriptor spec: the only attributes defined are now __name__, __doc__, __objclass__, __get__ and __set__. This is also what's implemented now. A bunch of things (including the precedence rules used when an attribute exists both in the instance __dict__ and in the class __dict__) are clarified. The C API and other stuff still need to be fleshed out. Index: pep-0252.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0252.txt,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -r1.10 -r1.11 *** pep-0252.txt 2001/07/05 18:57:36 1.10 --- pep-0252.txt 2001/07/09 19:05:39 1.11 *************** *** 12,22 **** This PEP proposes changes to the introspection API for types that ! makes them look more like classes. For example, type(x) will be ! equivalent to x.__class__ for most built-in types. When C is ! x.__class__, x.meth(a) will be equivalent to C.meth(x, a), and ! C.__dict__ contains descriptors for x's methods and other ! attributes. ! The PEP also introduces a new approach to specifying attributes, using attribute descriptors, or descriptors for short. Descriptors unify and generalize several different common --- 12,22 ---- This PEP proposes changes to the introspection API for types that ! makes them look more like classes, and their instances more like ! class instances. For example, type(x) will be equivalent to ! x.__class__ for most built-in types. When C is x.__class__, ! x.meth(a) will generally be equivalent to C.meth(x, a), and ! C.__dict__ contains x's methods and other attributes. ! This PEP also introduces a new approach to specifying attributes, using attribute descriptors, or descriptors for short. Descriptors unify and generalize several different common *************** *** 25,29 **** --- 25,32 ---- generalized attribute represented by getter and setter functions. + Based on the generalized descriptor API, this PEP also introduces + a way to declare class methods and static methods. + Introduction *************** *** 73,77 **** (The last two rules together are often summarized as the ! left-to-right, depth-first rule for attribute search.) The type-based introspection API is supported in one form or --- 76,83 ---- (The last two rules together are often summarized as the ! left-to-right, depth-first rule for attribute search. This is the ! classic Python attribute lookup rule. Note that PEP 253 will ! propose to change the attribute lookup order, and if accepted, ! this PEP will follow suit.) The type-based introspection API is supported in one form or *************** *** 112,117 **** processors. For example, the socket module exports the SocketType object, but this currently doesn't tell us what methods are ! defined on socket objects. Using the class API, SocketType shows ! us exactly what the methods for socket objects are, and we can even extract their docstrings, without creating a socket. (Since this is a C extension module, the source-scanning approach to --- 118,123 ---- processors. For example, the socket module exports the SocketType object, but this currently doesn't tell us what methods are ! defined on socket objects. Using the class API, SocketType would ! show exactly what the methods for socket objects are, and we can even extract their docstrings, without creating a socket. (Since this is a C extension module, the source-scanning approach to *************** *** 125,154 **** knowable by inspection of the object's type or class, which is accessible through obj.__class__ or type(obj). (I'm using type ! and class interchangeably, because that's the goal of the ! exercise.) ! ! (XXX static and dynamic are lousy names, because the "static" ! attributes may actually behave quite dynamically.) ! The names and values of dynamic properties are typically stored in ! a dictionary, and this dictionary is typically accessible as ! obj.__dict__. The rest of this specification is more concerned ! with discovering the names and properties of static attributes ! than with dynamic attributes. Examples of dynamic attributes are instance variables of class instances, module attributes, etc. Examples of static attributes are the methods of built-in objects like lists and dictionaries, ! and the attributes of frame and code objects (c.co_code, c.co_filename, etc.). When an object with dynamic attributes exposes these through its __dict__ attribute, __dict__ is a static attribute. In the discussion below, I distinguish two kinds of objects: regular objects (e.g. lists, ints, functions) and meta-objects. ! Meta-objects are types and classes. Meta-objects are also regular objects, but we're mostly interested in them because they are referenced by the __class__ attribute of regular objects (or by ! the __bases__ attribute of meta-objects). The class introspection API consists of the following elements: --- 131,163 ---- knowable by inspection of the object's type or class, which is accessible through obj.__class__ or type(obj). (I'm using type ! and class interchangeably; a clumsy but descriptive term that fits ! both is "meta-object".) ! (XXX static and dynamic are not great terms to use here, because ! "static" attributes may actually behave quite dynamically, and ! because they have nothing to do with static class members in C++ ! or Java.) Examples of dynamic attributes are instance variables of class instances, module attributes, etc. Examples of static attributes are the methods of built-in objects like lists and dictionaries, ! and the attributes of frame and code objects (f.f_code, c.co_filename, etc.). When an object with dynamic attributes exposes these through its __dict__ attribute, __dict__ is a static attribute. + The names and values of dynamic properties are typically stored in + a dictionary, and this dictionary is typically accessible as + obj.__dict__. The rest of this specification is more concerned + with discovering the names and properties of static attributes + than with dynamic attributes; the latter are easily discovered by + inspection of obj.__dict__. + In the discussion below, I distinguish two kinds of objects: regular objects (e.g. lists, ints, functions) and meta-objects. ! Types and classes and meta-objects. Meta-objects are also regular objects, but we're mostly interested in them because they are referenced by the __class__ attribute of regular objects (or by ! the __bases__ attribute of other meta-objects). The class introspection API consists of the following elements: *************** *** 162,170 **** - attribute descriptors. 1. The __dict__ attribute on regular objects A regular object may have a __dict__ attribute. If it does, this should be a mapping (not necessarily a dictionary) ! supporting at least __getitem__, keys(), and has_key(). This gives the dynamic attributes of the object. The keys in the mapping give attribute names, and the corresponding values give --- 171,183 ---- - attribute descriptors. + Together, these not only tell us about *all* attributes defined by + a meta-object, but they also help us calculate the value of a + specific attribute of a given object. + 1. The __dict__ attribute on regular objects A regular object may have a __dict__ attribute. If it does, this should be a mapping (not necessarily a dictionary) ! supporting at least __getitem__(), keys(), and has_key(). This gives the dynamic attributes of the object. The keys in the mapping give attribute names, and the corresponding values give *************** *** 179,195 **** 2. The __class__ attribute on regular objects ! A regular object may have a __class__ attributes. If it does, ! this references a meta-object. A meta-object can define static ! attributes for the regular object whose __class__ it is. 3. The __dict__ attribute on meta-objects A meta-object may have a __dict__ attribute, of the same form ! as the __dict__ attribute for regular objects (mapping, etc). ! If it does, the keys of the meta-object's __dict__ are names of ! static attributes for the corresponding regular object. The ! values are attribute descriptors; we'll explain these later. ! (An unbound method is a special case of an attribute ! descriptor.) Becase a meta-object is also a regular object, the items in a --- 192,209 ---- 2. The __class__ attribute on regular objects ! A regular object usually has a __class__ attribute. If it ! does, this references a meta-object. A meta-object can define ! static attributes for the regular object whose __class__ it ! is. This is normally done through the following mechanism: 3. The __dict__ attribute on meta-objects A meta-object may have a __dict__ attribute, of the same form ! as the __dict__ attribute for regular objects (a mapping but ! not necessarily a dictionary). If it does, the keys of the ! meta-object's __dict__ are names of static attributes for the ! corresponding regular object. The values are attribute ! descriptors; we'll explain these later. An unbound method is a ! special case of an attribute descriptor. Becase a meta-object is also a regular object, the items in a *************** *** 208,241 **** meta-objects, the bases. An absent __bases__ is equivalent to an empty sequece of bases. There must never be a cycle in the ! relationship between meta objects defined by __bases__ attributes; in other words, the __bases__ attributes define an ! inheritance tree, where the root of the tree is the __class__ ! attribute of a regular object, and the leaves of the trees are ! meta-objects without bases. The __dict__ attributes of the ! meta-objects in the inheritance tree supply attribute ! descriptors for the regular object whose __class__ is at the ! top of the inheritance tree. 5. Precedence rules ! When two meta-objects in the inheritance tree both define an ! attribute descriptor with the same name, the left-to-right ! depth-first rule applies. (XXX define rigorously.) When a dynamic attribute (one defined in a regular object's __dict__) has the same name as a static attribute (one defined ! by a meta-object in the inheritance tree rooted at the regular ! object's __class__), the dynamic attribute *usually* wins, but ! for some attributes the meta-object may specify that the static ! attribute overrides the dynamic attribute. ! ! (We can't have a simples rule like "static overrides dynamic" ! or "dynamic overrides static", because some static attributes ! indeed override dynamic attributes, e.g. a key '__class__' in ! an instance's __dict__ is ignored in favor of the statically ! defined __class__ pointer, but on the other hand most keys in ! inst.__dict__ override attributes defined in inst.__class__. ! The mechanism whereby a meta-object can specify that a ! particular attribute has precedence is not yet specified.) 6. Attribute descriptors --- 222,264 ---- meta-objects, the bases. An absent __bases__ is equivalent to an empty sequece of bases. There must never be a cycle in the ! relationship between meta-objects defined by __bases__ attributes; in other words, the __bases__ attributes define an ! directed acyclic graph. (It is not necessarily a tree, since ! multiple classes can have the same base class.) The __dict__ ! attributes of the meta-objects in the inheritance graph supply ! attribute descriptors for the regular object whose __class__ is ! at the top of the inheritance graph. 5. Precedence rules ! When two meta-objects in the inheritance graph for a given ! regular object both define an attribute descriptor with the ! same name, the left-to-right depth-first rule applies. (This ! is the classic Python attribute lookup rule. Note that PEP 253 ! will propose to change the attribute lookup order, and if ! accepted, this PEP will follow suit.) When a dynamic attribute (one defined in a regular object's __dict__) has the same name as a static attribute (one defined ! by a meta-object in the inheritance graph rooted at the regular ! object's __class__), the static attribute has precedence if it ! is a descriptor that defines a __set__ method (see below); ! otherwise (if there is no __set__ method) the dynamic attribute ! has precedence. ! ! Rationale: we can't have a simples rule like "static overrides ! dynamic" or "dynamic overrides static", because some static ! attributes indeed override dynamic attributes, e.g. a key ! '__class__' in an instance's __dict__ is ignored in favor of ! the statically defined __class__ pointer, but on the other hand ! most keys in inst.__dict__ override attributes defined in ! inst.__class__. Presence of a __set__ method on a descriptor ! indicates that this is a data descriptor. (Even read-only data ! descriptors have a __set__ method: it always raises an ! exception.) Absence of a __set__ method on a descriptor ! indicates that the descriptor isn't interested in intercepting ! assignment, and then the classic rule applies: an instance ! variable with the same name as a method hides the method until ! it is deleted. 6. Attribute descriptors *************** *** 243,250 **** This is where it gets interesting -- and messy. Attribute descriptors (descriptors for short) are stored in the ! meta-object's __dict__, and have two uses: a descriptor can be ! used to get or set the corresponding attribute value on the ! (non-meta) object, and it has an additional interface that ! describes the attribute for documentation or introspection purposes. --- 266,274 ---- This is where it gets interesting -- and messy. Attribute descriptors (descriptors for short) are stored in the ! meta-object's __dict__ (or in the __dict__ of one of its ! ancestors), and have two uses: a descriptor can be used to get ! or set the corresponding attribute value on the (regular, ! non-meta) object, and it has an additional interface that ! describes the attribute for documentation and introspection purposes. *************** *** 257,270 **** If an object found in the meta-object's __dict__ is not an ! attribute descriptor, backward compatibility dictates ! semantics. This basically means that if it is a Python function or an unbound method, the attribute is a method; ! otherwise, it is the default value for a data attribute. ! Backwards compatibility also dictates that (in the absence of a ! __setattr__ method) it is legal to assign to an attribute of ! type method, and that this creates a data attribute shadowing ! the method for this particular instance. However, these ! semantics are only required for backwards compatibility with ! regular classes. The introspection API is a read-only API. We don't define the --- 281,294 ---- If an object found in the meta-object's __dict__ is not an ! attribute descriptor, backward compatibility dictates certain ! minimal semantics. This basically means that if it is a Python function or an unbound method, the attribute is a method; ! otherwise, it is the default value for a dynamic data ! attribute. Backwards compatibility also dictates that (in the ! absence of a __setattr__ method) it is legal to assign to an ! attribute corresponding to a method, and that this creates a ! data attribute shadowing the method for this particular ! instance. However, these semantics are only required for ! backwards compatibility with regular classes. The introspection API is a read-only API. We don't define the *************** *** 272,395 **** __class__ and __bases__), nor the effect of assignment to the items of a __dict__. Generally, such assignments should be ! considered off-limits. An extension of this PEP may define some ! semantics for some such assignments. (Especially because ! currently instances support assignment to __class__ and __dict__, ! and classes support assignment to __bases__ and __dict__.) Specification of the attribute descriptor API ! Attribute descriptors have the following attributes. In the examples, x is an object, C is x.__class__, x.meth() is a method, ! and x.ivar is a data attribute or instance variable. ! - name: the original attribute name. Note that because of ! aliasing and renaming, the attribute may be known under a different name, but this is the name under which it was born. ! Example: C.meth.name == 'meth'. ! - doc: the attribute's documentation string. ! - objclass: the class that declared this attribute. The descriptor only applies to objects that are instances of this class (this includes instances of its subclasses). Example: ! C.meth.objclass is C. ! - kind: either "method" or "data". This distinguishes between ! methods and data attributes. The primary operation on a method ! attribute is to call it. The primary operations on a data ! attribute are to get and to set it. Example: C.meth.kind == ! 'method'; C.ivar.kind == 'data'. ! ! - default: for optional data attributes, this gives a default or ! initial value. XXX Python has two kinds of semantics for ! referencing "absent" attributes: this may raise an ! AttributeError, or it may produce a default value stored ! somewhere in the class. There could be a flag that ! distinguishes between these two cases. Also, there could be a ! flag that tells whether it's OK to delete an attribute (and what ! happens then -- a default value takes its place, or it's truly ! gone). ! ! - attrclass: for data attributes, this can be the class of the ! attribute value, or None. If this is not None, the attribute ! value is restricted to being an instance of this class (or of a ! subclass thereof). If this is None, the attribute value is not ! constrained. For method attributes, this should normally be ! None (a class is not sufficient information to describe a method ! signature). If and when optional static typing is added to ! Python, this the meaning of this attribute may change to ! describe the type of the attribute. ! ! - signature: for methods, an object that describes the signature ! of the method. Signature objects will be described further ! below. ! ! - readonly: Boolean indicating whether assignment to this ! attribute is disallowed. This is usually true for methods. ! Example: C.meth.readonly == 1; C.ivar.readonly == 0. ! ! - get(): a function of one argument that retrieves the attribute ! value from an object. Examples: C.ivar.get(x) ~~ x.ivar; ! C.meth.get(x) ~~ x.meth. ! ! - set(): a function of two arguments that sets the attribute value ! on the object. If readonly is set, this method raises a ! TypeError exception. Example: C.ivar.set(x, y) ~~ x.ivar = y. ! ! - call(): for method descriptors, this is a function of at least ! one argument that calls the method. The first argument is the ! object whose method is called; the remaining arguments ! (including keyword arguments) are passed on to the method. ! Example: C.meth.call(x, 1, 2) ~~ x.meth(1, 2). ! ! - bind(): for method descriptiors, this is a function of one ! argument that returns a "bound method object". This in turn can ! be called exactly like the method should be called (in fact this ! is what is returned for a bound method). This is the same as ! get(). Example: C.meth.bind(x) ~~ x.meth. ! ! For convenience, __name__ and __doc__ are defined as aliases for ! name and doc. Also for convenience, calling the descriptor can do ! one of three things: ! ! - Calling a method descriptor is the same as calling its call() ! method. Example: C.meth(x, 1, 2) ~~ x.meth(1, 2). ! ! - Calling a data descriptor with one argument is the same as ! calling its get() method. Example: C.ivar(x) ~~ x.ivar. ! ! - Calling a data descriptor with two arguments is the same as ! calling its set() method. Example: C.ivar(x, y) ~~ x.ivar = y. ! ! Note that this specification does not define how to create ! specific attribute descriptors. This is up to the individual ! attribute descriptor implementations, of which there may be many. ! Specification of the signature object API XXX Discussion XXX Examples XXX Backwards compatibility XXX - Compatibility of C API - XXX - Warnings and Errors XXX Implementation --- 296,379 ---- __class__ and __bases__), nor the effect of assignment to the items of a __dict__. Generally, such assignments should be ! considered off-limits. A future PEP may define some semantics for ! some such assignments. (Especially because currently instances ! support assignment to __class__ and __dict__, and classes support ! assignment to __bases__ and __dict__.) Specification of the attribute descriptor API ! Attribute descriptors may have the following attributes. In the examples, x is an object, C is x.__class__, x.meth() is a method, ! and x.ivar is a data attribute or instance variable. All ! attributes are optional -- a specific attribute may or may not be ! present on a given descriptor. An absent attribute means that the ! corresponding information is not available or the corresponding ! functionality is not implemented. ! - __name__: the attribute name. Because of aliasing and renaming, ! the attribute may (additionally or exclusively) be known under a different name, but this is the name under which it was born. ! Example: C.meth.__name__ == 'meth'. ! - __doc__: the attribute's documentation string. This may be ! None. ! - __objclass__: the class that declared this attribute. The descriptor only applies to objects that are instances of this class (this includes instances of its subclasses). Example: ! C.meth.__objclass__ is C. ! ! - __get__(): a function callable with one or two arguments that ! retrieves the attribute value from an object. With one ! argument, X, this either (for data attributes) retrieves the ! attribute value from X or (for method attributes) binds the ! attribute to X (returning some form of "bound" object that ! receives an implied first argument of X when called). With two ! arguments, X and T, T must be a meta-object that restricts the ! type of X. X must either be an instance of T (in which the ! effect is the same as when T is omitted), or None. When X is ! None, this should be a method descriptor, and the result is an ! *unbound* method restricted to objects whose type is (a ! descendent of) T. (For methods, this is called a "binding" ! operation, even if X==None. Exactly what is returned by the ! binding operation depends on the semantics of the descriptor; ! for example, class methods ignore the instance and bind to the ! type instead.) ! ! - __set__(): a function of two arguments that sets the attribute ! value on the object. If the attribute is read-only, this method ! raises a TypeError exception. (Not an AttributeError!) ! Example: C.ivar.set(x, y) ~~ x.ivar = y. ! Method attributes may also be callable; in this case they act as ! unbound method. Example: C.meth(C(), x) ~~ C().meth(x). ! C API XXX + Discussion XXX + Examples XXX + Backwards compatibility XXX Warnings and Errors XXX + Implementation *************** *** 403,412 **** here, see the file Lib/test/test_descr.py. ! Note: the code in this branch goes beyond this PEP; it is also ! on the way to implementing PEP 253 (Subtyping Built-in Types). References XXX Copyright --- 387,398 ---- here, see the file Lib/test/test_descr.py. ! Note: the code in this branch goes way beyond this PEP; it is also ! the experimentation area for PEP 253 (Subtyping Built-in Types). + References XXX + Copyright From tim@digicool.com Mon Jul 9 21:56:20 2001 From: tim@digicool.com (Tim Peters) Date: Mon, 9 Jul 2001 16:56:20 -0400 Subject: [Python-checkins] CVS: python/dist/src/Objects descrobject.c,1.1.2.13,1.1.2.14 In-Reply-To: Message-ID: [Guido] > ... > Note that the presence of a __set__ method doesn't mean that the > attribute can actually be assigned to: this is also used to make > attributes deliberately read-only, by making the __set__ method always > raise an exception. (Q: should it raise AttributeError or TypeError? > Traditionally, this has raised TypeError!) I always thought AttributeError was to an instance dict as NameError is to a global dict: "ain't got no such name". So I vote for TypeError. AttributeError is more appropriate when trying to fetch an attribute that doesn't exist. A twist: suppose Spam.i can only take on string values. Should Spam.i = 42 then raise TypeError or AttributeError? Obviously TypeError. Trying to do Spam.readonly = 12 is the same thing, in that Spam.readonly can only take on no new values . From barry@digicool.com Mon Jul 9 23:17:04 2001 From: barry@digicool.com (Barry A. Warsaw) Date: Mon, 9 Jul 2001 18:17:04 -0400 Subject: [Python-checkins] CVS: python/dist/src/Objects descrobject.c,1.1.2.13,1.1.2.14 References: Message-ID: <15178.11616.469925.357734@anthem.wooz.org> >>>>> "TP" == Tim Peters writes: TP> I always thought AttributeError was to an instance dict as TP> NameError is to a global dict: "ain't got no such name". I agree completely. -Barry From gvanrossum@users.sourceforge.net Tue Jul 10 12:50:12 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 10 Jul 2001 04:50:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib SocketServer.py,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv4088 Modified Files: SocketServer.py Log Message: IMPORTANT FIX: This should definitely go into the 2.1.1 release!!! Fix various serious problems: - The ThreadingTCPServer class and its derived classes were completely broken because the main thread would close the request before the handler thread had time to look at it. This was introduced by Ping's close_request() patch. The fix moves the close_request() calls to after the handler has run to completion in the BaseServer class and the ForkingMixIn class; when using the ThreadingMixIn, closing the request is the handler's responsibility. - The ForkingUDPServer class has always been been broken because the socket was closed in the child before calling the handler. I fixed this by simply not calling server_close() in the child at all. - I cannot get the UnixDatagramServer class to work at all. The recvfrom() call doesn't return a meaningful client address. I added a comment to this effect. Maybe it works on other Unix versions. - The __all__ variable was missing ThreadingMixIn and ForkingMixIn. - Bumped __version__ to "0.4". - Added a note about the test suite (to be checked in shortly). Index: SocketServer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/SocketServer.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -r1.24 -r1.25 *** SocketServer.py 2001/04/11 04:02:05 1.24 --- SocketServer.py 2001/07/10 11:50:09 1.25 *************** *** 121,127 **** # Author of the BaseServer patch: Luke Kenneth Casson Leighton ! __version__ = "0.3" import socket import sys --- 121,132 ---- # Author of the BaseServer patch: Luke Kenneth Casson Leighton ! # XXX Warning! ! # There is a test suite for this module, but it cannot be run by the ! # standard regression test. ! # To run it manually, run Lib/test/test_socketserver.py. + __version__ = "0.4" + import socket import sys *************** *** 130,134 **** __all__ = ["TCPServer","UDPServer","ForkingUDPServer","ForkingTCPServer", "ThreadingUDPServer","ThreadingTCPServer","BaseRequestHandler", ! "StreamRequestHandler","DatagramRequestHandler"] if hasattr(socket, "AF_UNIX"): __all__.extend(["UnixStreamServer","UnixDatagramServer", --- 135,140 ---- __all__ = ["TCPServer","UDPServer","ForkingUDPServer","ForkingTCPServer", "ThreadingUDPServer","ThreadingTCPServer","BaseRequestHandler", ! "StreamRequestHandler","DatagramRequestHandler", ! "ThreadingMixIn", "ForkingMixIn"] if hasattr(socket, "AF_UNIX"): __all__.extend(["UnixStreamServer","UnixDatagramServer", *************** *** 216,220 **** except: self.handle_error(request, client_address) ! self.close_request(request) def verify_request(self, request, client_address): --- 222,226 ---- except: self.handle_error(request, client_address) ! self.close_request(request) def verify_request(self, request, client_address): *************** *** 233,236 **** --- 239,243 ---- """ self.finish_request(request, client_address) + self.close_request(request) def server_close(self): *************** *** 424,427 **** --- 431,435 ---- self.active_children = [] self.active_children.append(pid) + self.close_request(request) return else: *************** *** 429,439 **** # This must never return, hence os._exit()! try: - self.server_close() self.finish_request(request, client_address) os._exit(0) except: try: ! self.handle_error(request, ! client_address) finally: os._exit(1) --- 437,445 ---- # This must never return, hence os._exit()! try: self.finish_request(request, client_address) os._exit(0) except: try: ! self.handle_error(request, client_address) finally: os._exit(1) *************** *** 545,548 **** --- 551,557 ---- class DatagramRequestHandler(BaseRequestHandler): + + # XXX Regrettably, I cannot get this working on Linux; + # s.recvfrom() doesn't return a meaningful client address. """Define self.rfile and self.wfile for datagram sockets.""" From gvanrossum@users.sourceforge.net Tue Jul 10 12:52:40 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 10 Jul 2001 04:52:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_socketserver.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv4431 Added Files: test_socketserver.py Log Message: A test suite for SocketServer.py that exposes the various bugs just fixed. Regrettably, this must be run manually -- somehow the I/O redirection of the regression test breaks the test. When run under the regression test, this raises ImportError with a warning to that effect. Bugfix candidate! --- NEW FILE: test_socketserver.py --- # Test suite for SocketServer.py # XXX This must be run manually -- somehow the I/O redirection of the # regression test breaks the test. from test_support import verbose, verify, TESTFN if not verbose: raise ImportError, "test_socketserver can only be run manually" from SocketServer import * import socket import select import time import threading import os NREQ = 3 DELAY = 0.5 class MyMixinHandler: def handle(self): time.sleep(DELAY) line = self.rfile.readline() time.sleep(DELAY) self.wfile.write(line) class MyStreamHandler(MyMixinHandler, StreamRequestHandler): pass class MyDatagramHandler(MyMixinHandler, DatagramRequestHandler): pass class MyMixinServer: def serve_a_few(self): for i in range(NREQ): self.handle_request() def handle_error(self, request, client_address): self.close_request(request) self.server_close() raise teststring = "hello world\n" def receive(sock, n, timeout=20): r, w, x = select.select([sock], [], [], timeout) if sock in r: return sock.recv(n) else: raise RuntimeError, "timed out on %s" % `sock` def testdgram(proto, addr): s = socket.socket(proto, socket.SOCK_DGRAM) s.sendto(teststring, addr) buf = data = receive(s, 100) while data and '\n' not in buf: data = receive(s, 100) buf += data verify(buf == teststring) s.close() def teststream(proto, addr): s = socket.socket(proto, socket.SOCK_STREAM) s.connect(addr) s.send(teststring) buf = data = receive(s, 100) while data and '\n' not in buf: data = receive(s, 100) buf += data verify(buf == teststring) s.close() class ServerThread(threading.Thread): def __init__(self, addr, svrcls, hdlrcls): threading.Thread.__init__(self) self.__addr = addr self.__svrcls = svrcls self.__hdlrcls = hdlrcls def run(self): class svrcls(MyMixinServer, self.__svrcls): pass if verbose: print "thread: creating server" svr = svrcls(self.__addr, self.__hdlrcls) if verbose: print "thread: serving three times" svr.serve_a_few() if verbose: print "thread: done" seed = 0 def pickport(): global seed seed += 1 return 10000 + (os.getpid() % 1000)*10 + seed host = "" testfiles = [] def pickaddr(proto): if proto == socket.AF_INET: return (host, pickport()) else: fn = TESTFN + str(pickport()) testfiles.append(fn) return fn def cleanup(): for fn in testfiles: try: os.remove(fn) except os.error: pass testfiles[:] = [] def testloop(proto, servers, hdlrcls, testfunc): for svrcls in servers: addr = pickaddr(proto) if verbose: print "ADDR =", addr print "CLASS =", svrcls t = ServerThread(addr, svrcls, hdlrcls) if verbose: print "server created" t.start() if verbose: print "server running" for i in range(NREQ): time.sleep(DELAY) if verbose: print "test client", i testfunc(proto, addr) if verbose: print "waiting for server" t.join() if verbose: print "done" tcpservers = [TCPServer, ThreadingTCPServer] if hasattr(os, 'fork'): tcpservers.append(ForkingTCPServer) udpservers = [UDPServer, ThreadingUDPServer] if hasattr(os, 'fork'): udpservers.append(ForkingUDPServer) if not hasattr(socket, 'AF_UNIX'): streamservers = [] dgramservers = [] else: class ForkingUnixStreamServer(ForkingMixIn, UnixStreamServer): pass streamservers = [UnixStreamServer, ThreadingUnixStreamServer, ForkingUnixStreamServer] class ForkingUnixDatagramServer(ForkingMixIn, UnixDatagramServer): pass dgramservers = [UnixDatagramServer, ThreadingUnixDatagramServer, ForkingUnixDatagramServer] def testall(): testloop(socket.AF_INET, tcpservers, MyStreamHandler, teststream) testloop(socket.AF_INET, udpservers, MyDatagramHandler, testdgram) testloop(socket.AF_UNIX, streamservers, MyStreamHandler, teststream) # Alas, on Linux (at least) recvfrom() doesn't return a meaningful # client address so this cannot work: ##testloop(socket.AF_UNIX, dgramservers, MyDatagramHandler, testdgram) def main(): try: testall() finally: cleanup() main() From fdrake@users.sourceforge.net Tue Jul 10 15:19:47 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 10 Jul 2001 07:19:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/mac undoc.tex,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/mac In directory usw-pr-cvs1:/tmp/cvs-serv10417/mac Modified Files: undoc.tex Log Message: Added descriptions for some modules that previously did not have any information about them, based on comments from Jack Jansen. Index: undoc.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/mac/undoc.tex,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** undoc.tex 2001/04/10 20:32:16 1.2 --- undoc.tex 2001/07/10 14:19:45 1.3 *************** *** 12,24 **** \declaremodule{standard}{buildtools} \platform{Mac} ! \modulesynopsis{Helper module for BuildApplet, BuildApplication and macfreeze} ! \section{\module{py_resource} --- } \declaremodule[pyresource]{standard}{py_resource} \platform{Mac} ! \modulesynopsis{} \section{\module{cfmfile} --- Code Fragment Resource module} \declaremodule{standard}{cfmfile} --- 12,30 ---- \declaremodule{standard}{buildtools} \platform{Mac} ! \modulesynopsis{Helper module for BuildApplet, BuildApplication and ! macfreeze} ! \section{\module{py_resource} --- Resources from Python code} \declaremodule[pyresource]{standard}{py_resource} \platform{Mac} ! \modulesynopsis{Helper to create \texttt{'PYC '} resources for compiled ! applications} + This module is primarily used as a help module for BuildApplet and + BuildApplication. It is able to store compiled Python code as + \texttt{'PYC '} resources in a file. + \section{\module{cfmfile} --- Code Fragment Resource module} \declaremodule{standard}{cfmfile} *************** *** 62,69 **** ! \section{\module{mactty} --- } \declaremodule{standard}{mactty} \platform{Mac} ! \modulesynopsis{} --- 68,75 ---- ! \section{\module{mactty} --- Serial line connections} \declaremodule{standard}{mactty} \platform{Mac} ! \modulesynopsis{Easy access serial to line connections} *************** *** 90,103 **** ! \section{\module{preferences} --- } \declaremodule{standard}{preferences} \platform{Mac} ! \modulesynopsis{} ! \section{\module{pythonprefs} --- } \declaremodule{standard}{pythonprefs} \platform{Mac} ! \modulesynopsis{} --- 96,120 ---- ! \section{\module{preferences} --- Application preferences manager} \declaremodule{standard}{preferences} \platform{Mac} ! \modulesynopsis{Nice application preferences manager with support for ! defaults} ! ! The \module{preferences} module allows storage of user preferences in ! the system-wide preferences folder, with defaults coming from the ! application itself and the possibility to override preferences for ! specific situations. ! \section{\module{pythonprefs} --- Preferences manager for Python} \declaremodule{standard}{pythonprefs} \platform{Mac} ! \modulesynopsis{Specialized preferences manager for the Python ! interpreter} ! ! This module is a specialization of the \refmodule{preferences} module ! that allows reading and writing of the preferences for the Python ! interpreter. From fdrake@users.sourceforge.net Tue Jul 10 15:20:22 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 10 Jul 2001 07:20:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/mac undoc.tex,1.2,1.2.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/mac In directory usw-pr-cvs1:/tmp/cvs-serv10629/mac Modified Files: Tag: release21-maint undoc.tex Log Message: Added descriptions for some modules that previously did not have any information about them, based on comments from Jack Jansen. Index: undoc.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/mac/undoc.tex,v retrieving revision 1.2 retrieving revision 1.2.2.1 diff -C2 -r1.2 -r1.2.2.1 *** undoc.tex 2001/04/10 20:32:16 1.2 --- undoc.tex 2001/07/10 14:20:20 1.2.2.1 *************** *** 12,24 **** \declaremodule{standard}{buildtools} \platform{Mac} ! \modulesynopsis{Helper module for BuildApplet, BuildApplication and macfreeze} ! \section{\module{py_resource} --- } \declaremodule[pyresource]{standard}{py_resource} \platform{Mac} ! \modulesynopsis{} \section{\module{cfmfile} --- Code Fragment Resource module} \declaremodule{standard}{cfmfile} --- 12,30 ---- \declaremodule{standard}{buildtools} \platform{Mac} ! \modulesynopsis{Helper module for BuildApplet, BuildApplication and ! macfreeze} ! \section{\module{py_resource} --- Resources from Python code} \declaremodule[pyresource]{standard}{py_resource} \platform{Mac} ! \modulesynopsis{Helper to create \texttt{'PYC '} resources for compiled ! applications} + This module is primarily used as a help module for BuildApplet and + BuildApplication. It is able to store compiled Python code as + \texttt{'PYC '} resources in a file. + \section{\module{cfmfile} --- Code Fragment Resource module} \declaremodule{standard}{cfmfile} *************** *** 62,69 **** ! \section{\module{mactty} --- } \declaremodule{standard}{mactty} \platform{Mac} ! \modulesynopsis{} --- 68,75 ---- ! \section{\module{mactty} --- Serial line connections} \declaremodule{standard}{mactty} \platform{Mac} ! \modulesynopsis{Easy access serial to line connections} *************** *** 90,103 **** ! \section{\module{preferences} --- } \declaremodule{standard}{preferences} \platform{Mac} ! \modulesynopsis{} ! \section{\module{pythonprefs} --- } \declaremodule{standard}{pythonprefs} \platform{Mac} ! \modulesynopsis{} --- 96,120 ---- ! \section{\module{preferences} --- Application preferences manager} \declaremodule{standard}{preferences} \platform{Mac} ! \modulesynopsis{Nice application preferences manager with support for ! defaults} ! ! The \module{preferences} module allows storage of user preferences in ! the system-wide preferences folder, with defaults coming from the ! application itself and the possibility to override preferences for ! specific situations. ! \section{\module{pythonprefs} --- Preferences manager for Python} \declaremodule{standard}{pythonprefs} \platform{Mac} ! \modulesynopsis{Specialized preferences manager for the Python ! interpreter} ! ! This module is a specialization of the \refmodule{preferences} module ! that allows reading and writing of the preferences for the Python ! interpreter. From gvanrossum@users.sourceforge.net Tue Jul 10 16:46:36 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 10 Jul 2001 08:46:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_socketserver.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv1489 Modified Files: test_socketserver.py Log Message: Ported to Windows: - Set the host to "localhost" instead of "". - Skip the AF_UNIX tests when socket.AF_UNIX is not defined. Index: test_socketserver.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_socketserver.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** test_socketserver.py 2001/07/10 11:52:38 1.1 --- test_socketserver.py 2001/07/10 15:46:34 1.2 *************** *** 91,95 **** return 10000 + (os.getpid() % 1000)*10 + seed ! host = "" testfiles = [] def pickaddr(proto): --- 91,95 ---- return 10000 + (os.getpid() % 1000)*10 + seed ! host = "localhost" testfiles = [] def pickaddr(proto): *************** *** 148,155 **** testloop(socket.AF_INET, tcpservers, MyStreamHandler, teststream) testloop(socket.AF_INET, udpservers, MyDatagramHandler, testdgram) ! testloop(socket.AF_UNIX, streamservers, MyStreamHandler, teststream) ! # Alas, on Linux (at least) recvfrom() doesn't return a meaningful ! # client address so this cannot work: ! ##testloop(socket.AF_UNIX, dgramservers, MyDatagramHandler, testdgram) def main(): --- 148,156 ---- testloop(socket.AF_INET, tcpservers, MyStreamHandler, teststream) testloop(socket.AF_INET, udpservers, MyDatagramHandler, testdgram) ! if hasattr(socket, 'AF_UNIX'): ! testloop(socket.AF_UNIX, streamservers, MyStreamHandler, teststream) ! # Alas, on Linux (at least) recvfrom() doesn't return a meaningful ! # client address so this cannot work: ! ##testloop(socket.AF_UNIX, dgramservers, MyDatagramHandler, testdgram) def main(): From fdrake@users.sourceforge.net Tue Jul 10 17:10:10 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 10 Jul 2001 09:10:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.128,1.129 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv6887/api Modified Files: api.tex Log Message: Document PyObject_New(), PyObject_NewVar(), PyObject_Init(), PyObject_InitVar(), PyObject_Del(), PyObject_NEW(), PyObject_NEW_VAR(), and PyObject_DEL(). Add notes to PyMem_Malloc() and PyMem_New() about the memory buffers not being initialized. This fixes SF bug #439012. Added explicit return value information for PyList_SetItem(), PyDict_SetItem(), and PyDict_SetItemString(). Corrected return type for PyList_SET_ITEM(). Fixed index entries in the descriptions of PyLong_AsLong() and PyLong_AsUnignedLong(). This fixes the API manual portion of SF bug #440037. Note that the headers properly declare everything as 'extern "C"' for C++ users. Document _Py_NoneStruct. Added links to the Extending & Embedding manual for PyArg_ParseTuple() and PyArg_ParseTupleAndKeywords(). Added note that PyArg_Parse() should not be used in new code. Fix up a few style nits -- avoid "e.g." and "i.e." -- these make translation more difficult, as well as reading the English more difficult for non-native speakers. Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.128 retrieving revision 1.129 diff -C2 -r1.128 -r1.129 *** api.tex 2001/07/09 14:35:01 1.128 --- api.tex 2001/07/10 16:10:08 1.129 *************** *** 108,112 **** --- 108,117 ---- \envvar{exec_prefix}. + \Cpp{} users should note that though the API is defined entirely using + C, the header files do properly declare the entry points to be + \code{extern "C"}, so there is no need to do anything special to use + the API from \Cpp. + \section{Objects, Types and Reference Counts \label{objects}} *************** *** 306,315 **** object. Therefore, the generic functions that return object references, like \cfunction{PyObject_GetItem()} and ! \cfunction{PySequence_GetItem()}, always return a new reference (i.e., ! the caller becomes the owner of the reference). It is important to realize that whether you own a reference returned by a function depends on which function you call only --- \emph{the ! plumage} (i.e., the type of the type of the object passed as an argument to the function) \emph{doesn't enter into it!} Thus, if you extract an item from a list using \cfunction{PyList_GetItem()}, you --- 311,320 ---- object. Therefore, the generic functions that return object references, like \cfunction{PyObject_GetItem()} and ! \cfunction{PySequence_GetItem()}, always return a new reference (the ! caller becomes the owner of the reference). It is important to realize that whether you own a reference returned by a function depends on which function you call only --- \emph{the ! plumage} (the type of the type of the object passed as an argument to the function) \emph{doesn't enter into it!} Thus, if you extract an item from a list using \cfunction{PyList_GetItem()}, you *************** *** 876,880 **** that class. Do not pass an invalid exception type or value. (Violating these rules will cause subtle problems later.) This call ! takes away a reference to each object, i.e.\ you must own a reference to each object before the call and after the call you no longer own these references. (If you don't understand this, don't use this --- 881,885 ---- that class. Do not pass an invalid exception type or value. (Violating these rules will cause subtle problems later.) This call ! takes away a reference to each object: you must own a reference to each object before the call and after the call you no longer own these references. (If you don't understand this, don't use this *************** *** 1220,1224 **** \cfunction{PyImport_ImportModuleEx()} below, leaving the \var{globals} and \var{locals} arguments set to \NULL{}. When the ! \var{name} argument contains a dot (i.e., when it specifies a submodule of a package), the \var{fromlist} argument is set to the list \code{['*']} so that the return value is the named module rather --- 1225,1229 ---- \cfunction{PyImport_ImportModuleEx()} below, leaving the \var{globals} and \var{locals} arguments set to \NULL{}. When the ! \var{name} argument contains a dot (when it specifies a submodule of a package), the \var{fromlist} argument is set to the list \code{['*']} so that the return value is the named module rather *************** *** 3315,3318 **** --- 3320,3324 ---- PyObject *item} Sets the item at index \var{index} in list to \var{item}. + Returns \code{0} on success or \code{-1} on failure. \strong{Note:} This function ``steals'' a reference to \var{item} and discards a reference to an item already in the list at the affected *************** *** 3320,3330 **** \end{cfuncdesc} ! \begin{cfuncdesc}{PyObject*}{PyList_SET_ITEM}{PyObject *list, int i, PyObject *o} Macro form of \cfunction{PyList_SetItem()} without error checking. \strong{Note:} This function ``steals'' a reference to \var{item}, and, unlike \cfunction{PyList_SetItem()}, does \emph{not} discard a ! reference to any item that it being replaced. This is normally only ! used to fill in new lists where there is no previous content.. \end{cfuncdesc} --- 3326,3337 ---- \end{cfuncdesc} ! \begin{cfuncdesc}{void}{PyList_SET_ITEM}{PyObject *list, int i, PyObject *o} Macro form of \cfunction{PyList_SetItem()} without error checking. \strong{Note:} This function ``steals'' a reference to \var{item}, and, unlike \cfunction{PyList_SetItem()}, does \emph{not} discard a ! reference to any item that it being replaced; any reference in ! \var{list} at position \var{i} will be leaked. This is normally only ! used to fill in new lists where there is no previous content. \end{cfuncdesc} *************** *** 3416,3422 **** \begin{cfuncdesc}{int}{PyDict_SetItem}{PyObject *p, PyObject *key, PyObject *val} ! Inserts \var{value} into the dictionary with a key of \var{key}. \var{key} must be hashable; if it isn't, \exception{TypeError} will be raised. \end{cfuncdesc} --- 3423,3430 ---- \begin{cfuncdesc}{int}{PyDict_SetItem}{PyObject *p, PyObject *key, PyObject *val} ! Inserts \var{value} into the dictionary \var{p} with a key of \var{key}. \var{key} must be hashable; if it isn't, \exception{TypeError} will be raised. + Returns \code{0} on success or \code{-1} on failure. \end{cfuncdesc} *************** *** 3424,3430 **** char *key, PyObject *val} ! Inserts \var{value} into the dictionary using \var{key} as a key. \var{key} should be a \ctype{char*}. The key object is created using \code{PyString_FromString(\var{key})}. \ttindex{PyString_FromString()} \end{cfuncdesc} --- 3432,3439 ---- char *key, PyObject *val} ! Inserts \var{value} into the dictionary \var{p} using \var{key} as a key. \var{key} should be a \ctype{char*}. The key object is created using \code{PyString_FromString(\var{key})}. + Returns \code{0} on success or \code{-1} on failure. \ttindex{PyString_FromString()} \end{cfuncdesc} *************** *** 3439,3442 **** --- 3448,3452 ---- Removes the entry in dictionary \var{p} which has a key specified by the string \var{key}. + Returns \code{0} on success or \code{-1} on failure. \end{cfuncdesc} *************** *** 3608,3612 **** \var{pylong}. If \var{pylong} is greater than \constant{LONG_MAX}\ttindex{LONG_MAX}, an \exception{OverflowError} is ! raised.\withsubitem{(built-in exception)}{OverflowError} \end{cfuncdesc} --- 3618,3622 ---- \var{pylong}. If \var{pylong} is greater than \constant{LONG_MAX}\ttindex{LONG_MAX}, an \exception{OverflowError} is ! raised.\withsubitem{(built-in exception)}{\ttindex{OverflowError}} \end{cfuncdesc} *************** *** 3615,3619 **** \var{pylong}. If \var{pylong} is greater than \constant{ULONG_MAX}\ttindex{ULONG_MAX}, an \exception{OverflowError} ! is raised.\withsubitem{(built-in exception)}{OverflowError} \end{cfuncdesc} --- 3625,3629 ---- \var{pylong}. If \var{pylong} is greater than \constant{ULONG_MAX}\ttindex{ULONG_MAX}, an \exception{OverflowError} ! is raised.\withsubitem{(built-in exception)}{\ttindex{OverflowError}} \end{cfuncdesc} *************** *** 4600,4604 **** \begin{csimplemacrodesc}{Py_BLOCK_THREADS} ! This macro expands to \samp{PyEval_RestoreThread(_save);} i.e. it is equivalent to \code{Py_END_ALLOW_THREADS} without the closing brace. It is a no-op when thread support is disabled at compile --- 4610,4614 ---- \begin{csimplemacrodesc}{Py_BLOCK_THREADS} ! This macro expands to \samp{PyEval_RestoreThread(_save);}: it is equivalent to \code{Py_END_ALLOW_THREADS} without the closing brace. It is a no-op when thread support is disabled at compile *************** *** 4607,4611 **** \begin{csimplemacrodesc}{Py_UNBLOCK_THREADS} ! This macro expands to \samp{_save = PyEval_SaveThread();} i.e. it is equivalent to \code{Py_BEGIN_ALLOW_THREADS} without the opening brace and variable declaration. It is a no-op when thread support is --- 4617,4621 ---- \begin{csimplemacrodesc}{Py_UNBLOCK_THREADS} ! This macro expands to \samp{_save = PyEval_SaveThread();}: it is equivalent to \code{Py_BEGIN_ALLOW_THREADS} without the opening brace and variable declaration. It is a no-op when thread support is *************** *** 4759,4764 **** \begin{cfuncdesc}{void*}{PyMem_Malloc}{size_t n} Allocates \var{n} bytes and returns a pointer of type \ctype{void*} to ! the allocated memory, or \NULL{} if the request fails. Requesting zero bytes returns a non-\NULL{} pointer. \end{cfuncdesc} --- 4769,4775 ---- \begin{cfuncdesc}{void*}{PyMem_Malloc}{size_t n} Allocates \var{n} bytes and returns a pointer of type \ctype{void*} to ! the allocated memory, or \NULL{} if the request fails. Requesting zero bytes returns a non-\NULL{} pointer. + The memory will not have been initialized in any way. \end{cfuncdesc} *************** *** 4767,4774 **** contents will be unchanged to the minimum of the old and the new sizes. If \var{p} is \NULL{}, the call is equivalent to ! \cfunction{PyMem_Malloc(\var{n})}; if \var{n} is equal to zero, the memory block ! is resized but is not freed, and the returned pointer is non-\NULL{}. ! Unless \var{p} is \NULL{}, it must have been returned by a previous ! call to \cfunction{PyMem_Malloc()} or \cfunction{PyMem_Realloc()}. \end{cfuncdesc} --- 4778,4786 ---- contents will be unchanged to the minimum of the old and the new sizes. If \var{p} is \NULL{}, the call is equivalent to ! \cfunction{PyMem_Malloc(\var{n})}; if \var{n} is equal to zero, the ! memory block is resized but is not freed, and the returned pointer is ! non-\NULL{}. Unless \var{p} is \NULL{}, it must have been returned by ! a previous call to \cfunction{PyMem_Malloc()} or ! \cfunction{PyMem_Realloc()}. \end{cfuncdesc} *************** *** 4788,4791 **** --- 4800,4804 ---- sizeof(\var{TYPE}))} bytes of memory. Returns a pointer cast to \ctype{\var{TYPE}*}. + The memory will not have been initialized in any way. \end{cfuncdesc} *************** *** 4884,4912 **** \begin{cfuncdesc}{PyObject*}{PyObject_Init}{PyObject *op, ! PyTypeObject *type} \end{cfuncdesc} \begin{cfuncdesc}{PyVarObject*}{PyObject_InitVar}{PyVarObject *op, ! PyTypeObject *type, int size} \end{cfuncdesc} \begin{cfuncdesc}{\var{TYPE}*}{PyObject_New}{TYPE, PyTypeObject *type} \end{cfuncdesc} \begin{cfuncdesc}{\var{TYPE}*}{PyObject_NewVar}{TYPE, PyTypeObject *type, int size} \end{cfuncdesc} \begin{cfuncdesc}{void}{PyObject_Del}{PyObject *op} \end{cfuncdesc} \begin{cfuncdesc}{\var{TYPE}*}{PyObject_NEW}{TYPE, PyTypeObject *type} \end{cfuncdesc} \begin{cfuncdesc}{\var{TYPE}*}{PyObject_NEW_VAR}{TYPE, PyTypeObject *type, int size} \end{cfuncdesc} \begin{cfuncdesc}{void}{PyObject_DEL}{PyObject *op} \end{cfuncdesc} --- 4897,4959 ---- \begin{cfuncdesc}{PyObject*}{PyObject_Init}{PyObject *op, ! PyTypeObject *type} ! Initialize a newly-allocated object \var{op} with its type and ! initial reference. Returns the initialized object. If \var{type} ! indicates that the object participates in the cyclic garbage ! detector, it it added to the detector's set of observed objects. ! Other fields of the object are not affected. \end{cfuncdesc} \begin{cfuncdesc}{PyVarObject*}{PyObject_InitVar}{PyVarObject *op, ! PyTypeObject *type, int size} ! This does everything \cfunction{PyObject_Init()} does, and also ! initializes the length information for a variable-size object. \end{cfuncdesc} \begin{cfuncdesc}{\var{TYPE}*}{PyObject_New}{TYPE, PyTypeObject *type} + Allocate a new Python object using the C structure type \var{TYPE} + and the Python type object \var{type}. Fields not defined by the + Python object header are not initialized; the object's reference + count will be one. The size of the memory + allocation is determined from the \member{tp_basicsize} field of the + type object. \end{cfuncdesc} \begin{cfuncdesc}{\var{TYPE}*}{PyObject_NewVar}{TYPE, PyTypeObject *type, int size} + Allocate a new Python object using the C structure type \var{TYPE} + and the Python type object \var{type}. Fields not defined by the + Python object header are not initialized. The allocated memory + allows for the \var{TYPE} structure plus \var{size} fields of the + size given by the \member{tp_itemsize} field of \var{type}. This is + useful for implementing objects like tuples, which are able to + determine their size at construction time. Embedding the array of + fields into the same allocation decreases the number of allocations, + improving the memory management efficiency. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyObject_Del}{PyObject *op} + Releases memory allocated to an object using + \cfunction{PyObject_New()} or \cfunction{PyObject_NewVar()}. This + is normally called from the \member{tp_dealloc} handler specified in + the object's type. The fields of the object should not be accessed + after this call as the memory is no longer a valid Python object. \end{cfuncdesc} \begin{cfuncdesc}{\var{TYPE}*}{PyObject_NEW}{TYPE, PyTypeObject *type} + Macro version of \cfunction{PyObject_New()}, to gain performance at + the expense of safety. This does not check \var{type} for a \NULL{} + value. \end{cfuncdesc} \begin{cfuncdesc}{\var{TYPE}*}{PyObject_NEW_VAR}{TYPE, PyTypeObject *type, int size} + Macro version of \cfunction{PyObject_NewVar()}, to gain performance + at the expense of safety. This does not check \var{type} for a + \NULL{} value. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyObject_DEL}{PyObject *op} + Macro version of \cfunction{PyObject_Del()}. \end{cfuncdesc} *************** *** 4943,4947 **** \end{cfuncdesc} ! PyArg_ParseTupleAndKeywords, PyArg_ParseTuple, PyArg_Parse Py_BuildValue --- 4990,5016 ---- \end{cfuncdesc} ! \begin{cfuncdesc}{int}{PyArg_ParseTuple}{PyObject *args, char *format, ! \moreargs} ! Parse the parameters of a function that takes only positional ! parameters into local variables. See ! \citetitle[../ext/parseTuple.html]{Extending and Embedding the ! Python Interpreter} for more information. ! \end{cfuncdesc} ! ! \begin{cfuncdesc}{int}{PyArg_ParseTupleAndKeywords}{PyObject *args, ! PyObject *kw, char *format, char *keywords[], \moreargs} ! Parse the parameters of a function that takes both positional and ! keyword parameters into local variables. See ! \citetitle[../ext/parseTupleAndKeywords.html]{Extending and ! Embedding the Python Interpreter} for more information. ! \end{cfuncdesc} ! ! \begin{cfuncdesc}{int}{PyArg_Parse}{PyObject *args, char *format, \moreargs} ! Function used to deconstruct the argument lists of ``old-style'' ! functions --- these are functions which use the ! \constant{METH_OLDARGS} parameter parsing method. This is not ! recommended for new code, and most code in the standard interpreter ! has been modified to no longer use this. ! \end{cfuncdesc} Py_BuildValue *************** *** 4949,4953 **** DL_IMPORT ! _Py_NoneStruct --- 5018,5026 ---- DL_IMPORT ! \begin{cvardesc}{PyObject}{_Py_NoneStruct} ! Object which is visible in Python as \code{None}. This should only ! be accessed using the \code{Py_None} macro, which evaluates to a ! pointer to this object. ! \end{cvardesc} *************** *** 5224,5228 **** objects do not have to define this method since they can never directly create reference cycles. Note that the object must still ! be valid after calling this method (i.e., don't just call \cfunction{Py_DECREF()} on a reference). The collector will call this method if it detects that this object is involved in a --- 5297,5301 ---- objects do not have to define this method since they can never directly create reference cycles. Note that the object must still ! be valid after calling this method (don't just call \cfunction{Py_DECREF()} on a reference). The collector will call this method if it detects that this object is involved in a From fdrake@users.sourceforge.net Tue Jul 10 17:11:12 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 10 Jul 2001 09:11:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.117.2.7,1.117.2.8 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv7167/api Modified Files: Tag: release21-maint api.tex Log Message: Document PyObject_New(), PyObject_NewVar(), PyObject_Init(), PyObject_InitVar(), PyObject_Del(), PyObject_NEW(), PyObject_NEW_VAR(), and PyObject_DEL(). Add notes to PyMem_Malloc() and PyMem_New() about the memory buffers not being initialized. This fixes SF bug #439012. Added explicit return value information for PyList_SetItem(), PyDict_SetItem(), and PyDict_SetItemString(). Corrected return type for PyList_SET_ITEM(). Fixed index entries in the descriptions of PyLong_AsLong() and PyLong_AsUnignedLong(). This fixes the API manual portion of SF bug #440037. Note that the headers properly declare everything as 'extern "C"' for C++ users. Document _Py_NoneStruct. Added links to the Extending & Embedding manual for PyArg_ParseTuple() and PyArg_ParseTupleAndKeywords(). Added note that PyArg_Parse() should not be used in new code. Fix up a few style nits -- avoid "e.g." and "i.e." -- these make translation more difficult, as well as reading the English more difficult for non-native speakers. Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.117.2.7 retrieving revision 1.117.2.8 diff -C2 -r1.117.2.7 -r1.117.2.8 *** api.tex 2001/07/09 14:34:16 1.117.2.7 --- api.tex 2001/07/10 16:11:09 1.117.2.8 *************** *** 108,112 **** --- 108,117 ---- \envvar{exec_prefix}. + \Cpp{} users should note that though the API is defined entirely using + C, the header files do properly declare the entry points to be + \code{extern "C"}, so there is no need to do anything special to use + the API from \Cpp. + \section{Objects, Types and Reference Counts \label{objects}} *************** *** 306,315 **** object. Therefore, the generic functions that return object references, like \cfunction{PyObject_GetItem()} and ! \cfunction{PySequence_GetItem()}, always return a new reference (i.e., ! the caller becomes the owner of the reference). It is important to realize that whether you own a reference returned by a function depends on which function you call only --- \emph{the ! plumage} (i.e., the type of the type of the object passed as an argument to the function) \emph{doesn't enter into it!} Thus, if you extract an item from a list using \cfunction{PyList_GetItem()}, you --- 311,320 ---- object. Therefore, the generic functions that return object references, like \cfunction{PyObject_GetItem()} and ! \cfunction{PySequence_GetItem()}, always return a new reference (the ! caller becomes the owner of the reference). It is important to realize that whether you own a reference returned by a function depends on which function you call only --- \emph{the ! plumage} (the type of the type of the object passed as an argument to the function) \emph{doesn't enter into it!} Thus, if you extract an item from a list using \cfunction{PyList_GetItem()}, you *************** *** 876,880 **** that class. Do not pass an invalid exception type or value. (Violating these rules will cause subtle problems later.) This call ! takes away a reference to each object, i.e.\ you must own a reference to each object before the call and after the call you no longer own these references. (If you don't understand this, don't use this --- 881,885 ---- that class. Do not pass an invalid exception type or value. (Violating these rules will cause subtle problems later.) This call ! takes away a reference to each object: you must own a reference to each object before the call and after the call you no longer own these references. (If you don't understand this, don't use this *************** *** 1220,1224 **** \cfunction{PyImport_ImportModuleEx()} below, leaving the \var{globals} and \var{locals} arguments set to \NULL{}. When the ! \var{name} argument contains a dot (i.e., when it specifies a submodule of a package), the \var{fromlist} argument is set to the list \code{['*']} so that the return value is the named module rather --- 1225,1229 ---- \cfunction{PyImport_ImportModuleEx()} below, leaving the \var{globals} and \var{locals} arguments set to \NULL{}. When the ! \var{name} argument contains a dot (when it specifies a submodule of a package), the \var{fromlist} argument is set to the list \code{['*']} so that the return value is the named module rather *************** *** 3256,3259 **** --- 3261,3265 ---- PyObject *item} Sets the item at index \var{index} in list to \var{item}. + Returns \code{0} on success or \code{-1} on failure. \strong{Note:} This function ``steals'' a reference to \var{item} and discards a reference to an item already in the list at the affected *************** *** 3261,3271 **** \end{cfuncdesc} ! \begin{cfuncdesc}{PyObject*}{PyList_SET_ITEM}{PyObject *list, int i, PyObject *o} Macro form of \cfunction{PyList_SetItem()} without error checking. \strong{Note:} This function ``steals'' a reference to \var{item}, and, unlike \cfunction{PyList_SetItem()}, does \emph{not} discard a ! reference to any item that it being replaced. This is normally only ! used to fill in new lists where there is no previous content.. \end{cfuncdesc} --- 3267,3278 ---- \end{cfuncdesc} ! \begin{cfuncdesc}{void}{PyList_SET_ITEM}{PyObject *list, int i, PyObject *o} Macro form of \cfunction{PyList_SetItem()} without error checking. \strong{Note:} This function ``steals'' a reference to \var{item}, and, unlike \cfunction{PyList_SetItem()}, does \emph{not} discard a ! reference to any item that it being replaced; any reference in ! \var{list} at position \var{i} will be leaked. This is normally only ! used to fill in new lists where there is no previous content. \end{cfuncdesc} *************** *** 3357,3363 **** \begin{cfuncdesc}{int}{PyDict_SetItem}{PyObject *p, PyObject *key, PyObject *val} ! Inserts \var{value} into the dictionary with a key of \var{key}. \var{key} must be hashable; if it isn't, \exception{TypeError} will be raised. \end{cfuncdesc} --- 3364,3371 ---- \begin{cfuncdesc}{int}{PyDict_SetItem}{PyObject *p, PyObject *key, PyObject *val} ! Inserts \var{value} into the dictionary \var{p} with a key of \var{key}. \var{key} must be hashable; if it isn't, \exception{TypeError} will be raised. + Returns \code{0} on success or \code{-1} on failure. \end{cfuncdesc} *************** *** 3365,3371 **** char *key, PyObject *val} ! Inserts \var{value} into the dictionary using \var{key} as a key. \var{key} should be a \ctype{char*}. The key object is created using \code{PyString_FromString(\var{key})}. \ttindex{PyString_FromString()} \end{cfuncdesc} --- 3373,3380 ---- char *key, PyObject *val} ! Inserts \var{value} into the dictionary \var{p} using \var{key} as a key. \var{key} should be a \ctype{char*}. The key object is created using \code{PyString_FromString(\var{key})}. + Returns \code{0} on success or \code{-1} on failure. \ttindex{PyString_FromString()} \end{cfuncdesc} *************** *** 3380,3383 **** --- 3389,3393 ---- Removes the entry in dictionary \var{p} which has a key specified by the string \var{key}. + Returns \code{0} on success or \code{-1} on failure. \end{cfuncdesc} *************** *** 3549,3553 **** \var{pylong}. If \var{pylong} is greater than \constant{LONG_MAX}\ttindex{LONG_MAX}, an \exception{OverflowError} is ! raised.\withsubitem{(built-in exception)}{OverflowError} \end{cfuncdesc} --- 3559,3563 ---- \var{pylong}. If \var{pylong} is greater than \constant{LONG_MAX}\ttindex{LONG_MAX}, an \exception{OverflowError} is ! raised.\withsubitem{(built-in exception)}{\ttindex{OverflowError}} \end{cfuncdesc} *************** *** 3556,3560 **** \var{pylong}. If \var{pylong} is greater than \constant{ULONG_MAX}\ttindex{ULONG_MAX}, an \exception{OverflowError} ! is raised.\withsubitem{(built-in exception)}{OverflowError} \end{cfuncdesc} --- 3566,3570 ---- \var{pylong}. If \var{pylong} is greater than \constant{ULONG_MAX}\ttindex{ULONG_MAX}, an \exception{OverflowError} ! is raised.\withsubitem{(built-in exception)}{\ttindex{OverflowError}} \end{cfuncdesc} *************** *** 4541,4545 **** \begin{csimplemacrodesc}{Py_BLOCK_THREADS} ! This macro expands to \samp{PyEval_RestoreThread(_save);} i.e. it is equivalent to \code{Py_END_ALLOW_THREADS} without the closing brace. It is a no-op when thread support is disabled at compile --- 4551,4555 ---- \begin{csimplemacrodesc}{Py_BLOCK_THREADS} ! This macro expands to \samp{PyEval_RestoreThread(_save);}: it is equivalent to \code{Py_END_ALLOW_THREADS} without the closing brace. It is a no-op when thread support is disabled at compile *************** *** 4548,4552 **** \begin{csimplemacrodesc}{Py_UNBLOCK_THREADS} ! This macro expands to \samp{_save = PyEval_SaveThread();} i.e. it is equivalent to \code{Py_BEGIN_ALLOW_THREADS} without the opening brace and variable declaration. It is a no-op when thread support is --- 4558,4562 ---- \begin{csimplemacrodesc}{Py_UNBLOCK_THREADS} ! This macro expands to \samp{_save = PyEval_SaveThread();}: it is equivalent to \code{Py_BEGIN_ALLOW_THREADS} without the opening brace and variable declaration. It is a no-op when thread support is *************** *** 4700,4705 **** \begin{cfuncdesc}{void*}{PyMem_Malloc}{size_t n} Allocates \var{n} bytes and returns a pointer of type \ctype{void*} to ! the allocated memory, or \NULL{} if the request fails. Requesting zero bytes returns a non-\NULL{} pointer. \end{cfuncdesc} --- 4710,4716 ---- \begin{cfuncdesc}{void*}{PyMem_Malloc}{size_t n} Allocates \var{n} bytes and returns a pointer of type \ctype{void*} to ! the allocated memory, or \NULL{} if the request fails. Requesting zero bytes returns a non-\NULL{} pointer. + The memory will not have been initialized in any way. \end{cfuncdesc} *************** *** 4708,4715 **** contents will be unchanged to the minimum of the old and the new sizes. If \var{p} is \NULL{}, the call is equivalent to ! \cfunction{PyMem_Malloc(\var{n})}; if \var{n} is equal to zero, the memory block ! is resized but is not freed, and the returned pointer is non-\NULL{}. ! Unless \var{p} is \NULL{}, it must have been returned by a previous ! call to \cfunction{PyMem_Malloc()} or \cfunction{PyMem_Realloc()}. \end{cfuncdesc} --- 4719,4727 ---- contents will be unchanged to the minimum of the old and the new sizes. If \var{p} is \NULL{}, the call is equivalent to ! \cfunction{PyMem_Malloc(\var{n})}; if \var{n} is equal to zero, the ! memory block is resized but is not freed, and the returned pointer is ! non-\NULL{}. Unless \var{p} is \NULL{}, it must have been returned by ! a previous call to \cfunction{PyMem_Malloc()} or ! \cfunction{PyMem_Realloc()}. \end{cfuncdesc} *************** *** 4729,4732 **** --- 4741,4745 ---- sizeof(\var{TYPE}))} bytes of memory. Returns a pointer cast to \ctype{\var{TYPE}*}. + The memory will not have been initialized in any way. \end{cfuncdesc} *************** *** 4825,4853 **** \begin{cfuncdesc}{PyObject*}{PyObject_Init}{PyObject *op, ! PyTypeObject *type} \end{cfuncdesc} \begin{cfuncdesc}{PyVarObject*}{PyObject_InitVar}{PyVarObject *op, ! PyTypeObject *type, int size} \end{cfuncdesc} \begin{cfuncdesc}{\var{TYPE}*}{PyObject_New}{TYPE, PyTypeObject *type} \end{cfuncdesc} \begin{cfuncdesc}{\var{TYPE}*}{PyObject_NewVar}{TYPE, PyTypeObject *type, int size} \end{cfuncdesc} \begin{cfuncdesc}{void}{PyObject_Del}{PyObject *op} \end{cfuncdesc} \begin{cfuncdesc}{\var{TYPE}*}{PyObject_NEW}{TYPE, PyTypeObject *type} \end{cfuncdesc} \begin{cfuncdesc}{\var{TYPE}*}{PyObject_NEW_VAR}{TYPE, PyTypeObject *type, int size} \end{cfuncdesc} \begin{cfuncdesc}{void}{PyObject_DEL}{PyObject *op} \end{cfuncdesc} --- 4838,4900 ---- \begin{cfuncdesc}{PyObject*}{PyObject_Init}{PyObject *op, ! PyTypeObject *type} ! Initialize a newly-allocated object \var{op} with its type and ! initial reference. Returns the initialized object. If \var{type} ! indicates that the object participates in the cyclic garbage ! detector, it it added to the detector's set of observed objects. ! Other fields of the object are not affected. \end{cfuncdesc} \begin{cfuncdesc}{PyVarObject*}{PyObject_InitVar}{PyVarObject *op, ! PyTypeObject *type, int size} ! This does everything \cfunction{PyObject_Init()} does, and also ! initializes the length information for a variable-size object. \end{cfuncdesc} \begin{cfuncdesc}{\var{TYPE}*}{PyObject_New}{TYPE, PyTypeObject *type} + Allocate a new Python object using the C structure type \var{TYPE} + and the Python type object \var{type}. Fields not defined by the + Python object header are not initialized; the object's reference + count will be one. The size of the memory + allocation is determined from the \member{tp_basicsize} field of the + type object. \end{cfuncdesc} \begin{cfuncdesc}{\var{TYPE}*}{PyObject_NewVar}{TYPE, PyTypeObject *type, int size} + Allocate a new Python object using the C structure type \var{TYPE} + and the Python type object \var{type}. Fields not defined by the + Python object header are not initialized. The allocated memory + allows for the \var{TYPE} structure plus \var{size} fields of the + size given by the \member{tp_itemsize} field of \var{type}. This is + useful for implementing objects like tuples, which are able to + determine their size at construction time. Embedding the array of + fields into the same allocation decreases the number of allocations, + improving the memory management efficiency. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyObject_Del}{PyObject *op} + Releases memory allocated to an object using + \cfunction{PyObject_New()} or \cfunction{PyObject_NewVar()}. This + is normally called from the \member{tp_dealloc} handler specified in + the object's type. The fields of the object should not be accessed + after this call as the memory is no longer a valid Python object. \end{cfuncdesc} \begin{cfuncdesc}{\var{TYPE}*}{PyObject_NEW}{TYPE, PyTypeObject *type} + Macro version of \cfunction{PyObject_New()}, to gain performance at + the expense of safety. This does not check \var{type} for a \NULL{} + value. \end{cfuncdesc} \begin{cfuncdesc}{\var{TYPE}*}{PyObject_NEW_VAR}{TYPE, PyTypeObject *type, int size} + Macro version of \cfunction{PyObject_NewVar()}, to gain performance + at the expense of safety. This does not check \var{type} for a + \NULL{} value. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyObject_DEL}{PyObject *op} + Macro version of \cfunction{PyObject_Del()}. \end{cfuncdesc} *************** *** 4884,4888 **** \end{cfuncdesc} ! PyArg_ParseTupleAndKeywords, PyArg_ParseTuple, PyArg_Parse Py_BuildValue --- 4931,4957 ---- \end{cfuncdesc} ! \begin{cfuncdesc}{int}{PyArg_ParseTuple}{PyObject *args, char *format, ! \moreargs} ! Parse the parameters of a function that takes only positional ! parameters into local variables. See ! \citetitle[../ext/parseTuple.html]{Extending and Embedding the ! Python Interpreter} for more information. ! \end{cfuncdesc} ! ! \begin{cfuncdesc}{int}{PyArg_ParseTupleAndKeywords}{PyObject *args, ! PyObject *kw, char *format, char *keywords[], \moreargs} ! Parse the parameters of a function that takes both positional and ! keyword parameters into local variables. See ! \citetitle[../ext/parseTupleAndKeywords.html]{Extending and ! Embedding the Python Interpreter} for more information. ! \end{cfuncdesc} ! ! \begin{cfuncdesc}{int}{PyArg_Parse}{PyObject *args, char *format, \moreargs} ! Function used to deconstruct the argument lists of ``old-style'' ! functions --- these are functions which use the ! \constant{METH_OLDARGS} parameter parsing method. This is not ! recommended for new code, and most code in the standard interpreter ! has been modified to no longer use this. ! \end{cfuncdesc} Py_BuildValue *************** *** 4890,4894 **** DL_IMPORT ! _Py_NoneStruct --- 4959,4967 ---- DL_IMPORT ! \begin{cvardesc}{PyObject}{_Py_NoneStruct} ! Object which is visible in Python as \code{None}. This should only ! be accessed using the \code{Py_None} macro, which evaluates to a ! pointer to this object. ! \end{cvardesc} *************** *** 5165,5169 **** objects do not have to define this method since they can never directly create reference cycles. Note that the object must still ! be valid after calling this method (i.e., don't just call \cfunction{Py_DECREF()} on a reference). The collector will call this method if it detects that this object is involved in a --- 5238,5242 ---- objects do not have to define this method since they can never directly create reference cycles. Note that the object must still ! be valid after calling this method (don't just call \cfunction{Py_DECREF()} on a reference). The collector will call this method if it detects that this object is involved in a From fdrake@users.sourceforge.net Tue Jul 10 17:19:15 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 10 Jul 2001 09:19:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api refcounts.dat,1.25,1.26 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv9396/api Modified Files: refcounts.dat Log Message: Corrected the refcount information for PyList_SET_ITEM(). Index: refcounts.dat =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/refcounts.dat,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -r1.25 -r1.26 *** refcounts.dat 2001/07/06 23:31:49 1.25 --- refcounts.dat 2001/07/10 16:19:13 1.26 *************** *** 406,410 **** PyList_Reverse:PyObject*:list:0: ! PyList_SET_ITEM:PyObject*::0: PyList_SET_ITEM:PyObject*:list:0: PyList_SET_ITEM:int:i:: --- 406,410 ---- PyList_Reverse:PyObject*:list:0: ! PyList_SET_ITEM:void::: PyList_SET_ITEM:PyObject*:list:0: PyList_SET_ITEM:int:i:: From fdrake@users.sourceforge.net Tue Jul 10 17:19:28 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 10 Jul 2001 09:19:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api refcounts.dat,1.23,1.23.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv9425/api Modified Files: Tag: release21-maint refcounts.dat Log Message: Corrected the refcount information for PyList_SET_ITEM(). Index: refcounts.dat =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/refcounts.dat,v retrieving revision 1.23 retrieving revision 1.23.4.1 diff -C2 -r1.23 -r1.23.4.1 *** refcounts.dat 2001/01/28 06:39:35 1.23 --- refcounts.dat 2001/07/10 16:19:26 1.23.4.1 *************** *** 401,405 **** PyList_Reverse:PyObject*:list:0: ! PyList_SET_ITEM:PyObject*::0: PyList_SET_ITEM:PyObject*:list:0: PyList_SET_ITEM:int:i:: --- 401,405 ---- PyList_Reverse:PyObject*:list:0: ! PyList_SET_ITEM:void::: PyList_SET_ITEM:PyObject*:list:0: PyList_SET_ITEM:int:i:: From fdrake@users.sourceforge.net Tue Jul 10 17:21:01 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 10 Jul 2001 09:21:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc ACKS,1.16.4.3,1.16.4.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv9934 Modified Files: Tag: release21-maint ACKS Log Message: Add another name. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ACKS,v retrieving revision 1.16.4.3 retrieving revision 1.16.4.4 diff -C2 -r1.16.4.3 -r1.16.4.4 *** ACKS 2001/07/02 15:12:25 1.16.4.3 --- ACKS 2001/07/10 16:20:59 1.16.4.4 *************** *** 20,23 **** --- 20,24 ---- Pehr Anderson Oliver Andrich + Jesús Cea Avión Daniel Barclay Chris Barker From gvanrossum@users.sourceforge.net Tue Jul 10 17:28:06 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 10 Jul 2001 09:28:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.64,2.16.8.65 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv11637 Modified Files: Tag: descr-branch typeobject.c Log Message: type_new(): only accept the special 1-argument form when the metatype argument is &PyType_Type. When it isn't, we're being invoked by a derived type's tp_new() slot, and we should always return a new object. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.64 retrieving revision 2.16.8.65 diff -C2 -r2.16.8.64 -r2.16.8.65 *** typeobject.c 2001/07/08 04:30:29 2.16.8.64 --- typeobject.c 2001/07/10 16:28:04 2.16.8.65 *************** *** 449,453 **** int i, nbases, nslots, slotoffset, dynamic; ! if (PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 && (kwds == NULL || (PyDict_Check(kwds) && PyDict_Size(kwds) == 0))) { /* type(x) -> x.__class__ */ --- 449,454 ---- int i, nbases, nslots, slotoffset, dynamic; ! if (metatype == &PyType_Type && ! PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 && (kwds == NULL || (PyDict_Check(kwds) && PyDict_Size(kwds) == 0))) { /* type(x) -> x.__class__ */ From gvanrossum@users.sourceforge.net Tue Jul 10 17:33:55 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 10 Jul 2001 09:33:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects floatobject.c,2.81.6.5,2.81.6.6 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv13204 Modified Files: Tag: descr-branch floatobject.c Log Message: float_new(): prevent core dump on 'float()' call without argument, by initializing x to zero (Py_False being a good stand-in). Index: floatobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v retrieving revision 2.81.6.5 retrieving revision 2.81.6.6 diff -C2 -r2.81.6.5 -r2.81.6.6 *** floatobject.c 2001/07/07 22:55:30 2.81.6.5 --- floatobject.c 2001/07/10 16:33:53 2.81.6.6 *************** *** 634,638 **** float_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { ! PyObject *x; static char *kwlist[] = {"x", 0}; --- 634,638 ---- float_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { ! PyObject *x = Py_False; /* Integer zero */ static char *kwlist[] = {"x", 0}; From gvanrossum@users.sourceforge.net Tue Jul 10 17:44:37 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 10 Jul 2001 09:44:37 -0700 Subject: [Python-checkins] CVS: python/dist/src acconfig.h,1.49,1.50 config.h.in,2.97,2.98 configure,1.215,1.216 configure.in,1.223,1.224 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv15227 Modified Files: acconfig.h config.h.in configure configure.in Log Message: SF Patch #432457 by Jason Tishler: support for readline 4.2. This patch allows the readline module to build cleanly with GNU readline 4.2 without breaking the build for earlier GNU readline versions. The configure script checks for the presence of rl_completion_matches in libreadline. Index: acconfig.h =================================================================== RCS file: /cvsroot/python/python/dist/src/acconfig.h,v retrieving revision 1.49 retrieving revision 1.50 diff -C2 -r1.49 -r1.50 *** acconfig.h 2001/06/26 22:22:36 1.49 --- acconfig.h 2001/07/10 16:44:35 1.50 *************** *** 87,90 **** --- 87,93 ---- #undef HAVE_PTH + /* Define if you have readline 4.2 */ + #undef HAVE_RL_COMPLETION_MATCHES + /* Define if your compiler supports variable length function prototypes (e.g. void fprintf(FILE *, char *, ...);) *and* */ Index: config.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/config.h.in,v retrieving revision 2.97 retrieving revision 2.98 diff -C2 -r2.97 -r2.98 *** config.h.in 2001/06/26 22:22:36 2.97 --- config.h.in 2001/07/10 16:44:35 2.98 *************** *** 149,152 **** --- 149,155 ---- #undef HAVE_PTH + /* Define if you have readline 4.2 */ + #undef HAVE_RL_COMPLETION_MATCHES + /* Define if your compiler supports variable length function prototypes (e.g. void fprintf(FILE *, char *, ...);) *and* */ *************** *** 297,303 **** #undef SIZEOF_WCHAR_T - /* Define if you have the _getpty function. */ - #undef HAVE__GETPTY - /* Define if you have the alarm function. */ #undef HAVE_ALARM --- 300,303 ---- *************** *** 393,396 **** --- 393,399 ---- #undef HAVE_GETPID + /* Define if you have the _getpty function. */ + #undef HAVE__GETPTY + /* Define if you have the getpwent function. */ #undef HAVE_GETPWENT *************** *** 555,566 **** #undef HAVE_WAITPID ! /* Define if you have the header file. */ ! #undef HAVE_DB_H /* Define if you have the header file. */ #undef HAVE_DB1_NDBM_H ! /* Define if you have the header file. */ ! #undef HAVE_DB_185_H /* Define if you have the header file. */ --- 558,569 ---- #undef HAVE_WAITPID ! /* Define if you have the header file. */ ! #undef HAVE_DB_185_H /* Define if you have the header file. */ #undef HAVE_DB1_NDBM_H ! /* Define if you have the header file. */ ! #undef HAVE_DB_H /* Define if you have the header file. */ Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.215 retrieving revision 1.216 diff -C2 -r1.215 -r1.216 *** configure 2001/06/27 20:22:04 1.215 --- configure 2001/07/10 16:44:35 1.216 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.222 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.224 # Guess values for system-dependent variables and create Makefiles. *************** *** 6815,6818 **** --- 6815,6863 ---- fi + # check for readline 4.2 + echo $ac_n "checking for rl_completion_matches in -lreadline""... $ac_c" 1>&6 + echo "configure:6820: checking for rl_completion_matches in -lreadline" >&5 + ac_lib_var=`echo readline'_'rl_completion_matches | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + ac_save_LIBS="$LIBS" + LIBS="-lreadline -ltermcap $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" + fi + rm -f conftest* + LIBS="$ac_save_LIBS" + + fi + if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF + #define HAVE_RL_COMPLETION_MATCHES 1 + EOF + + else + echo "$ac_t""no" 1>&6 + fi + + # THIS MUST BE LAST, IT CAN BREAK OTHER TESTS! # Add sys/socket.h to confdefs.h *************** *** 6823,6832 **** EOF echo $ac_n "checking for socklen_t""... $ac_c" 1>&6 ! echo "configure:6826: checking for socklen_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_socklen_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < --- 6868,6877 ---- EOF echo $ac_n "checking for socklen_t""... $ac_c" 1>&6 ! echo "configure:6871: checking for socklen_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_socklen_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < *************** *** 6877,6881 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6880: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then --- 6922,6926 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6925: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.223 retrieving revision 1.224 diff -C2 -r1.223 -r1.224 *** configure.in 2001/06/27 20:22:04 1.223 --- configure.in 2001/07/10 16:44:35 1.224 *************** *** 1662,1665 **** --- 1662,1669 ---- fi + # check for readline 4.2 + AC_CHECK_LIB(readline, rl_completion_matches, + AC_DEFINE(HAVE_RL_COMPLETION_MATCHES), , -ltermcap) + # THIS MUST BE LAST, IT CAN BREAK OTHER TESTS! # Add sys/socket.h to confdefs.h From gvanrossum@users.sourceforge.net Tue Jul 10 17:45:34 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 10 Jul 2001 09:45:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules readline.c,2.35,2.36 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv16111/Modules Modified Files: readline.c Log Message: SF Patch #432457 by Jason Tishler: support for readline 4.2. This patch allows the readline module to build cleanly with GNU readline 4.2 without breaking the build for earlier GNU readline versions. The configure script checks for the presence of rl_completion_matches in libreadline. Index: readline.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/readline.c,v retrieving revision 2.35 retrieving revision 2.36 diff -C2 -r2.35 -r2.36 *** readline.c 2001/04/13 18:14:27 2.35 --- readline.c 2001/07/10 16:45:32 2.36 *************** *** 22,25 **** --- 22,29 ---- #include + #ifdef HAVE_RL_COMPLETION_MATCHES + #define completion_matches(x, y) rl_completion_matches((x), ((rl_compentry_func_t *)(y))) + #endif + /* Pointers needed from outside (but not declared in a header file). */ extern DL_IMPORT(int) (*PyOS_InputHook)(void); From gvanrossum@users.sourceforge.net Tue Jul 10 18:11:21 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 10 Jul 2001 10:11:21 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0253.txt,1.7,1.8 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv21863 Modified Files: pep-0253.txt Log Message: Intermediate checkin (documented tp_new, tp_init, tp_alloc properly). Index: pep-0253.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0253.txt,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** pep-0253.txt 2001/07/05 19:00:02 1.7 --- pep-0253.txt 2001/07/10 17:11:19 1.8 *************** *** 22,26 **** describe all aspects of a Python type that are relevant to the Python interpreter. A few fields contain dimensional information ! (e.g. the basic allocation size of instances), others contain various flags, but most fields are pointers to functions to implement various kinds of behaviors. A NULL pointer means that --- 22,26 ---- describe all aspects of a Python type that are relevant to the Python interpreter. A few fields contain dimensional information ! (like the basic allocation size of instances), others contain various flags, but most fields are pointers to functions to implement various kinds of behaviors. A NULL pointer means that *************** *** 40,71 **** This PEP will introduce the following features: ! - a type can be a factory function for its instances ! - types can be subtyped in C ! - types can be subtyped in Python with the class statement ! - multiple inheritance from types is supported (insofar as ! practical) ! - the standard coercions functions (int, tuple, str etc.) will be ! redefined to be the corresponding type objects, which serve as ! their own factory functions ! - there will be a standard type hierarchy ! - a class statement can contain a metaclass declaration, ! specifying the metaclass to be used to create the new class ! - a class statement can contain a slots declaration, specifying ! the specific names of the instance variables supported This PEP builds on PEP 252, which adds standard introspection to ! types; e.g., when the type object defines the tp_hash slot, the ! type object has a __hash__ method. PEP 252 also adds a ! dictionary to type objects which contains all methods. At the ! Python level, this dictionary is read-only for built-in types; at ! the C level, it is accessible directly (but it should not be ! modified except as part of initialization). For binary compatibility, a flag bit in the tp_flags slot --- 40,74 ---- This PEP will introduce the following features: ! - a type can be a factory function for its instances ! - types can be subtyped in C ! - types can be subtyped in Python with the class statement ! - multiple inheritance from types is supported (insofar as ! practical -- you still can't multiply inherit from list and ! dictionary) ! - the standard coercions functions (int, tuple, str etc.) will ! be redefined to be the corresponding type objects, which serve ! as their own factory functions ! - a class statement can contain a __metaclass__ declaration, ! specifying the metaclass to be used to create the new class ! - a class statement can contain a __slots__ declaration, ! specifying the specific names of the instance variables ! supported ! - there will be a standard type hierarchy (maybe) This PEP builds on PEP 252, which adds standard introspection to ! types; for example, when a particular type object initializes the ! tp_hash slot, that type object has a __hash__ method when ! introspected. PEP 252 also adds a dictionary to type objects ! which contains all methods. At the Python level, this dictionary ! is read-only for built-in types; at the C level, it is accessible ! directly (but it should not be modified except as part of ! initialization). For binary compatibility, a flag bit in the tp_flags slot *************** *** 80,91 **** In current Python, a distinction is made between types and classes. This PEP together with PEP 254 will remove that ! distinction. However, for backwards compatibility there will ! probably remain a bit of a distinction for years to come, and ! without PEP 254, the distinction is still large: types ultimately ! have a built-in type as a base class, while classes ultimately ! derive from a user-defined class. Therefore, in the rest of this ! PEP, I will use the word type whenever I can -- including base ! type or supertype, derived type or subtype, and metatype. ! However, sometimes the terminology necessarily blends, e.g. an object's type is given by its __class__ attribute, and subtyping in Python is spelled with a class statement. If further --- 83,94 ---- In current Python, a distinction is made between types and classes. This PEP together with PEP 254 will remove that ! distinction. However, for backwards compatibility the distinction ! will probably remain for years to come, and without PEP 254, the ! distinction is still large: types ultimately have a built-in type ! as a base class, while classes ultimately derive from a ! user-defined class. Therefore, in the rest of this PEP, I will ! use the word type whenever I can -- including base type or ! supertype, derived type or subtype, and metatype. However, ! sometimes the terminology necessarily blends, for example an object's type is given by its __class__ attribute, and subtyping in Python is spelled with a class statement. If further *************** *** 96,102 **** About metatypes ! Inevitably the following discussion will come to mention metatypes ! (or metaclasses). Metatypes are nothing new in Python: Python has ! always been able to talk about the type of a type: >>> a = 0 --- 99,105 ---- About metatypes ! Inevitably the discussion comes to metatypes (or metaclasses). ! Metatypes are nothing new in Python: Python has always been able ! to talk about the type of a type: >>> a = 0 *************** *** 114,127 **** requirement, and in fact a useful and relevant 3rd party extension (ExtensionClasses by Jim Fulton) creates an additional metatype. ! A related feature is the "Don Beaudry hook", which says that if a ! metatype is callable, its instances (which are regular types) can ! be subclassed (really subtyped) using a Python class statement. ! I will use this rule to support subtyping of built-in types, and ! in fact it greatly simplifies the logic of class creation to ! always simply call the metatype. When no base class is specified, ! a default metatype is called -- the default metatype is the ! "ClassType" object, so the class statement will behave as before ! in the normal case. Python uses the concept of metatypes or metaclasses in a different --- 117,133 ---- requirement, and in fact a useful and relevant 3rd party extension (ExtensionClasses by Jim Fulton) creates an additional metatype. + The type of classic classes, known as types.ClassType, can also be + considered a distinct metatype. ! A feature closely connected to metatypes is the "Don Beaudry ! hook", which says that if a metatype is callable, its instances ! (which are regular types) can be subclassed (really subtyped) ! using a Python class statement. I will use this rule to support ! subtyping of built-in types, and in fact it greatly simplifies the ! logic of class creation to always simply call the metatype. When ! no base class is specified, a default metatype is called -- the ! default metatype is the "ClassType" object, so the class statement ! will behave as before in the normal case. (This default can be ! changed per module by setting the global variable __metaclass__.) Python uses the concept of metatypes or metaclasses in a different *************** *** 139,147 **** many regular types. (It will be possible to subtype metatypes in Python, so it won't be absolutely necessary to write C in order to ! use metatypes; but the power of Python metatypes will be limited, ! e.g. Python code will never be allowed to allocate raw memory and ! initialize it at will.) ! Metatypes determine various *policies* for types, e.g. what happens when a type is called, how dynamic types are (whether a type's __dict__ can be modified after it is created), what the --- 145,153 ---- many regular types. (It will be possible to subtype metatypes in Python, so it won't be absolutely necessary to write C in order to ! use metatypes; but the power of Python metatypes will be limited. ! For example, Python code will never be allowed to allocate raw ! memory and initialize it at will.) ! Metatypes determine various *policies* for types,such as what happens when a type is called, how dynamic types are (whether a type's __dict__ can be modified after it is created), what the *************** *** 185,188 **** --- 191,213 ---- is being called. + (Confusion alert: the tp_call slot of a regular type object (such + as PyInt_Type or PyList_Type) defines what happens when + *instances* of that type are called; in particular, the tp_call + slot in the function type, PyFunction_Type, is the key to making + functions callable. As another example, PyInt_Type.tp_call is + NULL, because integers are not callable. The new paradigm makes + *type objects* callable. Since type objects are instances of + their metatype (PyType_Type), the metatype's tp_call slot + (PyType_Type.tp_call) points to a function that is invoked when + any type object is called. Now, since each type has do do + something different to create an instance of itself, + PyType_Type.tp_call immediately defers to the tp_new slot of the + type that is being called. To add to the confusion, PyType_Type + itself is also callable: its tp_new slot creates a new type. This + is used by the class statement (via the Don Beaudry hook, see + above). And what makes PyType_Type callable? The tp_call slot of + *its* metatype -- but since it is its own metatype, that is its + own tp_call slot!) + If the type's tp_new slot is NULL, an exception is raised. Otherwise, the tp_new slot is called. The signature for the *************** *** 204,207 **** --- 229,308 ---- should always be a new reference, owned by the caller. + One the tp_new slot has returned an object, further initialization + is attempted by calling the tp_init() slot of the resulting + object's type, if not NULL. This has the following signature: + + PyObject *tp_init(PyObject *self, + PyObject *args, + PyObject *kwds) + + It corresponds more closely to the __init__() method of classic + classes, and in fact is mapped to that by the slot/special-method + correspondence rules. The difference in responsibilities between + the tp_new() slot and the tp_init() slot lies in the invariants + they ensure. The tp_new() slot should ensure only the most + essential invariants, without which the C code that implements the + object's wold break. The tp_init() slot should be used for + overridable user-specific initializations. Take for example the + dictionary type. The implementation has an internal pointer to a + hash table which should never be NULL. This invariant is taken + care of by the tp_new() slot for dictionaries. The dictionary + tp_init() slot, on the other hand, could be used to give the + dictionary an initial set of keys and values based on the + arguments passed in. + + You may wonder why the tp_new() slot shouldn't call the tp_init() + slot itself. The reason is that in certain circumstances (like + support for persistent objects), it is important to be able to + create an object of a particular type without initializing it any + further than necessary. This may conveniently be done by calling + the tp_new() slot without calling tp_init(). It is also possible + that tp_init() is not called, or called more than once -- its + operation should be robust even in these anomalous cases. + + For some objects, tp_new() may return an existing object. For + example, the factory function for integers caches the integers -1 + throug 99. This is permissible only when the type argument to + tp_new() is the type that defined the tp_new() function (in the + example, if type == &PyInt_Type), and when the tp_init() slot for + this type does nothing. If the type argument differs, the + tp_new() call is initiated by by a derived type's tp_new() to + create the object and initialize the base type portion of the + object; in this case tp_new() should always return a new object + (or raise an exception). + + There's a third slot related to object creation: tp_alloc(). Its + responsibility is to allocate the memory for the object, + initialize the reference count and type pointer field, and + initialize the rest of the object to all zeros. It should also + register the object with the garbage collection subsystem if the + type supports garbage collection. This slot exists so that + derived types can override the memory allocation policy + (e.g. which heap is being used) separately from the initialization + code. The signature is: + + PyObject *tp_alloc(PyTypeObject *type, int nitems) + + The type argument is the type of the new object. The nitems + argument is normally zero, except for objects with a variable + allocation size (basically strings, tuples, and longs). The + allocation size is given by the following expression: + + type->tp_basicsize + nitems * type->tp_itemsize + + This slot is only used for subclassable types. The tp_new() + function of the base class must call the tp_alloc() slot of the + type passed in as its first argument. It is the tp_new() + function's responsibility to calculate the number of items. The + tp_alloc() slot will set the ob_size field of the new object if + the type->tp_itemsize field is nonzero. + + XXX The keyword arguments are currently not passed to tp_new(); + its kwds argument is always NULL. This is a relic from a previous + revision and should probably be fixed. Both tp_new() and + tp_init() should receive exactly the same arguments, and both + should check that the arguments are acceptable, because they may + be called independently. + Requirements for a type to allow subtyping *************** *** 241,247 **** A similar reasoning applies to destruction: if a subtype changes ! the instance allocator (e.g. to use a different heap), it must ! also change the instance deallocator; but it must still call on ! the base type's destructor to DECREF the base type's instance variables. --- 342,348 ---- A similar reasoning applies to destruction: if a subtype changes ! the instance allocator (for example to use a different heap), it ! must also change the instance deallocator; but it must still call ! on the base type's destructor to DECREF the base type's instance variables. *************** *** 312,316 **** the base type must also be exported. ! If the base type has a type-checking macro (e.g. PyDict_Check()), this macro probably should be changed to recognize subtypes. This can be done by using the new PyObject_TypeCheck(object, type) --- 413,417 ---- the base type must also be exported. ! If the base type has a type-checking macro (like PyDict_Check()), this macro probably should be changed to recognize subtypes. This can be done by using the new PyObject_TypeCheck(object, type) *************** *** 435,439 **** Exception: if the subtype defines no additional fields in its ! structure (i.e., it only defines new behavior, no new data), the tp_basicsize and the tp_dealloc fields may be set to zero. --- 536,540 ---- Exception: if the subtype defines no additional fields in its ! structure (it only defines new behavior, no new data), the tp_basicsize and the tp_dealloc fields may be set to zero. *************** *** 452,457 **** base class's tp_dealloc slot. Because deallocation functions typically are not exported, this call has to be made via the base ! type's type structure, e.g., when deriving from the standard list ! type: PyList_Type.tp_dealloc(self); --- 553,558 ---- base class's tp_dealloc slot. Because deallocation functions typically are not exported, this call has to be made via the base ! type's type structure, for example, when deriving from the ! standard list type: PyList_Type.tp_dealloc(self); *************** *** 460,465 **** type, the subtype must call the base type's tp_clear() slot instead, followed by a call to free the object's memory from the ! appropriate heap, e.g. PyObject_DEL(self) if the subtype uses the ! standard heap. But in this case subtyping is not recommended.) A subtype is not usable until PyType_InitDict() is called for it; --- 561,567 ---- type, the subtype must call the base type's tp_clear() slot instead, followed by a call to free the object's memory from the ! appropriate heap, such as PyObject_DEL(self) if the subtype uses ! the standard heap. But in this case subtyping is not ! recommended.) A subtype is not usable until PyType_InitDict() is called for it; *************** *** 507,511 **** the string "C"); the list of base classes (a singleton tuple containing B); and the results of executing the class body, in the ! form of a dictionary (e.g. {"var1": 1, "method1": , ...}). --- 609,613 ---- the string "C"); the list of base classes (a singleton tuple containing B); and the results of executing the class body, in the ! form of a dictionary (for example {"var1": 1, "method1": , ...}). *************** *** 581,586 **** still referencing it); and some more auxiliary storage (to be described later). It initializes this storage to zeros except for ! a few crucial slots (e.g. tp_name is set to point to the type ! name) and then sets the tp_base slot to point to B. Then PyType_InitDict() is called to inherit B's slots. Finally, C's tp_dict slot is updated with the contents of the namespace --- 683,688 ---- still referencing it); and some more auxiliary storage (to be described later). It initializes this storage to zeros except for ! a few crucial slots (for example, tp_name is set to point to the ! type name) and then sets the tp_base slot to point to B. Then PyType_InitDict() is called to inherit B's slots. Finally, C's tp_dict slot is updated with the contents of the namespace *************** *** 642,649 **** identical in the contents of all their slots except for their deallocation slot. But this requires that all type-checking code ! (e.g. the PyDict_Check()) recognizes both types. We'll come back ! to this solution in the context of subtyping. Another alternative ! is to require the metatype's tp_call to leave the allocation to ! the tp_construct method, by passing in a NULL pointer. But this doesn't work once we allow subtyping. --- 744,751 ---- identical in the contents of all their slots except for their deallocation slot. But this requires that all type-checking code ! (like PyDict_Check()) recognizes both types. We'll come back to ! this solution in the context of subtyping. Another alternative is ! to require the metatype's tp_call to leave the allocation to the ! tp_construct method, by passing in a NULL pointer. But this doesn't work once we allow subtyping. From jvr@users.sourceforge.net Tue Jul 10 20:25:42 2001 From: jvr@users.sourceforge.net (Just van Rossum) Date: Tue, 10 Jul 2001 12:25:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Tools/IDE PyBrowser.py,1.8,1.9 PyEdit.py,1.20,1.21 PyFontify.py,1.4,1.5 Wcontrols.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Tools/IDE In directory usw-pr-cvs1:/tmp/cvs-serv30899 Modified Files: PyBrowser.py PyEdit.py PyFontify.py Wcontrols.py Log Message: - fixed some re usage, partly so it'll still work when re uses pre instead of sre, and partly fixing re -> regex porting oversights - fixed PyFontify.py so it actually *works* again.. Index: PyBrowser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PyBrowser.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** PyBrowser.py 2001/06/19 21:37:32 1.8 --- PyBrowser.py 2001/07/10 19:25:40 1.9 *************** *** 14,18 **** arrows = (nullid, closedid, openid, closedsolidid, opensolidid) ! has_ctlcharsRE = re.compile('[\000-\037\177-\377]') def ctlcharsREsearch(str): if has_ctlcharsRE.search(str) is None: --- 14,18 ---- arrows = (nullid, closedid, openid, closedsolidid, opensolidid) ! has_ctlcharsRE = re.compile(r'[\000-\037\177-\377]') def ctlcharsREsearch(str): if has_ctlcharsRE.search(str) is None: Index: PyEdit.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PyEdit.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -r1.20 -r1.21 *** PyEdit.py 2001/07/05 07:06:26 1.20 --- PyEdit.py 2001/07/10 19:25:40 1.21 *************** *** 791,795 **** def _makewholewordpattern(word): # first, escape special regex chars ! for esc in "\\[]().*^+$?": word = _escape(word, esc) notwordcharspat = '[^' + _wordchars + ']' --- 791,795 ---- def _makewholewordpattern(word): # first, escape special regex chars ! for esc in "\\[]()|.*^+$?": word = _escape(word, esc) notwordcharspat = '[^' + _wordchars + ']' *************** *** 1167,1171 **** ! _identifieRE = re.compile("[A-Za-z_][A-Za-z_0-9]*") def identifieRE_match(str): --- 1167,1171 ---- ! _identifieRE = re.compile(r"[A-Za-z_][A-Za-z_0-9]*") def identifieRE_match(str): Index: PyFontify.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PyFontify.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** PyFontify.py 2001/02/21 13:54:31 1.4 --- PyFontify.py 2001/07/10 19:25:40 1.5 *************** *** 20,24 **** # Tim (the-incredib-ly y'rs) Peters and Cristian Tismer # So, who owns the copyright? ;-) How about this: ! # Copyright 1996-2000: # Mitchell S. Chapman, # Zachary Roadhouse, --- 20,24 ---- # Tim (the-incredib-ly y'rs) Peters and Cristian Tismer # So, who owns the copyright? ;-) How about this: ! # Copyright 1996-2001: # Mitchell S. Chapman, # Zachary Roadhouse, *************** *** 26,32 **** # Just van Rossum ! __version__ = "0.3.3" ! import string, re # First a little helper, since I don't like to repeat things. (Tismer speaking) --- 26,33 ---- # Just van Rossum ! __version__ = "0.4" ! import string ! import re # First a little helper, since I don't like to repeat things. (Tismer speaking) *************** *** 44,77 **** "class", "except", "import", "pass", "continue", "finally", "in", "print", ! "def", "for", "is", "raise"] # Build up a regular expression which will match anything # interesting, including multi-line triple-quoted strings. ! commentPat = "#.*" ! pat = "q[^\q\n]*\(\\\\[\000-\377][^\q\n]*\)*q" ! quotePat = replace(pat, "q", "'") + "\|" + replace(pat, 'q', '"') # Way to go, Tim! ! pat = """ qqq [^\\q]* ! \( ! \( \\\\[\000-\377] ! \| q ! \( \\\\[\000-\377] ! \| [^\\q] ! \| q ! \( \\\\[\000-\377] ! \| [^\\q] ! \) ! \) ! \) [^\\q]* ! \)* qqq """ pat = string.join(string.split(pat), '') # get rid of whitespace ! tripleQuotePat = replace(pat, "q", "'") + "\|" + replace(pat, 'q', '"') # Build up a regular expression which matches all and only --- 45,78 ---- "class", "except", "import", "pass", "continue", "finally", "in", "print", ! "def", "for", "is", "raise", "yield"] # Build up a regular expression which will match anything # interesting, including multi-line triple-quoted strings. ! commentPat = r"#[^\n]*" ! pat = r"q[^\\q\n]*(\\[\000-\377][^\\q\n]*)*q" ! quotePat = replace(pat, "q", "'") + "|" + replace(pat, 'q', '"') # Way to go, Tim! ! pat = r""" qqq [^\\q]* ! ( ! ( \\[\000-\377] ! | q ! ( \\[\000-\377] ! | [^\q] ! | q ! ( \\[\000-\377] ! | [^\\q] ! ) ! ) ! ) [^\\q]* ! )* qqq """ pat = string.join(string.split(pat), '') # get rid of whitespace ! tripleQuotePat = replace(pat, "q", "'") + "|" + replace(pat, 'q', '"') # Build up a regular expression which matches all and only *************** *** 80,91 **** # nonKeyPat identifies characters which may legally precede # a keyword pattern. ! nonKeyPat = "\(^\|[^a-zA-Z0-9_.\"']\)" ! keyPat = nonKeyPat + "\(" ! for keyword in keywordsList: ! keyPat = keyPat + keyword + "\|" ! keyPat = keyPat[:-2] + "\)" + nonKeyPat ! matchPat = commentPat + "\|" + keyPat + "\|" + tripleQuotePat + "\|" + quotePat matchRE = re.compile(matchPat) --- 81,89 ---- # nonKeyPat identifies characters which may legally precede # a keyword pattern. ! nonKeyPat = r"(^|[^a-zA-Z0-9_.\"'])" ! keyPat = nonKeyPat + "(" + "|".join(keywordsList) + ")" + nonKeyPat ! matchPat = commentPat + "|" + keyPat + "|" + tripleQuotePat + "|" + quotePat matchRE = re.compile(matchPat) *************** *** 112,116 **** while 1: m = search(pytext, end) ! if not m or m.start() >= searchto: break # EXIT LOOP match = m.group(0) --- 110,117 ---- while 1: m = search(pytext, end) ! if m is None: ! break # EXIT LOOP ! start = m.start() ! if start >= searchto: break # EXIT LOOP match = m.group(0) *************** *** 133,140 **** if match in ["def", "class"]: m = idSearch(pytext, end) ! if m and m.start() == end: ! match = m.group(0) ! end = start + len(match) ! tags_append((identifierTag, start, end, None)) elif c == "#": tags_append((commentTag, start, end, None)) --- 134,143 ---- if match in ["def", "class"]: m = idSearch(pytext, end) ! if m is not None: ! start = m.start() ! if start == end: ! match = m.group(0) ! end = start + len(match) ! tags_append((identifierTag, start, end, None)) elif c == "#": tags_append((commentTag, start, end, None)) Index: Wcontrols.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/Wcontrols.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** Wcontrols.py 2001/01/23 14:58:20 1.5 --- Wcontrols.py 2001/07/10 19:25:40 1.6 *************** *** 382,393 **** - class __xxxx_PopupControl(ControlWidget): - - def __init__(self, possize, title = "Button", callback = None): - procID = Controls.popupMenuProc # | Controls.useWFont - ControlWidget.__init__(self, possize, title, procID, callback, 0, 0, 1) - self._isdefault = 0 - - def _scalebarvalue(absmin, absmax, curmin, curmax): if curmin <= absmin and curmax >= absmax: --- 382,385 ---- From gvanrossum@users.sourceforge.net Tue Jul 10 21:01:54 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 10 Jul 2001 13:01:54 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0253.txt,1.8,1.9 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv7549 Modified Files: pep-0253.txt Log Message: Another intermediate checkin. Removed a lot of lies about an older idea for what tp_alloc() should be. Index: pep-0253.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0253.txt,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** pep-0253.txt 2001/07/10 17:11:19 1.8 --- pep-0253.txt 2001/07/10 20:01:52 1.9 *************** *** 19,27 **** Traditionally, types in Python have been created statically, by declaring a global variable of type PyTypeObject and initializing ! it with a static initializer. The fields in the type object describe all aspects of a Python type that are relevant to the ! Python interpreter. A few fields contain dimensional information (like the basic allocation size of instances), others contain ! various flags, but most fields are pointers to functions to implement various kinds of behaviors. A NULL pointer means that the type does not implement the specific behavior; in that case --- 19,27 ---- Traditionally, types in Python have been created statically, by declaring a global variable of type PyTypeObject and initializing ! it with a static initializer. The slots in the type object describe all aspects of a Python type that are relevant to the ! Python interpreter. A few slots contain dimensional information (like the basic allocation size of instances), others contain ! various flags, but most slots are pointers to functions to implement various kinds of behaviors. A NULL pointer means that the type does not implement the specific behavior; in that case *************** *** 75,79 **** indicates the existence of the various new slots in the type object introduced below. Types that don't have the ! Py_TPFLAGS_HAVE_CLASS bit set in their tp_flags field are assumed to have NULL values for all the subtyping slots. (Warning: the current implementation prototype is not yet consistent in its --- 75,79 ---- indicates the existence of the various new slots in the type object introduced below. Types that don't have the ! Py_TPFLAGS_HAVE_CLASS bit set in their tp_flags slot are assumed to have NULL values for all the subtyping slots. (Warning: the current implementation prototype is not yet consistent in its *************** *** 252,255 **** --- 252,261 ---- arguments passed in. + Note that for immutable object types, the initialization cannot be + done by the tp_init() slot: this would provide the Python user + with a way to change the initialiation. Therefore, immutable + objects typically have an empty tp_init() implementation and do + all their initialization in their tp_new() slot. + You may wonder why the tp_new() slot shouldn't call the tp_init() slot itself. The reason is that in certain circumstances (like *************** *** 274,284 **** There's a third slot related to object creation: tp_alloc(). Its responsibility is to allocate the memory for the object, ! initialize the reference count and type pointer field, and ! initialize the rest of the object to all zeros. It should also ! register the object with the garbage collection subsystem if the ! type supports garbage collection. This slot exists so that ! derived types can override the memory allocation policy ! (e.g. which heap is being used) separately from the initialization ! code. The signature is: PyObject *tp_alloc(PyTypeObject *type, int nitems) --- 280,290 ---- There's a third slot related to object creation: tp_alloc(). Its responsibility is to allocate the memory for the object, ! initialize the reference count (ob_refcnt) and the type pointer ! (ob_type), and initialize the rest of the object to all zeros. It ! should also register the object with the garbage collection ! subsystem if the type supports garbage collection. This slot ! exists so that derived types can override the memory allocation ! policy (e.g. which heap is being used) separately from the ! initialization code. The signature is: PyObject *tp_alloc(PyTypeObject *type, int nitems) *************** *** 295,300 **** type passed in as its first argument. It is the tp_new() function's responsibility to calculate the number of items. The ! tp_alloc() slot will set the ob_size field of the new object if ! the type->tp_itemsize field is nonzero. XXX The keyword arguments are currently not passed to tp_new(); --- 301,311 ---- type passed in as its first argument. It is the tp_new() function's responsibility to calculate the number of items. The ! tp_alloc() slot will set the ob_size member of the new object if ! the type->tp_itemsize member is nonzero. ! ! (Note: in certain debugging compilation modes, the type structure ! used to have members named tp_alloc and a tp_free slot already, ! counters for the number of allocations and deallocations. These ! are renamed to tp_allocs and tp_deallocs.) XXX The keyword arguments are currently not passed to tp_new(); *************** *** 305,412 **** be called independently. - Requirements for a type to allow subtyping ! The simplest form of subtyping is subtyping in C. It is the ! simplest form because we can require the C code to be aware of the ! various problems, and it's acceptable for C code that doesn't ! follow the rules to dump core. For added simplicity, it is ! limited to single inheritance. The idea behind subtyping is very similar to that of single inheritance in C++. A base type is described by a structure ! declaration plus a type object. A derived type can extend the ! structure (but must leave the names, order and type of the fields of the base structure unchanged) and can override certain slots in ! the type object, leaving others the same. ! Most issues have to do with construction and destruction of ! instances of derived types. ! Creation of a new object is separated into allocation and ! initialization: allocation allocates the memory, and ! initialization fill it with appropriate initial values. The ! separation is needed for the convenience of subtypes. ! Instantiation of a subtype goes as follows: ! ! 1. allocate memory for the whole (subtype) instance ! 2. initialize the base type ! 3. initialize the subtype's instance variables ! ! If allocation and initialization were done by the same function, ! you would need a way to tell the base type's constructor to ! allocate additional memory for the subtype's instance variables, ! and there would be no way to change the allocation method for a ! subtype (without giving up on calling the base type to initialize ! its part of the instance structure). ! ! A similar reasoning applies to destruction: if a subtype changes ! the instance allocator (for example to use a different heap), it ! must also change the instance deallocator; but it must still call ! on the base type's destructor to DECREF the base type's instance ! variables. ! ! In this proposal, I assign stricter meanings to two existing ! slots for deallocation and deinitialization, and I add two new ! slots for allocation and initialization. ! ! The tp_clear slot gets the new task of deinitializing an object so ! that all that remains to be done is free its memory. Originally, ! all it had to do was clear object references. The difference is ! subtle: the list and dictionary objects contain references to an ! additional heap-allocated piece of memory that isn't freed by ! tp_clear in Python 2.1, but which must be freed by tp_clear under ! this proposal. It should be safe to call tp_clear repeatedly on ! the same object. If an object contains no references to other ! objects or heap-allocated memory, the tp_clear slot may be NULL. ! ! The only additional requirement for the tp_dealloc slot is that it ! should do the right thing whether or not tp_clear has been called. ! ! The new slots are tp_alloc for allocation and tp_init for ! initialization. Their signatures: ! ! PyObject *tp_alloc(PyTypeObject *type, ! PyObject *args, ! PyObject *kwds) ! ! int tp_init(PyObject *self, ! PyObject *args, ! PyObject *kwds) ! ! [XXX We'll have to rename tp_alloc to something else, because in ! debug mode there's already a tp_alloc field.] ! ! The arguments for tp_alloc are the same as for tp_new, described ! above. The arguments for tp_init are the same except that the ! first argument is replaced with the instance to be initialized. ! Its return value is 0 for success or -1 for failure. ! ! It is possible that tp_init is called more than once or not at ! all. The implementation should allow this usage. The object may ! be non-functional until tp_init is called, and a second call to ! tp_init may raise an exception, but it should not be possible to ! cause a core dump or memory leakage this way. ! ! Because tp_init is in a sense optional, tp_alloc is required to do ! *some* initialization of the object. It must initialize ob_refcnt ! to 1 and ob_type to its type argument. It should zero out the ! rest of the object. ! ! The constructor arguments are passed to tp_alloc so that for ! variable-size objects (like tuples and strings) it knows to ! allocate the right amount of memory. ! ! For immutable types, tp_alloc may have to do the full ! initialization; otherwise, different calls to tp_init might cause ! an immutable object to be modified, which is considered a grave ! offense in Python (unlike in Fortran :-). ! ! Not every type can serve as a base type. The assumption is made ! that if a type has a non-NULL value in its tp_init slot, it is ! ready to be subclassed; otherwise, it is not, and using it as a ! base class will raise an exception. ! In order to be usefully subtyped in C, a type must also export the structure declaration for its instances through a header file, as it is needed in order to derive a subtype. The type object for --- 316,383 ---- be called independently. + Standard implementations for tp_alloc() and tp_new() are + available. PyType_GenericAlloc() allocates an object from the + standard heap and initializes it properly. It uses the above + formula to determine the amount of memory to allocate, and takes + care of GC registration. The only reason not to use this + implementation would be to allocate objects from different heap + (as is done by some very small frequently used objects like ints + and tuples). PyType_GenericNew() adds very little: it just calls + the type's tp_alloc() slot with zero for nitems. But for mutable + types that do all their initialization in their tp_init() slot, + this may be just the ticket. ! Preparing a type for subtyping The idea behind subtyping is very similar to that of single inheritance in C++. A base type is described by a structure ! declaration (similar to the C++ class declaration) plus a type ! object (similar to the C++ vtable). A derived type can extend the ! structure (but must leave the names, order and type of the members of the base structure unchanged) and can override certain slots in ! the type object, leaving others the same. (Unlike C++ vtables, ! all Python type objects have the same memory lay-out.) ! The base type must do the following: ! - Add the flag value Py_TPFLAGS_BASETYPE to tp_flags. ! - Declare and use tp_new(), tp_alloc() and optional tp_init() slots. ! - Declare and use tp_dealloc() and tp_free(). ! - Export its object structure declaration. ! - Export a subtyping-aware type-checking macro. ! ! The requirements and signatures for tp_new(), tp_alloc() and ! tp_init() have already been discussed above: tp_alloc() should ! allocate the memory and initialize it to mostly zeros; tp_new() ! should call the tp_alloc() slot and then proceed to do the ! minimally required initialization; tp_init() should be used for ! more extensive initialization of mutable objects. ! ! It should come as no surprise that there are similar conventions ! at the end of an object's lifetime. The slots involved are ! tp_dealloc() (familiar to all who have ever implemented a Python ! extension type) and tp_free(), the new kid on he block. (The ! names aren't quite symmetric; tp_free() corresponds to tp_alloc(), ! which is fine, but tp_dealloc() corresponds to tp_new(). Maybe ! the tp_dealloc slot should be renamed?) ! ! The tp_free() slot should be used to free the memory and ! unregister the object with the garbage collection subsystem, and ! can be overridden by a derived class; tp_dealloc() should ! deinitialize the object (e.g. by calling Py_XDECREF() for various ! sub-objects) and then call tp_free() to deallocate the memory. ! The signature for tp_dealloc() is the same as it always was: ! ! void tp_dealloc(PyObject *object) ! The signature for tp_free() is the same: ! ! void tp_free(PyObject *object) ! ! (In a previous version of this PEP, there was also role reserved ! for the tp_clear() slot. This turned out to be a bad idea.) ! ! In order to be usefully subtyped in C, a type must export the structure declaration for its instances through a header file, as it is needed in order to derive a subtype. The type object for *************** *** 414,491 **** If the base type has a type-checking macro (like PyDict_Check()), ! this macro probably should be changed to recognize subtypes. This ! can be done by using the new PyObject_TypeCheck(object, type) ! macro, which calls a function that follows the base class links. ! ! (An argument against changing the type-checking macro could be ! that the type check is used frequently and a function call would ! slow things down too much, but I find this hard to believe. One ! could also fear that a subtype might break an invariant assumed by ! the support functions of the base type. Usually it is best to ! change the base type to remove this reliance, at least to the ! point of raising an exception rather than dumping core when the ! invariant is broken.) ! ! Here are the inteactions between, tp_alloc, tp_clear, tp_dealloc ! and subtypes; all assuming that the base type defines tp_init ! (otherwise it cannot be subtyped anyway): ! ! - If the base type's allocation scheme doesn't use the standard ! heap, it should not define tp_alloc. This is a signal for the ! subclass to provide its own tp_alloc *and* tp_dealloc ! implementation (probably using the standard heap). ! ! - If the base type's tp_dealloc does anything besides calling ! PyObject_DEL() (typically, calling Py_XDECREF() on contained ! objects or freeing dependent memory blocks), it should define a ! tp_clear that does the same without calling PyObject_DEL(), and ! which checks for zero pointers before and zeros the pointers ! afterwards, so that calling tp_clear more than once or calling ! tp_dealloc after tp_clear will not attempt to DECREF or free the ! same object/memory twice. (It should also be allowed to ! continue using the object after tp_clear -- tp_clear should ! simply reset the object to its pristine state.) ! ! - If the derived type overrides tp_alloc, it should also override ! tp_dealloc, and tp_dealloc should call the derived type's ! tp_clear if non-NULL (or its own tp_clear). ! ! - If the derived type overrides tp_clear, it should call the base ! type's tp_clear if non-NULL. ! ! - If the base type defines tp_init as well as tp_new, its tp_new ! should be inheritable: it should call the tp_alloc and the ! tp_init of the type passed in as its first argument. ! ! - If the base type defines tp_init as well as tp_alloc, its ! tp_alloc should be inheritable: it should look in the ! tp_basicsize slot of the type passed in for the amount of memory ! to allocate, and it should initialize all allocated bytes to ! zero. ! ! - For types whose tp_itemsize is nonzero, the allocation size used ! in tp_alloc should be tp_basicsize + n*tp_itemsize, rounded up ! to the next integral multiple of sizeof(PyObject *), where n is ! the number of items determined by the arguments to tp_alloc. ! ! - Things are further complicated by the garbage collection API. ! This affects tp_basicsize, and the actions to be taken by ! tp_alloc. tp_alloc should look at the Py_TPFLAGS_GC flag bit in ! the tp_flags field of the type passed in, and not assume that ! this is the same as the corresponding bit in the base type. (In ! part, the GC API is at fault; Neil Schemenauer has a patch that ! fixes the API, but it is currently backwards incompatible.) ! ! Note: the rules here are very complicated -- probably too ! complicated. It may be better to give up on subtyping immutable ! types, types with custom allocators, and types with variable size ! allocation (such as int, string and tuple) -- then the rules can ! be much simplified because you can assume allocation on the ! standard heap, no requirement beyond zeroing memory in tp_alloc, ! and no variable length allocation. Creating a subtype of a built-in type in C Let's assume we're deriving from a mutable base type whose tp_itemsize is zero. The subtype code is not GC-aware, although --- 385,412 ---- If the base type has a type-checking macro (like PyDict_Check()), ! this macro should be made to recognize subtypes. This can be done ! by using the new PyObject_TypeCheck(object, type) macro, which ! calls a function that follows the base class links. ! ! The PyObject_TypeCheck() macro contains a slight optimization: it ! first compares object->ob_type directly to the type argument, and ! if this is a match, bypasses the function call. This should make ! it fast enough for most situations. ! ! Note that this change in the type-checking macro means that C ! functions that require an instance of the base type may be invoked ! with instances of the derived type. Before enabling subtyping of ! a particular type, its code should be checked to make sure that ! this won't break anything. Creating a subtype of a built-in type in C + The simplest form of subtyping is subtyping in C. It is the + simplest form because we can require the C code to be aware of + some of the problems, and it's acceptable for C code that doesn't + follow the rules to dump core. For added simplicity, it is + limited to single inheritance. + Let's assume we're deriving from a mutable base type whose tp_itemsize is zero. The subtype code is not GC-aware, although *************** *** 502,511 **** } spamlistobject; ! Note that the base type structure field (here PyListObject) must ! be the first field in the structure; any following fields are ! extension fields. Also note that the base type is not referenced ! via a pointer; the actual contents of its structure must be ! included! (The goal is for the memory lay out of the beginning of ! the subtype instance to be the same as that of the base type instance.) --- 423,432 ---- } spamlistobject; ! Note that the base type structure member (here PyListObject) must ! be the first member of the structure; any following members are ! additions. Also note that the base type is not referenced via a ! pointer; the actual contents of its structure must be included! ! (The goal is for the memory lay out of the beginning of the ! subtype instance to be the same as that of the base type instance.) *************** *** 513,568 **** it. Most of the slots in the type object may be initialized to zero, which is a signal that the base type slot must be copied ! into it. Some fields that must be initialized properly: - The object header must be filled in as usual; the type should be &PyType_Type. ! - The tp_basicsize field must be set to the size of the subtype instance struct (in the above example: sizeof(spamlistobject)). ! - The tp_base field must be set to the address of the base type's type object. ! - If the derived slot defines any pointer fields, the tp_dealloc slot function requires special attention, see below; otherwise, it can be set to zero, to inherit the base type's deallocation function. ! - The tp_flags field must be set to the usual Py_TPFLAGS_DEFAULT value. ! - The tp_name field must be set; it is recommended to set tp_doc as well (these are not inherited). ! Exception: if the subtype defines no additional fields in its ! structure (it only defines new behavior, no new data), the ! tp_basicsize and the tp_dealloc fields may be set to zero. ! ! In order to complete the initialization of the type, ! PyType_InitDict() must be called. This replaces zero slots in the ! subtype with the value of the corresponding base type slots. (It ! also fills in tp_dict, the type's dictionary, and does various ! other initializations necessary for type objects.) The subtype's tp_dealloc slot deserves special attention. If the ! derived type defines no additional pointers that need to be DECREF'ed or freed when the object is deallocated, it can be set ! to zero. Otherwise, the subtype's deallocation function must call ! Py_XDECREF() for any PyObject * fields and the correct memory freeing function for any other pointers it owns, and then call the ! base class's tp_dealloc slot. Because deallocation functions ! typically are not exported, this call has to be made via the base ! type's type structure, for example, when deriving from the standard list type: PyList_Type.tp_dealloc(self); ! (If the subtype uses a different allocation heap than the base ! type, the subtype must call the base type's tp_clear() slot ! instead, followed by a call to free the object's memory from the ! appropriate heap, such as PyObject_DEL(self) if the subtype uses ! the standard heap. But in this case subtyping is not ! recommended.) A subtype is not usable until PyType_InitDict() is called for it; this is best done during module initialization, assuming the --- 434,486 ---- it. Most of the slots in the type object may be initialized to zero, which is a signal that the base type slot must be copied ! into it. Some slots that must be initialized properly: - The object header must be filled in as usual; the type should be &PyType_Type. ! - The tp_basicsize slot must be set to the size of the subtype instance struct (in the above example: sizeof(spamlistobject)). ! - The tp_base slot must be set to the address of the base type's type object. ! - If the derived slot defines any pointer members, the tp_dealloc slot function requires special attention, see below; otherwise, it can be set to zero, to inherit the base type's deallocation function. ! - The tp_flags slot must be set to the usual Py_TPFLAGS_DEFAULT value. ! - The tp_name slot must be set; it is recommended to set tp_doc as well (these are not inherited). ! If the subtype defines no additional structure members (it only ! defines new behavior, no new data), the tp_basicsize and the ! tp_dealloc slots may be left set to zero. The subtype's tp_dealloc slot deserves special attention. If the ! derived type defines no additional pointer members that need to be DECREF'ed or freed when the object is deallocated, it can be set ! to zero. Otherwise, the subtype's tp_dealloc() function must call ! Py_XDECREF() for any PyObject * members and the correct memory freeing function for any other pointers it owns, and then call the ! base class's tp_dealloc() slot. This call has to be made via the ! base type's type structure, for example, when deriving from the standard list type: PyList_Type.tp_dealloc(self); ! If the subtype wants to use a different allocation heap than the ! base type, the subtype must override both the tp_alloc() and the ! tp_free() slots. These will be called by the base class's ! tp_new() and tp_dealloc() slots, respectively. + In order to complete the initialization of the type, + PyType_InitDict() must be called. This replaces slots initialized + to zero in the subtype with the value of the corresponding base + type slots. (It also fills in tp_dict, the type's dictionary, and + does various other initializations necessary for type objects.) + A subtype is not usable until PyType_InitDict() is called for it; this is best done during module initialization, assuming the *************** *** 570,584 **** the Python core (which don't live in a particular module) would be to initialize the subtype in their constructor function. It is ! allowed to call PyType_InitDict() more than once, the second and further calls have no effect. In order to avoid unnecessary calls, a test for tp_dict==NULL can be made. ! To create a subtype instance, the base type's tp_alloc slot must ! be called with the subtype as its first argument. Then, if the ! base type has a tp_init slot, that must be called to initialize ! the base portion of the instance; finally the subtype's own fields ! must be initialized. After allocation, the initialization can ! also be done by calling the subtype's tp_init slot, assuming this ! correctly calls its base type's tp_init slot. --- 488,515 ---- the Python core (which don't live in a particular module) would be to initialize the subtype in their constructor function. It is ! allowed to call PyType_InitDict() more than once; the second and further calls have no effect. In order to avoid unnecessary calls, a test for tp_dict==NULL can be made. + + (During initialization of the Python interpreter, some types are + actually used before they are initialized. As long as the slots + that are actually needed are initialized, especially tp_dealloc, + this works, but it is fragile and not recommended as a general + practice.) + + To create a subtype instance, the subtype's tp_new() slot is + called. This should first call the base type's tp_new() slot and + then initialize the subtype's additional data members. To further + initialize the instance, the tp_init() slot is typically called. + Note that the tp_new() slot should *not* call the tp_init() slot; + this is up to tp_new()'s caller (typically a factory function). + There are circumstances where it is appropriate not to call + tp_init(). + + If a subtype defines a tp_init() slot, the tp_init() slot should + normally first call the base type's tp_init() slot. ! (XXX There should be a paragraph or two about argument passing ! here.) From tim_one@users.sourceforge.net Tue Jul 10 21:13:46 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 10 Jul 2001 13:13:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.80.2.19,2.80.2.20 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv9749/descr/dist/src/Objects Modified Files: Tag: descr-branch dictobject.c Log Message: dict_new() and EMPTY_TO_MINSIZE: minor performance boost in dict_new, by exploiting that tp_alloc guarantees to zero out the dictobject struct. So dict_new can skipping doing that too (for two scalar members, + the ma_smalltable member consisting of 8 dictentry structs each in turn containing 3 scalar members). Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.80.2.19 retrieving revision 2.80.2.20 diff -C2 -r2.80.2.19 -r2.80.2.20 *** dictobject.c 2001/07/09 03:28:36 2.80.2.19 --- dictobject.c 2001/07/10 20:13:44 2.80.2.20 *************** *** 127,137 **** #endif ! /* Set PyDictObject* mp to empty but w/ PyDict_MINSIZE slots, using ! ma_smalltable. */ ! #define EMPTY_TO_MINSIZE(mp) do { \ ! memset((mp)->ma_smalltable, 0, sizeof((mp)->ma_smalltable)); \ (mp)->ma_table = (mp)->ma_smalltable; \ (mp)->ma_mask = PyDict_MINSIZE - 1; \ (mp)->ma_used = (mp)->ma_fill = 0; \ } while(0) --- 127,148 ---- #endif ! /* Initialization macros. ! There are two ways to create a dict: PyDict_New() is the main C API ! function, and the tp_new slot maps to dict_new(). In the latter case we ! can save a little time over what PyDict_New does because it's guaranteed ! that the PyDictObject struct is already zeroed out. ! Everyone except dict_new() should use EMPTY_TO_MINSIZE (unless they have ! an excellent reason not to). ! */ ! ! #define INIT_NONZERO_DICT_SLOTS(mp) do { \ (mp)->ma_table = (mp)->ma_smalltable; \ (mp)->ma_mask = PyDict_MINSIZE - 1; \ + } while(0) + + #define EMPTY_TO_MINSIZE(mp) do { \ + memset((mp)->ma_smalltable, 0, sizeof((mp)->ma_smalltable)); \ (mp)->ma_used = (mp)->ma_fill = 0; \ + INIT_NONZERO_DICT_SLOTS(mp); \ } while(0) *************** *** 1681,1685 **** if (self != NULL) { PyDictObject *d = (PyDictObject *)self; ! EMPTY_TO_MINSIZE(d); d->ma_lookup = lookdict_string; #ifdef SHOW_CONVERSION_COUNTS --- 1692,1698 ---- if (self != NULL) { PyDictObject *d = (PyDictObject *)self; ! /* It's guaranteed that tp->alloc zeroed out the struct. */ ! assert(d->ma_table == NULL && d->ma_fill == 0 && d->ma_used == 0); ! INIT_NONZERO_DICT_SLOTS(d); d->ma_lookup = lookdict_string; #ifdef SHOW_CONVERSION_COUNTS From gvanrossum@users.sourceforge.net Tue Jul 10 21:46:26 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 10 Jul 2001 13:46:26 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0253.txt,1.9,1.10 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv17390 Modified Files: pep-0253.txt Log Message: Just a little bit more cleanup. Added a TODO list. Index: pep-0253.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0253.txt,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -r1.9 -r1.10 *** pep-0253.txt 2001/07/10 20:01:52 1.9 --- pep-0253.txt 2001/07/10 20:46:24 1.10 *************** *** 61,66 **** supported - - there will be a standard type hierarchy (maybe) - This PEP builds on PEP 252, which adds standard introspection to types; for example, when a particular type object initializes the --- 61,64 ---- *************** *** 341,351 **** The base type must do the following: ! - Add the flag value Py_TPFLAGS_BASETYPE to tp_flags. ! - Declare and use tp_new(), tp_alloc() and optional tp_init() slots. ! - Declare and use tp_dealloc() and tp_free(). ! - Export its object structure declaration. ! - Export a subtyping-aware type-checking macro. The requirements and signatures for tp_new(), tp_alloc() and tp_init() have already been discussed above: tp_alloc() should --- 339,354 ---- The base type must do the following: + + - Add the flag value Py_TPFLAGS_BASETYPE to tp_flags. + + - Declare and use tp_new(), tp_alloc() and optional tp_init() + slots. + + - Declare and use tp_dealloc() and tp_free(). ! - Export its object structure declaration. + - Export a subtyping-aware type-checking macro. + The requirements and signatures for tp_new(), tp_alloc() and tp_init() have already been discussed above: tp_alloc() should *************** *** 435,458 **** zero, which is a signal that the base type slot must be copied into it. Some slots that must be initialized properly: - - - The object header must be filled in as usual; the type should be - &PyType_Type. - - - The tp_basicsize slot must be set to the size of the subtype - instance struct (in the above example: sizeof(spamlistobject)). ! - The tp_base slot must be set to the address of the base type's ! type object. ! - If the derived slot defines any pointer members, the tp_dealloc ! slot function requires special attention, see below; otherwise, ! it can be set to zero, to inherit the base type's deallocation ! function. ! - The tp_flags slot must be set to the usual Py_TPFLAGS_DEFAULT ! value. ! - The tp_name slot must be set; it is recommended to set tp_doc ! as well (these are not inherited). If the subtype defines no additional structure members (it only --- 438,462 ---- zero, which is a signal that the base type slot must be copied into it. Some slots that must be initialized properly: ! - The object header must be filled in as usual; the type should ! be &PyType_Type. ! - The tp_basicsize slot must be set to the size of the subtype ! instance struct (in the above example: ! sizeof(spamlistobject)). ! ! - The tp_base slot must be set to the address of the base type's ! type object. ! ! - If the derived slot defines any pointer members, the ! tp_dealloc slot function requires special attention, see ! below; otherwise, it can be set to zero, to inherit the base ! type's deallocation function. ! - The tp_flags slot must be set to the usual Py_TPFLAGS_DEFAULT ! value. ! - The tp_name slot must be set; it is recommended to set tp_doc ! as well (these are not inherited). If the subtype defines no additional structure members (it only *************** *** 531,548 **** Assume B is a type object. Since type objects are objects, and ! every object has a type, B has a type. B's type is accessible via ! type(B) or B.__class__ (the latter notation is new for types; it ! is introduced in PEP 252). Let's say B's type is M (for Metatype). The class statement will create a new type, C. Since C will be a type object just like B, we view the creation of C as an instantiation of the metatype, M. The information that needs ! to be provided for the creation of C is: its name (in this example ! the string "C"); the list of base classes (a singleton tuple ! containing B); and the results of executing the class body, in the ! form of a dictionary (for example {"var1": 1, "method1": , ...}). ! I propose to rig the class statement to make the following call: C = M("C", (B,), dict) --- 535,557 ---- Assume B is a type object. Since type objects are objects, and ! every object has a type, B has a type. Since B is itself a type, ! we also call its type its metatype. B's metatype is accessible ! via type(B) or B.__class__ (the latter notation is new for types; ! it is introduced in PEP 252). Let's say this metatype is M (for Metatype). The class statement will create a new type, C. Since C will be a type object just like B, we view the creation of C as an instantiation of the metatype, M. The information that needs ! to be provided for the creation of a subclass is: ! - its name (in this example the string "C"); + - its bases (a singleton tuple containing B); + + - the results of executing the class body, in the form of a + dictionary (for example {"var1": 1, "method1": , ...}). + + The class statement will result in the following call: + C = M("C", (B,), dict) *************** *** 550,558 **** class body). In other words, the metatype (M) is called. ! Note that even though we currently require there to be exactly one ! base class, we still pass in a (singleton) sequence of base ! classes; this makes it possible to support multiple inheritance ! later (or for types with a different metaclass!) without changing ! this interface. In current Python, this is called the "Don Beaudry hook" after its --- 559,565 ---- class body). In other words, the metatype (M) is called. ! Note that even though the example has only one base, we still pass ! in a (singleton) sequence of bases; this makes the interface ! uniform with the multiple-inheritance case. In current Python, this is called the "Don Beaudry hook" after its *************** *** 561,576 **** when no base class is specified), current Python calls PyClass_New(), the C level factory function for classes, directly. ! I propose to change this so that Python *always* determines a ! metaclass and calls it as given above. When one or more bases are ! given, the type of the first base is used as the metatype; ! when no base class is given, a default metaclass is chosen. By ! setting the default metaclass to PyClass_Type, the metatype of "classic" classes, the classic behavior of the class statement is ! retained. There are two further refinements here. First, a useful feature is to be able to specify a metatype directly. If the class statement defines a variable __metaclass__, that is the metatype ! to call. Second, with multiple bases, not all bases need to have the same --- 568,588 ---- when no base class is specified), current Python calls PyClass_New(), the C level factory function for classes, directly. ! ! Under the new system this is changed so that Python *always* ! determines a metatype and calls it as given above. When one or ! more bases are given, the type of the first base is used as the ! metatype; when no base is given, a default metatype is chosen. By ! setting the default metatype to PyClass_Type, the metatype of "classic" classes, the classic behavior of the class statement is ! retained. This default can be changed per module by setting the ! global variable __metaclass__. There are two further refinements here. First, a useful feature is to be able to specify a metatype directly. If the class statement defines a variable __metaclass__, that is the metatype ! to call. (Note that setting __metaclass__ at the module level ! only affects class statements without a base class and without an ! explicit __metaclass__ declaration; but setting __metaclass__ in a ! class statement overrides the default metatype unconditionally.) Second, with multiple bases, not all bases need to have the same *************** *** 583,612 **** This conflict resultion can be implemented in the metatypes itself: the class statement just calls the metatype of the first ! base, and this metatype's constructor looks for the most derived ! metatype. If that is itself, it proceeds; otherwise, it calls ! that metatype's constructor. (Ultimate flexibility: another ! metatype might choose to require that all bases have the same ! metatype, or that there's only one base class, or whatever.) ! ! (Theoretically, it might be possible to automatically derive a new ! metatype that is a subtype of all given metatypes; but since it is ! questionable how conflicting method definitions of the various ! metatypes should be merged, I don't think this is useful or ! feasible. Should the need arise, the user can derive such a ! metatype and specify it using the __metaclass__ variable. It is ! also possible to have a new metatype that does this.) ! ! HIRO Note that calling M requires that M itself has a type: the ! meta-metatype. In the current implementation, I have introduced a ! new type object for this purpose, named turtle because of my ! fondness of the phrase "turtles all the way down". However I now ! believe that it would be better if M were its own metatype, just ! like before. This can be accomplished by making M's tp_call slot ! slightly more flexible. ! In any case, the work for creating C is done by M's tp_construct ! slot. It allocates space for an "extended" type structure, which contains space for: the type object; the auxiliary structures (as_sequence etc.); the string object containing the type name (to --- 595,628 ---- This conflict resultion can be implemented in the metatypes itself: the class statement just calls the metatype of the first ! base (or that specified by the __metaclass__ variable), and this ! metatype's constructor looks for the most derived metatype. If ! that is itself, it proceeds; otherwise, it calls that metatype's ! constructor. (Ultimate flexibility: another metatype might choose ! to require that all bases have the same metatype, or that there's ! only one base class, or whatever.) ! ! (In [1], a new metaclass is automatically derived that is a ! subclass of all given metaclasses. But since it is questionable ! in Python how conflicting method definitions of the various ! metaclasses should be merged, I don't think this is feasible. ! Should the need arise, the user can derive such a metaclass ! manually and specify it using the __metaclass__ variable. It is ! also possible to have a new metaclass that does this.) Note that calling M requires that M itself has a type: the ! meta-metatype. And the meta-metatype has a type, the ! meta-meta-metatype. And so on. This is normally cut short at ! some level by making a metatype be its own metatype. This is ! indeed what happens in Python: the ob_type reference in ! PyType_Type is set to &PyType_Type. In the absence of third party ! metatypes, PyType_Type is the only metatype in the Python ! interpreter. ! ! (In a previous version of this PEP, there was one additional ! meta-level, and there was a meta-metatype called "turtle". This ! turned out to be unnecessary.) ! In any case, the work for creating C is done by M's tp_new() slot. ! It allocates space for an "extended" type structure, which contains space for: the type object; the auxiliary structures (as_sequence etc.); the string object containing the type name (to *************** *** 621,640 **** ! Implementation ! A prototype implementation of this PEP is available from CVS as a ! branch named "descr-branch". To experiment with this ! implementation, proceed to check out Python from CVS according to ! the instructions at http://sourceforge.net/cvs/?group_id=5470 but ! add the arguments "-r descr-branch" to the cvs checkout command. ! (You can also start with an existing checkout and do "cvs update ! -r descr-branch".) For some examples of the features described ! here, see the file Lib/test/test_descr.py and the extension module ! Modules/spam.c. ! Note: the code in this branch is for PEP 252, PEP 253, and ! pep-254. References --- 637,674 ---- ! XXX To be done ! Additional topics to be discussed in this PEP: ! - class methods and static methods + - mapping between type object slots (tp_foo) and special methods + (__foo__) + - built-in names for built-in types (object, int, str, list etc.) + + - multiple inheritance restrictions + + - __slots__ + + - the HEAPTYPE and DYNAMICTYPE flag bits + + - API docs for all the new functions + + + Implementation + + A prototype implementation of this PEP (and for PEP 252) is + available from CVS as a branch named "descr-branch". To + experiment with this implementation, proceed to check out Python + from CVS according to the instructions at + http://sourceforge.net/cvs/?group_id=5470 but add the arguments + "-r descr-branch" to the cvs checkout command. (You can also + start with an existing checkout and do "cvs update -r + descr-branch".) For some examples of the features described here, + see the file Lib/test/test_descr.py and the extension module + Modules/xxsubtype.c. + + References *************** *** 647,697 **** This document has been placed in the public domain. - - - Junk text (to be reused somewhere above) - - The deallocation mechanism chosen should match the allocation - mechanism: an allocation policy should prescribe both the - allocation and deallocation mechanism. And again, planning ahead - for subtyping would be nice. But the available mechanisms are - different. The deallocation function has always been part of the - type structure, as tp_dealloc, which combines the - "uninitialization" with deallocation. This was good enough for - the traditional situation, where it matched the combined - allocation and initialization of the creation function. But now - imagine a type whose creation function uses a special free list - for allocation. It's deallocation function puts the object's - memory back on the same free list. But when allocation and - creation are separate, the object may have been allocated from the - regular heap, and it would be wrong (in some cases disastrous) if - it were placed on the free list by the deallocation function. - - A solution would be for the tp_construct function to somehow mark - whether the object was allocated from the special free list, so - that the tp_dealloc function can choose the right deallocation - method (assuming that the only two alternatives are a special free - list or the regular heap). A variant that doesn't require space - for an allocation flag bit would be to have two type objects, - identical in the contents of all their slots except for their - deallocation slot. But this requires that all type-checking code - (like PyDict_Check()) recognizes both types. We'll come back to - this solution in the context of subtyping. Another alternative is - to require the metatype's tp_call to leave the allocation to the - tp_construct method, by passing in a NULL pointer. But this - doesn't work once we allow subtyping. - - Eventually, when we add any form of subtyping, we'll have to - separate deallocation from uninitialization. The way to do this - is to add a separate slot to the type object that does the - uninitialization without the deallocation. Fortunately, there is - already such a slot: tp_clear, currently used by the garbage - collection subsystem. A simple rule makes this slot reusable as - an uninitialization: for types that support separate allocation - and initialization, tp_clear must be defined (even if the object - doesn't support garbage collection) and it must DECREF all - contained objects and FREE all other memory areas the object owns. - It must also be reentrant: it must be possible to clear an already - cleared object. The easiest way to do this is to replace all - pointers DECREFed or FREEd with NULL pointers. --- 681,684 ---- From bwarsaw@users.sourceforge.net Tue Jul 10 22:37:06 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 10 Jul 2001 14:37:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/pynche README,2.14,2.15 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/pynche In directory usw-pr-cvs1:/tmp/cvs-serv28916 Modified Files: README Log Message: Updated documentation, and bump the version number to 1.2. Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/pynche/README,v retrieving revision 2.14 retrieving revision 2.15 diff -C2 -r2.14 -r2.15 *** README 2001/04/18 03:48:41 2.14 --- README 2001/07/10 21:37:04 2.15 *************** *** 3,7 **** Contact: Barry A. Warsaw Email: bwarsaw@python.org ! Version: 1.1 Introduction --- 3,7 ---- Contact: Barry A. Warsaw Email: bwarsaw@python.org ! Version: 1.2 Introduction *************** *** 32,37 **** subdirectory. ! Pynche is pronounced `Pinch-ee'. Running Standalone --- 32,38 ---- subdirectory. ! Pynche is pronounced: Pin'-chee + Running Standalone *************** *** 67,78 **** same as 45dd1f). Running as a Modal Dialog Pynche can be run as a modal dialog, inside another application, ! say as a general color chooser. In fact, Grail 0.6 already uses ! Pynche and a future version of IDLE may as well. Pynche supports ! the API implemented by the Tkinter standard tkColorChooser module, ! with a few changes as described below. By importing pyColorChooser ! from the Pynche package, you can run pyColorChooser.askcolor() --- 68,80 ---- same as 45dd1f). + Running as a Modal Dialog Pynche can be run as a modal dialog, inside another application, ! say as a general color chooser. In fact, Grail 0.6 uses Pynche ! and a future version of IDLE may as well. Pynche supports the API ! implemented by the Tkinter standard tkColorChooser module, with a ! few changes as described below. By importing pyColorChooser from ! the Pynche package, you can run pyColorChooser.askcolor() *************** *** 129,132 **** --- 131,135 ---- askcolor() is used and cannot be changed on subsequent calls. + The Colorstrip Window *************** *** 149,158 **** Click on "Update while dragging" if you want Pynche to update the selected color while you drag along any variation strip (this will ! be slower). Click on "Hexadecimal" to display the arrow numbers ! in hex. There are also two shortcut buttons in this window, which auto-select Black (0/0/0) and White (255/255/255). The Proof Window --- 152,162 ---- Click on "Update while dragging" if you want Pynche to update the selected color while you drag along any variation strip (this will ! be a bit slower). Click on "Hexadecimal" to display the arrow ! numbers in hex. There are also two shortcut buttons in this window, which auto-select Black (0/0/0) and White (255/255/255). + The Proof Window *************** *** 173,176 **** --- 177,181 ---- in the Color List Window (see below). + The Type-in Window *************** *** 186,189 **** --- 191,195 ---- in hex. + Other Views *************** *** 192,195 **** --- 198,202 ---- Pynche window. + The Text Window *************** *** 215,218 **** --- 222,226 ---- has a background. + The Color List Window *************** *** 236,239 **** --- 244,248 ---- "" in the Aliases window. + The Details Window *************** *** 289,292 **** --- 298,302 ---- +25 == Shift Right Arrow + Keyboard Accelerators *************** *** 296,299 **** --- 306,310 ---- Alt-q in any window exits Pynche (except when running as a modal). + Persistency *************** *** 326,329 **** --- 337,341 ---- --initfile. + Color Name Database Files *************** *** 353,359 **** dialog. To Do ! Here's a brief list of things I want to do: - Better support for resizing the top level windows --- 365,372 ---- dialog. + To Do ! Here's a brief list of things I want to do (some mythical day): - Better support for resizing the top level windows *************** *** 365,368 **** --- 378,383 ---- - Support setting the font in the text view + + - Support distutils setup.py for installation I'm open to suggestions! From bwarsaw@users.sourceforge.net Tue Jul 10 22:37:30 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 10 Jul 2001 14:37:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/pynche ChipViewer.py,2.8,2.9 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/pynche In directory usw-pr-cvs1:/tmp/cvs-serv29064 Modified Files: ChipViewer.py Log Message: Update a comment. Index: ChipViewer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/pynche/ChipViewer.py,v retrieving revision 2.8 retrieving revision 2.9 diff -C2 -r2.8 -r2.9 *** ChipViewer.py 1999/04/26 23:17:15 2.8 --- ChipViewer.py 2001/07/10 21:37:28 2.9 *************** *** 85,89 **** def update_yourself(self, red, green, blue): # Selected always shows the #rrggbb name of the color, nearest always ! # shows the name of the nearest color in the database. TBD: should # an exact match be indicated in some way? # --- 85,89 ---- def update_yourself(self, red, green, blue): # Selected always shows the #rrggbb name of the color, nearest always ! # shows the name of the nearest color in the database. BAW: should # an exact match be indicated in some way? # From bwarsaw@users.sourceforge.net Tue Jul 10 22:38:49 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 10 Jul 2001 14:38:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/pynche ColorDB.py,2.7,2.8 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/pynche In directory usw-pr-cvs1:/tmp/cvs-serv29358 Modified Files: ColorDB.py Log Message: De-string-module-ification and other Python 2.x improvements. Index: ColorDB.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/pynche/ColorDB.py,v retrieving revision 2.7 retrieving revision 2.8 diff -C2 -r2.7 -r2.8 *** ColorDB.py 1999/04/26 23:17:15 2.7 --- ColorDB.py 2001/07/10 21:38:47 2.8 *************** *** 22,26 **** import sys - import string import re from types import * --- 22,25 ---- *************** *** 31,34 **** --- 30,35 ---- DEFAULT_DB = None + SPACE = ' ' + COMMASPACE = ', ' *************** *** 46,53 **** # key is (red, green, blue) tuple, value is (name, [aliases]) self.__byrgb = {} - # # key is name, value is (red, green, blue) self.__byname = {} - # # all unique names (non-aliases). built-on demand self.__allnames = None --- 47,52 ---- *************** *** 57,78 **** break # get this compiled regular expression from derived class - ## print '%3d: %s' % (lineno, line[:-1]) mo = self._re.match(line) if not mo: ! sys.stderr.write('Error in %s, line %d\n' % (fp.name, lineno)) ! lineno = lineno + 1 continue - # # extract the red, green, blue, and name - # red, green, blue = self._extractrgb(mo) name = self._extractname(mo) ! keyname = string.lower(name) ! ## print keyname, '(%d, %d, %d)' % (red, green, blue) ! # ! # TBD: for now the `name' is just the first named color with the # rgb values we find. Later, we might want to make the two word # version the `name', or the CapitalizedVersion, etc. - # key = (red, green, blue) foundname, aliases = self.__byrgb.get(key, (name, [])) --- 56,71 ---- break # get this compiled regular expression from derived class mo = self._re.match(line) if not mo: ! print >> sys.stderr, 'Error in', fp.name, ' line', lineno ! lineno += 1 continue # extract the red, green, blue, and name red, green, blue = self._extractrgb(mo) name = self._extractname(mo) ! keyname = name.lower() ! # BAW: for now the `name' is just the first named color with the # rgb values we find. Later, we might want to make the two word # version the `name', or the CapitalizedVersion, etc. key = (red, green, blue) foundname, aliases = self.__byrgb.get(key, (name, [])) *************** *** 80,86 **** aliases.append(name) self.__byrgb[key] = (foundname, aliases) - # # add to byname lookup - # self.__byname[keyname] = key lineno = lineno + 1 --- 73,77 ---- *************** *** 88,92 **** # override in derived classes def _extractrgb(self, mo): ! return map(int, mo.group('red', 'green', 'blue')) def _extractname(self, mo): --- 79,83 ---- # override in derived classes def _extractrgb(self, mo): ! return [int(x) for x in mo.group('red', 'green', 'blue')] def _extractname(self, mo): *************** *** 105,109 **** def find_byname(self, name): """Return (red, green, blue) for name""" ! name = string.lower(name) try: return self.__byname[name] --- 96,100 ---- def find_byname(self, name): """Return (red, green, blue) for name""" ! name = name.lower() try: return self.__byname[name] *************** *** 113,117 **** def nearest(self, red, green, blue): """Return the name of color nearest (red, green, blue)""" ! # TBD: should we use Voronoi diagrams, Delaunay triangulation, or # octree for speeding up the locating of nearest point? Exhaustive # search is inefficient, but seems fast enough. --- 104,108 ---- def nearest(self, red, green, blue): """Return the name of color nearest (red, green, blue)""" ! # BAW: should we use Voronoi diagrams, Delaunay triangulation, or # octree for speeding up the locating of nearest point? Exhaustive # search is inefficient, but seems fast enough. *************** *** 119,123 **** nearest_name = '' for name, aliases in self.__byrgb.values(): ! r, g, b = self.__byname[string.lower(name)] rdelta = red - r gdelta = green - g --- 110,114 ---- nearest_name = '' for name, aliases in self.__byrgb.values(): ! r, g, b = self.__byname[name.lower()] rdelta = red - r gdelta = green - g *************** *** 137,141 **** # sort irregardless of case def nocase_cmp(n1, n2): ! return cmp(string.lower(n1), string.lower(n2)) self.__allnames.sort(nocase_cmp) return self.__allnames --- 128,132 ---- # sort irregardless of case def nocase_cmp(n1, n2): ! return cmp(n1.lower(), n2.lower()) self.__allnames.sort(nocase_cmp) return self.__allnames *************** *** 164,168 **** def _extractname(self, mo): ! return string.strip(mo.group('name')) class WebsafeDB(ColorDB): --- 155,159 ---- def _extractname(self, mo): ! return mo.group('name').strip() class WebsafeDB(ColorDB): *************** *** 173,177 **** def _extractname(self, mo): ! return string.upper(mo.group('hexrgb')) --- 164,168 ---- def _extractname(self, mo): ! return mo.group('hexrgb').upper() *************** *** 219,225 **** _namedict = {} ! def rrggbb_to_triplet(color, atoi=string.atoi): """Converts a #rrggbb color to the tuple (red, green, blue).""" - global _namedict rgbtuple = _namedict.get(color) if rgbtuple is None: --- 210,216 ---- _namedict = {} ! ! def rrggbb_to_triplet(color): """Converts a #rrggbb color to the tuple (red, green, blue).""" rgbtuple = _namedict.get(color) if rgbtuple is None: *************** *** 229,233 **** green = color[3:5] blue = color[5:7] ! rgbtuple = (atoi(red, 16), atoi(green, 16), atoi(blue, 16)) _namedict[color] = rgbtuple return rgbtuple --- 220,224 ---- green = color[3:5] blue = color[5:7] ! rgbtuple = int(red, 16), int(green, 16), int(blue, 16) _namedict[color] = rgbtuple return rgbtuple *************** *** 261,266 **** if __name__ == '__main__': - import string - colordb = get_colordb('/usr/openwin/lib/rgb.txt') if not colordb: --- 252,255 ---- *************** *** 272,276 **** print target, ':', red, green, blue, triplet_to_rrggbb(rgbtuple) name, aliases = colordb.find_byrgb(rgbtuple) ! print 'name:', name, 'aliases:', string.join(aliases, ", ") r, g, b = (1, 1, 128) # nearest to navy r, g, b = (145, 238, 144) # nearest to lightgreen --- 261,265 ---- print target, ':', red, green, blue, triplet_to_rrggbb(rgbtuple) name, aliases = colordb.find_byrgb(rgbtuple) ! print 'name:', name, 'aliases:', COMMASPACE.join(aliases) r, g, b = (1, 1, 128) # nearest to navy r, g, b = (145, 238, 144) # nearest to lightgreen *************** *** 287,289 **** aliases = colordb.aliases_of(r, g, b) print '%20s: (%3d/%3d/%3d) == %s' % (n, r, g, b, ! string.join(aliases[1:])) --- 276,278 ---- aliases = colordb.aliases_of(r, g, b) print '%20s: (%3d/%3d/%3d) == %s' % (n, r, g, b, ! SPACE.join(aliases[1:])) From bwarsaw@users.sourceforge.net Tue Jul 10 22:39:20 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 10 Jul 2001 14:39:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/pynche DetailsViewer.py,2.9,2.10 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/pynche In directory usw-pr-cvs1:/tmp/cvs-serv29488 Modified Files: DetailsViewer.py Log Message: __delta(): Use augmented assignments. Index: DetailsViewer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/pynche/DetailsViewer.py,v retrieving revision 2.9 retrieving revision 2.10 diff -C2 -r2.9 -r2.10 *** DetailsViewer.py 1999/04/27 18:54:12 2.9 --- DetailsViewer.py 2001/07/10 21:39:18 2.10 *************** *** 211,225 **** elif atbound == WRAP or (atbound == RATIO and len(tie) < 2): if red < 0: ! red = red + 256 if green < 0: ! green = green + 256 if blue < 0: ! blue = blue + 256 if red > 255: ! red = red - 256 if green > 255: ! green = green - 256 if blue > 255: ! blue = blue - 256 elif atbound == RATIO: # for when 2 or 3 colors are tied together --- 211,225 ---- elif atbound == WRAP or (atbound == RATIO and len(tie) < 2): if red < 0: ! red += 256 if green < 0: ! green += 256 if blue < 0: ! blue += 256 if red > 255: ! red -= 256 if green > 255: ! green -= 256 if blue > 255: ! blue -= 256 elif atbound == RATIO: # for when 2 or 3 colors are tied together From bwarsaw@users.sourceforge.net Tue Jul 10 22:39:43 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 10 Jul 2001 14:39:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/pynche ListViewer.py,2.13,2.14 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/pynche In directory usw-pr-cvs1:/tmp/cvs-serv29596 Modified Files: ListViewer.py Log Message: __populate(): Use augmented assignments. Index: ListViewer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/pynche/ListViewer.py,v retrieving revision 2.13 retrieving revision 2.14 diff -C2 -r2.13 -r2.14 *** ListViewer.py 2001/04/18 03:53:29 2.13 --- ListViewer.py 2001/07/10 21:39:41 2.14 *************** *** 91,95 **** if textend+3 > widest: widest = textend+3 ! row = row + 1 canvheight = (row-1)*20 + 25 canvas.config(scrollregion=(0, 0, 150, canvheight)) --- 91,95 ---- if textend+3 > widest: widest = textend+3 ! row += 1 canvheight = (row-1)*20 + 25 canvas.config(scrollregion=(0, 0, 150, canvheight)) From bwarsaw@users.sourceforge.net Tue Jul 10 22:42:06 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 10 Jul 2001 14:42:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/pynche Main.py,2.19,2.20 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/pynche In directory usw-pr-cvs1:/tmp/cvs-serv30150 Modified Files: Main.py Log Message: __version__: Bump to 1.2 De-string-module-ification. Index: Main.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/pynche/Main.py,v retrieving revision 2.19 retrieving revision 2.20 diff -C2 -r2.19 -r2.20 *** Main.py 2001/04/18 03:49:00 2.19 --- Main.py 2001/07/10 21:42:04 2.20 *************** *** 47,60 **** initialcolor initial color, as a color name or #RRGGBB format - """ ! __version__ = '1.1' import sys import os - import string import getopt import ColorDB from PyncheWidget import PyncheWidget from Switchboard import Switchboard --- 47,59 ---- initialcolor initial color, as a color name or #RRGGBB format """ ! __version__ = '1.2' import sys import os import getopt import ColorDB + from PyncheWidget import PyncheWidget from Switchboard import Switchboard *************** *** 80,92 **** def docstring(): ! return string.rstrip(__doc__ % globals()) ! def usage(status, msg=''): print docstring() if msg: print msg ! sys.exit(status) --- 79,93 ---- + # Do this because PyncheWidget.py wants to get at the interpolated docstring + # too, for its Help menu. def docstring(): ! return __doc__ % globals() ! def usage(code, msg=''): print docstring() if msg: print msg ! sys.exit(code) *************** *** 217,220 **** --- 218,222 ---- run(app, sb) sb.save_views() + From bwarsaw@users.sourceforge.net Tue Jul 10 22:43:45 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 10 Jul 2001 14:43:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/pynche PyncheWidget.py,2.26,2.27 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/pynche In directory usw-pr-cvs1:/tmp/cvs-serv30524 Modified Files: PyncheWidget.py Log Message: De-string-module-ification. Index: PyncheWidget.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/pynche/PyncheWidget.py,v retrieving revision 2.26 retrieving revision 2.27 diff -C2 -r2.26 -r2.27 *** PyncheWidget.py 2001/04/18 03:50:07 2.26 --- PyncheWidget.py 2001/07/10 21:43:43 2.27 *************** *** 7,11 **** import sys import os - import string from Tkinter import * import tkMessageBox --- 7,10 ---- *************** *** 222,228 **** contents = fp.read() # wax the last page, it contains Emacs cruft ! i = string.rfind(contents, '\f') if i > 0: ! contents = string.rstrip(contents[:i]) finally: if fp: --- 221,227 ---- contents = fp.read() # wax the last page, it contains Emacs cruft ! i = contents.rfind('\f') if i > 0: ! contents = contents[:i].rstrip() finally: if fp: *************** *** 259,267 **** self.__menutext = module.ADDTOVIEW # find the underline character ! underline = string.find(module.ADDTOVIEW, '%') if underline == -1: underline = 0 else: ! self.__menutext = string.replace(module.ADDTOVIEW, '%', '', 1) self.__underline = underline self.__window = None --- 258,266 ---- self.__menutext = module.ADDTOVIEW # find the underline character ! underline = module.ADDTOVIEW.find('%') if underline == -1: underline = 0 else: ! self.__menutext = module.ADDTOVIEW.replace('%', '', 1) self.__underline = underline self.__window = None From bwarsaw@users.sourceforge.net Tue Jul 10 22:44:26 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 10 Jul 2001 14:44:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/pynche StripViewer.py,2.14,2.15 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/pynche In directory usw-pr-cvs1:/tmp/cvs-serv30697 Modified Files: StripViewer.py Log Message: De-string-module-ification. Index: StripViewer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/pynche/StripViewer.py,v retrieving revision 2.14 retrieving revision 2.15 diff -C2 -r2.14 -r2.15 *** StripViewer.py 2001/04/18 03:51:55 2.14 --- StripViewer.py 2001/07/10 21:44:24 2.15 *************** *** 25,29 **** """ - import string from Tkinter import * import ColorDB --- 25,28 ---- *************** *** 47,51 **** --- 46,53 ---- BTNDRAG = 6 + SPACE = ' ' + + def constant(numchips): step = 255.0 / (numchips - 1) *************** *** 142,146 **** tags=self._TAG) text = self._canvas.create_text( ! x - self._ARROWWIDTH + 15, # TBD: kludge self._ARROWHEIGHT - self._TEXTYOFFSET, justify=RIGHT, --- 144,148 ---- tags=self._TAG) text = self._canvas.create_text( ! x - self._ARROWWIDTH + 15, # BAW: kludge self._ARROWHEIGHT - self._TEXTYOFFSET, justify=RIGHT, *************** *** 152,156 **** coords = self._canvas.bbox(self._TAG) assert coords ! return coords[2] - 6 # TBD: kludge --- 154,158 ---- coords = self._canvas.bbox(self._TAG) assert coords ! return coords[2] - 6 # BAW: kludge *************** *** 183,187 **** canvaswidth = numchips * (chipwidth + 1) ! canvasheight = chipheight + 43 # TBD: Kludge # create the canvas and pack it --- 185,189 ---- canvaswidth = numchips * (chipwidth + 1) ! canvasheight = chipheight + 43 # BAW: Kludge # create the canvas and pack it *************** *** 302,306 **** i = i + 1 # call the raw tcl script ! colors = string.join(chips) tk.eval('setcolor %s {%s}' % (self.__canvas._w, colors)) # move the arrows around --- 304,308 ---- i = i + 1 # call the raw tcl script ! colors = SPACE.join(chips) tk.eval('setcolor %s {%s}' % (self.__canvas._w, colors)) # move the arrows around From bwarsaw@users.sourceforge.net Tue Jul 10 22:45:01 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 10 Jul 2001 14:45:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/pynche TextViewer.py,2.11,2.12 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/pynche In directory usw-pr-cvs1:/tmp/cvs-serv30857 Modified Files: TextViewer.py Log Message: __init__(): Use augmented assignments. Index: TextViewer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/pynche/TextViewer.py,v retrieving revision 2.11 retrieving revision 2.12 diff -C2 -r2.11 -r2.12 *** TextViewer.py 2001/04/18 03:52:54 2.11 --- TextViewer.py 2001/07/10 21:44:59 2.12 *************** *** 5,9 **** In the top part of the window is a standard text widget with some sample text ! in it. You are free to edit this text in any way you want (TBD: allow you to change font characteristics). If you want changes in other viewers to update text characteristics, turn on Track color changes. --- 5,9 ---- In the top part of the window is a standard text widget with some sample text ! in it. You are free to edit this text in any way you want (BAW: allow you to change font characteristics). If you want changes in other viewers to update text characteristics, turn on Track color changes. *************** *** 21,24 **** --- 21,26 ---- ADDTOVIEW = 'Text Window...' + + class TextViewer: def __init__(self, switchboard, master=None): *************** *** 92,96 **** l.grid(row=row, column=0, sticky=E) self.__labels.append(l) ! row = row + 1 col = 1 for text in ('Foreground', 'Background'): --- 94,98 ---- l.grid(row=row, column=0, sticky=E) self.__labels.append(l) ! row += 1 col = 1 for text in ('Foreground', 'Background'): *************** *** 98,102 **** l.grid(row=1, column=col) self.__labels.append(l) ! col = col + 1 # # radios --- 100,104 ---- l.grid(row=1, column=col) self.__labels.append(l) ! col += 1 # # radios From bwarsaw@users.sourceforge.net Tue Jul 10 22:45:29 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 10 Jul 2001 14:45:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/pynche pyColorChooser.py,2.6,2.7 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/pynche In directory usw-pr-cvs1:/tmp/cvs-serv31045 Modified Files: pyColorChooser.py Log Message: Update a comment. Index: pyColorChooser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/pynche/pyColorChooser.py,v retrieving revision 2.6 retrieving revision 2.7 diff -C2 -r2.6 -r2.7 *** pyColorChooser.py 2001/02/01 20:52:08 2.6 --- pyColorChooser.py 2001/07/10 21:45:27 2.7 *************** *** 6,9 **** --- 6,11 ---- import ColorDB + + class Chooser: """Ask for a color""" *************** *** 55,60 **** if self.__sb.canceled_p(): return None, None ! # try to return the color name from the database if there is an exact ! # match, otherwise use the "#rrggbb" spec. TBD: Forget about color # aliases for now, maybe later we should return these too. name = None --- 57,62 ---- if self.__sb.canceled_p(): return None, None ! # Try to return the color name from the database if there is an exact ! # match, otherwise use the "#rrggbb" spec. BAW: Forget about color # aliases for now, maybe later we should return these too. name = None From bwarsaw@users.sourceforge.net Tue Jul 10 22:48:53 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 10 Jul 2001 14:48:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/pynche Switchboard.py,2.9,2.10 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/pynche In directory usw-pr-cvs1:/tmp/cvs-serv32127 Modified Files: Switchboard.py Log Message: __init__(), save_views(): Catch ValueError along with IOError and EOFError so any failures in unmarshalling are just ignored. Use print>> instead of sys.stderr.write(). Index: Switchboard.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/pynche/Switchboard.py,v retrieving revision 2.9 retrieving revision 2.10 diff -C2 -r2.9 -r2.10 *** Switchboard.py 1999/04/27 18:53:29 2.9 --- Switchboard.py 2001/07/10 21:48:51 2.10 *************** *** 46,49 **** --- 46,51 ---- import marshal + + class Switchboard: def __init__(self, initfile): *************** *** 64,72 **** self.__optiondb = marshal.load(fp) if type(self.__optiondb) <> DictType: ! sys.stderr.write( ! 'Problem reading options from file: %s\n' % ! initfile) self.__optiondb = {} ! except (IOError, EOFError): pass finally: --- 66,73 ---- self.__optiondb = marshal.load(fp) if type(self.__optiondb) <> DictType: ! print >> sys.stderr, \ ! 'Problem reading options from file:', initfile self.__optiondb = {} ! except (IOError, EOFError, ValueError): pass finally: *************** *** 119,124 **** fp = open(self.__initfile, 'w') except IOError: ! sys.stderr.write('Cannot write options to file: %s\n' % ! self.__initfile) else: marshal.dump(self.__optiondb, fp) --- 120,125 ---- fp = open(self.__initfile, 'w') except IOError: ! print >> sys.stderr, 'Cannot write options to file:', \ ! self.__initfile else: marshal.dump(self.__optiondb, fp) From bwarsaw@users.sourceforge.net Tue Jul 10 22:50:47 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 10 Jul 2001 14:50:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/pynche TypeinViewer.py,2.14,2.15 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/pynche In directory usw-pr-cvs1:/tmp/cvs-serv32699 Modified Files: TypeinViewer.py Log Message: Change the way hex type-ins are displayed. The old way was way too fragile. Now the leading "0x" on hex numbers are displayed as labels and the type-in entry fields just accept the hex digits. Be sure to strip off the "0x" string when displaying hex values too. Also, de-string-module-ification, and other Python 2.x improvements. Index: TypeinViewer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/pynche/TypeinViewer.py,v retrieving revision 2.14 retrieving revision 2.15 diff -C2 -r2.14 -r2.15 *** TypeinViewer.py 2001/02/01 21:31:58 2.14 --- TypeinViewer.py 2001/07/10 21:50:44 2.15 *************** *** 13,20 **** """ ! from Tkinter import * ! import string import re class TypeinViewer: def __init__(self, switchboard, master=None): --- 13,22 ---- """ ! import sys import re + from Tkinter import * + + class TypeinViewer: def __init__(self, switchboard, master=None): *************** *** 32,36 **** self.__xl = Label(self.__frame, text='Red:') self.__xl.grid(row=0, column=0, sticky=E) ! self.__x = Entry(self.__frame, width=4) self.__x.grid(row=0, column=1) self.__x.bindtags(self.__x.bindtags() + ('Normalize', 'Update')) --- 34,43 ---- self.__xl = Label(self.__frame, text='Red:') self.__xl.grid(row=0, column=0, sticky=E) ! subframe = Frame(self.__frame) ! subframe.grid(row=0, column=1) ! self.__xox = Label(subframe, text='0x') ! self.__xox.grid(row=0, column=0, sticky=E) ! self.__xox['font'] = 'courier' ! self.__x = Entry(subframe, width=3) self.__x.grid(row=0, column=1) self.__x.bindtags(self.__x.bindtags() + ('Normalize', 'Update')) *************** *** 40,51 **** self.__yl = Label(self.__frame, text='Green:') self.__yl.grid(row=1, column=0, sticky=E) ! self.__y = Entry(self.__frame, width=4) ! self.__y.grid(row=1, column=1) self.__y.bindtags(self.__y.bindtags() + ('Normalize', 'Update')) # Blue self.__zl = Label(self.__frame, text='Blue:') self.__zl.grid(row=2, column=0, sticky=E) ! self.__z = Entry(self.__frame, width=4) ! self.__z.grid(row=2, column=1) self.__z.bindtags(self.__z.bindtags() + ('Normalize', 'Update')) # Update while typing? --- 47,68 ---- self.__yl = Label(self.__frame, text='Green:') self.__yl.grid(row=1, column=0, sticky=E) ! subframe = Frame(self.__frame) ! subframe.grid(row=1, column=1) ! self.__yox = Label(subframe, text='0x') ! self.__yox.grid(row=0, column=0, sticky=E) ! self.__yox['font'] = 'courier' ! self.__y = Entry(subframe, width=3) ! self.__y.grid(row=0, column=1) self.__y.bindtags(self.__y.bindtags() + ('Normalize', 'Update')) # Blue self.__zl = Label(self.__frame, text='Blue:') self.__zl.grid(row=2, column=0, sticky=E) ! subframe = Frame(self.__frame) ! subframe.grid(row=2, column=1) ! self.__zox = Label(subframe, text='0x') ! self.__zox.grid(row=0, column=0, sticky=E) ! self.__zox['font'] = 'courier' ! self.__z = Entry(subframe, width=3) ! self.__z.grid(row=0, column=1) self.__z.bindtags(self.__z.bindtags() + ('Normalize', 'Update')) # Update while typing? *************** *** 63,66 **** --- 80,90 ---- def __togglehex(self, event=None): red, green, blue = self.__sb.current_rgb() + if self.__hexp.get(): + label = '0x' + else: + label = ' ' + self.__xox['text'] = label + self.__yox['text'] = label + self.__zox['text'] = label self.update_yourself(red, green, blue) *************** *** 71,99 **** if contents and contents[0] in 'xX' and self.__hexp.get(): contents = '0' + contents ! # figure out what the contents value is in the current base try: if self.__hexp.get(): ! v = string.atoi(contents, 16) else: ! v = string.atoi(contents) except ValueError: v = None ! # if value is not legal, delete the last character inserted and ring ! # the bell ! if v is None or v < 0 or v > 255: i = ew.index(INSERT) if event.char: contents = contents[:i-1] + contents[i:] ! icursor = icursor-1 ew.bell() elif self.__hexp.get(): ! # Special case: our contents were 0x0 and we just deleted the ! # trailing 0. We want our contents to now be 0x and not 0x0. ! if v == 0 and contents == '0': ! contents = '0x' ! icursor = END ! ew.bell() ! elif not (v == 0 and contents == '0x'): ! contents = hex(v) else: contents = int(v) --- 95,119 ---- if contents and contents[0] in 'xX' and self.__hexp.get(): contents = '0' + contents ! # Figure out the contents in the current base. try: if self.__hexp.get(): ! v = int(contents, 16) else: ! v = int(contents) except ValueError: v = None ! # If value is not legal, or empty, delete the last character inserted ! # and ring the bell. Don't ring the bell if the field is empty (it'll ! # just equal zero. ! if v is None: ! pass ! elif v < 0 or v > 255: i = ew.index(INSERT) if event.char: contents = contents[:i-1] + contents[i:] ! icursor -= 1 ew.bell() elif self.__hexp.get(): ! contents = hex(v)[2:] else: contents = int(v) *************** *** 107,140 **** def __update(self, event=None): ! redstr = self.__x.get() ! greenstr = self.__y.get() ! bluestr = self.__z.get() if self.__hexp.get(): ! red = string.atoi(redstr, 16) ! green = string.atoi(greenstr, 16) ! blue = string.atoi(bluestr, 16) else: ! def intify(colorstr): ! if colorstr == '': ! return 0 ! else: ! return string.atoi(colorstr) ! red, green, blue = map(intify, (redstr, greenstr, bluestr)) self.__sb.update_views(red, green, blue) def update_yourself(self, red, green, blue): if self.__hexp.get(): ! # Special case: our contents were 0x0 and we just deleted the ! # trailing 0. We want our contents to now be 0x and not 0x0. ! def hexify((color, widget)): ! contents = widget.get() ! if not (color == 0 and contents == '0x'): ! return hex(color) ! return contents ! redstr, greenstr, bluestr = map(hexify, ((red, self.__x), ! (green, self.__y), ! (blue, self.__z))) else: ! redstr, greenstr, bluestr = red, green, blue x, y, z = self.__x, self.__y, self.__z xicursor = x.index(INSERT) --- 127,145 ---- def __update(self, event=None): ! redstr = self.__x.get() or '0' ! greenstr = self.__y.get() or '0' ! bluestr = self.__z.get() or '0' if self.__hexp.get(): ! base = 16 else: ! base = 10 ! red, green, blue = [int(x, base) for x in (redstr, greenstr, bluestr)] self.__sb.update_views(red, green, blue) def update_yourself(self, red, green, blue): if self.__hexp.get(): ! sred, sgreen, sblue = [hex(x)[2:] for x in (red, green, blue)] else: ! sred, sgreen, sblue = red, green, blue x, y, z = self.__x, self.__y, self.__z xicursor = x.index(INSERT) *************** *** 144,150 **** y.delete(0, END) z.delete(0, END) ! x.insert(0, redstr) ! y.insert(0, greenstr) ! z.insert(0, bluestr) x.icursor(xicursor) y.icursor(yicursor) --- 149,155 ---- y.delete(0, END) z.delete(0, END) ! x.insert(0, sred) ! y.insert(0, sgreen) ! z.insert(0, sblue) x.icursor(xicursor) y.icursor(yicursor) From tim_one@users.sourceforge.net Tue Jul 10 23:10:32 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 10 Jul 2001 15:10:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.1.2.32,1.1.2.33 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv4533/descr/dist/src/Lib/test Modified Files: Tag: descr-branch test_descr.py Log Message: Hack repair: During the merge from the trunk, I hacked around bad test_descr assumptions about exact dict traversal order by replacing them with qually bad (but correct ) assumptions about the same thing. These changes remove the assumptions about dict traversal order. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_descr.py,v retrieving revision 1.1.2.32 retrieving revision 1.1.2.33 diff -C2 -r1.1.2.32 -r1.1.2.33 *** test_descr.py 2001/07/09 01:26:19 1.1.2.32 --- test_descr.py 2001/07/10 22:10:30 1.1.2.33 *************** *** 119,124 **** for i in dictionary.__iter__(d): l.append(i) verify(l == l1) ! testunop({1:2,3:4}, 2, "len(a)", "__len__") ! testunop({1:2,3:4}, "{1: 2, 3: 4}", "repr(a)", "__repr__") testset2op({1:2,3:4}, 2, 3, {1:2,2:3,3:4}, "a[b]=c", "__setitem__") --- 119,126 ---- for i in dictionary.__iter__(d): l.append(i) verify(l == l1) ! d = {1:2, 3:4} ! testunop(d, 2, "len(a)", "__len__") ! verify(eval(repr(d), {}) == d) ! verify(eval(d.__repr__(), {}) == d) testset2op({1:2,3:4}, 2, 3, {1:2,2:3,3:4}, "a[b]=c", "__setitem__") *************** *** 280,285 **** for i in type(spamdict({})).__iter__(d): l.append(i) verify(l == l1) ! testunop(spamdict({1:2,3:4}), 2, "len(a)", "__len__") ! testunop(spamdict({1:2,3:4}), "{1: 2, 3: 4}", "repr(a)", "__repr__") testset2op(spamdict({1:2,3:4}), 2, 3, spamdict({1:2,2:3,3:4}), "a[b]=c", "__setitem__") --- 282,289 ---- for i in type(spamdict({})).__iter__(d): l.append(i) verify(l == l1) ! straightd = {1:2, 3:4} ! spamd = spamdict(straightd) ! testunop(spamd, 2, "len(a)", "__len__") ! testunop(spamd, repr(straightd), "repr(a)", "__repr__") testset2op(spamdict({1:2,3:4}), 2, 3, spamdict({1:2,2:3,3:4}), "a[b]=c", "__setitem__") From gvanrossum@users.sourceforge.net Wed Jul 11 01:57:11 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 10 Jul 2001 17:57:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.65,2.16.8.66 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv32471 Modified Files: Tag: descr-branch typeobject.c Log Message: subtype_dealloc(): - add some comments and an assert; - finalize GC if needed. type_new(): - always override the tp_alloc and tp_free slots; - install subtype_dealloc as the tp_dealloc slot. Alas, the last bullet stabilizes the reference count of heap types (previously, for each instance a reference was added but never removed), but doesn't make them go away when the last reference goes. Heap types have (at least) two references to themselves: one in tp_mro and (at least) one added by add_members(), in the descriptor for __dict__. I suppose this means we have to make types GC'able, since this is easily invoked in user code (e.g. a function defining a new class will leak that class). Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.65 retrieving revision 2.16.8.66 diff -C2 -r2.16.8.65 -r2.16.8.66 *** typeobject.c 2001/07/10 16:28:04 2.16.8.65 --- typeobject.c 2001/07/11 00:57:09 2.16.8.66 *************** *** 162,165 **** --- 162,166 ---- /* This exists so we can DECREF self->ob_type */ + /* Find the nearest base with a different tp_dealloc */ type = self->ob_type; base = type->tp_base; *************** *** 168,171 **** --- 169,174 ---- assert(base); } + + /* If we added a dict, DECREF it */ if (dictoffset && !base->tp_dictoffset) { PyObject **dictptr = (PyObject **) ((char *)self + dictoffset); *************** *** 176,180 **** --- 179,191 ---- } } + + /* Finalize GC if the base doesn't do GC and we do */ + if (PyType_IS_GC(type) && !PyType_IS_GC(base)) + PyObject_GC_Fini(self); + + /* Call the base tp_dealloc() */ + assert(f); f(self); + /* Can't reference self beyond this point */ if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { *************** *** 638,645 **** type->tp_setattro = PyObject_GenericSetAttr; } ! if (base->tp_new == NULL) ! type->tp_new = PyType_GenericNew; ! if (base->tp_alloc == NULL) ! type->tp_alloc = PyType_GenericAlloc; /* Initialize the rest */ --- 649,657 ---- type->tp_setattro = PyObject_GenericSetAttr; } ! type->tp_dealloc = subtype_dealloc; ! ! /* Always override allocation strategy to use regular heap */ ! type->tp_alloc = PyType_GenericAlloc; ! type->tp_free = _PyObject_Del; /* Initialize the rest */ From tim_one@users.sourceforge.net Wed Jul 11 05:08:51 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 10 Jul 2001 21:08:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib uu.py,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv23108/python/dist/src/lib Modified Files: uu.py Log Message: SF patch #440144: Tests and minor bugfix for uu module decode(): While writing tests for uu.py, Nick Mathewson discovered that the 'Truncated input file' exception could never get raised, because its "if not str:" test was actually testing the builtin function "str", not the local string vrbl "s" as intended. Bugfix candidate. Index: uu.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/uu.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -r1.16 -r1.17 *** uu.py 2001/03/01 04:27:19 1.16 --- uu.py 2001/07/11 04:08:49 1.17 *************** *** 136,140 **** out_file.write(data) s = in_file.readline() ! if not str: raise Error, 'Truncated input file' --- 136,140 ---- out_file.write(data) s = in_file.readline() ! if not s: raise Error, 'Truncated input file' From fdrake@users.sourceforge.net Wed Jul 11 07:27:02 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 10 Jul 2001 23:27:02 -0700 Subject: [Python-checkins] CVS: python/dist/src configure.in,1.224,1.225 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv10491 Modified Files: configure.in Log Message: Check for --with-pydebug earlier, and record the result. When setting up the basic OPT value for GCC, only use optimization if not using debugging mode. Fix a typo in a comment in the IPv6 check. Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.224 retrieving revision 1.225 diff -C2 -r1.224 -r1.225 *** configure.in 2001/07/10 16:44:35 1.224 --- configure.in 2001/07/11 06:27:00 1.225 *************** *** 304,307 **** --- 304,317 ---- fi + # Check for --with-pydebug + AC_MSG_CHECKING(for --with-pydebug) + AC_ARG_WITH(pydebug, + [ --with-pydebug build with Py_DEBUG defined], [ + if test "$withval" != no + then AC_DEFINE(Py_DEBUG) AC_MSG_RESULT(yes); Py_DEBUG='true' + else AC_MSG_RESULT(no); Py_DEBUG='false' + fi], + [AC_MSG_RESULT(no)]) + # Optimizer/debugger flags AC_SUBST(OPT) *************** *** 312,320 **** case $ac_cv_prog_cc_g in yes) ! OPT="-g -O2 -Wall -Wstrict-prototypes";; *) ! OPT="-O2 -Wall -Wstrict-prototypes";; ! esac ! ;; *) case $ac_sys_system in --- 322,336 ---- case $ac_cv_prog_cc_g in yes) ! if test "$Py_DEBUG" = 'true' ; then ! # Optimization messes up debuggers, so turn it off for ! # debug builds. ! OPT="-g -Wall -Wstrict-prototypes" ! else ! OPT="-g -O3 -Wall -Wstrict-prototypes" ! fi;; *) ! OPT="-O3 -Wall -Wstrict-prototypes";; ! esac ! ;; *) case $ac_sys_system in *************** *** 386,390 **** esac ], ! AC_TRY_RUN([ /* AF_INET6 avalable check */ #include #include --- 402,406 ---- esac ], ! AC_TRY_RUN([ /* AF_INET6 available check */ #include #include *************** *** 861,874 **** AC_CHECK_LIB(dl, dlopen) # Dynamic linking for SunOS/Solaris and SYSV AC_CHECK_LIB(dld, shl_load) # Dynamic linking for HP-UX - - # Check for --with-pydebug - AC_MSG_CHECKING(for --with-pydebug) - AC_ARG_WITH(pydebug, - [ --with-pydebug build with Py_DEBUG defined], [ - if test "$withval" != no - then AC_DEFINE(Py_DEBUG) AC_MSG_RESULT(yes) - else AC_MSG_RESULT(no) - fi], - [AC_MSG_RESULT(no)]) # checks for system dependent C++ extensions support --- 877,880 ---- From fdrake@users.sourceforge.net Wed Jul 11 07:27:59 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 10 Jul 2001 23:27:59 -0700 Subject: [Python-checkins] CVS: python/dist/src configure,1.216,1.217 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv10671 Modified Files: configure Log Message: The usual... Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.216 retrieving revision 1.217 diff -C2 -r1.216 -r1.217 *** configure 2001/07/10 16:44:35 1.216 --- configure 2001/07/11 06:27:56 1.217 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.224 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.225 [...4211 lines suppressed...] if eval "test \"`echo '$''{'ac_cv_type_socklen_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < *************** *** 6922,6926 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6925: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then --- 6928,6932 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6931: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then From twouters@users.sourceforge.net Wed Jul 11 12:38:22 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 11 Jul 2001 04:38:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib uu.py,1.16,1.16.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv32088/Lib Modified Files: Tag: release21-maint uu.py Log Message: Backport Tim's checkin 1.17: SF patch #440144: Tests and minor bugfix for uu module decode(): While writing tests for uu.py, Nick Mathewson discovered that the 'Truncated input file' exception could never get raised, because its "if not str:" test was actually testing the builtin function "str", not the local string vrbl "s" as intended. Index: uu.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/uu.py,v retrieving revision 1.16 retrieving revision 1.16.4.1 diff -C2 -r1.16 -r1.16.4.1 *** uu.py 2001/03/01 04:27:19 1.16 --- uu.py 2001/07/11 11:38:20 1.16.4.1 *************** *** 136,140 **** out_file.write(data) s = in_file.readline() ! if not str: raise Error, 'Truncated input file' --- 136,140 ---- out_file.write(data) s = in_file.readline() ! if not s: raise Error, 'Truncated input file' From twouters@users.sourceforge.net Wed Jul 11 13:03:46 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 11 Jul 2001 05:03:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python import.c,2.175.2.1,2.175.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv4272/Python Modified Files: Tag: release21-maint import.c Log Message: Backport of Tim's checkin 2.178: SF bug #438295: [Windows] __init__.py cause strange behavior Probable fix (the bug report doesn't have enough info to say for sure). find_init_module(): Insist on a case-sensitive match for __init__ files. Given __INIT__.PY instead, find_init_module() thought that was fine, but the later attempt to do find_module("__INIT__.PY") didn't and its caller silently suppressed the resulting ImportError. Now find_init_module() refuses to accept __INIT__.PY to begin with. Index: import.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/import.c,v retrieving revision 2.175.2.1 retrieving revision 2.175.2.2 diff -C2 -r2.175.2.1 -r2.175.2.2 *** import.c 2001/05/23 12:51:22 2.175.2.1 --- import.c 2001/07/11 12:03:44 2.175.2.2 *************** *** 1195,1218 **** find_init_module(char *buf) { ! size_t save_len = strlen(buf); size_t i = save_len; struct stat statbuf; if (save_len + 13 >= MAXPATHLEN) return 0; buf[i++] = SEP; ! strcpy(buf+i, "__init__.py"); if (stat(buf, &statbuf) == 0) { ! buf[save_len] = '\0'; ! return 1; } ! i += strlen(buf+i); ! if (Py_OptimizeFlag) ! strcpy(buf+i, "o"); ! else ! strcpy(buf+i, "c"); if (stat(buf, &statbuf) == 0) { ! buf[save_len] = '\0'; ! return 1; } buf[save_len] = '\0'; --- 1195,1235 ---- find_init_module(char *buf) { ! const size_t save_len = strlen(buf); size_t i = save_len; + char *pname; /* pointer to start of __init__ */ struct stat statbuf; + /* For calling case_ok(buf, len, namelen, name): + * /a/b/c/d/e/f/g/h/i/j/k/some_long_module_name.py\0 + * ^ ^ ^ ^ + * |--------------------- buf ---------------------| + * |------------------- len ------------------| + * |------ name -------| + * |----- namelen -----| + */ if (save_len + 13 >= MAXPATHLEN) return 0; buf[i++] = SEP; ! pname = buf + i; ! strcpy(pname, "__init__.py"); if (stat(buf, &statbuf) == 0) { ! if (case_ok(buf, ! save_len + 9, /* len("/__init__") */ ! 8, /* len("__init__") */ ! pname)) { ! buf[save_len] = '\0'; ! return 1; ! } } ! i += strlen(pname); ! strcpy(buf+i, Py_OptimizeFlag ? "o" : "c"); if (stat(buf, &statbuf) == 0) { ! if (case_ok(buf, ! save_len + 9, /* len("/__init__") */ ! 8, /* len("__init__") */ ! pname)) { ! buf[save_len] = '\0'; ! return 1; ! } } buf[save_len] = '\0'; From twouters@users.sourceforge.net Wed Jul 11 13:05:52 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 11 Jul 2001 05:05:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib SocketServer.py,1.24,1.24.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv4498/Lib Modified Files: Tag: release21-maint SocketServer.py Log Message: Backport of Guido's checkin 1.25: Fix various serious problems: - The ThreadingTCPServer class and its derived classes were completely broken because the main thread would close the request before the handler thread had time to look at it. This was introduced by Ping's close_request() patch. The fix moves the close_request() calls to after the handler has run to completion in the BaseServer class and the ForkingMixIn class; when using the ThreadingMixIn, closing the request is the handler's responsibility. - The ForkingUDPServer class has always been been broken because the socket was closed in the child before calling the handler. I fixed this by simply not calling server_close() in the child at all. - I cannot get the UnixDatagramServer class to work at all. The recvfrom() call doesn't return a meaningful client address. I added a comment to this effect. Maybe it works on other Unix versions. - The __all__ variable was missing ThreadingMixIn and ForkingMixIn. - Bumped __version__ to "0.4". - Added a note about the test suite (to be checked in shortly). Index: SocketServer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/SocketServer.py,v retrieving revision 1.24 retrieving revision 1.24.2.1 diff -C2 -r1.24 -r1.24.2.1 *** SocketServer.py 2001/04/11 04:02:05 1.24 --- SocketServer.py 2001/07/11 12:05:49 1.24.2.1 *************** *** 121,127 **** # Author of the BaseServer patch: Luke Kenneth Casson Leighton ! __version__ = "0.3" import socket import sys --- 121,132 ---- # Author of the BaseServer patch: Luke Kenneth Casson Leighton ! # XXX Warning! ! # There is a test suite for this module, but it cannot be run by the ! # standard regression test. ! # To run it manually, run Lib/test/test_socketserver.py. + __version__ = "0.4" + import socket import sys *************** *** 130,134 **** __all__ = ["TCPServer","UDPServer","ForkingUDPServer","ForkingTCPServer", "ThreadingUDPServer","ThreadingTCPServer","BaseRequestHandler", ! "StreamRequestHandler","DatagramRequestHandler"] if hasattr(socket, "AF_UNIX"): __all__.extend(["UnixStreamServer","UnixDatagramServer", --- 135,140 ---- __all__ = ["TCPServer","UDPServer","ForkingUDPServer","ForkingTCPServer", "ThreadingUDPServer","ThreadingTCPServer","BaseRequestHandler", ! "StreamRequestHandler","DatagramRequestHandler", ! "ThreadingMixIn", "ForkingMixIn"] if hasattr(socket, "AF_UNIX"): __all__.extend(["UnixStreamServer","UnixDatagramServer", *************** *** 216,220 **** except: self.handle_error(request, client_address) ! self.close_request(request) def verify_request(self, request, client_address): --- 222,226 ---- except: self.handle_error(request, client_address) ! self.close_request(request) def verify_request(self, request, client_address): *************** *** 233,236 **** --- 239,243 ---- """ self.finish_request(request, client_address) + self.close_request(request) def server_close(self): *************** *** 424,427 **** --- 431,435 ---- self.active_children = [] self.active_children.append(pid) + self.close_request(request) return else: *************** *** 429,439 **** # This must never return, hence os._exit()! try: - self.server_close() self.finish_request(request, client_address) os._exit(0) except: try: ! self.handle_error(request, ! client_address) finally: os._exit(1) --- 437,445 ---- # This must never return, hence os._exit()! try: self.finish_request(request, client_address) os._exit(0) except: try: ! self.handle_error(request, client_address) finally: os._exit(1) *************** *** 545,548 **** --- 551,557 ---- class DatagramRequestHandler(BaseRequestHandler): + + # XXX Regrettably, I cannot get this working on Linux; + # s.recvfrom() doesn't return a meaningful client address. """Define self.rfile and self.wfile for datagram sockets.""" From twouters@users.sourceforge.net Wed Jul 11 13:15:17 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 11 Jul 2001 05:15:17 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_socketserver,NONE,1.1.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv6120/output Added Files: Tag: release21-maint test_socketserver Log Message: Backport of the socketserver test, including output file (which is still necessary in the 2.1 branch.) Guido's original checkin message: A test suite for SocketServer.py that exposes the various bugs just fixed. Regrettably, this must be run manually -- somehow the I/O redirection of the regression test breaks the test. When run under the regression test, this raises ImportError with a warning to that effect. --- NEW FILE: test_socketserver --- test_socketserver From twouters@users.sourceforge.net Wed Jul 11 13:15:17 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 11 Jul 2001 05:15:17 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_socketserver.py,NONE,1.2.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv6120 Added Files: Tag: release21-maint test_socketserver.py Log Message: Backport of the socketserver test, including output file (which is still necessary in the 2.1 branch.) Guido's original checkin message: A test suite for SocketServer.py that exposes the various bugs just fixed. Regrettably, this must be run manually -- somehow the I/O redirection of the regression test breaks the test. When run under the regression test, this raises ImportError with a warning to that effect. --- NEW FILE: test_socketserver.py --- # Test suite for SocketServer.py # XXX This must be run manually -- somehow the I/O redirection of the # regression test breaks the test. from test_support import verbose, verify, TESTFN if not verbose: raise ImportError, "test_socketserver can only be run manually" from SocketServer import * import socket import select import time import threading import os NREQ = 3 DELAY = 0.5 class MyMixinHandler: def handle(self): time.sleep(DELAY) line = self.rfile.readline() time.sleep(DELAY) self.wfile.write(line) class MyStreamHandler(MyMixinHandler, StreamRequestHandler): pass class MyDatagramHandler(MyMixinHandler, DatagramRequestHandler): pass class MyMixinServer: def serve_a_few(self): for i in range(NREQ): self.handle_request() def handle_error(self, request, client_address): self.close_request(request) self.server_close() raise teststring = "hello world\n" def receive(sock, n, timeout=20): r, w, x = select.select([sock], [], [], timeout) if sock in r: return sock.recv(n) else: raise RuntimeError, "timed out on %s" % `sock` def testdgram(proto, addr): s = socket.socket(proto, socket.SOCK_DGRAM) s.sendto(teststring, addr) buf = data = receive(s, 100) while data and '\n' not in buf: data = receive(s, 100) buf += data verify(buf == teststring) s.close() def teststream(proto, addr): s = socket.socket(proto, socket.SOCK_STREAM) s.connect(addr) s.send(teststring) buf = data = receive(s, 100) while data and '\n' not in buf: data = receive(s, 100) buf += data verify(buf == teststring) s.close() class ServerThread(threading.Thread): def __init__(self, addr, svrcls, hdlrcls): threading.Thread.__init__(self) self.__addr = addr self.__svrcls = svrcls self.__hdlrcls = hdlrcls def run(self): class svrcls(MyMixinServer, self.__svrcls): pass if verbose: print "thread: creating server" svr = svrcls(self.__addr, self.__hdlrcls) if verbose: print "thread: serving three times" svr.serve_a_few() if verbose: print "thread: done" seed = 0 def pickport(): global seed seed += 1 return 10000 + (os.getpid() % 1000)*10 + seed host = "localhost" testfiles = [] def pickaddr(proto): if proto == socket.AF_INET: return (host, pickport()) else: fn = TESTFN + str(pickport()) testfiles.append(fn) return fn def cleanup(): for fn in testfiles: try: os.remove(fn) except os.error: pass testfiles[:] = [] def testloop(proto, servers, hdlrcls, testfunc): for svrcls in servers: addr = pickaddr(proto) if verbose: print "ADDR =", addr print "CLASS =", svrcls t = ServerThread(addr, svrcls, hdlrcls) if verbose: print "server created" t.start() if verbose: print "server running" for i in range(NREQ): time.sleep(DELAY) if verbose: print "test client", i testfunc(proto, addr) if verbose: print "waiting for server" t.join() if verbose: print "done" tcpservers = [TCPServer, ThreadingTCPServer] if hasattr(os, 'fork'): tcpservers.append(ForkingTCPServer) udpservers = [UDPServer, ThreadingUDPServer] if hasattr(os, 'fork'): udpservers.append(ForkingUDPServer) if not hasattr(socket, 'AF_UNIX'): streamservers = [] dgramservers = [] else: class ForkingUnixStreamServer(ForkingMixIn, UnixStreamServer): pass streamservers = [UnixStreamServer, ThreadingUnixStreamServer, ForkingUnixStreamServer] class ForkingUnixDatagramServer(ForkingMixIn, UnixDatagramServer): pass dgramservers = [UnixDatagramServer, ThreadingUnixDatagramServer, ForkingUnixDatagramServer] def testall(): testloop(socket.AF_INET, tcpservers, MyStreamHandler, teststream) testloop(socket.AF_INET, udpservers, MyDatagramHandler, testdgram) if hasattr(socket, 'AF_UNIX'): testloop(socket.AF_UNIX, streamservers, MyStreamHandler, teststream) # Alas, on Linux (at least) recvfrom() doesn't return a meaningful # client address so this cannot work: ##testloop(socket.AF_UNIX, dgramservers, MyDatagramHandler, testdgram) def main(): try: testall() finally: cleanup() main() From twouters@users.sourceforge.net Wed Jul 11 13:18:26 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 11 Jul 2001 05:18:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules readline.c,2.35,2.35.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv6445/Modules Modified Files: Tag: release21-maint readline.c Log Message: Backport of Guido's checkins of acconfig.h (1.50), configure.in (1.224) and readline.c (2.36), and re-generated config.h.in and configure: SF Patch #432457 by Jason Tishler: support for readline 4.2. This patch allows the readline module to build cleanly with GNU readline 4.2 without breaking the build for earlier GNU readline versions. The configure script checks for the presence of rl_completion_matches in libreadline. Index: readline.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/readline.c,v retrieving revision 2.35 retrieving revision 2.35.2.1 diff -C2 -r2.35 -r2.35.2.1 *** readline.c 2001/04/13 18:14:27 2.35 --- readline.c 2001/07/11 12:18:24 2.35.2.1 *************** *** 22,25 **** --- 22,29 ---- #include + #ifdef HAVE_RL_COMPLETION_MATCHES + #define completion_matches(x, y) rl_completion_matches((x), ((rl_compentry_func_t *)(y))) + #endif + /* Pointers needed from outside (but not declared in a header file). */ extern DL_IMPORT(int) (*PyOS_InputHook)(void); From twouters@users.sourceforge.net Wed Jul 11 13:18:26 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 11 Jul 2001 05:18:26 -0700 Subject: [Python-checkins] CVS: python/dist/src acconfig.h,1.46,1.46.2.1 config.h.in,2.91.2.1,2.91.2.2 configure,1.207.2.1,1.207.2.2 configure.in,1.215.2.1,1.215.2.2 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv6445 Modified Files: Tag: release21-maint acconfig.h config.h.in configure configure.in Log Message: Backport of Guido's checkins of acconfig.h (1.50), configure.in (1.224) and readline.c (2.36), and re-generated config.h.in and configure: SF Patch #432457 by Jason Tishler: support for readline 4.2. This patch allows the readline module to build cleanly with GNU readline 4.2 without breaking the build for earlier GNU readline versions. The configure script checks for the presence of rl_completion_matches in libreadline. Index: acconfig.h =================================================================== RCS file: /cvsroot/python/python/dist/src/acconfig.h,v retrieving revision 1.46 retrieving revision 1.46.2.1 diff -C2 -r1.46 -r1.46.2.1 *** acconfig.h 2001/03/20 13:09:13 1.46 --- acconfig.h 2001/07/11 12:18:23 1.46.2.1 *************** *** 75,78 **** --- 75,81 ---- #undef HAVE_PTH + /* Define if you have readline 4.2 */ + #undef HAVE_RL_COMPLETION_MATCHES + /* Define if your compiler supports variable length function prototypes (e.g. void fprintf(FILE *, char *, ...);) *and* */ Index: config.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/config.h.in,v retrieving revision 2.91.2.1 retrieving revision 2.91.2.2 diff -C2 -r2.91.2.1 -r2.91.2.2 *** config.h.in 2001/05/11 16:21:06 2.91.2.1 --- config.h.in 2001/07/11 12:18:23 2.91.2.2 *************** *** 1,3 **** ! /* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define if on AIX 3. --- 1,3 ---- ! /* config.h.in. Generated automatically from configure.in by autoheader 2.13. */ /* Define if on AIX 3. *************** *** 137,140 **** --- 137,143 ---- #undef HAVE_PTH + /* Define if you have readline 4.2 */ + #undef HAVE_RL_COMPLETION_MATCHES + /* Define if your compiler supports variable length function prototypes (e.g. void fprintf(FILE *, char *, ...);) *and* */ *************** *** 270,273 **** --- 273,279 ---- #undef SIZEOF_VOID_P + /* Define if you have the _getpty function. */ + #undef HAVE__GETPTY + /* Define if you have the alarm function. */ #undef HAVE_ALARM *************** *** 357,363 **** #undef HAVE_GETPID - /* Define if you have the _getpty function. */ - #undef HAVE__GETPTY - /* Define if you have the getpwent function. */ #undef HAVE_GETPWENT --- 363,366 ---- *************** *** 519,530 **** #undef HAVE_WAITPID ! /* Define if you have the header file. */ ! #undef HAVE_DB_185_H /* Define if you have the header file. */ #undef HAVE_DB1_NDBM_H ! /* Define if you have the header file. */ ! #undef HAVE_DB_H /* Define if you have the header file. */ --- 522,533 ---- #undef HAVE_WAITPID ! /* Define if you have the header file. */ ! #undef HAVE_DB_H /* Define if you have the header file. */ #undef HAVE_DB1_NDBM_H ! /* Define if you have the header file. */ ! #undef HAVE_DB_185_H /* Define if you have the header file. */ Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.207.2.1 retrieving revision 1.207.2.2 diff -C2 -r1.207.2.1 -r1.207.2.2 *** configure 2001/05/11 16:35:03 1.207.2.1 --- configure 2001/07/11 12:18:23 1.207.2.2 *************** *** 2237,2240 **** --- 2237,2241 ---- #include "confdefs.h" #include + #include main() { *************** *** 2245,2249 **** } EOF [...3167 lines suppressed...] if eval "test \"`echo '$''{'ac_cv_type_socklen_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < *************** *** 6223,6227 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6226: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then --- 6278,6282 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6281: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.215.2.1 retrieving revision 1.215.2.2 diff -C2 -r1.215.2.1 -r1.215.2.2 *** configure.in 2001/05/11 16:21:06 1.215.2.1 --- configure.in 2001/07/11 12:18:24 1.215.2.2 *************** *** 1331,1334 **** --- 1331,1338 ---- fi + # check for readline 4.2 + AC_CHECK_LIB(readline, rl_completion_matches, + AC_DEFINE(HAVE_RL_COMPLETION_MATCHES), , -ltermcap) + # THIS MUST BE LAST, IT CAN BREAK OTHER TESTS! # Add sys/socket.h to confdefs.h From twouters@users.sourceforge.net Wed Jul 11 15:01:10 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 11 Jul 2001 07:01:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules posixmodule.c,2.187.2.1,2.187.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv27583/Modules Modified Files: Tag: release21-maint posixmodule.c Log Message: Patch #439995 (slightly modified from the uploaded version): Work around Linux's nonstandard nice() systemcall, which does not return the new priority. This closes SF bug #439990. Index: posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.187.2.1 retrieving revision 2.187.2.2 diff -C2 -r2.187.2.1 -r2.187.2.2 *** posixmodule.c 2001/06/27 13:01:12 2.187.2.1 --- posixmodule.c 2001/07/11 14:01:08 2.187.2.2 *************** *** 1079,1084 **** if (!PyArg_ParseTuple(args, "i:nice", &increment)) return NULL; value = nice(increment); ! if (value == -1) return posix_error(); return PyInt_FromLong((long) value); --- 1079,1101 ---- if (!PyArg_ParseTuple(args, "i:nice", &increment)) return NULL; + + /* There are two flavours of 'nice': one that returns the new + priority (as required by almost all standards out there) and the + Linux one, which returns '0' on success and advices the use of + getpriority() to get the new priority. + + If we are of the nice family that returns the new priority, we + need to clear errno before the call, and check if errno is filled + before calling posix_error() on a returnvalue of -1, because the + -1 may be the actual new priority! */ + + errno = 0; value = nice(increment); ! #ifdef HAVE_GETPRIORITY ! if (value == 0) ! value = getpriority(PRIO_PROCESS, 0); ! #endif ! if (value == -1 && errno != 0) ! /* either nice() or getpriority() returned an error */ return posix_error(); return PyInt_FromLong((long) value); From twouters@users.sourceforge.net Wed Jul 11 15:01:11 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 11 Jul 2001 07:01:11 -0700 Subject: [Python-checkins] CVS: python/dist/src config.h.in,2.91.2.2,2.91.2.3 configure.in,1.215.2.2,1.215.2.3 configure,1.207.2.2,1.207.2.3 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv27583 Modified Files: Tag: release21-maint config.h.in configure.in configure Log Message: Patch #439995 (slightly modified from the uploaded version): Work around Linux's nonstandard nice() systemcall, which does not return the new priority. This closes SF bug #439990. Index: config.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/config.h.in,v retrieving revision 2.91.2.2 retrieving revision 2.91.2.3 diff -C2 -r2.91.2.2 -r2.91.2.3 *** config.h.in 2001/07/11 12:18:23 2.91.2.2 --- config.h.in 2001/07/11 14:01:07 2.91.2.3 *************** *** 363,366 **** --- 363,369 ---- #undef HAVE_GETPID + /* Define if you have the getpriority function. */ + #undef HAVE_GETPRIORITY + /* Define if you have the getpwent function. */ #undef HAVE_GETPWENT Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.215.2.2 retrieving revision 1.215.2.3 diff -C2 -r1.215.2.2 -r1.215.2.3 *** configure.in 2001/07/11 12:18:24 1.215.2.2 --- configure.in 2001/07/11 14:01:07 1.215.2.3 *************** *** 1009,1013 **** sigaction siginterrupt sigrelse strftime strptime symlink sysconf \ tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ ! truncate uname waitpid _getpty) # check for openpty and forkpty --- 1009,1013 ---- sigaction siginterrupt sigrelse strftime strptime symlink sysconf \ tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ ! truncate uname waitpid _getpty getpriority) # check for openpty and forkpty Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.207.2.2 retrieving revision 1.207.2.3 diff -C2 -r1.207.2.2 -r1.207.2.3 *** configure 2001/07/11 12:18:23 1.207.2.2 --- configure 2001/07/11 14:01:07 1.207.2.3 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.215.2.1 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.215.2.2 # Guess values for system-dependent variables and create Makefiles. *************** *** 4248,4252 **** sigaction siginterrupt sigrelse strftime strptime symlink sysconf \ tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ ! truncate uname waitpid _getpty do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 --- 4248,4252 ---- sigaction siginterrupt sigrelse strftime strptime symlink sysconf \ tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ ! truncate uname waitpid _getpty getpriority do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 From twouters@users.sourceforge.net Wed Jul 11 15:45:37 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 11 Jul 2001 07:45:37 -0700 Subject: [Python-checkins] CVS: python/dist/src config.h.in,2.98,2.99 configure.in,1.225,1.226 configure,1.217,1.218 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv5710 Modified Files: config.h.in configure.in configure Log Message: Patch #439995 (slightly modified from the uploaded version): Work around Linux's nonstandard nice() systemcall, which does not return the new priority. This closes SF bug #439990. Index: config.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/config.h.in,v retrieving revision 2.98 retrieving revision 2.99 diff -C2 -r2.98 -r2.99 *** config.h.in 2001/07/10 16:44:35 2.98 --- config.h.in 2001/07/11 14:45:34 2.99 *************** *** 1,3 **** ! /* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define if on AIX 3. --- 1,3 ---- ! /* config.h.in. Generated automatically from configure.in by autoheader 2.13. */ /* Define if on AIX 3. *************** *** 300,303 **** --- 300,306 ---- #undef SIZEOF_WCHAR_T + /* Define if you have the _getpty function. */ + #undef HAVE__GETPTY + /* Define if you have the alarm function. */ #undef HAVE_ALARM *************** *** 393,398 **** #undef HAVE_GETPID ! /* Define if you have the _getpty function. */ ! #undef HAVE__GETPTY /* Define if you have the getpwent function. */ --- 396,401 ---- #undef HAVE_GETPID ! /* Define if you have the getpriority function. */ ! #undef HAVE_GETPRIORITY /* Define if you have the getpwent function. */ *************** *** 558,569 **** #undef HAVE_WAITPID ! /* Define if you have the header file. */ ! #undef HAVE_DB_185_H /* Define if you have the header file. */ #undef HAVE_DB1_NDBM_H ! /* Define if you have the header file. */ ! #undef HAVE_DB_H /* Define if you have the header file. */ --- 561,572 ---- #undef HAVE_WAITPID ! /* Define if you have the header file. */ ! #undef HAVE_DB_H /* Define if you have the header file. */ #undef HAVE_DB1_NDBM_H ! /* Define if you have the header file. */ ! #undef HAVE_DB_185_H /* Define if you have the header file. */ Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.225 retrieving revision 1.226 diff -C2 -r1.225 -r1.226 *** configure.in 2001/07/11 06:27:00 1.225 --- configure.in 2001/07/11 14:45:34 1.226 *************** *** 1176,1180 **** sigaction siginterrupt sigrelse strftime strptime symlink sysconf \ tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ ! truncate uname waitpid _getpty) # check for openpty and forkpty --- 1176,1180 ---- sigaction siginterrupt sigrelse strftime strptime symlink sysconf \ tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ ! truncate uname waitpid _getpty getpriority) # check for openpty and forkpty Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.217 retrieving revision 1.218 diff -C2 -r1.217 -r1.218 *** configure 2001/07/11 06:27:56 1.217 --- configure 2001/07/11 14:45:34 1.218 *************** *** 2494,2497 **** --- 2494,2498 ---- #include "confdefs.h" #include + #include main() { *************** *** 2502,2506 **** } EOF [...3394 lines suppressed...] if eval "test \"`echo '$''{'ac_cv_type_socklen_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < *************** *** 6928,6932 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6931: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then --- 6939,6943 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6942: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then From twouters@users.sourceforge.net Wed Jul 11 15:45:37 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 11 Jul 2001 07:45:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules posixmodule.c,2.190,2.191 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv5710/Modules Modified Files: posixmodule.c Log Message: Patch #439995 (slightly modified from the uploaded version): Work around Linux's nonstandard nice() systemcall, which does not return the new priority. This closes SF bug #439990. Index: posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.190 retrieving revision 2.191 diff -C2 -r2.190 -r2.191 *** posixmodule.c 2001/05/14 22:32:33 2.190 --- posixmodule.c 2001/07/11 14:45:34 2.191 *************** *** 1122,1127 **** if (!PyArg_ParseTuple(args, "i:nice", &increment)) return NULL; value = nice(increment); ! if (value == -1) return posix_error(); return PyInt_FromLong((long) value); --- 1122,1144 ---- if (!PyArg_ParseTuple(args, "i:nice", &increment)) return NULL; + + /* There are two flavours of 'nice': one that returns the new + priority (as required by almost all standards out there) and the + Linux one, which returns '0' on success and advices the use of + getpriority() to get the new priority. + + If we are of the nice family that returns the new priority, we + need to clear errno before the call, and check if errno is filled + before calling posix_error() on a returnvalue of -1, because the + -1 may be the actual new priority! */ + + errno = 0; value = nice(increment); ! #ifdef HAVE_GETPRIORITY ! if (value == 0) ! value = getpriority(PRIO_PROCESS, 0); ! #endif ! if (value == -1 && errno != 0) ! /* either nice() or getpriority() returned an error */ return posix_error(); return PyInt_FromLong((long) value); From effbot@users.sourceforge.net Wed Jul 11 18:27:09 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Wed, 11 Jul 2001 10:27:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Demo/xmlrpc - New directory Message-ID: Update of /cvsroot/python/python/dist/src/Demo/xmlrpc In directory usw-pr-cvs1:/tmp/cvs-serv8171/Demo/xmlrpc Log Message: Directory /cvsroot/python/python/dist/src/Demo/xmlrpc added to the repository From effbot@users.sourceforge.net Wed Jul 11 18:42:23 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Wed, 11 Jul 2001 10:42:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Demo/xmlrpc xmlrpc_handler.py,NONE,1.1 xmlrpcserver.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Demo/xmlrpc In directory usw-pr-cvs1:/tmp/cvs-serv11351/Demo/xmlrpc Added Files: xmlrpc_handler.py xmlrpcserver.py Log Message: xmlrpclib for python 2.2; initial checkin --- NEW FILE: xmlrpc_handler.py --- # # XML-RPC SERVER # $Id: xmlrpc_handler.py,v 1.1 2001/07/11 17:42:21 effbot Exp $ # # an asynchronous XML-RPC server for Medusa # # written by Sam Rushing # # Based on "xmlrpcserver.py" by Fredrik Lundh (fredrik@pythonware.com) # import http_server import xmlrpclib import regex import string import sys class xmlrpc_handler: def match (self, request): # Note: /RPC2 is not required by the spec, so you may override this method. if request.uri[:5] == '/RPC2': return 1 else: return 0 def handle_request (self, request): [path, params, query, fragment] = request.split_uri() if request.command in ('post', 'put'): request.collector = collector (self, request) else: request.error (400) def continue_request (self, data, request): params, method = xmlrpclib.loads (data) try: # generate response try: response = self.call (method, params) 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 request.error (500) else: # got a valid XML RPC response request['Content-Type'] = 'text/xml' request.push (response) request.done() def call (self, method, params): # override this method to implement RPC methods raise "NotYetImplemented" class collector: "gathers input for POST and PUT requests" def __init__ (self, handler, request): self.handler = handler self.request = request self.data = '' # make sure there's a content-length header cl = request.get_header ('content-length') if not cl: request.error (411) else: cl = string.atoi (cl) # using a 'numeric' terminator self.request.channel.set_terminator (cl) def collect_incoming_data (self, data): self.data = self.data + data def found_terminator (self): # set the terminator back to the default self.request.channel.set_terminator ('\r\n\r\n') self.handler.continue_request (self.data, self.request) if __name__ == '__main__': class rpc_demo (xmlrpc_handler): def call (self, method, params): print 'method="%s" params=%s' % (method, params) return "Sure, that works" import asyncore import http_server hs = http_server.http_server ('', 8000) rpc = rpc_demo() hs.install_handler (rpc) asyncore.loop() --- NEW FILE: xmlrpcserver.py --- # # XML-RPC SERVER # $Id: xmlrpcserver.py,v 1.1 2001/07/11 17:42:21 effbot Exp $ # # a simple XML-RPC server for Python # # History: # 1999-02-01 fl added to xmlrpclib distribution # # written by Fredrik Lundh, January 1999. # # Copyright (c) 1999 by Secret Labs AB. # Copyright (c) 1999 by Fredrik Lundh. # # fredrik@pythonware.com # http://www.pythonware.com # # -------------------------------------------------------------------- # Permission to use, copy, modify, and distribute this software and # its associated documentation for any purpose and without fee is # hereby granted. This software is provided as is. # -------------------------------------------------------------------- # import SocketServer, BaseHTTPServer import xmlrpclib import sys class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): def do_POST(self): try: # get arguments data = self.rfile.read(int(self.headers["content-length"])) params, method = xmlrpclib.loads(data) # generate response try: response = self.call(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 (from Skip Montanaro) self.wfile.flush() self.connection.shutdown(1) def call(self, method, params): # override this method to implement RPC methods print "CALL", method, params return params if __name__ == '__main__': server = SocketServer.TCPServer(('', 8000), RequestHandler) server.serve_forever() From effbot@users.sourceforge.net Wed Jul 11 18:42:23 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Wed, 11 Jul 2001 10:42:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib xmlrpclib.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv11351/Lib Added Files: xmlrpclib.py Log Message: xmlrpclib for python 2.2; initial checkin --- NEW FILE: xmlrpclib.py --- # # XML-RPC CLIENT LIBRARY # $Id: xmlrpclib.py,v 1.1 2001/07/11 17:42:21 effbot Exp $ # # an XML-RPC client interface for Python. # # the marshalling and response parser code can also be used to # implement XML-RPC servers. # # Notes: # this version is designed to work with Python 1.5.2 or newer. # unicode encoding support requires at least Python 1.6. # experimental HTTPS requires Python 2.0 built with SSL sockets. # expat parser support requires Python 2.0 with pyexpat support. # # History: # 1999-01-14 fl Created # 1999-01-15 fl Changed dateTime to use localtime # 1999-01-16 fl Added Binary/base64 element, default to RPC2 service # 1999-01-19 fl Fixed array data element (from Skip Montanaro) # 1999-01-21 fl Fixed dateTime constructor, etc. # 1999-02-02 fl Added fault handling, handle empty sequences, etc. # 1999-02-10 fl Fixed problem with empty responses (from Skip Montanaro) # 1999-06-20 fl Speed improvements, pluggable parsers/transports (0.9.8) # 2000-11-28 fl Changed boolean to check the truth value of its argument # 2001-02-24 fl Added encoding/Unicode/SafeTransport patches # 2001-02-26 fl Added compare support to wrappers (0.9.9/1.0b1) # 2001-03-28 fl Make sure response tuple is a singleton # 2001-03-29 fl Don't require empty params element (from Nicholas Riley) # 2001-06-10 fl Folded in _xmlrpclib accelerator support # # Copyright (c) 1999-2001 by Secret Labs AB. # Copyright (c) 1999-2001 by Fredrik Lundh. # # info@pythonware.com # http://www.pythonware.com # # -------------------------------------------------------------------- # The XML-RPC client interface is # # Copyright (c) 1999-2001 by Secret Labs AB # Copyright (c) 1999-2001 by Fredrik Lundh # # By obtaining, using, and/or copying this software and/or its # associated documentation, you agree that you have read, understood, # and will comply with the following terms and conditions: # # Permission to use, copy, modify, and distribute this software and # its associated documentation for any purpose and without fee is # hereby granted, provided that the above copyright notice appears in # all copies, and that both that copyright notice and this permission # notice appear in supporting documentation, and that the name of # Secret Labs AB or the author not be used in advertising or publicity # pertaining to distribution of the software without specific, written # prior permission. # # SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD # TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- # ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR # 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. # -------------------------------------------------------------------- # # things to look into before 1.0 final: # TODO: unicode marshalling -DONE # TODO: ascii-compatible encoding support -DONE # TODO: safe transport -DONE (but mostly untested) # TODO: sgmlop memory leak -DONE # TODO: sgmlop xml parsing -DONE # TODO: support unicode method names -DONE # TODO: update selftest -DONE # TODO: add docstrings -DONE # TODO: clean up parser encoding (trust the parser) -DONE # TODO: expat support -DONE # TODO: _xmlrpclib accelerator support -DONE # TODO: use smarter/faster escape from effdom # TODO: support basic authentication (see robin's patch) # TODO: fix host tuple handling in the server constructor # TODO: let transport verify schemes # TODO: update documentation # TODO: authentication plugins # TODO: memo problem (see HP's mail) import re, string, time, operator import urllib, xmllib from types import * from cgi import escape try: unicode except NameError: unicode = None # unicode support not available def _decode(data, encoding, is8bit=re.compile("[\x80-\xff]").search): # decode non-ascii string (if possible) if unicode and encoding and is8bit(data): data = unicode(data, encoding) return data if unicode: def _stringify(string): # convert to 7-bit ascii if possible try: return str(string) except UnicodeError: return string else: def _stringify(string): return string __version__ = "1.0b2" # -------------------------------------------------------------------- # Exceptions class Error: # base class for client errors pass class ProtocolError(Error): # indicates an HTTP protocol error def __init__(self, url, errcode, errmsg, headers): self.url = url self.errcode = errcode self.errmsg = errmsg self.headers = headers def __repr__(self): return ( "" % (self.url, self.errcode, self.errmsg) ) class ResponseError(Error): # indicates a broken response package pass class Fault(Error): # indicates a XML-RPC fault package def __init__(self, faultCode, faultString, **extra): self.faultCode = faultCode self.faultString = faultString def __repr__(self): return ( "" % (self.faultCode, repr(self.faultString)) ) # -------------------------------------------------------------------- # Special values # boolean wrapper # use True or False to generate a "boolean" XML-RPC value class Boolean: 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) def boolean(value, truefalse=(False, True)): # convert any Python value to XML-RPC boolean return truefalse[operator.truth(value)] # # dateTime wrapper # wrap your iso8601 string or time tuple or localtime integer value # in this class to generate a "dateTime.iso8601" XML-RPC value class DateTime: def __init__(self, value=0): t = type(value) if not isinstance(t, StringType): if not isinstance(t, TupleType): if value == 0: value = time.time() value = time.localtime(value) value = time.strftime("%Y%m%dT%H:%M:%S", value) self.value = value def __cmp__(self, other): if isinstance(other, DateTime): other = other.value return cmp(self.value, other) def __repr__(self): return "" % (self.value, id(self)) def decode(self, data): self.value = string.strip(data) def encode(self, out): out.write("") out.write(self.value) out.write("\n") def datetime(data): value = DateTime() value.decode(data) return value # # binary data wrapper class Binary: def __init__(self, data=None): self.data = data def __cmp__(self, other): if isinstance(other, Binary): other = other.data return cmp(self.data, other) def decode(self, data): import base64 self.data = base64.decodestring(data) def encode(self, out): import base64, StringIO out.write("\n") base64.encode(StringIO.StringIO(self.data), out) out.write("\n") def binary(data): value = Binary() value.decode(data) return value WRAPPERS = DateTime, Binary, Boolean # -------------------------------------------------------------------- # XML parsers try: # optional xmlrpclib accelerator. for more information on this # component, contact info@pythonware.com import _xmlrpclib FastParser = _xmlrpclib.Parser FastUnmarshaller = _xmlrpclib.Unmarshaller except (AttributeError, ImportError): FastParser = FastUnmarshaller = None # # the SGMLOP parser is about 15x faster than Python's builtin # XML parser. SGMLOP sources can be downloaded from: # # http://www.pythonware.com/products/xml/sgmlop.htm # try: import sgmlop if not hasattr(sgmlop, "XMLParser"): raise ImportError except ImportError: SgmlopParser = None # sgmlop accelerator not available else: class SgmlopParser: def __init__(self, target): # setup callbacks self.finish_starttag = target.start self.finish_endtag = target.end self.handle_data = target.data self.handle_xml = target.xml # activate parser self.parser = sgmlop.XMLParser() self.parser.register(self) self.feed = self.parser.feed self.entity = { "amp": "&", "gt": ">", "lt": "<", "apos": "'", "quot": '"' } def close(self): try: self.parser.close() finally: self.parser = self.feed = None # nuke circular reference def handle_proc(self, tag, attr): m = re.search("encoding\s*=\s*['\"]([^\"']+)[\"']", attr) if m: self.handle_xml(m.group(1), 1) def handle_entityref(self, entity): # entity try: self.handle_data(self.entity[entity]) except KeyError: self.handle_data("&%s;" % entity) try: from xml.parsers import expat except ImportError: ExpatParser = None else: class ExpatParser: # fast expat parser for Python 2.0. this is about 50% # slower than sgmlop, on roundtrip testing def __init__(self, target): self._parser = parser = expat.ParserCreate(None, None) self._target = target parser.StartElementHandler = target.start parser.EndElementHandler = target.end parser.CharacterDataHandler = target.data encoding = None if not parser.returns_unicode: encoding = "utf-8" target.xml(encoding, None) def feed(self, data): self._parser.Parse(data, 0) def close(self): self._parser.Parse("", 1) # end of data del self._target, self._parser # get rid of circular references class SlowParser(xmllib.XMLParser): # slow but safe standard parser, based on the XML parser in # Python's standard library. this is about 10 times slower # than sgmlop, on roundtrip testing. def __init__(self, target): self.handle_xml = target.xml self.unknown_starttag = target.start self.handle_data = target.data self.unknown_endtag = target.end xmllib.XMLParser.__init__(self) # -------------------------------------------------------------------- # XML-RPC marshalling and unmarshalling code class Marshaller: """Generate an XML-RPC params chunk from a Python data structure""" # USAGE: create a marshaller instance for each set of parameters, # and use "dumps" to convert your data (represented as a tuple) to # a XML-RPC params chunk. to write a fault response, pass a Fault # instance instead. you may prefer to use the "dumps" convenience # function for this purpose (see below). # by the way, if you don't understand what's going on in here, # that's perfectly ok. def __init__(self, encoding=None): self.memo = {} self.data = None self.encoding = encoding dispatch = {} def dumps(self, values): self.__out = [] self.write = write = self.__out.append if isinstance(values, Fault): # fault instance write("\n") self.__dump(vars(values)) write("\n") else: # parameter block write("\n") for v in values: write("\n") self.__dump(v) write("\n") write("\n") result = string.join(self.__out, "") del self.__out, self.write # don't need this any more return result def __dump(self, value): try: f = self.dispatch[type(value)] except KeyError: raise TypeError, "cannot marshal %s objects" % type(value) else: f(self, value) def dump_int(self, value): self.write("%s\n" % value) dispatch[IntType] = dump_int def dump_double(self, value): self.write("%s\n" % value) dispatch[FloatType] = dump_double def dump_string(self, value): self.write("%s\n" % escape(value)) dispatch[StringType] = dump_string if unicode: def dump_unicode(self, value): value = value.encode(self.encoding) self.write("%s\n" % escape(value)) dispatch[UnicodeType] = dump_unicode def container(self, value): if value: i = id(value) if self.memo.has_key(i): raise TypeError, "cannot marshal recursive data structures" self.memo[i] = None def dump_array(self, value): self.container(value) write = self.write write("\n") for v in value: self.__dump(v) write("\n") dispatch[TupleType] = dump_array dispatch[ListType] = dump_array def dump_struct(self, value): self.container(value) write = self.write write("\n") for k, v in value.items(): write("\n") if type(k) is not StringType: raise TypeError, "dictionary key must be string" write("%s\n" % escape(k)) self.__dump(v) write("\n") write("\n") dispatch[DictType] = dump_struct def dump_instance(self, value): # check for special wrappers if value.__class__ in WRAPPERS: value.encode(self) else: # store instance attributes as a struct (really?) self.dump_struct(value.__dict__) dispatch[InstanceType] = dump_instance class Unmarshaller: # unmarshal an XML-RPC response, based on incoming XML event # messages (start, data, end). call close to get the resulting # data structure # note that this reader is fairly tolerant, and gladly accepts # bogus XML-RPC data without complaining (but not bogus XML). # and again, if you don't understand what's going on in here, # that's perfectly ok. def __init__(self): self._type = None self._stack = [] self._marks = [] self._data = [] self._methodname = None self._encoding = "utf-8" self.append = self._stack.append def close(self): # return response tuple and target method if self._type is None or self._marks: raise ResponseError() if self._type == "fault": raise apply(Fault, (), self._stack[0]) return tuple(self._stack) def getmethodname(self): return self._methodname # # event handlers def xml(self, encoding, standalone): self._encoding = encoding # FIXME: assert standalone == 1 ??? def start(self, tag, attrs): # prepare to handle this element if tag == "array" or tag == "struct": self._marks.append(len(self._stack)) self._data = [] self._value = (tag == "value") def data(self, text): self._data.append(text) def end(self, tag): # call the appropriate end tag handler try: f = self.dispatch[tag] except KeyError: pass # unknown tag ? else: return f(self, self._data) # # accelerator support def end_dispatch(self, tag, data): # dispatch data try: f = self.dispatch[tag] except KeyError: pass # unknown tag ? else: return f(self, data) # # element decoders dispatch = {} def end_boolean(self, data, join=string.join): data = join(data, "") if data == "0": self.append(False) elif data == "1": self.append(True) else: raise TypeError, "bad boolean value" self._value = 0 dispatch["boolean"] = end_boolean def end_int(self, data, join=string.join): self.append(int(join(data, ""))) self._value = 0 dispatch["i4"] = end_int dispatch["int"] = end_int def end_double(self, data, join=string.join): self.append(float(join(data, ""))) self._value = 0 dispatch["double"] = end_double def end_string(self, data, join=string.join): data = join(data, "") if self._encoding: data = _decode(data, self._encoding) self.append(_stringify(data)) self._value = 0 dispatch["string"] = end_string dispatch["name"] = end_string # struct keys are always strings def end_array(self, data): mark = self._marks[-1] del self._marks[-1] # map arrays to Python lists self._stack[mark:] = [self._stack[mark:]] self._value = 0 dispatch["array"] = end_array def end_struct(self, data): mark = self._marks[-1] del self._marks[-1] # map structs to Python dictionaries dict = {} items = self._stack[mark:] for i in range(0, len(items), 2): dict[_stringify(items[i])] = items[i+1] self._stack[mark:] = [dict] self._value = 0 dispatch["struct"] = end_struct def end_base64(self, data, join=string.join): value = Binary() value.decode(join(data, "")) self.append(value) self._value = 0 dispatch["base64"] = end_base64 def end_dateTime(self, data, join=string.join): value = DateTime() value.decode(join(data, "")) self.append(value) dispatch["dateTime.iso8601"] = end_dateTime def end_value(self, data): # if we stumble upon an value element with no internal # elements, treat it as a string element if self._value: self.end_string(data) dispatch["value"] = end_value def end_params(self, data): self._type = "params" dispatch["params"] = end_params def end_fault(self, data): self._type = "fault" dispatch["fault"] = end_fault def end_methodName(self, data, join=string.join): data = join(data, "") if self._encoding: data = _decode(data, self._encoding) self._methodname = data self._type = "methodName" # no params dispatch["methodName"] = end_methodName # -------------------------------------------------------------------- # convenience functions def getparser(): """getparser() -> parser, unmarshaller Create an instance of the fastest available parser, and attach it to an unmarshalling object. Return both objects. """ if FastParser and FastUnmarshaller: target = FastUnmarshaller(True, False, binary, datetime) parser = FastParser(target) else: target = Unmarshaller() if FastParser: parser = FastParser(target) elif SgmlopParser: parser = SgmlopParser(target) elif ExpatParser: parser = ExpatParser(target) else: parser = SlowParser(target) return parser, target def dumps(params, methodname=None, methodresponse=None, encoding=None): """data [,options] -> marshalled data Convert an argument tuple or a Fault instance to an XML-RPC request (or response, if the methodresponse option is used). In addition to the data object, the following options can be given as keyword arguments: methodname: the method name for a methodCall packet methodresponse: true to create a methodResponse packet. If this option is used with a tuple, the tuple must be a singleton (i.e. it can contain only one element). encoding: the packet encoding (default is UTF-8) All 8-bit strings in the data structure are assumed to use the packet encoding. Unicode strings are automatically converted, as necessary. """ assert isinstance(params, TupleType) or isinstance(params, Fault),\ "argument must be tuple or Fault instance" if isinstance(params, Fault): methodresponse = 1 elif methodresponse and isinstance(params, TupleType): assert len(params) == 1, "response tuple must be a singleton" if not encoding: encoding = "utf-8" m = Marshaller(encoding) data = m.dumps(params) if encoding != "utf-8": xmlheader = "\n" % repr(encoding) else: xmlheader = "\n" # utf-8 is default # standard XML-RPC wrappings if methodname: # a method call if not isinstance(methodname, StringType): methodname = methodname.encode(encoding) data = ( xmlheader, "\n" "", methodname, "\n", data, "\n" ) elif methodresponse: # a method response, or a fault structure data = ( xmlheader, "\n", data, "\n" ) else: return data # return as is return string.join(data, "") def loads(data): """data -> unmarshalled data, method name Convert an XML-RPC packet to unmarshalled data plus a method name (None if not present). If the XML-RPC packet represents a fault condition, this function raises a Fault exception. """ p, u = getparser() p.feed(data) p.close() return u.close(), u.getmethodname() # -------------------------------------------------------------------- # request dispatcher class _Method: # some magic to bind an XML-RPC method to an RPC server. # supports "nested" methods (e.g. examples.getStateName) def __init__(self, send, name): self.__send = send self.__name = name def __getattr__(self, name): return _Method(self.__send, "%s.%s" % (self.__name, name)) def __call__(self, *args): return self.__send(self.__name, args) class Transport: """Handles an HTTP transaction to an XML-RPC server""" # client identifier (may be overridden) user_agent = "xmlrpclib.py/%s (by www.pythonware.com)" % __version__ def request(self, host, handler, request_body, verbose=0): # issue XML-RPC request h = self.make_connection(host) if verbose: h.set_debuglevel(1) self.send_request(h, handler, request_body) self.send_host(h, host) self.send_user_agent(h) self.send_content(h, request_body) errcode, errmsg, headers = h.getreply() if errcode != 200: raise ProtocolError( host + handler, errcode, errmsg, headers ) self.verbose = verbose return self.parse_response(h.getfile()) def make_connection(self, host): # create a HTTP connection object from a host descriptor import httplib return httplib.HTTP(host) def send_request(self, connection, handler, request_body): connection.putrequest("POST", handler) def send_host(self, connection, host): connection.putheader("Host", host) def send_user_agent(self, connection): connection.putheader("User-Agent", self.user_agent) def send_content(self, connection, request_body): connection.putheader("Content-Type", "text/xml") connection.putheader("Content-Length", str(len(request_body))) connection.endheaders() if request_body: connection.send(request_body) def parse_response(self, f): # read response from input file, and parse it p, u = getparser() while 1: response = f.read(1024) if not response: break if self.verbose: print "body:", repr(response) p.feed(response) f.close() p.close() return u.close() class SafeTransport(Transport): """Handles an HTTPS transaction to an XML-RPC server""" def make_connection(self, host): # create a HTTPS connection object from a host descriptor # host may be a string, or a (host, x509-dict) tuple import httplib if isinstance(host, TupleType): host, x509 = host else: x509 = {} try: HTTPS = httplib.HTTPS except AttributeError: raise NotImplementedError,\ "your version of httplib doesn't support HTTPS" else: return apply(HTTPS, (host, None), x509) def send_host(self, connection, host): if isinstance(host, TupleType): host, x509 = host connection.putheader("Host", host) class ServerProxy: """uri [,options] -> a logical connection to an XML-RPC server uri is the connection point on the server, given as scheme://host/target. The standard implementation always supports the "http" scheme. If SSL socket support is available (Python 2.0), it also supports "https". If the target part and the slash preceding it are both omitted, "/RPC2" is assumed. The following options can be given as keyword arguments: transport: a transport factory encoding: the request encoding (default is UTF-8) All 8-bit strings passed to the server proxy are assumed to use the given encoding. """ def __init__(self, uri, transport=None, encoding=None, verbose=0): # establish a "logical" server connection # get the url type, uri = urllib.splittype(uri) if type not in ("http", "https"): raise IOError, "unsupported XML-RPC protocol" self.__host, self.__handler = urllib.splithost(uri) if not self.__handler: self.__handler = "/RPC2" if transport is None: if type == "https": transport = SafeTransport() else: transport = Transport() self.__transport = transport self.__encoding = encoding self.__verbose = verbose def __request(self, methodname, params): # call a method on the remote server request = dumps(params, methodname, encoding=self.__encoding) response = self.__transport.request( self.__host, self.__handler, request, verbose=self.__verbose ) if len(response) == 1: response = response[0] return response def __repr__(self): return ( "" % (self.__host, self.__handler) ) __str__ = __repr__ def __getattr__(self, name): # magic method dispatcher return _Method(self.__request, name) # note: to call a remote object with an non-standard name, use # result getattr(server, "strange-python-name")(args) Server = ServerProxy # -------------------------------------------------------------------- # test code if __name__ == "__main__": # simple test program (from the XML-RPC specification) # server = Server("http://localhost:8000") # local server server = Server("http://betty.userland.com") print server try: print server.examples.getStateName(41) except Error, v: print "ERROR", v From fdrake@users.sourceforge.net Wed Jul 11 19:48:41 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 11 Jul 2001 11:48:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libselect.tex,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv24920/lib Modified Files: libselect.tex Log Message: Added information about the timeout parameter to the poll() method for polling objects. This closes SF bug #439823. Fixed a minor markup bug. Index: libselect.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libselect.tex,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -r1.17 -r1.18 *** libselect.tex 2000/12/11 15:50:07 1.17 --- libselect.tex 2001/07/11 18:48:39 1.18 *************** *** 92,96 **** used will check for all 3 types of events. ! \begin{tableii}{l|l}{code}{Constant}{Meaning} \lineii{POLLIN}{There is data to read} \lineii{POLLPRI}{There is urgent data to read} --- 92,96 ---- used will check for all 3 types of events. ! \begin{tableii}{l|l}{constant}{Constant}{Meaning} \lineii{POLLIN}{There is data to read} \lineii{POLLPRI}{There is urgent data to read} *************** *** 127,130 **** --- 127,134 ---- An empty list indicates that the call timed out and no file descriptors had any events to report. + If \var{timeout} is given, it specifies the length of time in + milliseconds which the system will wait for events before returning. + If \var{timeout} is omitted, negative, or \code{None}, the call will + block until there is an event for this poll object. \end{methoddesc} From fdrake@users.sourceforge.net Wed Jul 11 19:49:02 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 11 Jul 2001 11:49:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libselect.tex,1.17,1.17.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv24997/lib Modified Files: Tag: release21-maint libselect.tex Log Message: Added information about the timeout parameter to the poll() method for polling objects. This closes SF bug #439823. Fixed a minor markup bug. Index: libselect.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libselect.tex,v retrieving revision 1.17 retrieving revision 1.17.4.1 diff -C2 -r1.17 -r1.17.4.1 *** libselect.tex 2000/12/11 15:50:07 1.17 --- libselect.tex 2001/07/11 18:49:00 1.17.4.1 *************** *** 92,96 **** used will check for all 3 types of events. ! \begin{tableii}{l|l}{code}{Constant}{Meaning} \lineii{POLLIN}{There is data to read} \lineii{POLLPRI}{There is urgent data to read} --- 92,96 ---- used will check for all 3 types of events. ! \begin{tableii}{l|l}{constant}{Constant}{Meaning} \lineii{POLLIN}{There is data to read} \lineii{POLLPRI}{There is urgent data to read} *************** *** 127,130 **** --- 127,134 ---- An empty list indicates that the call timed out and no file descriptors had any events to report. + If \var{timeout} is given, it specifies the length of time in + milliseconds which the system will wait for events before returning. + If \var{timeout} is omitted, negative, or \code{None}, the call will + block until there is an event for this poll object. \end{methoddesc} From gvanrossum@users.sourceforge.net Wed Jul 11 20:09:30 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 11 Jul 2001 12:09:30 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0253.txt,1.10,1.11 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv29387 Modified Files: pep-0253.txt Log Message: Added a section on multiple inheritance. Index: pep-0253.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0253.txt,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -r1.10 -r1.11 *** pep-0253.txt 2001/07/10 20:46:24 1.10 --- pep-0253.txt 2001/07/11 19:09:28 1.11 *************** *** 283,287 **** subsystem if the type supports garbage collection. This slot exists so that derived types can override the memory allocation ! policy (e.g. which heap is being used) separately from the initialization code. The signature is: --- 283,287 ---- subsystem if the type supports garbage collection. This slot exists so that derived types can override the memory allocation ! policy (like which heap is being used) separately from the initialization code. The signature is: *************** *** 369,375 **** unregister the object with the garbage collection subsystem, and can be overridden by a derived class; tp_dealloc() should ! deinitialize the object (e.g. by calling Py_XDECREF() for various ! sub-objects) and then call tp_free() to deallocate the memory. ! The signature for tp_dealloc() is the same as it always was: void tp_dealloc(PyObject *object) --- 369,376 ---- unregister the object with the garbage collection subsystem, and can be overridden by a derived class; tp_dealloc() should ! deinitialize the object (usually by calling Py_XDECREF() for ! various sub-objects) and then call tp_free() to deallocate the ! memory. The signature for tp_dealloc() is the same as it always ! was: void tp_dealloc(PyObject *object) *************** *** 637,640 **** --- 638,729 ---- + Multiple Inheritance + + The Python class statement supports multiple inheritance, and we + will also support multiple inheritance involving built-in types. + + However, there are some restrictions. The C runtime architecture + doesn't make it feasible to have a meaningful subtype of two + different built-in types except in a few degenerate cases. + Changing the C runtime to support fully general multiple + inheritance would be too much of an upheaval of the code base. + + The main problem with multiple inheritance from different built-in + types stems from the fact that the C implementation of built-in + types accesses structure members directly; the C compiler + generates an offset relative to the object pointer and that's + that. For example, the list and dictionary type structures each + declare a number of different but overlapping structure members. + A C function accessing an object expecting a list won't work when + passed a dictionary, and vice versa, and there's not much we could + do about this without rewriting all code that accesses lists and + dictionaries. This would be too much work, so we won't do this. + + The problem with multiple inheritance is caused by conflicting + structure member allocations. Classes defined in Python normally + don't store their instance variables in structure members: they + are stored in an instance dictionary. This is the key to a + partial solution. Suppose we have the following two classes: + + class A(dictionary): + def foo(self): pass + + class B(dictionary): + def bar(self): pass + + class C(A, B): pass + + (Here, 'dictionary' is the type of built-in dictionary objects, + a.k.a. type({}) or {}.__class__ or types.DictType.) If we look at + the structure lay-out, we find that an A instance has the lay-out + of a dictionary followed by the __dict__ pointer, and a B instance + has the same lay-out; since there are no structure member lay-out + conflicts, this is okay. + + Here's another example: + + class X(object): + def foo(self): pass + + class Y(dictionary): + def bar(self): pass + + class Z(X, Y): pass + + (Here, 'object' is the base for all built-in types; its structure + lay-out only contains the ob_refcnt and ob_type members.) This + example is more complicated, because the __dict__ pointer for X + instances has a different offset than that for Y instances. Where + is the __dict__ pointer for Z instances? The answer is that the + offset for the __dict__ pointer is not hardcoded, it is stored in + the type object. + + Suppose on a particular machine an 'object' structure is 8 bytes + long, and a 'dictionary' struct is 60 bytes, and an object pointer + is 4 bytes. Then an X structure is 12 bytes (an object structure + followed by a __dict__ pointer), and a Y structure is 64 bytes (a + dictionary structure followed by a __dict__ pointer). The Z + structure has the same lay-out as the Y structure in this example. + Each type object (X, Y and Z) has a "__dict__ offset" which is + used to find the __dict__ pointer. Thus, the recipe for looking + up an instance variable is: + + 1. get the type of the instance + 2. get the __dict__ offset from the type object + 3. add the __dict__ offset to the instance pointer + 4. look in the resulting address to find a dictionary reference + 5. look up the instance variable name in that dictionary + + Of course, this recipe can only be implemented in C, and I have + left out some details. But this allows us to use multiple + inheritance patterns similar to the ones we can use with classic + classes. + + XXX I should write up the complete algorithm here to determine + base class compatibility, but I can't be bothered right now. Look + at best_base() in typeobject.c in the implementation mentioned + below. + + XXX To be done *************** *** 644,658 **** - mapping between type object slots (tp_foo) and special methods ! (__foo__) - built-in names for built-in types (object, int, str, list etc.) ! - multiple inheritance restrictions - __slots__ - the HEAPTYPE and DYNAMICTYPE flag bits - API docs for all the new functions --- 733,753 ---- - mapping between type object slots (tp_foo) and special methods ! (__foo__) (actually, this may belong in PEP 252) - built-in names for built-in types (object, int, str, list etc.) ! - method resolution order + - __dict__ + - __slots__ - the HEAPTYPE and DYNAMICTYPE flag bits + - GC support + - API docs for all the new functions + + - high level user overview From fdrake@users.sourceforge.net Wed Jul 11 21:35:39 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 11 Jul 2001 13:35:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.129,1.130 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv16230/api Modified Files: api.tex Log Message: Move the section on concrete numeric objects before the section on concrete sequence objects, since their API is simpler. This is in response to a comment in SF bug #440037. Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.129 retrieving revision 1.130 diff -C2 -r1.129 -r1.130 *** api.tex 2001/07/10 16:10:08 1.129 --- api.tex 2001/07/11 20:35:37 1.130 *************** *** 2219,2222 **** --- 2219,2471 ---- + \section{Numeric Objects \label{numericObjects}} + + \obindex{numeric} + + + \subsection{Plain Integer Objects \label{intObjects}} + + \obindex{integer} + \begin{ctypedesc}{PyIntObject} + This subtype of \ctype{PyObject} represents a Python integer object. + \end{ctypedesc} + + \begin{cvardesc}{PyTypeObject}{PyInt_Type} + This instance of \ctype{PyTypeObject} represents the Python plain + integer type. This is the same object as \code{types.IntType}. + \withsubitem{(in modules types)}{\ttindex{IntType}} + \end{cvardesc} + + \begin{cfuncdesc}{int}{PyInt_Check}{PyObject* o} + Returns true if \var{o} is of type \cdata{PyInt_Type}. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyInt_FromLong}{long ival} + Creates a new integer object with a value of \var{ival}. + + The current implementation keeps an array of integer objects for all + integers between \code{-1} and \code{100}, when you create an int in + that range you actually just get back a reference to the existing + object. So it should be possible to change the value of \code{1}. I + suspect the behaviour of Python in this case is undefined. :-) + \end{cfuncdesc} + + \begin{cfuncdesc}{long}{PyInt_AsLong}{PyObject *io} + Will first attempt to cast the object to a \ctype{PyIntObject}, if + it is not already one, and then return its value. + \end{cfuncdesc} + + \begin{cfuncdesc}{long}{PyInt_AS_LONG}{PyObject *io} + Returns the value of the object \var{io}. No error checking is + performed. + \end{cfuncdesc} + + \begin{cfuncdesc}{long}{PyInt_GetMax}{} + Returns the system's idea of the largest integer it can handle + (\constant{LONG_MAX}\ttindex{LONG_MAX}, as defined in the system + header files). + \end{cfuncdesc} + + + \subsection{Long Integer Objects \label{longObjects}} + + \obindex{long integer} + \begin{ctypedesc}{PyLongObject} + This subtype of \ctype{PyObject} represents a Python long integer + object. + \end{ctypedesc} + + \begin{cvardesc}{PyTypeObject}{PyLong_Type} + This instance of \ctype{PyTypeObject} represents the Python long + integer type. This is the same object as \code{types.LongType}. + \withsubitem{(in modules types)}{\ttindex{LongType}} + \end{cvardesc} + + \begin{cfuncdesc}{int}{PyLong_Check}{PyObject *p} + Returns true if its argument is a \ctype{PyLongObject}. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyLong_FromLong}{long v} + Returns a new \ctype{PyLongObject} object from \var{v}, or \NULL{} on + failure. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyLong_FromUnsignedLong}{unsigned long v} + Returns a new \ctype{PyLongObject} object from a C \ctype{unsigned + long}, or \NULL{} on failure. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyLong_FromDouble}{double v} + Returns a new \ctype{PyLongObject} object from the integer part of + \var{v}, or \NULL{} on failure. + \end{cfuncdesc} + + \begin{cfuncdesc}{long}{PyLong_AsLong}{PyObject *pylong} + Returns a C \ctype{long} representation of the contents of + \var{pylong}. If \var{pylong} is greater than + \constant{LONG_MAX}\ttindex{LONG_MAX}, an \exception{OverflowError} is + raised.\withsubitem{(built-in exception)}{\ttindex{OverflowError}} + \end{cfuncdesc} + + \begin{cfuncdesc}{unsigned long}{PyLong_AsUnsignedLong}{PyObject *pylong} + Returns a C \ctype{unsigned long} representation of the contents of + \var{pylong}. If \var{pylong} is greater than + \constant{ULONG_MAX}\ttindex{ULONG_MAX}, an \exception{OverflowError} + is raised.\withsubitem{(built-in exception)}{\ttindex{OverflowError}} + \end{cfuncdesc} + + \begin{cfuncdesc}{double}{PyLong_AsDouble}{PyObject *pylong} + Returns a C \ctype{double} representation of the contents of \var{pylong}. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyLong_FromString}{char *str, char **pend, + int base} + Return a new \ctype{PyLongObject} based on the string value in + \var{str}, which is interpreted according to the radix in \var{base}. + If \var{pend} is non-\NULL, \code{*\var{pend}} will point to the first + character in \var{str} which follows the representation of the + number. If \var{base} is \code{0}, the radix will be determined base + on the leading characters of \var{str}: if \var{str} starts with + \code{'0x'} or \code{'0X'}, radix 16 will be used; if \var{str} starts + with \code{'0'}, radix 8 will be used; otherwise radix 10 will be + used. If \var{base} is not \code{0}, it must be between \code{2} and + \code{36}, inclusive. Leading spaces are ignored. If there are no + digits, \exception{ValueError} will be raised. + \end{cfuncdesc} + + + \subsection{Floating Point Objects \label{floatObjects}} + + \obindex{floating point} + \begin{ctypedesc}{PyFloatObject} + This subtype of \ctype{PyObject} represents a Python floating point + object. + \end{ctypedesc} + + \begin{cvardesc}{PyTypeObject}{PyFloat_Type} + This instance of \ctype{PyTypeObject} represents the Python floating + point type. This is the same object as \code{types.FloatType}. + \withsubitem{(in modules types)}{\ttindex{FloatType}} + \end{cvardesc} + + \begin{cfuncdesc}{int}{PyFloat_Check}{PyObject *p} + Returns true if its argument is a \ctype{PyFloatObject}. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyFloat_FromDouble}{double v} + Creates a \ctype{PyFloatObject} object from \var{v}, or \NULL{} on + failure. + \end{cfuncdesc} + + \begin{cfuncdesc}{double}{PyFloat_AsDouble}{PyObject *pyfloat} + Returns a C \ctype{double} representation of the contents of \var{pyfloat}. + \end{cfuncdesc} + + \begin{cfuncdesc}{double}{PyFloat_AS_DOUBLE}{PyObject *pyfloat} + Returns a C \ctype{double} representation of the contents of + \var{pyfloat}, but without error checking. + \end{cfuncdesc} + + + \subsection{Complex Number Objects \label{complexObjects}} + + \obindex{complex number} + Python's complex number objects are implemented as two distinct types + when viewed from the C API: one is the Python object exposed to + Python programs, and the other is a C structure which represents the + actual complex number value. The API provides functions for working + with both. + + \subsubsection{Complex Numbers as C Structures} + + Note that the functions which accept these structures as parameters + and return them as results do so \emph{by value} rather than + dereferencing them through pointers. This is consistent throughout + the API. + + \begin{ctypedesc}{Py_complex} + The C structure which corresponds to the value portion of a Python + complex number object. Most of the functions for dealing with complex + number objects use structures of this type as input or output values, + as appropriate. It is defined as: + + \begin{verbatim} + typedef struct { + double real; + double imag; + } Py_complex; + \end{verbatim} + \end{ctypedesc} + + \begin{cfuncdesc}{Py_complex}{_Py_c_sum}{Py_complex left, Py_complex right} + Return the sum of two complex numbers, using the C + \ctype{Py_complex} representation. + \end{cfuncdesc} + + \begin{cfuncdesc}{Py_complex}{_Py_c_diff}{Py_complex left, Py_complex right} + Return the difference between two complex numbers, using the C + \ctype{Py_complex} representation. + \end{cfuncdesc} + + \begin{cfuncdesc}{Py_complex}{_Py_c_neg}{Py_complex complex} + Return the negation of the complex number \var{complex}, using the C + \ctype{Py_complex} representation. + \end{cfuncdesc} + + \begin{cfuncdesc}{Py_complex}{_Py_c_prod}{Py_complex left, Py_complex right} + Return the product of two complex numbers, using the C + \ctype{Py_complex} representation. + \end{cfuncdesc} + + \begin{cfuncdesc}{Py_complex}{_Py_c_quot}{Py_complex dividend, + Py_complex divisor} + Return the quotient of two complex numbers, using the C + \ctype{Py_complex} representation. + \end{cfuncdesc} + + \begin{cfuncdesc}{Py_complex}{_Py_c_pow}{Py_complex num, Py_complex exp} + Return the exponentiation of \var{num} by \var{exp}, using the C + \ctype{Py_complex} representation. + \end{cfuncdesc} + + + \subsubsection{Complex Numbers as Python Objects} + + \begin{ctypedesc}{PyComplexObject} + This subtype of \ctype{PyObject} represents a Python complex number object. + \end{ctypedesc} + + \begin{cvardesc}{PyTypeObject}{PyComplex_Type} + This instance of \ctype{PyTypeObject} represents the Python complex + number type. + \end{cvardesc} + + \begin{cfuncdesc}{int}{PyComplex_Check}{PyObject *p} + Returns true if its argument is a \ctype{PyComplexObject}. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyComplex_FromCComplex}{Py_complex v} + Create a new Python complex number object from a C + \ctype{Py_complex} value. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyComplex_FromDoubles}{double real, double imag} + Returns a new \ctype{PyComplexObject} object from \var{real} and \var{imag}. + \end{cfuncdesc} + + \begin{cfuncdesc}{double}{PyComplex_RealAsDouble}{PyObject *op} + Returns the real part of \var{op} as a C \ctype{double}. + \end{cfuncdesc} + + \begin{cfuncdesc}{double}{PyComplex_ImagAsDouble}{PyObject *op} + Returns the imaginary part of \var{op} as a C \ctype{double}. + \end{cfuncdesc} + + \begin{cfuncdesc}{Py_complex}{PyComplex_AsCComplex}{PyObject *op} + Returns the \ctype{Py_complex} value of the complex number \var{op}. + \end{cfuncdesc} + + + \section{Sequence Objects \label{sequenceObjects}} *************** *** 3530,3782 **** \end{verbatim} \end{cfuncdesc} - - - \section{Numeric Objects \label{numericObjects}} - - \obindex{numeric} - - - \subsection{Plain Integer Objects \label{intObjects}} - - \obindex{integer} - \begin{ctypedesc}{PyIntObject} - This subtype of \ctype{PyObject} represents a Python integer object. - \end{ctypedesc} - - \begin{cvardesc}{PyTypeObject}{PyInt_Type} - This instance of \ctype{PyTypeObject} represents the Python plain - integer type. This is the same object as \code{types.IntType}. - \withsubitem{(in modules types)}{\ttindex{IntType}} - \end{cvardesc} - - \begin{cfuncdesc}{int}{PyInt_Check}{PyObject* o} - Returns true if \var{o} is of type \cdata{PyInt_Type}. - \end{cfuncdesc} - - \begin{cfuncdesc}{PyObject*}{PyInt_FromLong}{long ival} - Creates a new integer object with a value of \var{ival}. - - The current implementation keeps an array of integer objects for all - integers between \code{-1} and \code{100}, when you create an int in - that range you actually just get back a reference to the existing - object. So it should be possible to change the value of \code{1}. I - suspect the behaviour of Python in this case is undefined. :-) - \end{cfuncdesc} - - \begin{cfuncdesc}{long}{PyInt_AsLong}{PyObject *io} - Will first attempt to cast the object to a \ctype{PyIntObject}, if - it is not already one, and then return its value. - \end{cfuncdesc} - - \begin{cfuncdesc}{long}{PyInt_AS_LONG}{PyObject *io} - Returns the value of the object \var{io}. No error checking is - performed. - \end{cfuncdesc} - - \begin{cfuncdesc}{long}{PyInt_GetMax}{} - Returns the system's idea of the largest integer it can handle - (\constant{LONG_MAX}\ttindex{LONG_MAX}, as defined in the system - header files). - \end{cfuncdesc} - - - \subsection{Long Integer Objects \label{longObjects}} - - \obindex{long integer} - \begin{ctypedesc}{PyLongObject} - This subtype of \ctype{PyObject} represents a Python long integer - object. - \end{ctypedesc} - - \begin{cvardesc}{PyTypeObject}{PyLong_Type} - This instance of \ctype{PyTypeObject} represents the Python long - integer type. This is the same object as \code{types.LongType}. - \withsubitem{(in modules types)}{\ttindex{LongType}} - \end{cvardesc} - - \begin{cfuncdesc}{int}{PyLong_Check}{PyObject *p} - Returns true if its argument is a \ctype{PyLongObject}. - \end{cfuncdesc} - - \begin{cfuncdesc}{PyObject*}{PyLong_FromLong}{long v} - Returns a new \ctype{PyLongObject} object from \var{v}, or \NULL{} on - failure. - \end{cfuncdesc} - - \begin{cfuncdesc}{PyObject*}{PyLong_FromUnsignedLong}{unsigned long v} - Returns a new \ctype{PyLongObject} object from a C \ctype{unsigned - long}, or \NULL{} on failure. - \end{cfuncdesc} - - \begin{cfuncdesc}{PyObject*}{PyLong_FromDouble}{double v} - Returns a new \ctype{PyLongObject} object from the integer part of - \var{v}, or \NULL{} on failure. - \end{cfuncdesc} - - \begin{cfuncdesc}{long}{PyLong_AsLong}{PyObject *pylong} - Returns a C \ctype{long} representation of the contents of - \var{pylong}. If \var{pylong} is greater than - \constant{LONG_MAX}\ttindex{LONG_MAX}, an \exception{OverflowError} is - raised.\withsubitem{(built-in exception)}{\ttindex{OverflowError}} - \end{cfuncdesc} - - \begin{cfuncdesc}{unsigned long}{PyLong_AsUnsignedLong}{PyObject *pylong} - Returns a C \ctype{unsigned long} representation of the contents of - \var{pylong}. If \var{pylong} is greater than - \constant{ULONG_MAX}\ttindex{ULONG_MAX}, an \exception{OverflowError} - is raised.\withsubitem{(built-in exception)}{\ttindex{OverflowError}} - \end{cfuncdesc} - - \begin{cfuncdesc}{double}{PyLong_AsDouble}{PyObject *pylong} - Returns a C \ctype{double} representation of the contents of \var{pylong}. - \end{cfuncdesc} - - \begin{cfuncdesc}{PyObject*}{PyLong_FromString}{char *str, char **pend, - int base} - Return a new \ctype{PyLongObject} based on the string value in - \var{str}, which is interpreted according to the radix in \var{base}. - If \var{pend} is non-\NULL, \code{*\var{pend}} will point to the first - character in \var{str} which follows the representation of the - number. If \var{base} is \code{0}, the radix will be determined base - on the leading characters of \var{str}: if \var{str} starts with - \code{'0x'} or \code{'0X'}, radix 16 will be used; if \var{str} starts - with \code{'0'}, radix 8 will be used; otherwise radix 10 will be - used. If \var{base} is not \code{0}, it must be between \code{2} and - \code{36}, inclusive. Leading spaces are ignored. If there are no - digits, \exception{ValueError} will be raised. - \end{cfuncdesc} - - - \subsection{Floating Point Objects \label{floatObjects}} - - \obindex{floating point} - \begin{ctypedesc}{PyFloatObject} - This subtype of \ctype{PyObject} represents a Python floating point - object. - \end{ctypedesc} - - \begin{cvardesc}{PyTypeObject}{PyFloat_Type} - This instance of \ctype{PyTypeObject} represents the Python floating - point type. This is the same object as \code{types.FloatType}. - \withsubitem{(in modules types)}{\ttindex{FloatType}} - \end{cvardesc} - - \begin{cfuncdesc}{int}{PyFloat_Check}{PyObject *p} - Returns true if its argument is a \ctype{PyFloatObject}. - \end{cfuncdesc} - - \begin{cfuncdesc}{PyObject*}{PyFloat_FromDouble}{double v} - Creates a \ctype{PyFloatObject} object from \var{v}, or \NULL{} on - failure. - \end{cfuncdesc} - - \begin{cfuncdesc}{double}{PyFloat_AsDouble}{PyObject *pyfloat} - Returns a C \ctype{double} representation of the contents of \var{pyfloat}. - \end{cfuncdesc} - - \begin{cfuncdesc}{double}{PyFloat_AS_DOUBLE}{PyObject *pyfloat} - Returns a C \ctype{double} representation of the contents of - \var{pyfloat}, but without error checking. - \end{cfuncdesc} - - - \subsection{Complex Number Objects \label{complexObjects}} - - \obindex{complex number} - Python's complex number objects are implemented as two distinct types - when viewed from the C API: one is the Python object exposed to - Python programs, and the other is a C structure which represents the - actual complex number value. The API provides functions for working - with both. - - \subsubsection{Complex Numbers as C Structures} - - Note that the functions which accept these structures as parameters - and return them as results do so \emph{by value} rather than - dereferencing them through pointers. This is consistent throughout - the API. - - \begin{ctypedesc}{Py_complex} - The C structure which corresponds to the value portion of a Python - complex number object. Most of the functions for dealing with complex - number objects use structures of this type as input or output values, - as appropriate. It is defined as: - - \begin{verbatim} - typedef struct { - double real; - double imag; - } Py_complex; - \end{verbatim} - \end{ctypedesc} - - \begin{cfuncdesc}{Py_complex}{_Py_c_sum}{Py_complex left, Py_complex right} - Return the sum of two complex numbers, using the C - \ctype{Py_complex} representation. - \end{cfuncdesc} - - \begin{cfuncdesc}{Py_complex}{_Py_c_diff}{Py_complex left, Py_complex right} - Return the difference between two complex numbers, using the C - \ctype{Py_complex} representation. - \end{cfuncdesc} - - \begin{cfuncdesc}{Py_complex}{_Py_c_neg}{Py_complex complex} - Return the negation of the complex number \var{complex}, using the C - \ctype{Py_complex} representation. - \end{cfuncdesc} - - \begin{cfuncdesc}{Py_complex}{_Py_c_prod}{Py_complex left, Py_complex right} - Return the product of two complex numbers, using the C - \ctype{Py_complex} representation. - \end{cfuncdesc} - - \begin{cfuncdesc}{Py_complex}{_Py_c_quot}{Py_complex dividend, - Py_complex divisor} - Return the quotient of two complex numbers, using the C - \ctype{Py_complex} representation. - \end{cfuncdesc} - - \begin{cfuncdesc}{Py_complex}{_Py_c_pow}{Py_complex num, Py_complex exp} - Return the exponentiation of \var{num} by \var{exp}, using the C - \ctype{Py_complex} representation. - \end{cfuncdesc} - - - \subsubsection{Complex Numbers as Python Objects} - - \begin{ctypedesc}{PyComplexObject} - This subtype of \ctype{PyObject} represents a Python complex number object. - \end{ctypedesc} - - \begin{cvardesc}{PyTypeObject}{PyComplex_Type} - This instance of \ctype{PyTypeObject} represents the Python complex - number type. - \end{cvardesc} - - \begin{cfuncdesc}{int}{PyComplex_Check}{PyObject *p} - Returns true if its argument is a \ctype{PyComplexObject}. - \end{cfuncdesc} - - \begin{cfuncdesc}{PyObject*}{PyComplex_FromCComplex}{Py_complex v} - Create a new Python complex number object from a C - \ctype{Py_complex} value. - \end{cfuncdesc} - - \begin{cfuncdesc}{PyObject*}{PyComplex_FromDoubles}{double real, double imag} - Returns a new \ctype{PyComplexObject} object from \var{real} and \var{imag}. - \end{cfuncdesc} - - \begin{cfuncdesc}{double}{PyComplex_RealAsDouble}{PyObject *op} - Returns the real part of \var{op} as a C \ctype{double}. - \end{cfuncdesc} - - \begin{cfuncdesc}{double}{PyComplex_ImagAsDouble}{PyObject *op} - Returns the imaginary part of \var{op} as a C \ctype{double}. - \end{cfuncdesc} - - \begin{cfuncdesc}{Py_complex}{PyComplex_AsCComplex}{PyObject *op} - Returns the \ctype{Py_complex} value of the complex number \var{op}. - \end{cfuncdesc} - --- 3779,3782 ---- From fdrake@users.sourceforge.net Wed Jul 11 21:40:07 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 11 Jul 2001 13:40:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.117.2.8,1.117.2.9 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv17776/api Modified Files: Tag: release21-maint api.tex Log Message: Move the section on concrete numeric objects before the section on concrete sequence objects, since their API is simpler. This is in response to a comment in SF bug #440037. (Does this really belong in the bugfix release? Yes: this is a readability bug, and those are important in the documentation.) Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.117.2.8 retrieving revision 1.117.2.9 diff -C2 -r1.117.2.8 -r1.117.2.9 *** api.tex 2001/07/10 16:11:09 1.117.2.8 --- api.tex 2001/07/11 20:40:05 1.117.2.9 *************** *** 2179,2182 **** --- 2179,2431 ---- + \section{Numeric Objects \label{numericObjects}} + + \obindex{numeric} + + + \subsection{Plain Integer Objects \label{intObjects}} + + \obindex{integer} + \begin{ctypedesc}{PyIntObject} + This subtype of \ctype{PyObject} represents a Python integer object. + \end{ctypedesc} + + \begin{cvardesc}{PyTypeObject}{PyInt_Type} + This instance of \ctype{PyTypeObject} represents the Python plain + integer type. This is the same object as \code{types.IntType}. + \withsubitem{(in modules types)}{\ttindex{IntType}} + \end{cvardesc} + + \begin{cfuncdesc}{int}{PyInt_Check}{PyObject* o} + Returns true if \var{o} is of type \cdata{PyInt_Type}. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyInt_FromLong}{long ival} + Creates a new integer object with a value of \var{ival}. + + The current implementation keeps an array of integer objects for all + integers between \code{-1} and \code{100}, when you create an int in + that range you actually just get back a reference to the existing + object. So it should be possible to change the value of \code{1}. I + suspect the behaviour of Python in this case is undefined. :-) + \end{cfuncdesc} + + \begin{cfuncdesc}{long}{PyInt_AsLong}{PyObject *io} + Will first attempt to cast the object to a \ctype{PyIntObject}, if + it is not already one, and then return its value. + \end{cfuncdesc} + + \begin{cfuncdesc}{long}{PyInt_AS_LONG}{PyObject *io} + Returns the value of the object \var{io}. No error checking is + performed. + \end{cfuncdesc} + + \begin{cfuncdesc}{long}{PyInt_GetMax}{} + Returns the system's idea of the largest integer it can handle + (\constant{LONG_MAX}\ttindex{LONG_MAX}, as defined in the system + header files). + \end{cfuncdesc} + + + \subsection{Long Integer Objects \label{longObjects}} + + \obindex{long integer} + \begin{ctypedesc}{PyLongObject} + This subtype of \ctype{PyObject} represents a Python long integer + object. + \end{ctypedesc} + + \begin{cvardesc}{PyTypeObject}{PyLong_Type} + This instance of \ctype{PyTypeObject} represents the Python long + integer type. This is the same object as \code{types.LongType}. + \withsubitem{(in modules types)}{\ttindex{LongType}} + \end{cvardesc} + + \begin{cfuncdesc}{int}{PyLong_Check}{PyObject *p} + Returns true if its argument is a \ctype{PyLongObject}. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyLong_FromLong}{long v} + Returns a new \ctype{PyLongObject} object from \var{v}, or \NULL{} on + failure. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyLong_FromUnsignedLong}{unsigned long v} + Returns a new \ctype{PyLongObject} object from a C \ctype{unsigned + long}, or \NULL{} on failure. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyLong_FromDouble}{double v} + Returns a new \ctype{PyLongObject} object from the integer part of + \var{v}, or \NULL{} on failure. + \end{cfuncdesc} + + \begin{cfuncdesc}{long}{PyLong_AsLong}{PyObject *pylong} + Returns a C \ctype{long} representation of the contents of + \var{pylong}. If \var{pylong} is greater than + \constant{LONG_MAX}\ttindex{LONG_MAX}, an \exception{OverflowError} is + raised.\withsubitem{(built-in exception)}{\ttindex{OverflowError}} + \end{cfuncdesc} + + \begin{cfuncdesc}{unsigned long}{PyLong_AsUnsignedLong}{PyObject *pylong} + Returns a C \ctype{unsigned long} representation of the contents of + \var{pylong}. If \var{pylong} is greater than + \constant{ULONG_MAX}\ttindex{ULONG_MAX}, an \exception{OverflowError} + is raised.\withsubitem{(built-in exception)}{\ttindex{OverflowError}} + \end{cfuncdesc} + + \begin{cfuncdesc}{double}{PyLong_AsDouble}{PyObject *pylong} + Returns a C \ctype{double} representation of the contents of \var{pylong}. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyLong_FromString}{char *str, char **pend, + int base} + Return a new \ctype{PyLongObject} based on the string value in + \var{str}, which is interpreted according to the radix in \var{base}. + If \var{pend} is non-\NULL, \code{*\var{pend}} will point to the first + character in \var{str} which follows the representation of the + number. If \var{base} is \code{0}, the radix will be determined base + on the leading characters of \var{str}: if \var{str} starts with + \code{'0x'} or \code{'0X'}, radix 16 will be used; if \var{str} starts + with \code{'0'}, radix 8 will be used; otherwise radix 10 will be + used. If \var{base} is not \code{0}, it must be between \code{2} and + \code{36}, inclusive. Leading spaces are ignored. If there are no + digits, \exception{ValueError} will be raised. + \end{cfuncdesc} + + + \subsection{Floating Point Objects \label{floatObjects}} + + \obindex{floating point} + \begin{ctypedesc}{PyFloatObject} + This subtype of \ctype{PyObject} represents a Python floating point + object. + \end{ctypedesc} + + \begin{cvardesc}{PyTypeObject}{PyFloat_Type} + This instance of \ctype{PyTypeObject} represents the Python floating + point type. This is the same object as \code{types.FloatType}. + \withsubitem{(in modules types)}{\ttindex{FloatType}} + \end{cvardesc} + + \begin{cfuncdesc}{int}{PyFloat_Check}{PyObject *p} + Returns true if its argument is a \ctype{PyFloatObject}. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyFloat_FromDouble}{double v} + Creates a \ctype{PyFloatObject} object from \var{v}, or \NULL{} on + failure. + \end{cfuncdesc} + + \begin{cfuncdesc}{double}{PyFloat_AsDouble}{PyObject *pyfloat} + Returns a C \ctype{double} representation of the contents of \var{pyfloat}. + \end{cfuncdesc} + + \begin{cfuncdesc}{double}{PyFloat_AS_DOUBLE}{PyObject *pyfloat} + Returns a C \ctype{double} representation of the contents of + \var{pyfloat}, but without error checking. + \end{cfuncdesc} + + + \subsection{Complex Number Objects \label{complexObjects}} + + \obindex{complex number} + Python's complex number objects are implemented as two distinct types + when viewed from the C API: one is the Python object exposed to + Python programs, and the other is a C structure which represents the + actual complex number value. The API provides functions for working + with both. + + \subsubsection{Complex Numbers as C Structures} + + Note that the functions which accept these structures as parameters + and return them as results do so \emph{by value} rather than + dereferencing them through pointers. This is consistent throughout + the API. + + \begin{ctypedesc}{Py_complex} + The C structure which corresponds to the value portion of a Python + complex number object. Most of the functions for dealing with complex + number objects use structures of this type as input or output values, + as appropriate. It is defined as: + + \begin{verbatim} + typedef struct { + double real; + double imag; + } Py_complex; + \end{verbatim} + \end{ctypedesc} + + \begin{cfuncdesc}{Py_complex}{_Py_c_sum}{Py_complex left, Py_complex right} + Return the sum of two complex numbers, using the C + \ctype{Py_complex} representation. + \end{cfuncdesc} + + \begin{cfuncdesc}{Py_complex}{_Py_c_diff}{Py_complex left, Py_complex right} + Return the difference between two complex numbers, using the C + \ctype{Py_complex} representation. + \end{cfuncdesc} + + \begin{cfuncdesc}{Py_complex}{_Py_c_neg}{Py_complex complex} + Return the negation of the complex number \var{complex}, using the C + \ctype{Py_complex} representation. + \end{cfuncdesc} + + \begin{cfuncdesc}{Py_complex}{_Py_c_prod}{Py_complex left, Py_complex right} + Return the product of two complex numbers, using the C + \ctype{Py_complex} representation. + \end{cfuncdesc} + + \begin{cfuncdesc}{Py_complex}{_Py_c_quot}{Py_complex dividend, + Py_complex divisor} + Return the quotient of two complex numbers, using the C + \ctype{Py_complex} representation. + \end{cfuncdesc} + + \begin{cfuncdesc}{Py_complex}{_Py_c_pow}{Py_complex num, Py_complex exp} + Return the exponentiation of \var{num} by \var{exp}, using the C + \ctype{Py_complex} representation. + \end{cfuncdesc} + + + \subsubsection{Complex Numbers as Python Objects} + + \begin{ctypedesc}{PyComplexObject} + This subtype of \ctype{PyObject} represents a Python complex number object. + \end{ctypedesc} + + \begin{cvardesc}{PyTypeObject}{PyComplex_Type} + This instance of \ctype{PyTypeObject} represents the Python complex + number type. + \end{cvardesc} + + \begin{cfuncdesc}{int}{PyComplex_Check}{PyObject *p} + Returns true if its argument is a \ctype{PyComplexObject}. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyComplex_FromCComplex}{Py_complex v} + Create a new Python complex number object from a C + \ctype{Py_complex} value. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyComplex_FromDoubles}{double real, double imag} + Returns a new \ctype{PyComplexObject} object from \var{real} and \var{imag}. + \end{cfuncdesc} + + \begin{cfuncdesc}{double}{PyComplex_RealAsDouble}{PyObject *op} + Returns the real part of \var{op} as a C \ctype{double}. + \end{cfuncdesc} + + \begin{cfuncdesc}{double}{PyComplex_ImagAsDouble}{PyObject *op} + Returns the imaginary part of \var{op} as a C \ctype{double}. + \end{cfuncdesc} + + \begin{cfuncdesc}{Py_complex}{PyComplex_AsCComplex}{PyObject *op} + Returns the \ctype{Py_complex} value of the complex number \var{op}. + \end{cfuncdesc} + + + \section{Sequence Objects \label{sequenceObjects}} *************** *** 3471,3723 **** \end{verbatim} \end{cfuncdesc} - - - \section{Numeric Objects \label{numericObjects}} - - \obindex{numeric} - - - \subsection{Plain Integer Objects \label{intObjects}} - - \obindex{integer} - \begin{ctypedesc}{PyIntObject} - This subtype of \ctype{PyObject} represents a Python integer object. - \end{ctypedesc} - - \begin{cvardesc}{PyTypeObject}{PyInt_Type} - This instance of \ctype{PyTypeObject} represents the Python plain - integer type. This is the same object as \code{types.IntType}. - \withsubitem{(in modules types)}{\ttindex{IntType}} - \end{cvardesc} - - \begin{cfuncdesc}{int}{PyInt_Check}{PyObject* o} - Returns true if \var{o} is of type \cdata{PyInt_Type}. - \end{cfuncdesc} - - \begin{cfuncdesc}{PyObject*}{PyInt_FromLong}{long ival} - Creates a new integer object with a value of \var{ival}. - - The current implementation keeps an array of integer objects for all - integers between \code{-1} and \code{100}, when you create an int in - that range you actually just get back a reference to the existing - object. So it should be possible to change the value of \code{1}. I - suspect the behaviour of Python in this case is undefined. :-) - \end{cfuncdesc} - - \begin{cfuncdesc}{long}{PyInt_AsLong}{PyObject *io} - Will first attempt to cast the object to a \ctype{PyIntObject}, if - it is not already one, and then return its value. - \end{cfuncdesc} - - \begin{cfuncdesc}{long}{PyInt_AS_LONG}{PyObject *io} - Returns the value of the object \var{io}. No error checking is - performed. - \end{cfuncdesc} - - \begin{cfuncdesc}{long}{PyInt_GetMax}{} - Returns the system's idea of the largest integer it can handle - (\constant{LONG_MAX}\ttindex{LONG_MAX}, as defined in the system - header files). - \end{cfuncdesc} - - - \subsection{Long Integer Objects \label{longObjects}} - - \obindex{long integer} - \begin{ctypedesc}{PyLongObject} - This subtype of \ctype{PyObject} represents a Python long integer - object. - \end{ctypedesc} - - \begin{cvardesc}{PyTypeObject}{PyLong_Type} - This instance of \ctype{PyTypeObject} represents the Python long - integer type. This is the same object as \code{types.LongType}. - \withsubitem{(in modules types)}{\ttindex{LongType}} - \end{cvardesc} - - \begin{cfuncdesc}{int}{PyLong_Check}{PyObject *p} - Returns true if its argument is a \ctype{PyLongObject}. - \end{cfuncdesc} - - \begin{cfuncdesc}{PyObject*}{PyLong_FromLong}{long v} - Returns a new \ctype{PyLongObject} object from \var{v}, or \NULL{} on - failure. - \end{cfuncdesc} - - \begin{cfuncdesc}{PyObject*}{PyLong_FromUnsignedLong}{unsigned long v} - Returns a new \ctype{PyLongObject} object from a C \ctype{unsigned - long}, or \NULL{} on failure. - \end{cfuncdesc} - - \begin{cfuncdesc}{PyObject*}{PyLong_FromDouble}{double v} - Returns a new \ctype{PyLongObject} object from the integer part of - \var{v}, or \NULL{} on failure. - \end{cfuncdesc} - - \begin{cfuncdesc}{long}{PyLong_AsLong}{PyObject *pylong} - Returns a C \ctype{long} representation of the contents of - \var{pylong}. If \var{pylong} is greater than - \constant{LONG_MAX}\ttindex{LONG_MAX}, an \exception{OverflowError} is - raised.\withsubitem{(built-in exception)}{\ttindex{OverflowError}} - \end{cfuncdesc} - - \begin{cfuncdesc}{unsigned long}{PyLong_AsUnsignedLong}{PyObject *pylong} - Returns a C \ctype{unsigned long} representation of the contents of - \var{pylong}. If \var{pylong} is greater than - \constant{ULONG_MAX}\ttindex{ULONG_MAX}, an \exception{OverflowError} - is raised.\withsubitem{(built-in exception)}{\ttindex{OverflowError}} - \end{cfuncdesc} - - \begin{cfuncdesc}{double}{PyLong_AsDouble}{PyObject *pylong} - Returns a C \ctype{double} representation of the contents of \var{pylong}. - \end{cfuncdesc} - - \begin{cfuncdesc}{PyObject*}{PyLong_FromString}{char *str, char **pend, - int base} - Return a new \ctype{PyLongObject} based on the string value in - \var{str}, which is interpreted according to the radix in \var{base}. - If \var{pend} is non-\NULL, \code{*\var{pend}} will point to the first - character in \var{str} which follows the representation of the - number. If \var{base} is \code{0}, the radix will be determined base - on the leading characters of \var{str}: if \var{str} starts with - \code{'0x'} or \code{'0X'}, radix 16 will be used; if \var{str} starts - with \code{'0'}, radix 8 will be used; otherwise radix 10 will be - used. If \var{base} is not \code{0}, it must be between \code{2} and - \code{36}, inclusive. Leading spaces are ignored. If there are no - digits, \exception{ValueError} will be raised. - \end{cfuncdesc} - - - \subsection{Floating Point Objects \label{floatObjects}} - - \obindex{floating point} - \begin{ctypedesc}{PyFloatObject} - This subtype of \ctype{PyObject} represents a Python floating point - object. - \end{ctypedesc} - - \begin{cvardesc}{PyTypeObject}{PyFloat_Type} - This instance of \ctype{PyTypeObject} represents the Python floating - point type. This is the same object as \code{types.FloatType}. - \withsubitem{(in modules types)}{\ttindex{FloatType}} - \end{cvardesc} - - \begin{cfuncdesc}{int}{PyFloat_Check}{PyObject *p} - Returns true if its argument is a \ctype{PyFloatObject}. - \end{cfuncdesc} - - \begin{cfuncdesc}{PyObject*}{PyFloat_FromDouble}{double v} - Creates a \ctype{PyFloatObject} object from \var{v}, or \NULL{} on - failure. - \end{cfuncdesc} - - \begin{cfuncdesc}{double}{PyFloat_AsDouble}{PyObject *pyfloat} - Returns a C \ctype{double} representation of the contents of \var{pyfloat}. - \end{cfuncdesc} - - \begin{cfuncdesc}{double}{PyFloat_AS_DOUBLE}{PyObject *pyfloat} - Returns a C \ctype{double} representation of the contents of - \var{pyfloat}, but without error checking. - \end{cfuncdesc} - - - \subsection{Complex Number Objects \label{complexObjects}} - - \obindex{complex number} - Python's complex number objects are implemented as two distinct types - when viewed from the C API: one is the Python object exposed to - Python programs, and the other is a C structure which represents the - actual complex number value. The API provides functions for working - with both. - - \subsubsection{Complex Numbers as C Structures} - - Note that the functions which accept these structures as parameters - and return them as results do so \emph{by value} rather than - dereferencing them through pointers. This is consistent throughout - the API. - - \begin{ctypedesc}{Py_complex} - The C structure which corresponds to the value portion of a Python - complex number object. Most of the functions for dealing with complex - number objects use structures of this type as input or output values, - as appropriate. It is defined as: - - \begin{verbatim} - typedef struct { - double real; - double imag; - } Py_complex; - \end{verbatim} - \end{ctypedesc} - - \begin{cfuncdesc}{Py_complex}{_Py_c_sum}{Py_complex left, Py_complex right} - Return the sum of two complex numbers, using the C - \ctype{Py_complex} representation. - \end{cfuncdesc} - - \begin{cfuncdesc}{Py_complex}{_Py_c_diff}{Py_complex left, Py_complex right} - Return the difference between two complex numbers, using the C - \ctype{Py_complex} representation. - \end{cfuncdesc} - - \begin{cfuncdesc}{Py_complex}{_Py_c_neg}{Py_complex complex} - Return the negation of the complex number \var{complex}, using the C - \ctype{Py_complex} representation. - \end{cfuncdesc} - - \begin{cfuncdesc}{Py_complex}{_Py_c_prod}{Py_complex left, Py_complex right} - Return the product of two complex numbers, using the C - \ctype{Py_complex} representation. - \end{cfuncdesc} - - \begin{cfuncdesc}{Py_complex}{_Py_c_quot}{Py_complex dividend, - Py_complex divisor} - Return the quotient of two complex numbers, using the C - \ctype{Py_complex} representation. - \end{cfuncdesc} - - \begin{cfuncdesc}{Py_complex}{_Py_c_pow}{Py_complex num, Py_complex exp} - Return the exponentiation of \var{num} by \var{exp}, using the C - \ctype{Py_complex} representation. - \end{cfuncdesc} - - - \subsubsection{Complex Numbers as Python Objects} - - \begin{ctypedesc}{PyComplexObject} - This subtype of \ctype{PyObject} represents a Python complex number object. - \end{ctypedesc} - - \begin{cvardesc}{PyTypeObject}{PyComplex_Type} - This instance of \ctype{PyTypeObject} represents the Python complex - number type. - \end{cvardesc} - - \begin{cfuncdesc}{int}{PyComplex_Check}{PyObject *p} - Returns true if its argument is a \ctype{PyComplexObject}. - \end{cfuncdesc} - - \begin{cfuncdesc}{PyObject*}{PyComplex_FromCComplex}{Py_complex v} - Create a new Python complex number object from a C - \ctype{Py_complex} value. - \end{cfuncdesc} - - \begin{cfuncdesc}{PyObject*}{PyComplex_FromDoubles}{double real, double imag} - Returns a new \ctype{PyComplexObject} object from \var{real} and \var{imag}. - \end{cfuncdesc} - - \begin{cfuncdesc}{double}{PyComplex_RealAsDouble}{PyObject *op} - Returns the real part of \var{op} as a C \ctype{double}. - \end{cfuncdesc} - - \begin{cfuncdesc}{double}{PyComplex_ImagAsDouble}{PyObject *op} - Returns the imaginary part of \var{op} as a C \ctype{double}. - \end{cfuncdesc} - - \begin{cfuncdesc}{Py_complex}{PyComplex_AsCComplex}{PyObject *op} - Returns the \ctype{Py_complex} value of the complex number \var{op}. - \end{cfuncdesc} - --- 3720,3723 ---- From gvanrossum@users.sourceforge.net Wed Jul 11 22:26:10 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 11 Jul 2001 14:26:10 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0253.txt,1.11,1.12 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv3385 Modified Files: pep-0253.txt Log Message: Exhausted myself today by adding a long section on the new MRO. Index: pep-0253.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0253.txt,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -r1.11 -r1.12 *** pep-0253.txt 2001/07/11 19:09:28 1.11 --- pep-0253.txt 2001/07/11 21:26:08 1.12 *************** *** 142,149 **** metatypes are typically written in C, and may be shared between many regular types. (It will be possible to subtype metatypes in ! Python, so it won't be absolutely necessary to write C in order to ! use metatypes; but the power of Python metatypes will be limited. ! For example, Python code will never be allowed to allocate raw ! memory and initialize it at will.) Metatypes determine various *policies* for types,such as what --- 142,149 ---- metatypes are typically written in C, and may be shared between many regular types. (It will be possible to subtype metatypes in ! Python, so it won't be absolutely necessary to write C to use ! metatypes; but the power of Python metatypes will be limited. For ! example, Python code will never be allowed to allocate raw memory ! and initialize it at will.) Metatypes determine various *policies* for types,such as what *************** *** 383,390 **** for the tp_clear() slot. This turned out to be a bad idea.) ! In order to be usefully subtyped in C, a type must export the ! structure declaration for its instances through a header file, as ! it is needed in order to derive a subtype. The type object for ! the base type must also be exported. If the base type has a type-checking macro (like PyDict_Check()), --- 383,390 ---- for the tp_clear() slot. This turned out to be a bad idea.) ! To be usefully subtyped in C, a type must export the structure ! declaration for its instances through a header file, as it is ! needed to derive a subtype. The type object for the base type ! must also be exported. If the base type has a type-checking macro (like PyDict_Check()), *************** *** 482,490 **** tp_new() and tp_dealloc() slots, respectively. ! In order to complete the initialization of the type, ! PyType_InitDict() must be called. This replaces slots initialized ! to zero in the subtype with the value of the corresponding base ! type slots. (It also fills in tp_dict, the type's dictionary, and ! does various other initializations necessary for type objects.) A subtype is not usable until PyType_InitDict() is called for it; --- 482,490 ---- tp_new() and tp_dealloc() slots, respectively. ! To complete the initialization of the type, PyType_InitDict() must ! be called. This replaces slots initialized to zero in the subtype ! with the value of the corresponding base type slots. (It also ! fills in tp_dict, the type's dictionary, and does various other ! initializations necessary for type objects.) A subtype is not usable until PyType_InitDict() is called for it; *************** *** 494,499 **** to initialize the subtype in their constructor function. It is allowed to call PyType_InitDict() more than once; the second and ! further calls have no effect. In order to avoid unnecessary ! calls, a test for tp_dict==NULL can be made. (During initialization of the Python interpreter, some types are --- 494,499 ---- to initialize the subtype in their constructor function. It is allowed to call PyType_InitDict() more than once; the second and ! further calls have no effect. To avoid unnecessary calls, a test ! for tp_dict==NULL can be made. (During initialization of the Python interpreter, some types are *************** *** 638,642 **** ! Multiple Inheritance The Python class statement supports multiple inheritance, and we --- 638,642 ---- ! Multiple inheritance The Python class statement supports multiple inheritance, and we *************** *** 726,733 **** --- 726,882 ---- + Method resolution order (the lookup rule) + + With multiple inheritance comes the question of method resolution + order: the order in which a class or type and its bases are + searched looking for a method of a given name. + + In classic Python, the rule is given by the following recursive + function, also known as the left-to-right depth-first rule: + + def classic_lookup(cls, name): + if cls.__dict__.has_key(name): + return cls.__dict__[name] + for base in cls.__bases__: + try: + return classic_lookup(base, name) + except AttributeError: + pass + raise AttributeError, name + + The problem with this becomes apparent when we consider a "diamond + diagram": + + class A: + ^ ^ def save(self): ... + / \ + / \ + / \ + / \ + class B class C: + ^ ^ def save(self): ... + \ / + \ / + \ / + \ / + class D + + Arrows point from a subtype to its base type(s). This particular + diagram means B and C derive from A, and D derives from B and C + (and hence also, indirectly, from A). + + Assume that C overrides the method save(), which is defined in the + base A. (C.save() probably calls A.save() and then saves some of + its own state.) B and D don't override save(). When we invoke + save() on a D instance, which method is called? According to the + classic lookup rule, A.save() is called, ignoring C.save()! + + This is not good. It probably breaks C (its state doesn't get + saved), defeating the whole purpose of inheriting from C in the + first place. + + Why was this not a problem in classic Python? Diamond diagrams is + found rarely in classic Python class hierarchies. Most class + hierarchies use single inheritance, and multiple inheritance is + usually confined to mix-in classes. In fact, the problem shown + here is probably the reason why multiple inheritance is impopular + in classic Python. + + Why will this be a problem in the new system? The 'object' type + at the top of the type hierarchy defines a number of methods that + can usefully be extended by subtypes, for example __getattr__(). + + (Aside: in classic Python, the __getattr__() method is not really + the implementation for the get-attribute operation; it is a hook + that only gets invoked when an attribute cannot be found by normal + means. This has often been cited as a shortcoming -- some class + designs have a legitimate need for a __getattr__() method that + gets called for *all* attribute references. But then of course + this method has to be able to invoke the default implementation + directly. The most natural way is to make the default + implementation available as object.__getattr__(self, name).) + + Thus, a classic class hierarchy like this: + + class B class C: + ^ ^ def __getattr__(self, name): ... + \ / + \ / + \ / + \ / + class D + + will change into a diamond diagram under the new system: + + object: + ^ ^ __getattr__() + / \ + / \ + / \ + / \ + class B class C: + ^ ^ def __getattr__(self, name): ... + \ / + \ / + \ / + \ / + class D + + and while in the original diagram C.__getattr__() is invoked, + under the new system with the classic lookup rule, + object.__getattr__() would be invoked! + + Fortunately, there's a lookup rule that's better. It's a bit + difficult to explain, but it does the right thing in the diamond + diagram, and it is the same as the classic lookup rule when there + are no diamonds in the inheritance graph (when it is a tree). + + The new lookup rule constructs a list of all classes in the + inheritance diagram in the order in which they will be searched. + This construction is done at class definition time to save time. + To explain the new lookup rule, let's first consider what such a + list would look like for the classic lookup rule. Note that in + the presence of diamonds the classic lookup visits some classes + multiple times. For example, in the ABCD diamond diagram above, + the classic lookup rule visits the classes in this order: + + D, B, A, C, A + + Note how A occurs twice in the list. The second occurrence is + redundant, since anything that could be found there would already + have been found when searching the first occurrence. + + We use this observation to explain our new lookup rule. Using the + classic lookup rule, construct the list of classes that would be + searched, including duplicates. Now for each class that occurs in + the list multiple times, remove all occurrences except for the + last. The resulting list contains each ancestor class exactly + once (including the most derived class, D in the example). + + Searching for methods in this order will do the right thing for + the diamond diagram. Because of the way the list is constructed, + it does not change the search order in situations where no diamond + is involved. + + Isn't this backwards incompatible? Won't it break existing code? + It would, if we changed the method resolution order for all + classes. However, in Python 2.2, the new lookup rule will only be + applied to types derived from built-in types, which is a new + feature. Class statements without a base class create "classic + classes", and so do class statements whose base classes are + themselves classic classes. For classic classes the classic + lookup rule will be used. (To experiment with the new lookup rule + for classic classes, you will be able to specify a different + metaclass explicitly.) We'll also provide a tool that analyzes a + class hierarchy looking for methods that would be affected by a + change in method resolution order. + + XXX To be done Additional topics to be discussed in this PEP: + - backwards compatibility issues!!! + - class methods and static methods *************** *** 737,742 **** - built-in names for built-in types (object, int, str, list etc.) - - method resolution order - - __dict__ --- 886,889 ---- *************** *** 748,751 **** --- 895,902 ---- - API docs for all the new functions + + - using __new__ + + - writing metaclasses (using mro() etc.) - high level user overview From tim_one@users.sourceforge.net Wed Jul 11 22:43:45 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 11 Jul 2001 14:43:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_uu.py,NONE,1.1 test_sundry.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv7075/python/dist/src/Lib/test Modified Files: test_sundry.py Added Files: test_uu.py Log Message: SF patch #440144: Tests and minor bugfix for uu module. New test_uu.py from Nick Mathewson, fiddled to work on Windows too. Somebody should check that it still works on non-Windows boxes, though! --- NEW FILE: test_uu.py --- """ Tests for uu module. Nick Mathewson """ from test_support import verify, TestFailed, verbose, TESTFN import sys, os import uu from StringIO import StringIO teststr = "The smooth-scaled python crept over the sleeping dog\n" expected = """\ M5&AE('-M;V]T:\"US8V%L960@<'ET:&]N(&-R97!T(&]V97(@=&AE('-L965P (:6YG(&1O9PH """ encoded1 = "begin 666 t1\n"+expected+"\n \nend\n" if verbose: print '1. encode file->file' inp = StringIO(teststr) out = StringIO() uu.encode(inp, out, "t1") verify(out.getvalue() == encoded1) inp = StringIO(teststr) out = StringIO() uu.encode(inp, out, "t1", 0644) verify(out.getvalue() == "begin 644 t1\n"+expected+"\n \nend\n") if verbose: print '2. decode file->file' inp = StringIO(encoded1) out = StringIO() uu.decode(inp, out) verify(out.getvalue() == teststr) inp = StringIO("""UUencoded files may contain many lines, even some that have 'begin' in them.\n"""+encoded1) out = StringIO() uu.decode(inp, out) verify(out.getvalue() == teststr) stdinsave = sys.stdin stdoutsave = sys.stdout try: if verbose: print '3. encode stdin->stdout' sys.stdin = StringIO(teststr) sys.stdout = StringIO() uu.encode("-", "-", "t1", 0666) verify(sys.stdout.getvalue() == encoded1) if verbose: print >>stdoutsave, '4. decode stdin->stdout' sys.stdin = StringIO(encoded1) sys.stdout = StringIO() uu.decode("-", "-") verify(sys.stdout.getvalue() == teststr) finally: sys.stdin = stdinsave sys.stdout = stdoutsave if verbose: print '5. encode file->file' tmpIn = TESTFN + "i" tmpOut = TESTFN + "o" try: fin = open(tmpIn, 'w') fin.write(teststr) fin.close() fin = open(tmpIn, 'r') fout = open(tmpOut, 'w') uu.encode(fin, fout, tmpIn, mode=0644) fin.close() fout.close() fout = open(tmpOut, 'r') s = fout.read() fout.close() verify(s == 'begin 644 ' + tmpIn + '\n' + expected + '\n \nend\n') os.unlink(tmpIn) if verbose: print '6. decode file-> file' uu.decode(tmpOut) fin = open(tmpIn, 'r') s = fin.read() fin.close() verify(s == teststr) # XXX is there an xp way to verify the mode? finally: try: fin.close() except: pass try: fout.close() except: pass try: os.unlink(tmpIn) except: pass try: os.unlink(tmpOut) except: pass if verbose: print '7. error: truncated input' inp = StringIO("begin 644 t1\n"+expected) out = StringIO() try: uu.decode(inp, out) raise TestFailed("No exception thrown") except uu.Error, e: verify(str(e) == 'Truncated input file') if verbose: print '8. error: missing begin' inp = StringIO("") out = StringIO() try: uu.decode(inp, out) raise TestFailed("No exception thrown") except uu.Error, e: verify(str(e) == 'No valid begin line found in input file') Index: test_sundry.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sundry.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** test_sundry.py 2001/04/06 18:59:17 1.4 --- test_sundry.py 2001/07/11 21:43:42 1.5 *************** *** 97,101 **** # can screw up all sorts of things (esp. if it prints!). #import user - import uu import webbrowser import whichdb --- 97,100 ---- From tim_one@users.sourceforge.net Wed Jul 11 23:21:19 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 11 Jul 2001 15:21:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_fileinput.py,NONE,1.1 test_sundry.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv14522/python/dist/src/lib/test Modified Files: test_sundry.py Added Files: test_fileinput.py Log Message: SF patch #440170: Tests for fileinput module. New test_fileinput.py from Nick Mathewson, fiddled to use TESTFN and sundry style nits. --- NEW FILE: test_fileinput.py --- ''' Tests for fileinput module. Nick Mathewson ''' from test_support import verify, verbose, TESTFN import sys, os, re from StringIO import StringIO from fileinput import FileInput # The fileinput module has 2 interfaces: the FileInput class which does # all the work, and a few functions (input, etc.) that use a global _state # variable. We only test the FileInput class, since the other functions # only provide a thin facade over FileInput. # Write lines (a list of lines) to temp file number i, and return the # temp file's name. def writeTmp(i, lines): name = TESTFN + str(i) f = open(name, 'w') f.writelines(lines) f.close() return name pat = re.compile(r'LINE (\d+) OF FILE (\d+)') def remove_tempfiles(*names): for name in names: try: os.unlink(name) except: pass def runTests(t1, t2, t3, t4, bs=0, round=0): start = 1 + round*6 if verbose: print '%s. Simple iteration (bs=%s)' % (start+0, bs) fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs) lines = list(fi) fi.close() verify(len(lines) == 31) verify(lines[4] == 'Line 5 of file 1\n') verify(lines[30] == 'Line 1 of file 4\n') verify(fi.lineno() == 31) verify(fi.filename() == t4) if verbose: print '%s. Status variables (bs=%s)' % (start+1, bs) fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs) s = "x" while s and s != 'Line 6 of file 2\n': s = fi.readline() verify(fi.filename() == t2) verify(fi.lineno() == 21) verify(fi.filelineno() == 6) verify(not fi.isfirstline()) verify(not fi.isstdin()) if verbose: print '%s. Nextfile (bs=%s)' % (start+2, bs) fi.nextfile() verify(fi.readline() == 'Line 1 of file 3\n') verify(fi.lineno() == 22) fi.close() if verbose: print '%s. Stdin (bs=%s)' % (start+3, bs) fi = FileInput(files=(t1, t2, t3, t4, '-'), bufsize=bs) savestdin = sys.stdin try: sys.stdin = StringIO("Line 1 of stdin\nLine 2 of stdin\n") lines = list(fi) verify(len(lines) == 33) verify(lines[32] == 'Line 2 of stdin\n') verify(fi.filename() == '') fi.nextfile() finally: sys.stdin = savestdin if verbose: print '%s. Boundary conditions (bs=%s)' % (start+4, bs) fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs) verify(fi.lineno() == 0) verify(fi.filename() == None) fi.nextfile() verify(fi.lineno() == 0) verify(fi.filename() == None) if verbose: print '%s. Inplace (bs=%s)' % (start+5, bs) savestdout = sys.stdout try: fi = FileInput(files=(t1, t2, t3, t4), inplace=1, bufsize=bs) for line in fi: line = line[:-1].upper() print line fi.close() finally: sys.stdout = savestdout fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs) for line in fi: verify(line[-1] == '\n') m = pat.match(line[:-1]) verify(m != None) verify(int(m.group(1)) == fi.filelineno()) fi.close() def writeFiles(): global t1, t2, t3, t4 t1 = writeTmp(1, ["Line %s of file 1\n" % (i+1) for i in range(15)]) t2 = writeTmp(2, ["Line %s of file 2\n" % (i+1) for i in range(10)]) t3 = writeTmp(3, ["Line %s of file 3\n" % (i+1) for i in range(5)]) t4 = writeTmp(4, ["Line %s of file 4\n" % (i+1) for i in range(1)]) # First, run the tests with default and teeny buffer size. for round, bs in (0, 0), (1, 30): try: writeFiles() runTests(t1, t2, t3, t4, bs, round) finally: remove_tempfiles(t1, t2, t3, t4) # Next, check for proper behavior with 0-byte files. if verbose: print "13. 0-byte files" try: t1 = writeTmp(1, [""]) t2 = writeTmp(2, [""]) t3 = writeTmp(3, ["The only line there is.\n"]) t4 = writeTmp(4, [""]) fi = FileInput(files=(t1, t2, t3, t4)) line = fi.readline() verify(line == 'The only line there is.\n') verify(fi.lineno() == 1) verify(fi.filelineno() == 1) verify(fi.filename() == t3) line = fi.readline() verify(not line) verify(fi.lineno() == 1) verify(fi.filelineno() == 0) verify(fi.filename() == t4) fi.close() finally: remove_tempfiles(t1, t2, t3, t4) if verbose: print "14. Files that don't end with newline" try: t1 = writeTmp(1, ["A\nB\nC"]) t2 = writeTmp(2, ["D\nE\nF"]) fi = FileInput(files=(t1, t2)) lines = list(fi) verify(lines == ["A\n", "B\n", "C", "D\n", "E\n", "F"]) verify(fi.filelineno() == 3) verify(fi.lineno() == 6) finally: remove_tempfiles(t1, t2) Index: test_sundry.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sundry.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** test_sundry.py 2001/07/11 21:43:42 1.5 --- test_sundry.py 2001/07/11 22:21:17 1.6 *************** *** 31,35 **** import encodings import filecmp - import fileinput import fnmatch import formatter --- 31,34 ---- From twouters@users.sourceforge.net Wed Jul 11 23:27:40 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 11 Jul 2001 15:27:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules posixmodule.c,2.187.2.2,2.187.2.3 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv15531/Modules Modified Files: Tag: release21-maint posixmodule.c Log Message: Re-do the broken-nice() patch to break less platforms. Hopefully none :P Also note that it isn't just Linux nice() that is broken: at least FreeBSD and BSDI also have this problem. os.nice() should probably just be emulated using getpriority()/setpriority(), if they are available, but that isn't worth putting in 2.1.1. Index: posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.187.2.2 retrieving revision 2.187.2.3 diff -C2 -r2.187.2.2 -r2.187.2.3 *** posixmodule.c 2001/07/11 14:01:08 2.187.2.2 --- posixmodule.c 2001/07/11 22:27:38 2.187.2.3 *************** *** 1068,1071 **** --- 1068,1077 ---- #ifdef HAVE_NICE + #if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H) + #if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS) + #include + #endif + #endif + static char posix_nice__doc__[] = "nice(inc) -> new_priority\n\ *************** *** 1082,1087 **** /* There are two flavours of 'nice': one that returns the new priority (as required by almost all standards out there) and the ! Linux one, which returns '0' on success and advices the use of ! getpriority() to get the new priority. If we are of the nice family that returns the new priority, we --- 1088,1093 ---- /* There are two flavours of 'nice': one that returns the new priority (as required by almost all standards out there) and the ! Linux/FreeBSD/BSDI one, which returns '0' on success and advices ! the use of getpriority() to get the new priority. If we are of the nice family that returns the new priority, we *************** *** 1092,1096 **** errno = 0; value = nice(increment); ! #ifdef HAVE_GETPRIORITY if (value == 0) value = getpriority(PRIO_PROCESS, 0); --- 1098,1102 ---- errno = 0; value = nice(increment); ! #if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY) if (value == 0) value = getpriority(PRIO_PROCESS, 0); From twouters@users.sourceforge.net Wed Jul 11 23:27:41 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 11 Jul 2001 15:27:41 -0700 Subject: [Python-checkins] CVS: python/dist/src configure,1.207.2.3,1.207.2.4 configure.in,1.215.2.3,1.215.2.4 config.h.in,2.91.2.3,2.91.2.4 acconfig.h,1.46.2.1,1.46.2.2 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv15531 Modified Files: Tag: release21-maint configure configure.in config.h.in acconfig.h Log Message: Re-do the broken-nice() patch to break less platforms. Hopefully none :P Also note that it isn't just Linux nice() that is broken: at least FreeBSD and BSDI also have this problem. os.nice() should probably just be emulated using getpriority()/setpriority(), if they are available, but that isn't worth putting in 2.1.1. Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.207.2.3 retrieving revision 1.207.2.4 diff -C2 -r1.207.2.3 -r1.207.2.4 *** configure 2001/07/11 14:01:07 1.207.2.3 --- configure 2001/07/11 22:27:38 1.207.2.4 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.215.2.2 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.215.2.3 # Guess values for system-dependent variables and create Makefiles. *************** *** 1818,1822 **** sys/param.h sys/select.h sys/socket.h sys/time.h sys/times.h \ sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ ! ndbm.h db1/ndbm.h gdbm/ndbm.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --- 1818,1822 ---- sys/param.h sys/select.h sys/socket.h sys/time.h sys/times.h \ sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ ! ndbm.h db1/ndbm.h gdbm/ndbm.h sys/resource.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` *************** *** 6216,6219 **** --- 6216,6264 ---- + echo $ac_n "checking for broken nice()""... $ac_c" 1>&6 + echo "configure:6220: checking for broken nice()" >&5 + if eval "test \"`echo '$''{'ac_cv_broken_nice'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null + then + ac_cv_broken_nice=yes + else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_broken_nice=no + fi + rm -fr conftest* + fi + + fi + + echo "$ac_t""$ac_cv_broken_nice" 1>&6 + if test "$ac_cv_broken_nice" = yes + then + cat >> confdefs.h <<\EOF + #define HAVE_BROKEN_NICE 1 + EOF + + fi + # THIS MUST BE LAST, IT CAN BREAK OTHER TESTS! # Add sys/socket.h to confdefs.h *************** *** 6224,6233 **** EOF echo $ac_n "checking for socklen_t""... $ac_c" 1>&6 ! echo "configure:6227: checking for socklen_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_socklen_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < --- 6269,6278 ---- EOF echo $ac_n "checking for socklen_t""... $ac_c" 1>&6 ! echo "configure:6272: checking for socklen_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_socklen_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < *************** *** 6278,6282 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6281: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then --- 6323,6327 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6326: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.215.2.3 retrieving revision 1.215.2.4 diff -C2 -r1.215.2.3 -r1.215.2.4 *** configure.in 2001/07/11 14:01:07 1.215.2.3 --- configure.in 2001/07/11 22:27:39 1.215.2.4 *************** *** 385,389 **** sys/param.h sys/select.h sys/socket.h sys/time.h sys/times.h \ sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ ! ndbm.h db1/ndbm.h gdbm/ndbm.h) AC_HEADER_DIRENT --- 385,389 ---- sys/param.h sys/select.h sys/socket.h sys/time.h sys/times.h \ sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ ! ndbm.h db1/ndbm.h gdbm/ndbm.h sys/resource.h) AC_HEADER_DIRENT *************** *** 1334,1337 **** --- 1334,1354 ---- AC_CHECK_LIB(readline, rl_completion_matches, AC_DEFINE(HAVE_RL_COMPLETION_MATCHES), , -ltermcap) + + AC_MSG_CHECKING(for broken nice()) + AC_CACHE_VAL(ac_cv_broken_nice, [ + AC_TRY_RUN([ + int main() + { + int val1 = nice(1); + if (val1 != -1 && val1 == nice(2)) + exit(0); + exit(1); + } + ],ac_cv_broken_nice=yes, ac_cv_broken_nice=no)]) + AC_MSG_RESULT($ac_cv_broken_nice) + if test "$ac_cv_broken_nice" = yes + then + AC_DEFINE(HAVE_BROKEN_NICE) + fi # THIS MUST BE LAST, IT CAN BREAK OTHER TESTS! Index: config.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/config.h.in,v retrieving revision 2.91.2.3 retrieving revision 2.91.2.4 diff -C2 -r2.91.2.3 -r2.91.2.4 *** config.h.in 2001/07/11 14:01:07 2.91.2.3 --- config.h.in 2001/07/11 22:27:39 2.91.2.4 *************** *** 155,158 **** --- 155,161 ---- #undef HAVE_WCHAR_H + /* Define if nice() returns success/failure instead of the new priority. */ + #undef HAVE_BROKEN_NICE + /* Define if malloc(0) returns a NULL pointer */ #undef MALLOC_ZERO_RETURNS_NULL *************** *** 605,608 **** --- 608,614 ---- /* Define if you have the header file. */ #undef HAVE_SYS_PARAM_H + + /* Define if you have the header file. */ + #undef HAVE_SYS_RESOURCE_H /* Define if you have the header file. */ Index: acconfig.h =================================================================== RCS file: /cvsroot/python/python/dist/src/acconfig.h,v retrieving revision 1.46.2.1 retrieving revision 1.46.2.2 diff -C2 -r1.46.2.1 -r1.46.2.2 *** acconfig.h 2001/07/11 12:18:23 1.46.2.1 --- acconfig.h 2001/07/11 22:27:39 1.46.2.2 *************** *** 96,99 **** --- 96,102 ---- #undef HAVE_WCHAR_H + /* Define if nice() returns success/failure instead of the new priority. */ + #undef HAVE_BROKEN_NICE + /* Define if malloc(0) returns a NULL pointer */ #undef MALLOC_ZERO_RETURNS_NULL From twouters@users.sourceforge.net Wed Jul 11 23:35:34 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 11 Jul 2001 15:35:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules posixmodule.c,2.191,2.192 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv16903/Modules Modified Files: posixmodule.c Log Message: Re-do the broken-nice() patch to break less platforms. Hopefully none :P Also note that it isn't just Linux nice() that is broken: at least FreeBSD and BSDI also have this problem. os.nice() should probably just be emulated using getpriority()/setpriority(), if they are available, but I'll get to that later. Index: posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.191 retrieving revision 2.192 diff -C2 -r2.191 -r2.192 *** posixmodule.c 2001/07/11 14:45:34 2.191 --- posixmodule.c 2001/07/11 22:35:31 2.192 *************** *** 1111,1114 **** --- 1111,1120 ---- #ifdef HAVE_NICE + #if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H) + #if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS) + #include + #endif + #endif + static char posix_nice__doc__[] = "nice(inc) -> new_priority\n\ *************** *** 1125,1130 **** /* There are two flavours of 'nice': one that returns the new priority (as required by almost all standards out there) and the ! Linux one, which returns '0' on success and advices the use of ! getpriority() to get the new priority. If we are of the nice family that returns the new priority, we --- 1131,1136 ---- /* There are two flavours of 'nice': one that returns the new priority (as required by almost all standards out there) and the ! Linux/FreeBSD/BSDI one, which returns '0' on success and advices ! the use of getpriority() to get the new priority. If we are of the nice family that returns the new priority, we *************** *** 1135,1139 **** errno = 0; value = nice(increment); ! #ifdef HAVE_GETPRIORITY if (value == 0) value = getpriority(PRIO_PROCESS, 0); --- 1141,1145 ---- errno = 0; value = nice(increment); ! #if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY) if (value == 0) value = getpriority(PRIO_PROCESS, 0); From twouters@users.sourceforge.net Wed Jul 11 23:35:34 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 11 Jul 2001 15:35:34 -0700 Subject: [Python-checkins] CVS: python/dist/src acconfig.h,1.50,1.51 config.h.in,2.99,2.100 configure,1.218,1.219 configure.in,1.226,1.227 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv16903 Modified Files: acconfig.h config.h.in configure configure.in Log Message: Re-do the broken-nice() patch to break less platforms. Hopefully none :P Also note that it isn't just Linux nice() that is broken: at least FreeBSD and BSDI also have this problem. os.nice() should probably just be emulated using getpriority()/setpriority(), if they are available, but I'll get to that later. Index: acconfig.h =================================================================== RCS file: /cvsroot/python/python/dist/src/acconfig.h,v retrieving revision 1.50 retrieving revision 1.51 diff -C2 -r1.50 -r1.51 *** acconfig.h 2001/07/10 16:44:35 1.50 --- acconfig.h 2001/07/11 22:35:31 1.51 *************** *** 117,120 **** --- 117,123 ---- #undef Py_UNICODE_SIZE + /* Define if nice() returns success/failure instead of the new priority. */ + #undef HAVE_BROKEN_NICE + /* Define if malloc(0) returns a NULL pointer */ #undef MALLOC_ZERO_RETURNS_NULL Index: config.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/config.h.in,v retrieving revision 2.99 retrieving revision 2.100 diff -C2 -r2.99 -r2.100 *** config.h.in 2001/07/11 14:45:34 2.99 --- config.h.in 2001/07/11 22:35:31 2.100 *************** *** 176,179 **** --- 176,182 ---- #undef Py_UNICODE_SIZE + /* Define if nice() returns success/failure instead of the new priority. */ + #undef HAVE_BROKEN_NICE + /* Define if malloc(0) returns a NULL pointer */ #undef MALLOC_ZERO_RETURNS_NULL *************** *** 641,644 **** --- 644,650 ---- /* Define if you have the header file. */ #undef HAVE_SYS_PARAM_H + + /* Define if you have the header file. */ + #undef HAVE_SYS_RESOURCE_H /* Define if you have the header file. */ Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.218 retrieving revision 1.219 diff -C2 -r1.218 -r1.219 *** configure 2001/07/11 14:45:34 1.218 --- configure 2001/07/11 22:35:31 1.219 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.225 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.226 # Guess values for system-dependent variables and create Makefiles. *************** *** 2075,2079 **** sys/param.h sys/select.h sys/socket.h sys/time.h sys/times.h \ sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ ! ndbm.h db1/ndbm.h gdbm/ndbm.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --- 2075,2079 ---- sys/param.h sys/select.h sys/socket.h sys/time.h sys/times.h \ sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ ! ndbm.h db1/ndbm.h gdbm/ndbm.h sys/resource.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` *************** *** 6877,6880 **** --- 6877,6925 ---- + echo $ac_n "checking for broken nice()""... $ac_c" 1>&6 + echo "configure:6881: checking for broken nice()" >&5 + if eval "test \"`echo '$''{'ac_cv_broken_nice'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null + then + ac_cv_broken_nice=yes + else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_broken_nice=no + fi + rm -fr conftest* + fi + + fi + + echo "$ac_t""$ac_cv_broken_nice" 1>&6 + if test "$ac_cv_broken_nice" = yes + then + cat >> confdefs.h <<\EOF + #define HAVE_BROKEN_NICE 1 + EOF + + fi + # THIS MUST BE LAST, IT CAN BREAK OTHER TESTS! # Add sys/socket.h to confdefs.h *************** *** 6885,6894 **** EOF echo $ac_n "checking for socklen_t""... $ac_c" 1>&6 ! echo "configure:6888: checking for socklen_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_socklen_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < --- 6930,6939 ---- EOF echo $ac_n "checking for socklen_t""... $ac_c" 1>&6 ! echo "configure:6933: checking for socklen_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_socklen_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < *************** *** 6939,6943 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6942: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then --- 6984,6988 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6987: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.226 retrieving revision 1.227 diff -C2 -r1.226 -r1.227 *** configure.in 2001/07/11 14:45:34 1.226 --- configure.in 2001/07/11 22:35:31 1.227 *************** *** 546,550 **** sys/param.h sys/select.h sys/socket.h sys/time.h sys/times.h \ sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ ! ndbm.h db1/ndbm.h gdbm/ndbm.h) AC_HEADER_DIRENT --- 546,550 ---- sys/param.h sys/select.h sys/socket.h sys/time.h sys/times.h \ sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ ! ndbm.h db1/ndbm.h gdbm/ndbm.h sys/resource.h) AC_HEADER_DIRENT *************** *** 1671,1674 **** --- 1671,1691 ---- AC_CHECK_LIB(readline, rl_completion_matches, AC_DEFINE(HAVE_RL_COMPLETION_MATCHES), , -ltermcap) + + AC_MSG_CHECKING(for broken nice()) + AC_CACHE_VAL(ac_cv_broken_nice, [ + AC_TRY_RUN([ + int main() + { + int val1 = nice(1); + if (val1 != -1 && val1 == nice(2)) + exit(0); + exit(1); + } + ],ac_cv_broken_nice=yes, ac_cv_broken_nice=no)]) + AC_MSG_RESULT($ac_cv_broken_nice) + if test "$ac_cv_broken_nice" = yes + then + AC_DEFINE(HAVE_BROKEN_NICE) + fi # THIS MUST BE LAST, IT CAN BREAK OTHER TESTS! From fdrake@users.sourceforge.net Thu Jul 12 03:08:31 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 11 Jul 2001 19:08:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/doc doc.tex,1.44,1.45 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/doc In directory usw-pr-cvs1:/tmp/cvs-serv15356/doc Modified Files: doc.tex Log Message: For \kbd, be more prescriptive regarding how keystrokes should be written. Index: doc.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/doc/doc.tex,v retrieving revision 1.44 retrieving revision 1.45 diff -C2 -r1.44 -r1.45 *** doc.tex 2001/07/09 16:04:03 1.44 --- doc.tex 2001/07/12 02:08:29 1.45 *************** *** 788,793 **** Mark a sequence of keystrokes. What form \var{key sequence} takes may depend on platform- or application-specific ! conventions. For example, an \program{xemacs} key sequence ! may be marked like \code{\e kbd\{C-x C-f\}}. \end{macrodesc} --- 788,798 ---- Mark a sequence of keystrokes. What form \var{key sequence} takes may depend on platform- or application-specific ! conventions. When there are no relevant conventions, the names ! of modifier keys should be spelled out, to improve accessibility ! for new users and non-native speakers. For example, an ! \program{xemacs} key sequence may be marked like ! \code{\e kbd\{C-x C-f\}}, but without reference to a specific ! application or platform, the same sequence should be marked as ! \code{\e kbd\{Control-x Control-f\}}. \end{macrodesc} From fdrake@users.sourceforge.net Thu Jul 12 03:09:53 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 11 Jul 2001 19:09:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libcmd.tex,1.8,1.9 libcurses.tex,1.33,1.34 libexcs.tex,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv15514/lib Modified Files: libcmd.tex libcurses.tex libexcs.tex Log Message: Follow the recommended practices for keystroke representation; this improves internal consistency in the documentation. Index: libcmd.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcmd.tex,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** libcmd.tex 2001/06/23 14:42:43 1.8 --- libcmd.tex 2001/07/12 02:09:51 1.9 *************** *** 34,41 **** If the \module{readline} module is loaded, input will automatically ! inherit \program{bash}-like history-list editing (e.g. \kbd{Ctrl-P} ! scrolls back to the last command, \kbd{Ctrl-N} forward to the next ! one, \kbd{Ctrl-F} moves the cursor to the right non-destructively, ! \kbd{Ctrl-B} moves the cursor to the left non-destructively, etc.). An end-of-file on input is passed back as the string \code{'EOF'}. --- 34,41 ---- If the \module{readline} module is loaded, input will automatically ! inherit \program{bash}-like history-list editing (e.g. \kbd{Control-P} ! scrolls back to the last command, \kbd{Control-N} forward to the next ! one, \kbd{Control-F} moves the cursor to the right non-destructively, ! \kbd{Control-B} moves the cursor to the left non-destructively, etc.). An end-of-file on input is passed back as the string \code{'EOF'}. Index: libcurses.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcurses.tex,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -r1.33 -r1.34 *** libcurses.tex 2001/07/06 19:28:48 1.33 --- libcurses.tex 2001/07/12 02:09:51 1.34 *************** *** 1305,1322 **** \begin{tableii}{l|l}{kbd}{Keystroke}{Action} ! \lineii{Ctrl-A}{Go to left edge of window.} ! \lineii{Ctrl-B}{Cursor left, wrapping to previous line if appropriate.} ! \lineii{Ctrl-D}{Delete character under cursor.} ! \lineii{Ctrl-E}{Go to right edge (stripspaces off) or end of line (stripspaces on).} ! \lineii{Ctrl-F}{Cursor right, wrapping to next line when appropriate.} ! \lineii{Ctrl-G}{Terminate, returning the window contents.} ! \lineii{Ctrl-H}{Delete character backward.} ! \lineii{Ctrl-J}{Terminate if the window is 1 line, otherwise insert newline.} ! \lineii{Ctrl-K}{If line is blank, delete it, otherwise clear to end of line.} ! \lineii{Ctrl-L}{Refresh screen.} ! \lineii{Ctrl-N}{Cursor down; move down one line.} ! \lineii{Ctrl-O}{Insert a blank line at cursor location.} ! \lineii{Ctrl-P}{Cursor up; move up one line.} \end{tableii} --- 1305,1324 ---- \begin{tableii}{l|l}{kbd}{Keystroke}{Action} ! \lineii{Control-A}{Go to left edge of window.} ! \lineii{Control-B}{Cursor left, wrapping to previous line if appropriate.} ! \lineii{Control-D}{Delete character under cursor.} ! \lineii{Control-E}{Go to right edge (stripspaces off) or end of line (stripspaces on).} ! \lineii{Control-F}{Cursor right, wrapping to next line when appropriate.} ! \lineii{Control-G}{Terminate, returning the window contents.} ! \lineii{Control-H}{Delete character backward.} ! \lineii{Control-J}{Terminate if the window is 1 line, otherwise ! insert newline.} ! \lineii{Control-K}{If line is blank, delete it, otherwise clear to ! end of line.} ! \lineii{Control-L}{Refresh screen.} ! \lineii{Control-N}{Cursor down; move down one line.} ! \lineii{Control-O}{Insert a blank line at cursor location.} ! \lineii{Control-P}{Cursor up; move up one line.} \end{tableii} *************** *** 1326,1334 **** \begin{tableii}{l|l}{constant}{Constant}{Keystroke} ! \lineii{KEY_LEFT}{\kbd{Ctrl-B}} ! \lineii{KEY_RIGHT}{\kbd{Ctrl-F}} ! \lineii{KEY_UP}{\kbd{Ctrl-P}} ! \lineii{KEY_DOWN}{\kbd{Ctrl-N}} ! \lineii{KEY_BACKSPACE}{\kbd{Ctrl-h}} \end{tableii} --- 1328,1336 ---- \begin{tableii}{l|l}{constant}{Constant}{Keystroke} ! \lineii{KEY_LEFT}{\kbd{Control-B}} ! \lineii{KEY_RIGHT}{\kbd{Control-F}} ! \lineii{KEY_UP}{\kbd{Control-P}} ! \lineii{KEY_DOWN}{\kbd{Control-N}} ! \lineii{KEY_BACKSPACE}{\kbd{Control-h}} \end{tableii} Index: libexcs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libexcs.tex,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -r1.37 -r1.38 *** libexcs.tex 2001/05/03 04:39:10 1.37 --- libexcs.tex 2001/07/12 02:09:51 1.38 *************** *** 178,182 **** \begin{excdesc}{KeyboardInterrupt} Raised when the user hits the interrupt key (normally ! \kbd{Control-C} or \kbd{DEL}). During execution, a check for interrupts is made regularly. % XXXJH xrefs here --- 178,182 ---- \begin{excdesc}{KeyboardInterrupt} Raised when the user hits the interrupt key (normally ! \kbd{Control-C} or \kbd{Delete}). During execution, a check for interrupts is made regularly. % XXXJH xrefs here From esr@users.sourceforge.net Thu Jul 12 03:39:47 2001 From: esr@users.sourceforge.net (Eric S. Raymond) Date: Wed, 11 Jul 2001 19:39:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libxmlrpclib.tex,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv19812 Added Files: libxmlrpclib.tex Log Message: First version of xmlrpclib docs. Probably has markup errors; is not complete, could probably stand to have some of the internal things like Marshaller documented. But I think it does a decent job on the entry points and externally visible things. Fred and Fredrik, do your stuff! You both need to proof this. --- NEW FILE: libxmlrpclib.tex --- \section{\module{xmlrpclib} --- XML-RPC client access} \declaremodule{standard}{xmlrpclib} \modulesynopsis{XML-RPC client access.} \moduleauthor{Fredrik Lundh}{effbot@telia.com} \sectionauthor{Eric S. Raymond}{esr@snark.thyrsus.com} % Not everyting is documented yet. It might be good to describe % Marshaller, Unmarshaller, getparser, dumps, loads, and Transport. \versionadded{2.2} XML-RPC is a Remote Procedure Call method that uses XML passed via HTTP as a transport. With it, a client can call methods with parameters on a remote server (the server is named by a URI) and get back structured data. This module supports writing XML-RPC client code; it handles all the details of translating between conformable Python objects and XML on the wire. \begin{seealso} \seetitle{http://xmlrpc-c.sourceforge.net/xmlrpc-howto/xmlrpc-howto.html} {XML-RPC HOWTO}{A good description of XML operation and client software in several languages. Contains pretty much everything an XML-RPC client developer needs to know.} \seetitle{http://xmlrpc-c.sourceforge.net/hacks.php} {XML-RPC-Hacks page}{Extensions for various open-source libraries to support instrospection and multicall.} \end{seealso} \begin{classdesc}{Server}{\optional{uri\optional{, transport, encoding, verbose}}} A \class{Server} instance is a server proxy that manages communication with a remote XML-RPC server. The required first argument is a URI (Uniform Resource Indicator), and will normally be the URL of the server. The optional second argument is a transport factory instance; by default it is an internal \class{SafeTransport} instance for https: URLs and an internal HTTP \class{Transport} instance otherwise. The optional third argument is an encoding, by default UTF-8. The optional fourth argument is a debugging flag. The returned instance is a proxy object with methods that can be used to invoke corresponding RPC calls on the remote server. If the remote server supports the introspection API, the proxy can also be used to query the remote server for the methods it supports (service discovery) and fetch other server-associated metadata. \class{Server} instance methods take Python basic types and objects as arguments and return Python basic types and classes. Types that are conformable (e.g. that can be marshalled through XML), include the following (and except where noted, they are unmarshalled as the same Python type): \begin{tableii}{l|l}{constant}{Name}{Meaning} \lineii{boolean}{The True and False constants that then module supplies} \lineii{integers}{Pass in directly} \lineii{floating-point numbers}{Pass in directly} \lineii{strings}{Pass in directly} \lineii{arrays}{Any Python sequence type containing conformable elements. Arrays are returned as lists} \lineii{structures}{A Python dictionary. Keys must be strings, values may be any conformable type.} \lineii{dates}{in seconds since the epoch; pass in an instance of the \class{DateTime} wrapper class} \lineii{binary data}{pass in an instance of the \class{Binary} wrapper class} \end{tableii} This is the full set of data types supported by XML-RPC. Method calls may also return a special \class{Fault} instance, used to signal XML-RPCserver errors, or a \class{ProtocolError} instance used to signal an error in the HTTP/HTTPS transport layer. \end{classdesc} \subsection{Server Objects \label{server-objects}} A \class{Server} instance proxy object has a method corresponding to each remote procedure call accepted by the XML-RPC server. Calling the method performs an RPC, dispatched by both name and argument signature (e.g. the same method name can be overloaded with multiple argument signatures). The RPC finishes by returning a value, which may be either returned data in a conformant type or a \class{Fault} or \class{ProtocolError} object indicating an error. Servers that support the XML introspection API support some common methods grouped under the reserved \member{system} member: \begin{methoddesc}{system.listMethods}{} This method returns a list of strings, one for each (non-system) method supported by the XML-RPC server. \end{methoddesc} \begin{methoddesc}{system.methodHelp}{name} This method takes one parameter, the name of a method implemented by the XML-RPC server.It returns an array of possible signatures for this method. A signature is an array of types. The first of these types is the return type of the method, the rest are parameters. Because multiple signatures (ie. overloading) is permitted, this method returns a list of signatures rather than a singleton. Signatures themselves are restricted to the top level parameters expected by a method. For instance if a method expects one array of structs as a parameter, and it returns a string, its signature is simply "string, array". If it expects three integers and returns a string, its signature is "string, int, int, int". If no signature is defined for the method, a non-array value is returned. In Python this means that the type of the returned value will be something other that list. \end{methoddesc} \begin{methoddesc}{system.methodHelp}{name} This method takes one parameter, the name of a method implemented by the XML-RPC server. It returns a documentation string describing the use of that method. If no such string is available, an empty string is returned. The documentation string may contain HTML markup. \end{methoddesc} Introspection methods are currently supported by servers written in PHP, C and Microsoft .NET. Partial introspection support is included in recent updates to UserLand Frontier. Introspection support for Perl, Python and Java is available at the XML-RPC Hacks page. \subsection{Boolean Objects \label{boolean-objects}} This class may be initialized from any Python value; the instance returned depends onlyon its truth value. It supports various Python operators through \class{__cmp__}, \class{__repr__}, \class{__int__}, and \class{__nonzero__} methods, all implemented in the obvious ways. It also has the following method, supported mainly for internal use by the unmarshalling code: \begin{methoddesc}{encode}{out} Write the XML-RPC encoding of this Boolean item to the out stream object. \end{methoddesc} \subsection{DateTime Objects \label{datetime-objects}} This class may initialized from date in seconds since the epoch, a time tuple, or an ISO 8601 time/date string. It has the following methods, supported mainly for internal use by the marshalling/unmarshalling code: \begin{methoddesc}{decode}{string} Accept a string as the instance's new time value. \end{methoddesc} \begin{methoddesc}{encode}{out} Write the XML-RPC encoding of this DateTime item to the out stream object. \end{methoddesc} It also supports certain of Python's built-in operators through \method{_cmp__} and \method{__repr__} methods. \subsection{Binary Objects \label{binary-objects}} This class may initialized from string data (which may include NULs). It has the following methods, supported mainly for internal use by the marshalling/unmarshalling code: \begin{methoddesc}{decode}{string} Accept a base64 string and decode it as the instance's new data. \end{methoddesc} \begin{methoddesc}{encode}{out} Write the XML-RPC base 64 encoding of this binary item to the out stream object. \end{methoddesc} It also supports certain of Python's built-in operators through a \method{_cmp__} method. \subsection{Fault Objects \label{fault-objects}} A \class{Fault} object encapsulates the content of an XML-RPC fault tag. Fault objects have the following members: \begin{memberdesc}{faultCode} A string indicating the fault type. \end{memberdesc} \begin{memberdesc}{faultString} A string containing a diagnostic message associated with the fault. \end{memberdesc} \subsection{ProtocolError Objects \label{protocol-error-objects}} A \class{ProtocolError} object describes a protocol error in the underlying transport layer (such as a 404 `not found' error if the server named by the URI does not exist). It has the following members: \begin{memberdesc}{url} The URI or URL that triggered te error. \end{memberdesc} \begin{memberdesc}{errcode} The error code. \end{memberdesc} \begin{memberdesc}{errmsg} The eror message of diagnostic string. \end{memberdesc} \begin{memberdesc}{headers} A string containing the headers of the HTTP/HTTPS request that triggered the error. \end{memberdesc} \subsection{Convenience Functions} \begin{funcdesc}{boolean}{value, \optional{truefals=(False, True)}} Convert any Python value to one of the XML-RPC boolean constants. The optional second argument supplies a conversion table to be indexed by the first argument's Python truth value. \end{funcdesc} \begin{funcdesc}{binary}{data} Trivially convert any Python string to a \class{Binary} object. \end{funcdesc} \subsection{Example of Client Usage \begin{verbatim} # simple test program (from the XML-RPC specification) # server = Server("http://localhost:8000") # local server server = Server("http://betty.userland.com") print server try: print server.examples.getStateName(41) except Error, v: print "ERROR", v \end{verbatim} % End From tim_one@users.sourceforge.net Thu Jul 12 06:20:15 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 11 Jul 2001 22:20:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib site.py,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv11147/python/dist/src/lib Modified Files: site.py Log Message: PEP 250: Add lib/site-packages to sys.path on Windows; also sys.prefix to sys.path if os.sep == ':' (Macs?). See PEP 250. Index: site.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/site.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -r1.28 -r1.29 *** site.py 2001/07/02 16:55:42 1.28 --- site.py 2001/07/12 05:20:13 1.29 *************** *** 142,149 **** "site-packages"), os.path.join(prefix, "lib", "site-python")] - elif os.sep == ':': - sitedirs = [os.path.join(prefix, "lib", "site-packages")] else: ! sitedirs = [prefix] for sitedir in sitedirs: if os.path.isdir(sitedir): --- 142,147 ---- "site-packages"), os.path.join(prefix, "lib", "site-python")] else: ! sitedirs = [prefix, os.path.join(prefix, "lib", "site-packages")] for sitedir in sitedirs: if os.path.isdir(sitedir): From gvanrossum@users.sourceforge.net Thu Jul 12 12:19:47 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 12 Jul 2001 04:19:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects intobject.c,2.57,2.58 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv4513 Modified Files: intobject.c Log Message: On int to the negative integral power, let float handle it instead of raising an error. This was one of the two issues that the VPython folks were particularly problematic for their students. (The other one was integer division...) This implements (my) SF patch #440487. Index: intobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v retrieving revision 2.57 retrieving revision 2.58 diff -C2 -r2.57 -r2.58 *** intobject.c 2001/06/18 19:21:11 2.57 --- intobject.c 2001/07/12 11:19:45 2.58 *************** *** 511,521 **** CONVERT_TO_LONG(w, iw); if (iw < 0) { ! if (iv) ! PyErr_SetString(PyExc_ValueError, ! "cannot raise integer to a negative power"); ! else ! PyErr_SetString(PyExc_ZeroDivisionError, ! "cannot raise 0 to a negative power"); ! return NULL; } if ((PyObject *)z != Py_None) { --- 511,519 ---- CONVERT_TO_LONG(w, iw); if (iw < 0) { ! /* Return a float. This works because we know that ! this calls float_pow() which converts its ! arguments to double. */ ! return PyFloat_Type.tp_as_number->nb_power( ! (PyObject *)v, (PyObject *)w, (PyObject *)z); } if ((PyObject *)z != Py_None) { From gvanrossum@users.sourceforge.net Thu Jul 12 12:21:19 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 12 Jul 2001 04:21:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.83,1.84 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv4886 Modified Files: longobject.c Log Message: On long to the negative long power, let float handle it instead of raising an error. This was one of the two issues that the VPython folks were particularly problematic for their students. (The other one was integer division...) This implements (my) SF patch #440487. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.83 retrieving revision 1.84 diff -C2 -r1.83 -r1.84 *** longobject.c 2001/06/16 08:48:40 1.83 --- longobject.c 2001/07/12 11:21:17 1.84 *************** *** 1544,1555 **** size_b = b->ob_size; if (size_b < 0) { ! if (a->ob_size) ! PyErr_SetString(PyExc_ValueError, ! "long integer to a negative power"); ! else ! PyErr_SetString(PyExc_ZeroDivisionError, ! "zero to a negative power"); ! z = NULL; ! goto error; } z = (PyLongObject *)PyLong_FromLong(1L); --- 1544,1554 ---- size_b = b->ob_size; if (size_b < 0) { ! /* Return a float. This works because we know that ! this calls float_pow() which converts its ! arguments to double. */ ! Py_DECREF(a); ! Py_DECREF(b); ! Py_DECREF(c); ! return PyFloat_Type.tp_as_number->nb_power(v, w, x); } z = (PyLongObject *)PyLong_FromLong(1L); From gvanrossum@users.sourceforge.net Thu Jul 12 12:27:18 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 12 Jul 2001 04:27:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libfuncs.tex,1.79,1.80 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv5779 Modified Files: libfuncs.tex Log Message: On int/long to the negative int/long power, let float handle it instead of raising an error. This was one of the two issues that the VPython folks were particularly problematic for their students. (The other one was integer division...) This implements (my) SF patch #440487. Index: libfuncs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfuncs.tex,v retrieving revision 1.79 retrieving revision 1.80 diff -C2 -r1.79 -r1.80 *** libfuncs.tex 2001/07/06 19:28:48 1.79 --- libfuncs.tex 2001/07/12 11:27:16 1.80 *************** *** 495,505 **** Return \var{x} to the power \var{y}; if \var{z} is present, return \var{x} to the power \var{y}, modulo \var{z} (computed more ! efficiently than \code{pow(\var{x}, \var{y}) \%\ \var{z}}). ! The arguments must have ! numeric types. With mixed operand types, the rules for binary ! arithmetic operators apply. The effective operand type is also the ! type of the result; if the result is not expressible in this type, the ! function raises an exception; for example, \code{pow(2, -1)} or ! \code{pow(2, 35000)} is not allowed. \end{funcdesc} --- 495,508 ---- Return \var{x} to the power \var{y}; if \var{z} is present, return \var{x} to the power \var{y}, modulo \var{z} (computed more ! efficiently than \code{pow(\var{x}, \var{y}) \%\ \var{z}}). The ! arguments must have numeric types. With mixed operand types, the ! coercion rules for binary arithmetic operators apply. For int and ! long int operands, the result has the same type as the operands ! (after coercion) unless the second argument is negative; in that ! case, all arguments are converted to float and a float result is ! delivered. For example, \code{10**2} returns \code{100}, but ! \code{10**-2} returns \code{0.01}. (This last feature was added in ! Python 2.2. In Python 2.1 and before, a negative second argument ! would raise an exception.) \end{funcdesc} From gvanrossum@users.sourceforge.net Thu Jul 12 12:54:40 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 12 Jul 2001 04:54:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.188,1.189 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv10784 Modified Files: NEWS Log Message: Add xmlrpc. (Tim & I should agree on where to add new additions: I add them at the top, Tim adds them at the bottom. I like the top better because folks who occasionally check out the NEWS file will see the latest news first.) Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.188 retrieving revision 1.189 diff -C2 -r1.188 -r1.189 *** NEWS 2001/07/05 14:46:25 1.188 --- NEWS 2001/07/12 11:54:37 1.189 *************** *** 139,142 **** --- 139,147 ---- Library + - Fredrik Lundh's xmlrpclib is now a standard library module. This + provides full client-side XML-RPC support. In addition, + Demo/xmlrpc/ contains two server frameworks (one SocketServer-based, + one asyncore-based). Thanks to Eric Raymond for the documentation. + - The xrange() object is simplified: it no longer supports slicing, repetition, comparisons, efficient 'in' checking, the tolist() From twouters@users.sourceforge.net Thu Jul 12 13:26:44 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Thu, 12 Jul 2001 05:26:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/PC WinMain.c,1.6,1.6.6.1 Message-ID: Update of /cvsroot/python/python/dist/src/PC In directory usw-pr-cvs1:/tmp/cvs-serv18231/PC Modified Files: Tag: release21-maint WinMain.c Log Message: Backport Tim's checkin 1.7: SF bug 418296: WinMain.c should use WIN32_LEAN_AND_MEAN. I believe Kevin Rodgers here! The old WINDOWS_LEAN_AND_MEAN has, AFAICT, always been wrong. Index: WinMain.c =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/WinMain.c,v retrieving revision 1.6 retrieving revision 1.6.6.1 diff -C2 -r1.6 -r1.6.6.1 *** WinMain.c 2000/07/22 23:59:33 1.6 --- WinMain.c 2001/07/12 12:26:42 1.6.6.1 *************** *** 1,5 **** /* Minimal main program -- everything is loaded from the library. */ ! #define WINDOWS_LEAN_AND_MEAN #include --- 1,5 ---- /* Minimal main program -- everything is loaded from the library. */ ! #define WIN32_LEAN_AND_MEAN #include From twouters@users.sourceforge.net Thu Jul 12 13:28:12 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Thu, 12 Jul 2001 05:28:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib pipes.py,1.8,1.8.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv19105/Lib Modified Files: Tag: release21-maint pipes.py Log Message: Backport Tim's checkin 1.9: SF bug 418615: regular expression bug in pipes.py. Obviously bad regexps, spotted by Jeffery Collins. Index: pipes.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pipes.py,v retrieving revision 1.8 retrieving revision 1.8.4.1 diff -C2 -r1.8 -r1.8.4.1 *** pipes.py 2001/02/07 23:14:30 1.8 --- pipes.py 2001/07/12 12:28:10 1.8.4.1 *************** *** 124,131 **** raise ValueError, \ 'Template.append: already ends with SINK' ! if kind[0] == 'f' and not re.search('\$IN\b', cmd): raise ValueError, \ 'Template.append: missing $IN in cmd' ! if kind[1] == 'f' and not re.search('\$OUT\b', cmd): raise ValueError, \ 'Template.append: missing $OUT in cmd' --- 124,131 ---- raise ValueError, \ 'Template.append: already ends with SINK' ! if kind[0] == 'f' and not re.search(r'\$IN\b', cmd): raise ValueError, \ 'Template.append: missing $IN in cmd' ! if kind[1] == 'f' and not re.search(r'\$OUT\b', cmd): raise ValueError, \ 'Template.append: missing $OUT in cmd' *************** *** 146,153 **** raise ValueError, \ 'Template.prepend: already begins with SOURCE' ! if kind[0] == 'f' and not re.search('\$IN\b', cmd): raise ValueError, \ 'Template.prepend: missing $IN in cmd' ! if kind[1] == 'f' and not re.search('\$OUT\b', cmd): raise ValueError, \ 'Template.prepend: missing $OUT in cmd' --- 146,153 ---- raise ValueError, \ 'Template.prepend: already begins with SOURCE' ! if kind[0] == 'f' and not re.search(r'\$IN\b', cmd): raise ValueError, \ 'Template.prepend: missing $IN in cmd' ! if kind[1] == 'f' and not re.search(r'\$OUT\b', cmd): raise ValueError, \ 'Template.prepend: missing $OUT in cmd' From twouters@users.sourceforge.net Thu Jul 12 13:43:13 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Thu, 12 Jul 2001 05:43:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules mmapmodule.c,2.27,2.27.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv22342/Modules Modified Files: Tag: release21-maint mmapmodule.c Log Message: Net result of Tim's checkins 2.28 through 2.31: - SF but #417587: compiler warnings compiling 2.1. Repaired *some* of the SGI compiler warnings Sjoerd Mullender reported. - Minor fiddling related to SF patch 416251 2.1c1 mmapmodule: unused vrbl cleanup - Fix the .find() method for memory maps. 1) it didn't obey the "start" parameter (and when it does, we must validate the value) 2) the return value needs to be an absolute index, rather than relative to some arbitrary point in the file (checking CVS, it appears this method never worked; these changes bring it into line with typical .find() behavior) - Fix new compiler warnings. Also boost "start" from (C) int to long and return a (C) long: PyArg_ParseTuple and Py_BuildValue may not let us get at the size_t we really want, but C int is clearly too small for a 64-bit box, and both the start parameter and the return value should work for large mapped files even on 32-bit boxes. The code really needs to be rethought from scratch (not by me, though ...). Index: mmapmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/mmapmodule.c,v retrieving revision 2.27 retrieving revision 2.27.4.1 diff -C2 -r2.27 -r2.27.4.1 *** mmapmodule.c 2001/01/14 05:05:51 2.27 --- mmapmodule.c 2001/07/12 12:43:11 2.27.4.1 *************** *** 164,177 **** PyObject *args) { - char value; - char *where; CHECK_VALID(NULL); if (!PyArg_ParseTuple(args, ":read_byte")) return NULL; if (self->pos < self->size) { ! where = self->data + self->pos; ! value = (char) *(where); self->pos += 1; ! return Py_BuildValue("c", (char) *(where)); } else { PyErr_SetString (PyExc_ValueError, "read byte out of range"); --- 164,174 ---- PyObject *args) { CHECK_VALID(NULL); if (!PyArg_ParseTuple(args, ":read_byte")) return NULL; if (self->pos < self->size) { ! char value = self->data[self->pos]; self->pos += 1; ! return Py_BuildValue("c", value); } else { PyErr_SetString (PyExc_ValueError, "read byte out of range"); *************** *** 228,241 **** PyObject *args) { ! int start = self->pos; char *needle; int len; CHECK_VALID(NULL); ! if (!PyArg_ParseTuple (args, "s#|i:find", &needle, &len, &start)) { return NULL; } else { ! char *p = self->data+self->pos; ! char *e = self->data+self->size; while (p < e) { char *s = p; --- 225,247 ---- PyObject *args) { ! long start = self->pos; char *needle; int len; CHECK_VALID(NULL); ! if (!PyArg_ParseTuple (args, "s#|l:find", &needle, &len, &start)) { return NULL; } else { ! char *p; ! char *e = self->data + self->size; ! ! if (start < 0) ! start += self->size; ! if (start < 0) ! start = 0; ! else if ((size_t)start > self->size) ! start = self->size; ! p = self->data + start; ! while (p < e) { char *s = p; *************** *** 246,251 **** if (!*n) { return Py_BuildValue ( ! "i", ! (int) (p - (self->data + start))); } p++; --- 252,257 ---- if (!*n) { return Py_BuildValue ( ! "l", ! (long) (p - self->data)); } p++; *************** *** 819,823 **** prot, flags, fd, 0); ! if (m_obj->data == (void *)-1) { Py_DECREF(m_obj); --- 825,829 ---- prot, flags, fd, 0); ! if (m_obj->data == (char *)-1) { Py_DECREF(m_obj); From gvanrossum@users.sourceforge.net Thu Jul 12 13:50:25 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 12 Jul 2001 05:50:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include compile.h,2.30,2.31 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv24799 Modified Files: compile.h Log Message: Enable nested scopes by default. Although this is a one-character change, more work needs to be done: the compiler can get rid of a lot of non-nested-scopes code, the documentation needs to be updated, the future statement can be simplified, etc. But this change enables the nested scope semantics everywhere, and that's the important part -- we can now test code for compatibility with nested scopes by default. Index: compile.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/compile.h,v retrieving revision 2.30 retrieving revision 2.31 diff -C2 -r2.30 -r2.31 *** compile.h 2001/06/18 22:08:13 2.30 --- compile.h 2001/07/12 12:50:23 2.31 *************** *** 63,67 **** PyCompilerFlags *); ! #define NESTED_SCOPES_DEFAULT 0 #define FUTURE_NESTED_SCOPES "nested_scopes" --- 63,67 ---- PyCompilerFlags *); ! #define NESTED_SCOPES_DEFAULT 1 #define FUTURE_NESTED_SCOPES "nested_scopes" From gvanrossum@users.sourceforge.net Thu Jul 12 13:51:24 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 12 Jul 2001 05:51:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_pow.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv24982 Modified Files: test_pow.py Log Message: Make the test pass now that 10**-15 returns a float instead of raising an exception. Index: test_pow.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pow.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** test_pow.py 2000/12/12 23:11:42 1.7 --- test_pow.py 2001/07/12 12:51:22 1.8 *************** *** 33,39 **** pow(ii, jj) except ValueError: ! pass # taking an int to a neg int power should fail ! else: ! raise ValueError, "pow(%s, %s) did not fail" % (ii, jj) for othertype in int, long, float: --- 33,37 ---- pow(ii, jj) except ValueError: ! raise ValueError, "pow(%s, %s) failed" % (ii, jj) for othertype in int, long, float: From nascheme@users.sourceforge.net Thu Jul 12 14:25:55 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Thu, 12 Jul 2001 06:25:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_gc.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv1072/Lib/test Modified Files: test_gc.py Log Message: Test GC of frame objects. Index: test_gc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_gc.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** test_gc.py 2001/01/17 19:11:13 1.7 --- test_gc.py 2001/07/12 13:25:53 1.8 *************** *** 1,3 **** --- 1,4 ---- from test_support import verify, verbose, TestFailed + import sys import gc *************** *** 108,111 **** --- 109,121 ---- raise TestFailed + def test_frame(): + def f(): + frame = sys._getframe() + gc.collect() + f() + if gc.collect() != 1: + raise TestFailed + + def test_saveall(): # Verify that cyclic garbage like lists show up in gc.garbage if the *************** *** 153,156 **** --- 163,167 ---- run_test("methods", test_method) run_test("functions", test_function) + run_test("frames", test_frame) run_test("finalizers", test_finalizer) run_test("__del__", test_del) From nascheme@users.sourceforge.net Thu Jul 12 14:26:43 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Thu, 12 Jul 2001 06:26:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv1353/Lib/test Modified Files: test_generators.py Log Message: Remove reference cycle breaking code. The GC now takes care of it. Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -r1.17 -r1.18 *** test_generators.py 2001/07/04 22:11:22 1.17 --- test_generators.py 2001/07/12 13:26:41 1.18 *************** *** 485,490 **** merged A into G A->G B->G C->G D->G E->G F->G G->G H->G I->G J->G K->G L->G M->G - >>> for s in sets: # XXX memory leak without this - ... s.clear() """ --- 485,488 ---- *************** *** 615,619 **** Print as many of these as you like -- *this* implementation is memory- ! efficient. XXX Except that it leaks unless you clear the dict! >>> m235 = LazyList(m235()) --- 613,617 ---- Print as many of these as you like -- *this* implementation is memory- ! efficient. >>> m235 = LazyList(m235()) *************** *** 626,632 **** [400, 405, 432, 450, 480, 486, 500, 512, 540, 576, 600, 625, 640, 648, 675] - >>> m235.clear() # XXX memory leak without this - Ye olde Fibonacci generator, LazyList style. --- 624,628 ---- *************** *** 651,656 **** >>> firstn(iter(fib), 17) [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584] - - >>> fib.clear() # XXX memory leak without this """ --- 647,650 ---- From nascheme@users.sourceforge.net Thu Jul 12 14:27:13 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Thu, 12 Jul 2001 06:27:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects frameobject.c,2.52,2.53 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv1503/Objects Modified Files: frameobject.c Log Message: GC for frame objects. Index: frameobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/frameobject.c,v retrieving revision 2.52 retrieving revision 2.53 diff -C2 -r2.52 -r2.53 *** frameobject.c 2001/06/23 05:26:56 2.52 --- frameobject.c 2001/07/12 13:27:11 2.53 *************** *** 71,74 **** --- 71,75 ---- Py_TRASHCAN_SAFE_BEGIN(f) + PyObject_GC_Fini(f); /* Kill all local variables */ slots = f->f_nlocals + f->f_ncells + f->f_nfreevars; *************** *** 98,116 **** } PyTypeObject PyFrame_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, "frame", ! sizeof(PyFrameObject), 0, ! (destructor)frame_dealloc, /*tp_dealloc*/ ! 0, /*tp_print*/ ! (getattrfunc)frame_getattr, /*tp_getattr*/ ! (setattrfunc)frame_setattr, /*tp_setattr*/ ! 0, /*tp_compare*/ ! 0, /*tp_repr*/ ! 0, /*tp_as_number*/ ! 0, /*tp_as_sequence*/ ! 0, /*tp_as_mapping*/ }; --- 99,198 ---- } + static int + frame_traverse(PyFrameObject *f, visitproc visit, void *arg) + { + PyObject **fastlocals, **p; + int i, err, slots; + #define VISIT(o) if (o) {if ((err = visit((PyObject *)(o), arg))) return err;} + + VISIT(f->f_back); + VISIT(f->f_code); + VISIT(f->f_builtins); + VISIT(f->f_globals); + VISIT(f->f_locals); + VISIT(f->f_trace); + VISIT(f->f_exc_type); + VISIT(f->f_exc_value); + VISIT(f->f_exc_traceback); + + /* locals */ + slots = f->f_nlocals + f->f_ncells + f->f_nfreevars; + fastlocals = f->f_localsplus; + for (i = slots; --i >= 0; ++fastlocals) { + VISIT(*fastlocals); + } + + /* stack */ + if (f->f_stacktop != NULL) { + for (p = f->f_valuestack; p < f->f_stacktop; p++) + VISIT(*p); + } + + return 0; + } + + static void + frame_clear(PyFrameObject *f) + { + PyObject **fastlocals, **p; + int i, slots; + + Py_XDECREF(f->f_exc_type); + f->f_exc_type = NULL; + + Py_XDECREF(f->f_exc_value); + f->f_exc_value = NULL; + + Py_XDECREF(f->f_exc_traceback); + f->f_exc_traceback = NULL; + + Py_XDECREF(f->f_trace); + f->f_trace = NULL; + + /* locals */ + slots = f->f_nlocals + f->f_ncells + f->f_nfreevars; + fastlocals = f->f_localsplus; + for (i = slots; --i >= 0; ++fastlocals) { + if (*fastlocals != NULL) { + Py_XDECREF(*fastlocals); + *fastlocals = NULL; + } + } + + /* stack */ + if (f->f_stacktop != NULL) { + for (p = f->f_valuestack; p < f->f_stacktop; p++) { + Py_XDECREF(*p); + *p = NULL; + } + } + } + + PyTypeObject PyFrame_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, "frame", ! sizeof(PyFrameObject) + PyGC_HEAD_SIZE, 0, ! (destructor)frame_dealloc, /* tp_dealloc */ ! 0, /* tp_print */ ! (getattrfunc)frame_getattr, /* tp_getattr */ ! (setattrfunc)frame_setattr, /* 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 */ ! 0, /* tp_getattro */ ! 0, /* tp_setattro */ ! 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */ ! 0, /* tp_doc */ ! (traverseproc)frame_traverse, /* tp_traverse */ ! (inquiry)frame_clear, /* tp_clear */ }; *************** *** 156,162 **** f = (PyFrameObject *) PyObject_MALLOC(sizeof(PyFrameObject) + ! extras*sizeof(PyObject *)); if (f == NULL) return (PyFrameObject *)PyErr_NoMemory(); PyObject_INIT(f, &PyFrame_Type); f->f_size = extras; --- 238,246 ---- f = (PyFrameObject *) PyObject_MALLOC(sizeof(PyFrameObject) + ! extras*sizeof(PyObject *) + ! PyGC_HEAD_SIZE); if (f == NULL) return (PyFrameObject *)PyErr_NoMemory(); + f = (PyFrameObject *) PyObject_FROM_GC(f); PyObject_INIT(f, &PyFrame_Type); f->f_size = extras; *************** *** 166,174 **** free_list = free_list->f_back; if (f->f_size < extras) { f = (PyFrameObject *) PyObject_REALLOC(f, sizeof(PyFrameObject) + ! extras*sizeof(PyObject *)); if (f == NULL) return (PyFrameObject *)PyErr_NoMemory(); f->f_size = extras; } --- 250,261 ---- free_list = free_list->f_back; if (f->f_size < extras) { + f = (PyFrameObject *) PyObject_AS_GC(f); f = (PyFrameObject *) PyObject_REALLOC(f, sizeof(PyFrameObject) + ! extras*sizeof(PyObject *) + ! PyGC_HEAD_SIZE); if (f == NULL) return (PyFrameObject *)PyErr_NoMemory(); + f = (PyFrameObject *) PyObject_FROM_GC(f); f->f_size = extras; } *************** *** 231,234 **** --- 318,322 ---- f->f_stacktop = f->f_valuestack; + PyObject_GC_Init(f); return f; } *************** *** 392,395 **** --- 480,484 ---- PyFrameObject *f = free_list; free_list = free_list->f_back; + f = (PyFrameObject *) PyObject_AS_GC(f); PyObject_DEL(f); } From nascheme@users.sourceforge.net Thu Jul 12 14:27:27 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Thu, 12 Jul 2001 06:27:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects iterobject.c,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv1562/Objects Modified Files: iterobject.c Log Message: GC for iterator objects. Index: iterobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/iterobject.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** iterobject.c 2001/05/01 17:01:25 1.4 --- iterobject.c 2001/07/12 13:27:25 1.5 *************** *** 19,22 **** --- 19,23 ---- Py_INCREF(seq); it->it_seq = seq; + PyObject_GC_Init(it); return (PyObject *)it; } *************** *** 24,31 **** --- 25,40 ---- iter_dealloc(seqiterobject *it) { + PyObject_GC_Fini(it); Py_DECREF(it->it_seq); + it = (seqiterobject *) PyObject_AS_GC(it); PyObject_DEL(it); } + static int + iter_traverse(seqiterobject *it, visitproc visit, void *arg) + { + return visit(it->it_seq, arg); + } + static PyObject * iter_next(seqiterobject *it, PyObject *args) *************** *** 98,102 **** 0, /* ob_size */ "iterator", /* tp_name */ ! sizeof(seqiterobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ --- 107,111 ---- 0, /* ob_size */ "iterator", /* tp_name */ ! sizeof(seqiterobject) + PyGC_HEAD_SIZE, /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ *************** *** 116,122 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ 0, /* tp_doc */ ! 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ --- 125,131 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */ 0, /* tp_doc */ ! (traverseproc)iter_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ *************** *** 145,148 **** --- 154,158 ---- Py_INCREF(sentinel); it->it_sentinel = sentinel; + PyObject_GC_Init(it); return (PyObject *)it; } *************** *** 150,158 **** --- 160,181 ---- calliter_dealloc(calliterobject *it) { + PyObject_GC_Fini(it); Py_DECREF(it->it_callable); Py_DECREF(it->it_sentinel); + it = (calliterobject *) PyObject_AS_GC(it); PyObject_DEL(it); } + static int + calliter_traverse(calliterobject *it, visitproc visit, void *arg) + { + int err; + if ((err = visit(it->it_callable, arg))) + return err; + if ((err = visit(it->it_sentinel, arg))) + return err; + return 0; + } + static PyObject * calliter_next(calliterobject *it, PyObject *args) *************** *** 201,205 **** 0, /* ob_size */ "callable-iterator", /* tp_name */ ! sizeof(calliterobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ --- 224,228 ---- 0, /* ob_size */ "callable-iterator", /* tp_name */ ! sizeof(calliterobject) + PyGC_HEAD_SIZE,/* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ *************** *** 219,225 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ 0, /* tp_doc */ ! 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ --- 242,248 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */ 0, /* tp_doc */ ! (traverseproc)calliter_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ From nascheme@users.sourceforge.net Thu Jul 12 14:27:37 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Thu, 12 Jul 2001 06:27:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects methodobject.c,2.33,2.34 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv1613/Objects Modified Files: methodobject.c Log Message: GC for method objects. Index: methodobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/methodobject.c,v retrieving revision 2.33 retrieving revision 2.34 diff -C2 -r2.33 -r2.34 *** methodobject.c 2000/09/01 23:29:27 2.33 --- methodobject.c 2001/07/12 13:27:35 2.34 *************** *** 25,28 **** --- 25,29 ---- Py_XINCREF(self); op->m_self = self; + PyObject_GC_Init(op); return (PyObject *)op; } *************** *** 63,66 **** --- 64,68 ---- meth_dealloc(PyCFunctionObject *m) { + PyObject_GC_Fini(m); Py_XDECREF(m->m_self); m->m_self = (PyObject *)free_list; *************** *** 68,71 **** --- 70,82 ---- } + static int + meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg) + { + if (m->m_self != NULL) + return visit(m->m_self, arg); + else + return 0; + } + static PyObject * meth_getattr(PyCFunctionObject *m, char *name) *************** *** 153,168 **** 0, "builtin_function_or_method", ! sizeof(PyCFunctionObject), 0, ! (destructor)meth_dealloc, /*tp_dealloc*/ ! 0, /*tp_print*/ ! (getattrfunc)meth_getattr, /*tp_getattr*/ ! 0, /*tp_setattr*/ ! (cmpfunc)meth_compare, /*tp_compare*/ ! (reprfunc)meth_repr, /*tp_repr*/ ! 0, /*tp_as_number*/ ! 0, /*tp_as_sequence*/ ! 0, /*tp_as_mapping*/ ! (hashfunc)meth_hash, /*tp_hash*/ }; --- 164,187 ---- 0, "builtin_function_or_method", ! sizeof(PyCFunctionObject) + PyGC_HEAD_SIZE, 0, ! (destructor)meth_dealloc, /* tp_dealloc */ ! 0, /* tp_print */ ! (getattrfunc)meth_getattr, /* tp_getattr */ ! 0, /* tp_setattr */ ! (cmpfunc)meth_compare, /* tp_compare */ ! (reprfunc)meth_repr, /* tp_repr */ ! 0, /* tp_as_number */ ! 0, /* tp_as_sequence */ ! 0, /* tp_as_mapping */ ! (hashfunc)meth_hash, /* tp_hash */ ! 0, /* tp_call */ ! 0, /* tp_str */ ! 0, /* tp_getattro */ ! 0, /* tp_setattro */ ! 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */ ! 0, /* tp_doc */ ! (traverseproc)meth_traverse, /* tp_traverse */ }; *************** *** 246,249 **** --- 265,269 ---- PyCFunctionObject *v = free_list; free_list = (PyCFunctionObject *)(v->m_self); + v = (PyCFunctionObject *) PyObject_AS_GC(v); PyObject_DEL(v); } From nascheme@users.sourceforge.net Thu Jul 12 14:27:51 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Thu, 12 Jul 2001 06:27:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.260,2.261 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv1717/Python Modified Files: ceval.c Log Message: GC for generator objects. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.260 retrieving revision 2.261 diff -C2 -r2.260 -r2.261 *** ceval.c 2001/07/03 23:39:52 2.260 --- ceval.c 2001/07/12 13:27:49 2.261 *************** *** 122,133 **** gen->gi_frame = f; gen->gi_running = 0; return (PyObject *)gen; } static void gen_dealloc(genobject *gen) { Py_DECREF(gen->gi_frame); ! PyObject_DEL(gen); } --- 122,141 ---- gen->gi_frame = f; gen->gi_running = 0; + PyObject_GC_Init(gen); return (PyObject *)gen; } + static int + gen_traverse(genobject *gen, visitproc visit, void *arg) + { + return visit((PyObject *)gen->gi_frame, arg); + } + static void gen_dealloc(genobject *gen) { + PyObject_GC_Fini(gen); Py_DECREF(gen->gi_frame); ! PyObject_Del(gen); } *************** *** 227,231 **** 0, /* ob_size */ "generator", /* tp_name */ ! sizeof(genobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ --- 235,239 ---- 0, /* ob_size */ "generator", /* tp_name */ ! sizeof(genobject) + PyGC_HEAD_SIZE, /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ *************** *** 245,251 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ 0, /* tp_doc */ ! 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ --- 253,259 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */ 0, /* tp_doc */ ! (traverseproc)gen_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ From twouters@users.sourceforge.net Thu Jul 12 14:38:20 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Thu, 12 Jul 2001 06:38:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.146,1.146.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv4522/Misc Modified Files: Tag: release21-maint NEWS Log Message: Preliminary NEWS entry for 2.1.1c1 Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.146 retrieving revision 1.146.2.1 diff -C2 -r1.146 -r1.146.2.1 *** NEWS 2001/04/16 18:46:45 1.146 --- NEWS 2001/07/12 13:38:18 1.146.2.1 *************** *** 1,2 **** --- 1,71 ---- + What's New in Python 2.1.1c1 ? + ============================== + + - Python 2.1.1 comes with the new, GPL-compatible PSF licence. + + - Several insecurities in dict comparison as well as a scoping bug, + that could lead to the Python interpreter crashing were fixed. + + - Python should compile and run out of the box using the Borland C + compiler (under Windows), thanks to Stephen Hansen. + + - A large number of bugs was fixed, both in code and in the + documentation, including (but not limited to) the following + bugreports from SourceForge: + + [ #416530 ] No notes for building on Mac OS X 10.0 + [ #416573 ] makesockaddr() AF_UNIX ignores sun_len + [ #417030 ] print '%*s' fails for unicode string + [ #417093 ] Case sensitive import: dir and .py file w/ same name + [ #417418 ] Python 2.1 compile error on HPUX + [ #417587 ] compiler warnings compiling 2.1 + [ #417845 ] Python 2.1: SocketServer.ThreadingMixIn + [ #417943 ] xreadlines documented twice for file obj + [ #418296 ] WinMain.c should use WIN32_LEAN_AND_MEAN. + [ #418615 ] regular expression bug in pipes.py. + [ #418977 ] Access Violation in PyCell_Set + [ #419434 ] Tutorial contains wrong sample code. + [ #419873 ] ThreadingTCPServer invalidating sockets + [ #420216 ] bad links in v2.1 docs + [ #420230 ] fileinput deletes backups without warnin + [ #420343 ] SystemError from tuple() builtin + [ #420399 ] wrong HTML ("trademark" symbols?) + [ #421999 ] wrong priority doc for ** vs unary - + [ #422108 ] Error in rich comparisons + [ #422121 ] Insecurities in dict comparison + [ #422702 ] dbhash.open default + [ #423087 ] A small typo in weakref documentation + [ #423429 ] very minor nit in library ref + [ #424776 ] SMTP Example does not work + [ #424951 ] ThreadingTCPServer file handle errors. + [ #425320 ] Typo in introduction. + [ #427698 ] objects with __eq__ are not hashable + [ #427783 ] Lang Ref section 4.1 s/is/in/ + [ #427985 ] optional "listen" parameter in asyncore + [ #428419 ] include/rangeobject.h needs extern "C" + [ #429059 ] No docs for os.getenv() + [ #429070 ] Thread.getDaemon()should be isDaemon() + [ #429361 ] popen2.Popen3.wait() exit code + [ #429554 ] PyList_SET_ITEM documentation omission + [ #430627 ] Fixes for templates/module.tex file + [ #430991 ] wrong co_lnotab + [ #431772 ] traceback.print_exc() causes traceback + [ #432369 ] ConfigParser: problem w/ mixed-case opts + [ #433228 ] repr(list) woes when len(list) big + [ #433904 ] rexec: all s_* methods return None only + [ #434186 ] 0x80000000/2 != 0x80000000>>1 + [ #434975 ] Typo on Posix Large File Support page + [ #435066 ] PyObject_ClearWeakRefs misdocumented + [ #436525 ] Wrong macro name + [ #437041 ] strfime %Z isn't an RFC 822 timezone + [ #437879 ] SocketServer.py related problems + [ #438032 ] Documentation errors in module "profile" + [ #439012 ] Need doc: initial state of allocs + [ #439104 ] Tuple richcompares has code-typo + [ #439798 ] Nested scopes core dump + [ #439823 ] poll docs should mention timeout unit + [ #440037 ] C API descriptions not complete/consistent + + What's New in Python 2.1 (final)? ================================= From fdrake@users.sourceforge.net Thu Jul 12 15:13:45 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 12 Jul 2001 07:13:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libre.tex,1.62,1.63 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv12642/lib Modified Files: libre.tex Log Message: Fix return value for m.group() for groups not in the part of the RE that matched; reported by Paul Moore. Wrapped several long lines. Index: libre.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libre.tex,v retrieving revision 1.62 retrieving revision 1.63 diff -C2 -r1.62 -r1.63 *** libre.tex 2001/07/06 20:30:11 1.62 --- libre.tex 2001/07/12 14:13:43 1.63 *************** *** 75,88 **** Regular expressions can contain both special and ordinary characters. ! Most ordinary characters, like \character{A}, \character{a}, or \character{0}, ! are the simplest regular expressions; they simply match themselves. ! You can concatenate ordinary characters, so \regexp{last} matches the ! string \code{'last'}. (In the rest of this section, we'll write RE's in ! \regexp{this special style}, usually without quotes, and strings to be ! matched \code{'in single quotes'}.) ! ! Some characters, like \character{|} or \character{(}, are special. Special ! characters either stand for classes of ordinary characters, or affect ! how the regular expressions around them are interpreted. The special characters are: --- 75,88 ---- Regular expressions can contain both special and ordinary characters. ! Most ordinary characters, like \character{A}, \character{a}, or ! \character{0}, are the simplest regular expressions; they simply match ! themselves. You can concatenate ordinary characters, so \regexp{last} ! matches the string \code{'last'}. (In the rest of this section, we'll ! write RE's in \regexp{this special style}, usually without quotes, and ! strings to be matched \code{'in single quotes'}.) ! ! Some characters, like \character{|} or \character{(}, are special. ! Special characters either stand for classes of ordinary characters, or ! affect how the regular expressions around them are interpreted. The special characters are: *************** *** 115,128 **** match 0 or 1 repetitions of the preceding RE. \regexp{ab?} will match either 'a' or 'ab'. - \item[\code{*?}, \code{+?}, \code{??}] The \character{*}, \character{+}, and - \character{?} qualifiers are all \dfn{greedy}; they match as much text as - possible. Sometimes this behaviour isn't desired; if the RE - \regexp{<.*>} is matched against \code{'

title

'}, it will match the - entire string, and not just \code{'

'}. - Adding \character{?} after the qualifier makes it perform the match in - \dfn{non-greedy} or \dfn{minimal} fashion; as \emph{few} characters as - possible will be matched. Using \regexp{.*?} in the previous - expression will match only \code{'

'}. \item[\code{\{\var{m},\var{n}\}}] Causes the resulting RE to match from \var{m} to \var{n} repetitions of the preceding RE, attempting to --- 115,129 ---- match 0 or 1 repetitions of the preceding RE. \regexp{ab?} will match either 'a' or 'ab'. + \item[\code{*?}, \code{+?}, \code{??}] The \character{*}, + \character{+}, and \character{?} qualifiers are all \dfn{greedy}; they + match as much text as possible. Sometimes this behaviour isn't + desired; if the RE \regexp{<.*>} is matched against + \code{'

title

'}, it will match the entire string, and not just + \code{'

'}. Adding \character{?} after the qualifier makes it + perform the match in \dfn{non-greedy} or \dfn{minimal} fashion; as + \emph{few} characters as possible will be matched. Using \regexp{.*?} + in the previous expression will match only \code{'

'}. + \item[\code{\{\var{m},\var{n}\}}] Causes the resulting RE to match from \var{m} to \var{n} repetitions of the preceding RE, attempting to *************** *** 168,175 **** You can match the characters not within a range by \dfn{complementing} ! the set. This is indicated by including a ! \character{\^} as the first character of the set; \character{\^} elsewhere will ! simply match the \character{\^} character. For example, \regexp{[{\^}5]} ! will match any character except \character{5}. \item[\character{|}]\code{A|B}, where A and B can be arbitrary REs, --- 169,176 ---- You can match the characters not within a range by \dfn{complementing} ! the set. This is indicated by including a \character{\^} as the first ! character of the set; \character{\^} elsewhere will simply match the ! \character{\^} character. For example, \regexp{[{\^}5]} will match ! any character except \character{5}. \item[\character{|}]\code{A|B}, where A and B can be arbitrary REs, *************** *** 400,405 **** \begin{datadesc}{I} \dataline{IGNORECASE} ! Perform case-insensitive matching; expressions like \regexp{[A-Z]} will match ! lowercase letters, too. This is not affected by the current locale. \end{datadesc} --- 401,407 ---- \begin{datadesc}{I} \dataline{IGNORECASE} ! Perform case-insensitive matching; expressions like \regexp{[A-Z]} ! will match lowercase letters, too. This is not affected by the ! current locale. \end{datadesc} *************** *** 415,423 **** beginning of the string and at the beginning of each line (immediately following each newline); and the pattern character ! \character{\$} matches at the end of the string and at the end of each line ! (immediately preceding each newline). ! By default, \character{\^} matches only at the beginning of the string, and ! \character{\$} only at the end of the string and immediately before the ! newline (if any) at the end of the string. \end{datadesc} --- 417,425 ---- beginning of the string and at the beginning of each line (immediately following each newline); and the pattern character ! \character{\$} matches at the end of the string and at the end of each ! line (immediately preceding each newline). By default, \character{\^} ! matches only at the beginning of the string, and \character{\$} only ! at the end of the string and immediately before the newline (if any) ! at the end of the string. \end{datadesc} *************** *** 441,447 **** Whitespace within the pattern is ignored, except when in a character class or preceded by an unescaped ! backslash, and, when a line contains a \character{\#} neither in a character ! class or preceded by an unescaped backslash, all characters from the ! leftmost such \character{\#} through the end of the line are ignored. % XXX should add an example here \end{datadesc} --- 443,450 ---- Whitespace within the pattern is ignored, except when in a character class or preceded by an unescaped ! backslash, and, when a line contains a \character{\#} neither in a ! character class or preceded by an unescaped backslash, all characters ! from the leftmost such \character{\#} through the end of the line are ! ignored. % XXX should add an example here \end{datadesc} *************** *** 522,536 **** The optional argument \var{count} is the maximum number of pattern ! occurrences to be replaced; \var{count} must be a non-negative integer, and ! the default value of 0 means to replace all occurrences. Empty matches for the pattern are replaced only when not adjacent to a ! previous match, so \samp{sub('x*', '-', 'abc')} returns \code{'-a-b-c-'}. If \var{repl} is a string, any backslash escapes in it are processed. That is, \samp{\e n} is converted to a single newline character, \samp{\e r} is converted to a linefeed, and so forth. Unknown escapes ! such as \samp{\e j} are left alone. Backreferences, such as \samp{\e 6}, are ! replaced with the substring matched by group 6 in the pattern. In addition to character escapes and backreferences as described --- 525,540 ---- The optional argument \var{count} is the maximum number of pattern ! occurrences to be replaced; \var{count} must be a non-negative ! integer, and the default value of 0 means to replace all occurrences. Empty matches for the pattern are replaced only when not adjacent to a ! previous match, so \samp{sub('x*', '-', 'abc')} returns ! \code{'-a-b-c-'}. If \var{repl} is a string, any backslash escapes in it are processed. That is, \samp{\e n} is converted to a single newline character, \samp{\e r} is converted to a linefeed, and so forth. Unknown escapes ! such as \samp{\e j} are left alone. Backreferences, such as \samp{\e ! 6}, are replaced with the substring matched by group 6 in the pattern. In addition to character escapes and backreferences as described *************** *** 642,646 **** \subsection{Match Objects \label{match-objects}} ! \class{MatchObject} instances support the following methods and attributes: \begin{methoddesc}[MatchObject]{expand}{template} --- 646,651 ---- \subsection{Match Objects \label{match-objects}} ! \class{MatchObject} instances support the following methods and ! attributes: \begin{methoddesc}[MatchObject]{expand}{template} *************** *** 648,654 **** template string \var{template}, as done by the \method{sub()} method. Escapes such as \samp{\e n} are converted to the appropriate ! characters, and numeric backreferences (\samp{\e 1}, \samp{\e 2}) and named ! backreferences (\samp{\e g<1>}, \samp{\e g}) are replaced by the contents of the ! corresponding group. \end{methoddesc} --- 653,659 ---- template string \var{template}, as done by the \method{sub()} method. Escapes such as \samp{\e n} are converted to the appropriate ! characters, and numeric backreferences (\samp{\e 1}, \samp{\e 2}) and ! named backreferences (\samp{\e g<1>}, \samp{\e g}) are replaced ! by the contents of the corresponding group. \end{methoddesc} *************** *** 665,669 **** in the pattern, an \exception{IndexError} exception is raised. If a group is contained in a part of the pattern that did not match, ! the corresponding result is \code{-1}. If a group is contained in a part of the pattern that matched multiple times, the last match is returned. --- 670,674 ---- in the pattern, an \exception{IndexError} exception is raised. If a group is contained in a part of the pattern that did not match, ! the corresponding result is \code{None}. If a group is contained in a part of the pattern that matched multiple times, the last match is returned. From fdrake@users.sourceforge.net Thu Jul 12 15:15:06 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 12 Jul 2001 07:15:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libre.tex,1.60.2.1,1.60.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv13040/lib Modified Files: Tag: release21-maint libre.tex Log Message: Fix return value for m.group() for groups not in the part of the RE that matched; reported by Paul Moore. Index: libre.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libre.tex,v retrieving revision 1.60.2.1 retrieving revision 1.60.2.2 diff -C2 -r1.60.2.1 -r1.60.2.2 *** libre.tex 2001/04/18 17:27:10 1.60.2.1 --- libre.tex 2001/07/12 14:15:03 1.60.2.2 *************** *** 663,667 **** in the pattern, an \exception{IndexError} exception is raised. If a group is contained in a part of the pattern that did not match, ! the corresponding result is \code{-1}. If a group is contained in a part of the pattern that matched multiple times, the last match is returned. --- 663,667 ---- in the pattern, an \exception{IndexError} exception is raised. If a group is contained in a part of the pattern that did not match, ! the corresponding result is \code{None}. If a group is contained in a part of the pattern that matched multiple times, the last match is returned. From fdrake@users.sourceforge.net Thu Jul 12 15:59:51 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 12 Jul 2001 07:59:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc ACKS,1.16.4.4,1.16.4.5 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv22931 Modified Files: Tag: release21-maint ACKS Log Message: Add credit for a last-minute fix in the re documentation. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ACKS,v retrieving revision 1.16.4.4 retrieving revision 1.16.4.5 diff -C2 -r1.16.4.4 -r1.16.4.5 *** ACKS 2001/07/10 16:20:59 1.16.4.4 --- ACKS 2001/07/12 14:59:49 1.16.4.5 *************** *** 110,113 **** --- 110,114 ---- Paolo Milani Skip Montanaro + Paul Moore Ross Moore Sjoerd Mullender From tim_one@users.sourceforge.net Thu Jul 12 21:15:27 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 12 Jul 2001 13:15:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild python20.wse,1.40,1.41 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv24345/python/dist/src/PCbuild Modified Files: python20.wse Log Message: Fiddle Windows installer to create Lib/site-packages/REAMDE as Lib\site-packages\README.txt. Index: python20.wse =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/python20.wse,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -r1.40 -r1.41 *** python20.wse 2001/04/18 21:12:25 1.40 --- python20.wse 2001/07/12 20:15:25 1.41 *************** *** 910,913 **** --- 910,919 ---- Flags=0000000000000010 end + item: Install File + Source=%_SRC_%\Lib\site-packages\README + Destination=%MAINDIR%\Lib\site-packages\README.txt + Description=Site packages + Flags=0000000000000010 + end item: Remark Text=*** Other *** From fdrake@users.sourceforge.net Thu Jul 12 22:08:35 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 12 Jul 2001 14:08:35 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib site.py,1.29,1.30 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv2886 Modified Files: site.py Log Message: Actually remove directories from sys.path if they do not exist; the intent is to avoid as many stat() calls as we can. Index: site.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/site.py,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -r1.29 -r1.30 *** site.py 2001/07/12 05:20:13 1.29 --- site.py 2001/07/12 21:08:33 1.30 *************** *** 80,83 **** --- 80,87 ---- dirs_in_sys_path = {} for dir in sys.path: + # Filter out paths that don't exist, but leave in the empty string + # since it's a special case. + if dir and not os.path.isdir(dir): + continue dir, dircase = makepath(dir) if not dirs_in_sys_path.has_key(dircase): From jackjansen@users.sourceforge.net Thu Jul 12 22:48:13 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Thu, 12 Jul 2001 14:48:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Python macglue.c,1.96,1.97 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Python In directory usw-pr-cvs1:/tmp/cvs-serv10973/Python/Mac/Python Modified Files: macglue.c Log Message: Fixed another case of the PyArg_Parse 'h' semantic change problem, sigh... Index: macglue.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Python/macglue.c,v retrieving revision 1.96 retrieving revision 1.97 diff -C2 -r1.96 -r1.97 *** macglue.c 2001/07/08 22:07:23 1.96 --- macglue.c 2001/07/12 21:48:10 1.97 *************** *** 1083,1087 **** PyMac_GetEventRecord(PyObject *v, EventRecord *e) { ! return PyArg_Parse(v, "(hll(hh)h)", &e->what, &e->message, --- 1083,1087 ---- PyMac_GetEventRecord(PyObject *v, EventRecord *e) { ! return PyArg_Parse(v, "(Hll(hh)H)", &e->what, &e->message, From fdrake@users.sourceforge.net Thu Jul 12 22:50:12 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 12 Jul 2001 14:50:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools push-docs.sh,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools In directory usw-pr-cvs1:/tmp/cvs-serv11504/tools Modified Files: push-docs.sh Log Message: Generate a more meaningful message regarding the type of the documentation release being discussed. Index: push-docs.sh =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/push-docs.sh,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -r1.10 -r1.11 *** push-docs.sh 2001/07/06 23:45:16 1.10 --- push-docs.sh 2001/07/12 21:50:10 1.11 *************** *** 72,76 **** Subject: [$DOCLABEL doc updates] ! The development version of the documentation has been updated: http://python.sourceforge.net/$DOCTYPE-docs/ --- 72,76 ---- Subject: [$DOCLABEL doc updates] ! The $DOCLABEL version of the documentation has been updated: http://python.sourceforge.net/$DOCTYPE-docs/ From tim_one@users.sourceforge.net Thu Jul 12 23:36:04 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 12 Jul 2001 15:36:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib __future__.py,1.5,1.6 symtable.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv20069/python/dist/src/Lib Modified Files: __future__.py symtable.py Log Message: Remove now-unnecessary "from __future__ import nested_scopes" stmts. Index: __future__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/__future__.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** __future__.py 2001/03/15 10:45:44 1.5 --- __future__.py 2001/07/12 22:36:02 1.6 *************** *** 67,69 **** `self.getMandatoryRelease()` + ")" ! nested_scopes = _Feature((2, 1, 0, "beta", 1), (2, 2, 0, "final", 0)) --- 67,69 ---- `self.getMandatoryRelease()` + ")" ! nested_scopes = _Feature((2, 1, 0, "beta", 1), (2, 2, 0, "alpha", 0)) Index: symtable.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/symtable.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** symtable.py 2001/04/16 18:43:18 1.4 --- symtable.py 2001/07/12 22:36:02 1.5 *************** *** 1,4 **** """Interface to the compiler's internal symbol tables""" - from __future__ import nested_scopes import _symtable --- 1,3 ---- From tim_one@users.sourceforge.net Thu Jul 12 23:36:04 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 12 Jul 2001 15:36:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild rmpyc.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv20069/python/dist/src/PCbuild Modified Files: rmpyc.py Log Message: Remove now-unnecessary "from __future__ import nested_scopes" stmts. Index: rmpyc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/rmpyc.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** rmpyc.py 2001/02/27 21:11:46 1.2 --- rmpyc.py 2001/07/12 22:36:02 1.3 *************** *** 1,6 **** # Remove all the .pyc and .pyo files under ../Lib. - from __future__ import nested_scopes - def deltree(root): import os --- 1,4 ---- From tim_one@users.sourceforge.net Thu Jul 12 23:36:04 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 12 Jul 2001 15:36:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,1.18,1.19 test_scope.py,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv20069/python/dist/src/Lib/test Modified Files: test_generators.py test_scope.py Log Message: Remove now-unnecessary "from __future__ import nested_scopes" stmts. Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -r1.18 -r1.19 *** test_generators.py 2001/07/12 13:26:41 1.18 --- test_generators.py 2001/07/12 22:36:02 1.19 *************** *** 1,4 **** - from __future__ import nested_scopes - tutorial_tests = """ Let's try a simple generator: --- 1,2 ---- Index: test_scope.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_scope.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -r1.16 -r1.17 *** test_scope.py 2001/05/08 04:08:16 1.16 --- test_scope.py 2001/07/12 22:36:02 1.17 *************** *** 1,4 **** - from __future__ import nested_scopes - from test.test_support import verify, TestFailed, check_syntax --- 1,2 ---- *************** *** 180,184 **** print "11. unoptimized namespaces" ! check_syntax("""from __future__ import nested_scopes def unoptimized_clash1(strip): def f(s): --- 178,182 ---- print "11. unoptimized namespaces" ! check_syntax("""\ def unoptimized_clash1(strip): def f(s): *************** *** 188,192 **** """) ! check_syntax("""from __future__ import nested_scopes def unoptimized_clash2(): from string import * --- 186,190 ---- """) ! check_syntax("""\ def unoptimized_clash2(): from string import * *************** *** 196,200 **** """) ! check_syntax("""from __future__ import nested_scopes def unoptimized_clash2(): from string import * --- 194,198 ---- """) ! check_syntax("""\ def unoptimized_clash2(): from string import * *************** *** 206,210 **** # XXX could allow this for exec with const argument, but what's the point ! check_syntax("""from __future__ import nested_scopes def error(y): exec "a = 1" --- 204,208 ---- # XXX could allow this for exec with const argument, but what's the point ! check_syntax("""\ def error(y): exec "a = 1" *************** *** 214,218 **** """) ! check_syntax("""from __future__ import nested_scopes def f(x): def g(): --- 212,216 ---- """) ! check_syntax("""\ def f(x): def g(): *************** *** 221,225 **** """) ! check_syntax("""from __future__ import nested_scopes def f(): def g(): --- 219,223 ---- """) ! check_syntax("""\ def f(): def g(): From tim_one@users.sourceforge.net Thu Jul 12 23:43:43 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 12 Jul 2001 15:43:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv21407/python/dist/src/Lib/test Modified Files: test_generators.py Log Message: Repair flawed example. Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -r1.19 -r1.20 *** test_generators.py 2001/07/12 22:36:02 1.19 --- test_generators.py 2001/07/12 22:43:41 1.20 *************** *** 48,52 **** >>> def f(): ... yield 1 ! ... return ... yield 2 # never reached ... --- 48,52 ---- >>> def f(): ... yield 1 ! ... raise StopIteration ... yield 2 # never reached ... From tim_one@users.sourceforge.net Thu Jul 12 23:55:44 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 12 Jul 2001 15:55:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,1.20,1.21 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv23886/python/dist/src/Lib/test Modified Files: test_generators.py Log Message: Remove the last remnants of the hacks to worm around leaks. Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -r1.20 -r1.21 *** test_generators.py 2001/07/12 22:43:41 1.20 --- test_generators.py 2001/07/12 22:55:42 1.21 *************** *** 436,442 **** ... def __str__(self): ... return self.name - ... - ... def clear(self): - ... self.__dict__.clear() >>> names = "ABCDEFGHIJKLM" --- 436,439 ---- *************** *** 595,601 **** ... sofar.append(fetch()) ... return sofar[i] - ... - ... def clear(self): - ... self.__dict__.clear() >>> def m235(): --- 592,595 ---- *************** *** 1345,1356 **** def test_main(): import doctest, test_generators ! if 0: ! # Temporary block to help track down leaks. So far, the blame ! # fell mostly on doctest. Later: the only leaks remaining are ! # in fun_tests, and only if you comment out the two LazyList.clear() ! # calls. ! for i in range(10000): doctest.master = None doctest.testmod(test_generators) else: doctest.testmod(test_generators) --- 1339,1347 ---- def test_main(): import doctest, test_generators ! if 0: # change to 1 to run forever (to check for leaks) ! while 1: doctest.master = None doctest.testmod(test_generators) + print ".", else: doctest.testmod(test_generators) From fdrake@users.sourceforge.net Fri Jul 13 00:39:26 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 12 Jul 2001 16:39:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libxmlrpclib.tex,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv31371/lib Modified Files: libxmlrpclib.tex Log Message: Several markup adjustments so this will format and be more consistent with the rest of the documnentation. Index: libxmlrpclib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libxmlrpclib.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** libxmlrpclib.tex 2001/07/12 02:39:45 1.1 --- libxmlrpclib.tex 2001/07/12 23:39:24 1.2 *************** *** 18,32 **** objects and XML on the wire. ! \begin{seealso} ! \seetitle{http://xmlrpc-c.sourceforge.net/xmlrpc-howto/xmlrpc-howto.html} ! {XML-RPC HOWTO}{A good description of XML operation and client ! software in several languages. Contains pretty much ! everything an XML-RPC client developer needs to know.} ! \seetitle{http://xmlrpc-c.sourceforge.net/hacks.php} ! {XML-RPC-Hacks page}{Extensions for various open-source ! libraries to support instrospection and multicall.} ! \end{seealso} ! ! \begin{classdesc}{Server}{\optional{uri\optional{, transport, encoding, verbose}}} A \class{Server} instance is a server proxy that manages communication with a remote XML-RPC server. The required first argument is a URI --- 18,23 ---- objects and XML on the wire. ! \begin{classdesc}{Server}{\optional{uri\optional{, transport\optional{, ! encoding\optional{, verbose}}}}} A \class{Server} instance is a server proxy that manages communication with a remote XML-RPC server. The required first argument is a URI *************** *** 51,74 **** \begin{tableii}{l|l}{constant}{Name}{Meaning} ! \lineii{boolean}{The True and False constants that then module supplies} \lineii{integers}{Pass in directly} \lineii{floating-point numbers}{Pass in directly} \lineii{strings}{Pass in directly} \lineii{arrays}{Any Python sequence type containing conformable ! elements. Arrays are returned as lists} \lineii{structures}{A Python dictionary. Keys must be strings, ! values may be any conformable type.} \lineii{dates}{in seconds since the epoch; pass in an instance of the ! \class{DateTime} wrapper class} ! \lineii{binary data}{pass in an instance of the \class{Binary} wrapper class} \end{tableii} This is the full set of data types supported by XML-RPC. Method calls ! may also return a special \class{Fault} instance, used to signal XML-RPCserver ! errors, or a \class{ProtocolError} instance used to signal an error in ! the HTTP/HTTPS transport layer. ! \end{classdesc} \subsection{Server Objects \label{server-objects}} --- 42,77 ---- \begin{tableii}{l|l}{constant}{Name}{Meaning} ! \lineii{boolean}{The \constant{True} and \constant{False} constants} \lineii{integers}{Pass in directly} \lineii{floating-point numbers}{Pass in directly} \lineii{strings}{Pass in directly} \lineii{arrays}{Any Python sequence type containing conformable ! elements. Arrays are returned as lists} \lineii{structures}{A Python dictionary. Keys must be strings, ! values may be any conformable type.} \lineii{dates}{in seconds since the epoch; pass in an instance of the ! \class{DateTime} wrapper class} ! \lineii{binary data}{pass in an instance of the \class{Binary} ! wrapper class} \end{tableii} This is the full set of data types supported by XML-RPC. Method calls ! may also raise a special \exception{Fault} instance, used to signal ! XML-RPC server errors, or \exception{ProtocolError} used to signal an ! error in the HTTP/HTTPS transport layer. \end{classdesc} + + \begin{seealso} + \seetitle[http://xmlrpc-c.sourceforge.net/xmlrpc-howto/xmlrpc-howto.html] + {XML-RPC HOWTO}{A good description of XML operation and + client software in several languages. Contains pretty much + everything an XML-RPC client developer needs to know.} + \seetitle[http://xmlrpc-c.sourceforge.net/hacks.php] + {XML-RPC-Hacks page}{Extensions for various open-source + libraries to support instrospection and multicall.} + \end{seealso} + + \subsection{Server Objects \label{server-objects}} *************** *** 121,130 **** Perl, Python and Java is available at the XML-RPC Hacks page. \subsection{Boolean Objects \label{boolean-objects}} This class may be initialized from any Python value; the instance ! returned depends onlyon its truth value. It supports various Python ! operators through \class{__cmp__}, \class{__repr__}, \class{__int__}, ! and \class{__nonzero__} methods, all implemented in the obvious ways. It also has the following method, supported mainly for internal use by --- 124,135 ---- Perl, Python and Java is available at the XML-RPC Hacks page. + \subsection{Boolean Objects \label{boolean-objects}} This class may be initialized from any Python value; the instance ! returned depends only on its truth value. It supports various Python ! operators through \method{__cmp__()}, \method{__repr__()}, ! \method{__int__()}, and \method{__nonzero__()} methods, all ! implemented in the obvious ways. It also has the following method, supported mainly for internal use by *************** *** 135,138 **** --- 140,144 ---- \end{methoddesc} + \subsection{DateTime Objects \label{datetime-objects}} *************** *** 153,156 **** --- 159,163 ---- \method{_cmp__} and \method{__repr__} methods. + \subsection{Binary Objects \label{binary-objects}} *************** *** 164,168 **** \begin{methoddesc}{encode}{out} ! Write the XML-RPC base 64 encoding of this binary item to the out stream object. \end{methoddesc} --- 171,176 ---- \begin{methoddesc}{encode}{out} ! Write the XML-RPC base 64 encoding of this binary item to the out ! stream object. \end{methoddesc} *************** *** 170,173 **** --- 178,182 ---- \method{_cmp__} method. + \subsection{Fault Objects \label{fault-objects}} *************** *** 183,186 **** --- 192,196 ---- \end{memberdesc} + \subsection{ProtocolError Objects \label{protocol-error-objects}} *************** *** 207,210 **** --- 217,221 ---- \end{memberdesc} + \subsection{Convenience Functions} *************** *** 219,237 **** \end{funcdesc} - \subsection{Example of Client Usage \begin{verbatim} ! # simple test program (from the XML-RPC specification) ! # server = Server("http://localhost:8000") # local server ! server = Server("http://betty.userland.com") ! print server ! try: ! print server.examples.getStateName(41) ! except Error, v: ! print "ERROR", v \end{verbatim} - - % End --- 230,247 ---- \end{funcdesc} + \subsection{Example of Client Usage \label{xmlrpc-client-example}} + \begin{verbatim} ! # simple test program (from the XML-RPC specification) ! # server = Server("http://localhost:8000") # local server ! server = Server("http://betty.userland.com") ! print server ! try: ! print server.examples.getStateName(41) ! except Error, v: ! print "ERROR", v \end{verbatim} From fdrake@users.sourceforge.net Fri Jul 13 00:40:15 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 12 Jul 2001 16:40:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc Makefile.deps,1.67,1.68 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv31486 Modified Files: Makefile.deps Log Message: Add entry for xmlrpclib documentation. Index: Makefile.deps =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile.deps,v retrieving revision 1.67 retrieving revision 1.68 diff -C2 -r1.67 -r1.68 *** Makefile.deps 2001/06/22 17:07:02 1.67 --- Makefile.deps 2001/07/12 23:40:13 1.68 *************** *** 179,182 **** --- 179,183 ---- lib/libdis.tex \ lib/libxmllib.tex \ + lib/libxmlrpclib.tex \ lib/libpyexpat.tex \ lib/xmldom.tex \ From fdrake@users.sourceforge.net Fri Jul 13 00:40:16 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 12 Jul 2001 16:40:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib lib.tex,1.187,1.188 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv31486/lib Modified Files: lib.tex Log Message: Add entry for xmlrpclib documentation. Index: lib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/lib.tex,v retrieving revision 1.187 retrieving revision 1.188 diff -C2 -r1.187 -r1.188 *** lib.tex 2001/06/20 21:37:34 1.187 --- lib.tex 2001/07/12 23:40:13 1.188 *************** *** 247,250 **** --- 247,251 ---- \input{xmlsaxreader} \input{libxmllib} + \input{libxmlrpclib} \input{libmm} % Multimedia Services From tim_one@users.sourceforge.net Fri Jul 13 03:59:28 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 12 Jul 2001 19:59:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.84,1.85 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv27050/python/dist/src/objects Modified Files: longobject.c Log Message: long_format(): Easy speedup for output bases that aren't a power of 2 (in particular, str(long) and repr(long) use base 10, and that gets a factor of 4 speedup). Another factor of 2 can be gotten by refactoring divrem1 to support in-place division, but that started getting messy so I'm leaving that out. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.84 retrieving revision 1.85 diff -C2 -r1.84 -r1.85 *** longobject.c 2001/07/12 11:21:17 1.84 --- longobject.c 2001/07/13 02:59:26 1.85 *************** *** 812,831 **** } else { Py_INCREF(a); do { digit rem; ! PyLongObject *temp = divrem1(a, (digit)base, &rem); if (temp == NULL) { - Py_DECREF(a); Py_DECREF(str); return NULL; } - if (rem < 10) - rem += '0'; - else - rem += 'A'-10; - assert(p > PyString_AS_STRING(str)); - *--p = (char) rem; - Py_DECREF(a); a = temp; SIGCHECK({ --- 812,838 ---- } else { + /* Not 0, and base not a power of 2. Divide repeatedly by + base, but for speed use the highest power of base that + fits in a digit. */ + digit powbase = base; /* powbase == base ** power */ + int power = 1; + for (;;) { + unsigned long newpow = powbase * (unsigned long)base; + if (newpow >> SHIFT) /* doesn't fit in a digit */ + break; + powbase = (digit)newpow; + ++power; + } + Py_INCREF(a); do { + int ntostore = power; digit rem; ! PyLongObject *temp = divrem1(a, powbase, &rem); ! Py_DECREF(a); if (temp == NULL) { Py_DECREF(str); return NULL; } a = temp; SIGCHECK({ *************** *** 834,837 **** --- 841,854 ---- return NULL; }) + while (--ntostore >= 0) { + digit nextrem = (digit)(rem / base); + char c = (char)(rem - nextrem * base); + assert(p > PyString_AS_STRING(str)); + c += (c < 10) ? '0' : 'A'-10; + *--p = c; + rem = nextrem; + if (a->ob_size == 0 && rem == 0) + break; /* skip leading zeroes */ + } } while (ABS(a->ob_size) != 0); Py_DECREF(a); From tim.one@home.com Fri Jul 13 05:02:00 2001 From: tim.one@home.com (Tim Peters) Date: Fri, 13 Jul 2001 00:02:00 -0400 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.188,1.189 In-Reply-To: Message-ID: [Guido] > (Tim & I should agree on where to add new additions: I add them at the > top, Tim adds them at the bottom. I like the top better because folks > who occasionally check out the NEWS file will see the latest news > first.) For everyone following this raging debate , Tim actually puts new items where he thinks they fit in "typical user" priority order, most important at the top; but since Tim is incapable of doing anything practical, and knows it, his new items tend to end up near the bottom. Tim has agreed to put new items at the top henceforth, relying on Guido's claim that he rearranges the order again before a release. From tim_one@users.sourceforge.net Fri Jul 13 10:12:14 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 13 Jul 2001 02:12:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv27507/python/dist/src/lib/test Modified Files: test_generators.py Log Message: Having fun on my own time: quicker flat_conjoin; Knights Tour solver simplified and generalized to rectangular boards. Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -r1.21 -r1.22 *** test_generators.py 2001/07/12 22:55:42 1.21 --- test_generators.py 2001/07/13 09:12:12 1.22 *************** *** 904,908 **** # NOTE WELL: This allows large problems to be solved with only trivial # demands on stack space. Without explicitly resumable generators, this is ! # much harder to achieve. def flat_conjoin(gs): # rename to conjoin to run tests with this instead --- 904,909 ---- # NOTE WELL: This allows large problems to be solved with only trivial # demands on stack space. Without explicitly resumable generators, this is ! # much harder to achieve. OTOH, this is much slower (up to a factor of 2) ! # than the fancy unrolled recursive conjoin. def flat_conjoin(gs): # rename to conjoin to run tests with this instead *************** *** 910,934 **** values = [None] * n iters = [None] * n i = 0 ! while i >= 0: ! # Need a fresh iterator. ! if i >= n: ! yield values ! # Backtrack. ! i -= 1 else: ! iters[i] = gs[i]().next ! # Need next value from current iterator. while i >= 0: try: values[i] = iters[i]() ! except StopIteration: ! # Backtrack. ! i -= 1 ! else: ! # Start fresh at next level. i += 1 break # A conjoin-based N-Queens solver. --- 911,943 ---- values = [None] * n iters = [None] * n + _StopIteration = StopIteration # make local because caught a *lot* i = 0 ! while 1: ! # Descend. ! try: ! while i < n: ! it = iters[i] = gs[i]().next ! values[i] = it() ! i += 1 ! except _StopIteration: ! pass else: ! assert i == n ! yield values ! # Backtrack until an older iterator can be resumed. ! i -= 1 while i >= 0: try: values[i] = iters[i]() ! # Success! Start fresh at next level. i += 1 break + except _StopIteration: + # Continue backtracking. + i -= 1 + else: + assert i < 0 + break # A conjoin-based N-Queens solver. *************** *** 987,1015 **** # (e.g., when used with flat_conjoin above, and passing hard=1 to the # constructor, a 200x200 Knight's Tour was found quickly -- note that we're ! # creating 10s of thousands of generators then!), so goes on at some length class Knights: ! def __init__(self, n, hard=0): ! self.n = n ! ! def coords2index(i, j): ! return i*n + j ! offsets = [( 1, 2), ( 2, 1), ( 2, -1), ( 1, -2), ! (-1, -2), (-2, -1), (-2, 1), (-1, 2)] ! succs = [] ! for i in range(n): ! for j in range(n): ! s = [coords2index(i+io, j+jo) for io, jo in offsets ! if 0 <= i+io < n and ! 0 <= j+jo < n] ! succs.append(s) ! del s ! del offsets ! free = [0] * n**2 # 0 if occupied, 1 if visited ! nexits = free[:] # number of free successors ! ! def decrexits(i0): # If we remove all exits from a free square, we're dead: # even if we move to it next, we can't leave it again. --- 996,1014 ---- # (e.g., when used with flat_conjoin above, and passing hard=1 to the # constructor, a 200x200 Knight's Tour was found quickly -- note that we're ! # creating 10s of thousands of generators then!), and is lengthy. class Knights: ! def __init__(self, m, n, hard=0): ! self.m, self.n = m, n ! # solve() will set up succs[i] to be a list of square #i's ! # successors. ! succs = self.succs = [] ! ! # Remove i0 from each of its successor's successor lists, i.e. ! # successors can't go back to i0 again. Return 0 if we can ! # detect this makes a solution impossible, else return 1. ! def remove_from_successors(i0, len=len): # If we remove all exits from a free square, we're dead: # even if we move to it next, we can't leave it again. *************** *** 1022,1100 **** ne0 = ne1 = 0 for i in succs[i0]: ! if free[i]: ! e = nexits[i] - 1 ! nexits[i] = e ! if e == 0: ! ne0 += 1 ! elif e == 1: ! ne1 += 1 return ne0 == 0 and ne1 < 2 ! def increxits(i0): for i in succs[i0]: ! if free[i]: ! nexits[i] += 1 # Generate the first move. def first(): ! if n < 1: return - # Initialize board structures. - for i in xrange(n**2): - free[i] = 1 - nexits[i] = len(succs[i]) - # Since we're looking for a cycle, it doesn't matter where we # start. Starting in a corner makes the 2nd move easy. ! corner = coords2index(0, 0) ! free[corner] = 0 ! decrexits(corner) self.lastij = corner yield corner ! increxits(corner) ! free[corner] = 1 # Generate the second moves. def second(): ! corner = coords2index(0, 0) assert self.lastij == corner # i.e., we started in the corner ! if n < 3: return ! assert nexits[corner] == len(succs[corner]) == 2 ! assert coords2index(1, 2) in succs[corner] ! assert coords2index(2, 1) in succs[corner] # Only two choices. Whichever we pick, the other must be the ! # square picked on move n**2, as it's the only way to get back # to (0, 0). Save its index in self.final so that moves before # the last know it must be kept free. for i, j in (1, 2), (2, 1): ! this, final = coords2index(i, j), coords2index(3-i, 3-j) ! assert free[this] and free[final] self.final = final - nexits[final] += 1 # it has an exit back to 0,0 ! free[this] = 0 ! decrexits(this) self.lastij = this yield this ! increxits(this) ! free[this] = 1 ! nexits[final] -= 1 ! ! # Generate moves 3 thru n**2-1. ! def advance(): # If some successor has only one exit, must take it. # Else favor successors with fewer exits. candidates = [] for i in succs[self.lastij]: ! if free[i]: ! e = nexits[i] ! assert e > 0, "else decrexits() pruning flawed" ! if e == 1: ! candidates = [(e, i)] ! break ! candidates.append((e, i)) else: candidates.sort() --- 1021,1089 ---- ne0 = ne1 = 0 for i in succs[i0]: ! s = succs[i] ! s.remove(i0) ! e = len(s) ! if e == 0: ! ne0 += 1 ! elif e == 1: ! ne1 += 1 return ne0 == 0 and ne1 < 2 + + # Put i0 back in each of its successor's successor lists. ! def add_to_successors(i0): for i in succs[i0]: ! succs[i].append(i0) # Generate the first move. def first(): ! if m < 1 or n < 1: return # Since we're looking for a cycle, it doesn't matter where we # start. Starting in a corner makes the 2nd move easy. ! corner = self.coords2index(0, 0) ! remove_from_successors(corner) self.lastij = corner yield corner ! add_to_successors(corner) # Generate the second moves. def second(): ! corner = self.coords2index(0, 0) assert self.lastij == corner # i.e., we started in the corner ! if m < 3 or n < 3: return ! assert len(succs[corner]) == 2 ! assert self.coords2index(1, 2) in succs[corner] ! assert self.coords2index(2, 1) in succs[corner] # Only two choices. Whichever we pick, the other must be the ! # square picked on move m*n, as it's the only way to get back # to (0, 0). Save its index in self.final so that moves before # the last know it must be kept free. for i, j in (1, 2), (2, 1): ! this = self.coords2index(i, j) ! final = self.coords2index(3-i, 3-j) self.final = final ! remove_from_successors(this) ! succs[final].append(corner) self.lastij = this yield this ! succs[final].remove(corner) ! add_to_successors(this) ! # Generate moves 3 thru m*n-1. ! def advance(len=len): # If some successor has only one exit, must take it. # Else favor successors with fewer exits. candidates = [] for i in succs[self.lastij]: ! e = len(succs[i]) ! assert e > 0, "else remove_from_successors() pruning flawed" ! if e == 1: ! candidates = [(e, i)] ! break ! candidates.append((e, i)) else: candidates.sort() *************** *** 1102,1118 **** for e, i in candidates: if i != self.final: ! if decrexits(i): ! free[i] = 0 self.lastij = i yield i ! free[i] = 1 ! increxits(i) ! # Generate moves 3 thru n**2-1. Alternative version using a # stronger (but more expensive) heuristic to order successors. ! # Since the # of backtracking levels is n**2, a poor move early on ! # can take eons to undo. Smallest n for which this matters a lot is ! # n==52. ! def advance_hard(midpoint=(n-1)/2.0): # If some successor has only one exit, must take it. # Else favor successors with fewer exits. --- 1091,1105 ---- for e, i in candidates: if i != self.final: ! if remove_from_successors(i): self.lastij = i yield i ! add_to_successors(i) ! # Generate moves 3 thru m*n-1. Alternative version using a # stronger (but more expensive) heuristic to order successors. ! # Since the # of backtracking levels is m*n, a poor move early on ! # can take eons to undo. Smallest square board for which this ! # matters a lot is 52x52. ! def advance_hard(vmid=(m-1)/2.0, hmid=(n-1)/2.0, len=len): # If some successor has only one exit, must take it. # Else favor successors with fewer exits. *************** *** 1121,1133 **** candidates = [] for i in succs[self.lastij]: ! if free[i]: ! e = nexits[i] ! assert e > 0, "else decrexits() pruning flawed" ! if e == 1: ! candidates = [(e, 0, i)] ! break ! i1, j1 = divmod(i, n) ! d = (i1 - midpoint)**2 + (j1 - midpoint)**2 ! candidates.append((e, -d, i)) else: candidates.sort() --- 1108,1119 ---- candidates = [] for i in succs[self.lastij]: ! e = len(succs[i]) ! assert e > 0, "else remove_from_successors() pruning flawed" ! if e == 1: ! candidates = [(e, 0, i)] ! break ! i1, j1 = self.index2coords(i) ! d = (i1 - vmid)**2 + (j1 - hmid)**2 ! candidates.append((e, -d, i)) else: candidates.sort() *************** *** 1135,1144 **** for e, d, i in candidates: if i != self.final: ! if decrexits(i): ! free[i] = 0 self.lastij = i yield i ! free[i] = 1 ! increxits(i) # Generate the last move. --- 1121,1128 ---- for e, d, i in candidates: if i != self.final: ! if remove_from_successors(i): self.lastij = i yield i ! add_to_successors(i) # Generate the last move. *************** *** 1147,1172 **** yield self.final ! if n <= 1: ! self.rowgenerators = [first] else: ! self.rowgenerators = [first, second] + \ ! [hard and advance_hard or advance] * (n**2 - 3) + \ [last] # Generate solutions. def solve(self): ! for x in conjoin(self.rowgenerators): yield x def printsolution(self, x): ! n = self.n ! assert len(x) == n**2 ! w = len(str(n**2 + 1)) format = "%" + str(w) + "d" ! squares = [[None] * n for i in range(n)] k = 1 for i in x: ! i1, j1 = divmod(i, n) squares[i1][j1] = format % k k += 1 --- 1131,1182 ---- yield self.final ! if m*n < 4: ! self.squaregenerators = [first] else: ! self.squaregenerators = [first, second] + \ ! [hard and advance_hard or advance] * (m*n - 3) + \ [last] + def coords2index(self, i, j): + assert 0 <= i < self.m + assert 0 <= j < self.n + return i * self.n + j + + def index2coords(self, index): + assert 0 <= index < self.m * self.n + return divmod(index, self.n) + + def _init_board(self): + succs = self.succs + del succs[:] + m, n = self.m, self.n + c2i = self.coords2index + + offsets = [( 1, 2), ( 2, 1), ( 2, -1), ( 1, -2), + (-1, -2), (-2, -1), (-2, 1), (-1, 2)] + rangen = range(n) + for i in range(m): + for j in rangen: + s = [c2i(i+io, j+jo) for io, jo in offsets + if 0 <= i+io < m and + 0 <= j+jo < n] + succs.append(s) + # Generate solutions. def solve(self): ! self._init_board() ! for x in conjoin(self.squaregenerators): yield x def printsolution(self, x): ! m, n = self.m, self.n ! assert len(x) == m*n ! w = len(str(m*n)) format = "%" + str(w) + "d" ! squares = [[None] * n for i in range(m)] k = 1 for i in x: ! i1, j1 = self.index2coords(i) squares[i1][j1] = format % k k += 1 *************** *** 1174,1178 **** sep = "+" + ("-" * w + "+") * n print sep ! for i in range(n): row = squares[i] print "|" + "|".join(row) + "|" --- 1184,1188 ---- sep = "+" + ("-" * w + "+") * n print sep ! for i in range(m): row = squares[i] print "|" + "|".join(row) + "|" *************** *** 1270,1274 **** 20,000 solutions even on a 6x6 board, so don't dare run this to exhaustion. ! >>> k = Knights(10) >>> LIMIT = 2 >>> count = 0 --- 1280,1284 ---- 20,000 solutions even on a 6x6 board, so don't dare run this to exhaustion. ! >>> k = Knights(10, 10) >>> LIMIT = 2 >>> count = 0 From twouters@users.sourceforge.net Fri Jul 13 16:10:57 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Fri, 13 Jul 2001 08:10:57 -0700 Subject: [Python-checkins] CVS: python/dist/src README,1.122.2.1,1.122.2.2 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv29804 Modified Files: Tag: release21-maint README Log Message: Expand the blob on Solaris to mention passing '-Xc' to compile Python correctly. Note that 'faulty' should actually be spelled 'fawlty', but I don't want those bugreports assigned to me ;) Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/README,v retrieving revision 1.122.2.1 retrieving revision 1.122.2.2 diff -C2 -r1.122.2.1 -r1.122.2.2 *** README 2001/05/09 18:13:29 1.122.2.1 --- README 2001/07/13 15:10:55 1.122.2.2 *************** *** 225,233 **** fix, let us know!) ! Solaris: When using Sun's C compiler with threads, at least on Solaris ! 2.5.1, you need to add the "-mt" compiler option (the simplest ! way is probably to specify the compiler with this option as ! the "CC" environment variable when running the configure ! script). Linux: A problem with threads and fork() was tracked down to a bug in --- 225,234 ---- fix, let us know!) ! Solaris: When using Sun's C compiler, it's necessary to compile in ! strict ANSI mode with multithreading enabled. This can be done ! by setting the 'CC' environment variable to 'cc -Xc -mt' ! before running the configure script. ANSI-compatibility mode ! ('-Xa') has been seen to compile the code without problems, ! but generate faulty code. Linux: A problem with threads and fork() was tracked down to a bug in From gvanrossum@users.sourceforge.net Fri Jul 13 18:06:29 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 13 Jul 2001 10:06:29 -0700 Subject: [Python-checkins] CVS: python/dist/src LICENSE,1.15.2.2,1.15.2.3 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv23826 Modified Files: Tag: release21-maint LICENSE Log Message: Argh. Somehow the header for the BEOPEN license had 2.1.1 in it. That should be 2.0. Index: LICENSE =================================================================== RCS file: /cvsroot/python/python/dist/src/LICENSE,v retrieving revision 1.15.2.2 retrieving revision 1.15.2.3 diff -C2 -r1.15.2.2 -r1.15.2.3 *** LICENSE 2001/06/27 11:25:48 1.15.2.2 --- LICENSE 2001/07/13 17:06:26 1.15.2.3 *************** *** 88,92 **** ! BEOPEN.COM TERMS AND CONDITIONS FOR PYTHON 2.1.1 ---------------------------------------------- --- 88,92 ---- ! BEOPEN.COM TERMS AND CONDITIONS FOR PYTHON 2.0 ---------------------------------------------- From gvanrossum@users.sourceforge.net Fri Jul 13 18:27:59 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 13 Jul 2001 10:27:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_socketserver.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv28539 Modified Files: test_socketserver.py Log Message: Should raise TestSkipped, not ImportError, when deciding to skip the test. Index: test_socketserver.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_socketserver.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** test_socketserver.py 2001/07/10 15:46:34 1.2 --- test_socketserver.py 2001/07/13 17:27:57 1.3 *************** *** 4,10 **** # regression test breaks the test. ! from test_support import verbose, verify, TESTFN if not verbose: ! raise ImportError, "test_socketserver can only be run manually" from SocketServer import * --- 4,10 ---- # regression test breaks the test. ! from test_support import verbose, verify, TESTFN, TestSkipped if not verbose: ! raise TestSkipped, "test_socketserver can only be run manually" from SocketServer import * From gvanrossum@users.sourceforge.net Fri Jul 13 19:05:48 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 13 Jul 2001 11:05:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib symbol.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv2962 Modified Files: symbol.py Log Message: Updated this file to match reality. Thanks Shane for pointing this out! Index: symbol.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/symbol.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -r1.12 -r1.13 *** symbol.py 2000/08/24 21:08:39 1.12 --- symbol.py 2001/07/13 18:05:46 1.13 *************** *** 31,78 **** continue_stmt = 274 return_stmt = 275 ! raise_stmt = 276 ! import_stmt = 277 ! import_as_name = 278 ! dotted_as_name = 279 ! dotted_name = 280 ! global_stmt = 281 ! exec_stmt = 282 ! assert_stmt = 283 ! compound_stmt = 284 ! if_stmt = 285 ! while_stmt = 286 ! for_stmt = 287 ! try_stmt = 288 ! except_clause = 289 ! suite = 290 ! test = 291 ! and_test = 292 ! not_test = 293 ! comparison = 294 ! comp_op = 295 ! expr = 296 ! xor_expr = 297 ! and_expr = 298 ! shift_expr = 299 ! arith_expr = 300 ! term = 301 ! factor = 302 ! power = 303 ! atom = 304 ! listmaker = 305 ! lambdef = 306 ! trailer = 307 ! subscriptlist = 308 ! subscript = 309 ! sliceop = 310 ! exprlist = 311 ! testlist = 312 ! dictmaker = 313 ! classdef = 314 ! arglist = 315 ! argument = 316 ! list_iter = 317 ! list_for = 318 ! list_if = 319 #--end constants-- --- 31,79 ---- continue_stmt = 274 return_stmt = 275 ! yield_stmt = 276 ! raise_stmt = 277 ! import_stmt = 278 ! import_as_name = 279 ! dotted_as_name = 280 ! dotted_name = 281 ! global_stmt = 282 ! exec_stmt = 283 ! assert_stmt = 284 ! compound_stmt = 285 ! if_stmt = 286 ! while_stmt = 287 ! for_stmt = 288 ! try_stmt = 289 ! except_clause = 290 ! suite = 291 ! test = 292 ! and_test = 293 ! not_test = 294 ! comparison = 295 ! comp_op = 296 ! expr = 297 ! xor_expr = 298 ! and_expr = 299 ! shift_expr = 300 ! arith_expr = 301 ! term = 302 ! factor = 303 ! power = 304 ! atom = 305 ! listmaker = 306 ! lambdef = 307 ! trailer = 308 ! subscriptlist = 309 ! subscript = 310 ! sliceop = 311 ! exprlist = 312 ! testlist = 313 ! dictmaker = 314 ! classdef = 315 ! arglist = 316 ! argument = 317 ! list_iter = 318 ! list_for = 319 ! list_if = 320 #--end constants-- From gvanrossum@users.sourceforge.net Fri Jul 13 20:48:09 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 13 Jul 2001 12:48:09 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0253.txt,1.12,1.13 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv23002 Modified Files: pep-0253.txt Log Message: Note to self. Index: pep-0253.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0253.txt,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -r1.12 -r1.13 *** pep-0253.txt 2001/07/11 21:26:08 1.12 --- pep-0253.txt 2001/07/13 19:48:07 1.13 *************** *** 881,884 **** --- 881,886 ---- - class methods and static methods + - cooperative methods and super() + - mapping between type object slots (tp_foo) and special methods (__foo__) (actually, this may belong in PEP 252) From jackjansen@users.sourceforge.net Fri Jul 13 21:54:10 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Fri, 13 Jul 2001 13:54:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/mlte - New directory Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/mlte In directory usw-pr-cvs1:/tmp/cvs-serv7327/mlte Log Message: Directory /cvsroot/python/python/dist/src/Mac/Modules/mlte added to the repository From jackjansen@users.sourceforge.net Fri Jul 13 21:56:45 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Fri, 13 Jul 2001 13:56:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/mlte Mltemodule.c,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/mlte In directory usw-pr-cvs1:/tmp/cvs-serv8106/Python/Mac/Modules/mlte Added Files: Mltemodule.c Log Message: First stab at an interface to the Multi Language Text Editor. It compiles and imports, but that's about all. Apple didn't put const in front of their input-only by-reference args, so that needs fixing first. --- NEW FILE: Mltemodule.c --- /* ========================== Module Mlte =========================== */ #include "Python.h" #include "macglue.h" #include "pymactoolbox.h" /* 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) #ifdef WITHOUT_FRAMEWORKS [...1280 lines suppressed...] m = Py_InitModule("Mlte", Mlte_methods); d = PyModule_GetDict(m); Mlte_Error = PyMac_GetOSErrException(); if (Mlte_Error == NULL || PyDict_SetItemString(d, "Error", Mlte_Error) != 0) return; TXNObject_Type.ob_type = &PyType_Type; Py_INCREF(&TXNObject_Type); if (PyDict_SetItemString(d, "TXNObjectType", (PyObject *)&TXNObject_Type) != 0) Py_FatalError("can't initialize TXNObjectType"); TXNFontMenuObject_Type.ob_type = &PyType_Type; Py_INCREF(&TXNFontMenuObject_Type); if (PyDict_SetItemString(d, "TXNFontMenuObjectType", (PyObject *)&TXNFontMenuObject_Type) != 0) Py_FatalError("can't initialize TXNFontMenuObjectType"); } /* ======================== End module Mlte ========================= */ From jackjansen@users.sourceforge.net Fri Jul 13 21:56:50 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Fri, 13 Jul 2001 13:56:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/mlte mltescan.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/mlte In directory usw-pr-cvs1:/tmp/cvs-serv8144/Python/Mac/Modules/mlte Added Files: mltescan.py Log Message: First stab at an interface to the Multi Language Text Editor. It compiles and imports, but that's about all. Apple didn't put const in front of their input-only by-reference args, so that needs fixing first. --- NEW FILE: mltescan.py --- # Scan an Apple header file, generating a Python file of generator calls. import sys import os BGENDIR=os.path.join(sys.prefix, ':Tools:bgen:bgen') sys.path.append(BGENDIR) from scantools import Scanner_OSX from bgenlocations import TOOLBOXDIR LONG = "MacTextEditor" SHORT = "mlte" OBJECTS = ("TXNObject", "TXNFontMenuObject") # ADD object typenames here def main(): input = "MacTextEditor.h" output = SHORT + "gen.py" defsoutput = TOOLBOXDIR + LONG + ".py" scanner = MyScanner(input, output, defsoutput) scanner.scan() scanner.gentypetest(SHORT+"typetest.py") scanner.close() print "=== Done scanning and generating, now importing the generated code... ===" exec "import " + SHORT + "support" print "=== Done. It's up to you to compile it now! ===" class MyScanner(Scanner_OSX): def destination(self, type, name, arglist): classname = "Function" listname = "functions" if arglist: t, n, m = arglist[0] if t in OBJECTS and m == "InMode": classname = "Method" listname = t + "_methods" return classname, listname def writeinitialdefs(self): self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n") def makeblacklistnames(self): return [ ] def makegreylist(self): return [] def makeblacklisttypes(self): return [ "TXNTab", # TBD "TXNMargins", # TBD "TXNControlData", #TBD "TXNATSUIFeatures", #TBD "TXNATSUIVariations", #TBD "TXNAttributeData", #TBD "TXNTypeAttributes", #TBD "TXNMatchTextRecord", #TBD "TXNBackground", #TBD "UniChar", #TBD "TXNFindUPP", ] def makerepairinstructions(self): return [ ([("void", "*", "OutMode"), ("ByteCount", "*", "InMode")], [("MlteInBuffer", "*", "InMode")]), ] if __name__ == "__main__": main() From jackjansen@users.sourceforge.net Fri Jul 13 21:56:54 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Fri, 13 Jul 2001 13:56:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/mlte mltesupport.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/mlte In directory usw-pr-cvs1:/tmp/cvs-serv8173/Python/Mac/Modules/mlte Added Files: mltesupport.py Log Message: First stab at an interface to the Multi Language Text Editor. It compiles and imports, but that's about all. Apple didn't put const in front of their input-only by-reference args, so that needs fixing first. --- NEW FILE: mltesupport.py --- # This script generates a Python interface for an Apple Macintosh Manager. # It uses the "bgen" package to generate C code. # The function specifications are generated by scanning the mamager's header file, # using the "scantools" package (customized for this particular manager). #error missing SetActionFilter import string # Declarations that change for each manager MODNAME = 'Mlte' # The name of the module # The following is *usually* unchanged but may still require tuning MODPREFIX = MODNAME # The prefix for module-wide routines INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner OUTPUTFILE = MODNAME + "module.c" # The file generated by this program from macsupport import * # Create the type objects includestuff = includestuff + """ #ifdef WITHOUT_FRAMEWORKS #include #else #include #endif /* For now we declare them forward here. They'll go to mactoolbox later */ staticforward PyObject *TXNObj_New(TXNObject); staticforward int TXNObj_Convert(PyObject *, TXNObject *); staticforward PyObject *TXNFontMenuObj_New(TXNFontMenuObject); staticforward int TXNFontMenuObj_Convert(PyObject *, TXNFontMenuObject *); // ADD declarations #ifdef NOTYET_USE_TOOLBOX_OBJECT_GLUE //extern PyObject *_CFTypeRefObj_New(CFTypeRef); //extern int _CFTypeRefObj_Convert(PyObject *, CFTypeRef *); //#define CFTypeRefObj_New _CFTypeRefObj_New //#define CFTypeRefObj_Convert _CFTypeRefObj_Convert #endif /* ** Parse/generate ADD records */ """ initstuff = initstuff + """ // PyMac_INIT_TOOLBOX_OBJECT_NEW(xxxx); """ TXNObject = OpaqueByValueType("TXNObject", "TXNObj") TXNFontMenuObject = OpaqueByValueType("TXNFontMenuObject", "TXNFontMenuObj") TXNFrameID = Type("TXNFrameID", "l") TXNVersionValue = Type("TXNVersionValue", "l") TXNFeatureBits = Type("TXNFeatureBits", "l") TXNInitOptions = Type("TXNInitOptions", "l") TXNFrameOptions = Type("TXNFrameOptions", "l") TXNContinuousFlags = Type("TXNContinuousFlags", "l") TXNMatchOptions = Type("TXNMatchOptions", "l") TXNFileType = OSTypeType("TXNFileType") TXNFrameType = Type("TXNFrameType", "l") TXNDataType = OSTypeType("TXNDataType") TXNControlTag = OSTypeType("TXNControlTag") TXNActionKey = Type("TXNActionKey", "l") TXNTabType = Type("TXNTabType", "b") TXNScrollBarState = Type("TXNScrollBarState", "l") TXNOffset = Type("TXNOffset", "l") TXNObjectRefcon = FakeType("(TXNObjectRefcon)0") # XXXX For now... TXNErrors = OSErrType("TXNErrors", "l") TXNTypeRunAttributes = OSTypeType("TXNTypeRunAttributes") TXNTypeRunAttributeSizes = Type("TXNTypeRunAttributeSizes", "l") TXNPermanentTextEncodingType = Type("TXNPermanentTextEncodingType", "l") TXTNTag = OSTypeType("TXTNTag") TXNBackgroundType = Type("TXNBackgroundType", "l") DragReference = OpaqueByValueType("DragReference", "DragObj") DragTrackingMessage = Type("DragTrackingMessage", "h") RgnHandle = OpaqueByValueType("RgnHandle", "ResObj") GWorldPtr = OpaqueByValueType("GWorldPtr", "GWorldObj") MlteInBuffer = VarInputBufferType('void *', 'ByteCount', 'l') # ADD object type here execfile("mltetypetest.py") # Our (opaque) objects class TXNObjDefinition(GlobalObjectDefinition): def outputCheckNewArg(self): Output("if (itself == NULL) return PyMac_Error(resNotFound);") class TXNFontMenuObjDefinition(GlobalObjectDefinition): def outputCheckNewArg(self): Output("if (itself == NULL) return PyMac_Error(resNotFound);") # ADD object class here # From here on it's basically all boiler plate... # Create the generator groups and link them module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff) TXNObject_object = TXNObjDefinition("TXNObject", "TXNObj", "TXNObject") TXNFontMenuObject_object = TXNFontMenuObjDefinition("TXNFontMenuObject", "TXNFontMenuObj", "TXNFontMenuObject") # ADD object here module.addobject(TXNObject_object) module.addobject(TXNFontMenuObject_object) # ADD addobject call here # Create the generator classes used to populate the lists Function = OSErrWeakLinkFunctionGenerator Method = OSErrWeakLinkMethodGenerator # Create and populate the lists functions = [] TXNObject_methods = [] TXNFontMenuObject_methods = [] # ADD _methods initializer here execfile(INPUTFILE) # add the populated lists to the generator groups # (in a different wordl the scan program would generate this) for f in functions: module.add(f) for f in TXNObject_methods: TXNObject_object.add(f) for f in TXNFontMenuObject_methods: TXNFontMenuObject_object.add(f) # ADD Manual generators here # generate output (open the output file as late as possible) SetOutputFileName(OUTPUTFILE) module.generate() From jackjansen@users.sourceforge.net Fri Jul 13 21:57:45 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Fri, 13 Jul 2001 13:57:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/scripts fullbuild.py,1.66,1.67 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory usw-pr-cvs1:/tmp/cvs-serv8462/Python/Mac/scripts Modified Files: fullbuild.py Log Message: Added Mlte module (which, to my surprise, is available for classic ppc as well). Index: fullbuild.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/fullbuild.py,v retrieving revision 1.66 retrieving revision 1.67 diff -C2 -r1.66 -r1.67 *** fullbuild.py 2001/06/26 21:52:03 1.66 --- fullbuild.py 2001/07/13 20:57:43 1.67 *************** *** 262,265 **** --- 262,266 ---- (":Mac:Build:Sndihooks.mcp", "Sndihooks.ppc"), (":Mac:Build:TE.mcp", "TE.ppc"), + (":Mac:Build:Mlte.ppc.mcp", "Mlte.ppc"), ]), *************** *** 290,293 **** --- 291,295 ---- (":Mac:Build:CF.carbon.mcp", "CF.carbon"), + (":Mac:Build:Mlte.carbon.mcp", "Mlte.carbon"), ]), From jackjansen@users.sourceforge.net Fri Jul 13 21:57:49 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Fri, 13 Jul 2001 13:57:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/scripts genpluginprojects.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory usw-pr-cvs1:/tmp/cvs-serv8505/Python/Mac/scripts Modified Files: genpluginprojects.py Log Message: Added Mlte module (which, to my surprise, is available for classic ppc as well). Index: genpluginprojects.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/genpluginprojects.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -r1.13 -r1.14 *** genpluginprojects.py 2001/06/26 21:52:08 1.13 --- genpluginprojects.py 2001/07/13 20:57:47 1.14 *************** *** 145,150 **** genpluginproject("ppc", "TE", libraries=["DragLib"]) genpluginproject("carbon", "TE") ! # OSX Only? genpluginproject("carbon", "CF") --- 145,152 ---- genpluginproject("ppc", "TE", libraries=["DragLib"]) genpluginproject("carbon", "TE") + genpluginproject("ppc", "Mlte", libraries=["Textension"]) + genpluginproject("carbon", "Mlte") ! # Carbon Only? genpluginproject("carbon", "CF") From gvanrossum@users.sourceforge.net Fri Jul 13 22:02:08 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 13 Jul 2001 14:02:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects funcobject.c,2.37.4.10,2.37.4.11 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv9773 Modified Files: Tag: descr-branch funcobject.c Log Message: func_descr_get(): When obj is None, replace it with NULL, so this returns an unbound method, not something bound to None! (Note: I wonder if there should be two separate types, bound method and unbound method, rather than the single method type that we have now that can deal with both. Also, it should be defined here rather than in classobject.c, since it is no longer specific to classic classes.) Index: funcobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/funcobject.c,v retrieving revision 2.37.4.10 retrieving revision 2.37.4.11 diff -C2 -r2.37.4.10 -r2.37.4.11 *** funcobject.c 2001/07/04 00:13:58 2.37.4.10 --- funcobject.c 2001/07/13 21:02:06 2.37.4.11 *************** *** 333,336 **** --- 333,338 ---- func_descr_get(PyObject *func, PyObject *obj, PyObject *type) { + if (obj == Py_None) + obj = NULL; return PyMethod_New(func, obj, type); } From gvanrossum@users.sourceforge.net Fri Jul 13 22:04:03 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 13 Jul 2001 14:04:03 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0252.txt,1.11,1.12 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv10134 Modified Files: pep-0252.txt Log Message: Add a section on static methods and class methods. Add a very uncooked section on the C API. Index: pep-0252.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0252.txt,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -r1.11 -r1.12 *** pep-0252.txt 2001/07/09 19:05:39 1.11 --- pep-0252.txt 2001/07/13 21:04:00 1.12 *************** *** 89,99 **** The type API is sometimes combined by a __dict__ that works the ! same was as for instances (e.g., for function objects in Python ! 2.1, f.__dict__ contains f's dynamic attributes, while f.__members__ lists the names of f's statically defined attributes). Some caution must be exercised: some objects don't list theire ! "intrinsic" attributes (e.g. __dict__ and __doc__) in __members__, while others do; sometimes attribute names that occur both in __members__ or __methods__ and as keys in __dict__, in which case --- 89,99 ---- The type API is sometimes combined by a __dict__ that works the ! same was as for instances (for example for function objects in ! Python 2.1, f.__dict__ contains f's dynamic attributes, while f.__members__ lists the names of f's statically defined attributes). Some caution must be exercised: some objects don't list theire ! "intrinsic" attributes (like __dict__ and __doc__) in __members__, while others do; sometimes attribute names that occur both in __members__ or __methods__ and as keys in __dict__, in which case *************** *** 155,159 **** In the discussion below, I distinguish two kinds of objects: ! regular objects (e.g. lists, ints, functions) and meta-objects. Types and classes and meta-objects. Meta-objects are also regular objects, but we're mostly interested in them because they are --- 155,159 ---- In the discussion below, I distinguish two kinds of objects: ! regular objects (like lists, ints, functions) and meta-objects. Types and classes and meta-objects. Meta-objects are also regular objects, but we're mostly interested in them because they are *************** *** 249,256 **** Rationale: we can't have a simples rule like "static overrides dynamic" or "dynamic overrides static", because some static ! attributes indeed override dynamic attributes, e.g. a key ! '__class__' in an instance's __dict__ is ignored in favor of ! the statically defined __class__ pointer, but on the other hand ! most keys in inst.__dict__ override attributes defined in inst.__class__. Presence of a __set__ method on a descriptor indicates that this is a data descriptor. (Even read-only data --- 249,256 ---- Rationale: we can't have a simples rule like "static overrides dynamic" or "dynamic overrides static", because some static ! attributes indeed override dynamic attributes; for example, a ! key '__class__' in an instance's __dict__ is ignored in favor ! of the statically defined __class__ pointer, but on the other ! hand most keys in inst.__dict__ override attributes defined in inst.__class__. Presence of a __set__ method on a descriptor indicates that this is a data descriptor. (Even read-only data *************** *** 276,282 **** descriptor's interface, neither for getting/setting the value nor for describing the attribute otherwise, except some trivial ! properties (e.g. it's reasonable to assume that __name__ and ! __doc__ should be the attribute's name and docstring). I will ! propose such an API below. If an object found in the meta-object's __dict__ is not an --- 276,282 ---- descriptor's interface, neither for getting/setting the value nor for describing the attribute otherwise, except some trivial ! properties (it's reasonable to assume that __name__ and __doc__ ! should be the attribute's name and docstring). I will propose ! such an API below. If an object found in the meta-object's __dict__ is not an *************** *** 336,344 **** None, this should be a method descriptor, and the result is an *unbound* method restricted to objects whose type is (a ! descendent of) T. (For methods, this is called a "binding" ! operation, even if X==None. Exactly what is returned by the ! binding operation depends on the semantics of the descriptor; ! for example, class methods ignore the instance and bind to the ! type instead.) - __set__(): a function of two arguments that sets the attribute --- 336,345 ---- None, this should be a method descriptor, and the result is an *unbound* method restricted to objects whose type is (a ! descendent of) T. Such an unbound method is a descriptor ! itself. For methods, this is called a "binding" operation, even ! if X==None. Exactly what is returned by the binding operation ! depends on the semantics of the descriptor; for example, static ! methods and class methods (see below) ignore the instance and ! bind to the type instead. - __set__(): a function of two arguments that sets the attribute *************** *** 347,357 **** Example: C.ivar.set(x, y) ~~ x.ivar = y. - Method attributes may also be callable; in this case they act as - unbound method. Example: C.meth(C(), x) ~~ C().meth(x). C API ! XXX --- 348,590 ---- Example: C.ivar.set(x, y) ~~ x.ivar = y. + Static methods and class methods + The descriptor API makes it possible to add static methods and + class methods. Static methods are easy to describe: they behave + pretty much like static methods in C++ or Java. Here's an + example: + + class C: + + def foo(x, y): + print "staticmethod", x, y + foo = staticmethod(foo) + + C.foo(1, 2) + c = C() + c.foo(1, 2) + + Both the call C.foo(1, 2) and the call c.foo(1, 2) call foo() with + two arguments, and print "staticmethod 1 2". No "self" is declared in + the definition of foo(), and no instance is required in the call. + + The line "foo = staticmethod(foo)" in the class statement is the + crucial element: this makes foo() a static method. The built-in + staticmethod() wraps its function argument in a special kind of + descriptor whose __get__() method returns the original function + unchanged. Without this, the __get__() method of standard + function objects would have created a bound method object for + 'c.foo' and an unbound method object for 'C.foo'. + + Class methods use a similar pattern to declare methods that + receive an implicit first argument that is the *class* for which + they are invoked. This has no C++ or Java equivalent, and is not + quite the same as what class methods are in Smalltalk, but may + serve a similar purpose. (Python also has real metaclasses, and + perhaps methods defined in a metaclass have more right to the name + "class method"; but I expect that most programmers won't be using + metaclasses.) Here's an example: + + class C: + + def foo(x, y): + print "classmethod", x, y + foo = classmethod(foo) + + C.foo(1) + c = C() + c.foo(1) + + Both the call C.foo(1) and the call c.foo(1) end up calling foo() + with *two* arguments, and print "classmethod __main__.C 1". The + first argument of foo() is implied, and it is the class, even if + the method was invoked via an instance. Now let's continue the + example: + + class D(C): + pass + + D.foo(1) + d = D() + d.foo(1) + + This prints "classmethod __main__.D 1" both times; in other words, + the class passed as the first argument of foo() is the class + involved in the call, not the class involved in the definition of + foo(). + + But notice this: + + class E(C): + def foo(x, y): # override C.foo + print "E.foo() called" + C.foo(y) + + E.foo(1) + e = E() + e.foo(1) + + In this example, the call to C.foo() from E.foo() will see class C + as its first argument, not class E. This is to be expected, since + the call specifies the class C. But it stresses the difference + between these class methods and methods defined in metaclasses + (where an upcall to a metamethod would pass the target class as an + explicit first argument). If you don't understand this, don't + worry, you're not alone. + + C API ! XXX The following is VERY rough text that I wrote with a different ! audience in mind; I'll have to go through this to edit it more. ! XXX It also doesn't go into enough detail for the C API. ! ! A built-in type can declare special data attributes in two ways: ! using a struct memberlist (defined in structmember.h) or a struct ! getsetlist (defined in descrobject.h). The struct memberlist is ! an old mechanism put to new use: each attribute has a descriptor ! record including its name, an enum giving its type (various C ! types are supported as well as PyObject *), an offset from the ! start of the instance, and a read-only flag. ! ! The struct getsetlist mechanism is new, and intended for cases ! that don't fit in that mold, because they either require ! additional checking, or are plain calculated attributes. Each ! attribute here has a name, a getter C function pointer, a setter C ! function pointer, and a context pointer. The function pointers ! are optional, so that for example setting the setter function ! pointer to NULL makes a read-only attribute. The context pointer ! is intended to pass auxiliary information to generic getter/setter ! functions, but I haven't found a need for this yet. ! ! Note that there is also a similar mechanism to declare built-in ! methods: these are PyMethodDef structures, which contain a name ! and a C function pointer (and some flags for the calling ! convention). ! ! Traditionally, built-in types have had to define their own ! tp_getattro and tp_setattro slot functions to make these attribute ! definitions work (PyMethodDef and struct memberlist are quite ! old). There are convenience functions that take an array of ! PyMethodDef or memberlist structures, an object, and an attribute ! name, and return or set the attribute if found in the list, or ! raise an exception if not found. But these convenience functions ! had to be explicitly called by the tp_getattro or tp_setattro ! method of the specific type, and they did a linear search of the ! array using strcmp() to find the array element describing the ! requested attribute. ! ! I now have a brand spanking new generic mechanism that improves ! this situation substantially. ! ! - Pointers to arrays of PyMethodDef, memberlist, getsetlist ! structures are part of the new type object (tp_methods, ! tp_members, tp_getset). ! ! - At type initialization time (in PyType_InitDict()), for each ! entry in those three arrays, a descriptor object is created and ! placed in a dictionary that belongs to the type (tp_dict). ! ! - Descriptors are very lean objects that mostly point to the ! corresponding structure. An implementation detail is that all ! descriptors share the same object type, and a discriminator ! field tells what kind of descriptor it is (method, member, or ! getset). ! ! - As explained in PEP 252, descriptors have a get() method that ! takes an object argument and returns that object's attribute; ! descriptors for writable attributes also have a set() method ! that takes an object and a value and set that object's ! attribute. Note that the get() object also serves as a bind() ! operation for methods, binding the unbound method implementation ! to the object. ! ! - Instead of providing their own tp_getattro and tp_setattro ! implementation, almost all built-in objects now place ! PyObject_GenericGetAttr and (if they have any writable ! attributes) PyObject_GenericSetAttr in their tp_getattro and ! tp_setattro slots. (Or, they can leave these NULL, and inherit ! them from the default base object, if they arrange for an ! explicit call to PyType_InitDict() for the type before the first ! instance is created.) ! ! - In the simplest case, PyObject_GenericGetAttr() does exactly one ! dictionary lookup: it looks up the attribute name in the type's ! dictionary (obj->ob_type->tp_dict). Upon success, there are two ! possibilities: the descriptor has a get method, or it doesn't. ! For speed, the get and set methods are type slots: tp_descr_get ! and tp_descr_set. If the tp_descr_get slot is non-NULL, it is ! called, passing the object as its only argument, and the return ! value from this call is the result of the getattr operation. If ! the tp_descr_get slot is NULL, as a fallback the descriptor ! itself is returned (compare class attributes that are not ! methods but simple values). ! ! - PyObject_GenericSetAttr() works very similar but uses the ! tp_descr_set slot and calls it with the object and the new ! attribute value; if the tp_descr_set slot is NULL, an ! AttributeError is raised. ! ! - But now for a more complicated case. The approach described ! above is suitable for most built-in objects such as lists, ! strings, numbers. However, some object types have a dictionary ! in each instance that can store arbitrary attribute. In fact, ! when you use a class statement to subtype an existing built-in ! type, you automatically get such a dictionary (unless you ! explicitly turn it off, using another advanced feature, ! __slots__). Let's call this the instance dict, to distinguish ! it from the type dict. ! ! - In the more complicated case, there's a conflict between names ! stored in the instance dict and names stored in the type dict. ! If both dicts have an entry with the same key, which one should ! we return? Looking as classic Python for guidance, I find ! conflicting rules: for class instances, the instance dict ! overrides the class dict, *except* for the special attributes ! (like __dict__ and __class__), which have priority over the ! instance dict. ! ! - I resolved this with the following set of rules, implemented in ! PyObject_GenericGetAttr(): ! ! 1. Look in the type dict. If you find a *data* descriptor, use ! its get() method to produce the result. This takes care of ! special attributes like __dict__ and __class__. ! ! 2. Look in the instance dict. If you find anything, that's it. ! (This takes care of the requirement that normally the ! instance dict overrides the class dict. ! ! 3. Look in the type dict again (in reality this uses the saved ! result from step 1, of course). If you find a descriptor, ! use its get() method; if you find something else, that's it; ! if it's not there, raise AttributeError. ! ! This requires a classification of descriptors in data and ! nondata descriptors. The current implementation quite sensibly ! classifies member and getset descriptors as data (even if they ! are read-only!) and member descriptors as nondata. ! Non-descriptors (like function pointers or plain values) are ! also classified as non-data. ! ! - This scheme has one drawback: in what I assume to be the most ! common case, referencing an instance variable stored in the ! instance dict, it does *two* dictionary lookups, whereas the ! classic scheme did a quick test for attributes starting with two ! underscores plus a single dictionary lookup. (Although the ! implementation is sadly structured as instance_getattr() calling ! instance_getattr1() calling instance_getattr2() which finally ! calls PyDict_GetItem(), and the underscore test calls ! PyString_AsString() rather than inlining this. I wonder if ! optimizing the snot out of this might not be a good idea to ! speed up Python 2.2, if we weren't going to rip it all out. :-) ! ! - A benchmark verifies that in fact this is as fast as classic ! instance variable lookup, so I'm no longer worried. ! ! - Modification for dynamic types: step 1 and 3 look in the ! dictionary of the type and all its base classes (in MRO ! sequence, or couse). From gvanrossum@users.sourceforge.net Fri Jul 13 22:47:40 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 13 Jul 2001 14:47:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects object.c,2.124.4.23,2.124.4.24 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv22194 Modified Files: Tag: descr-branch object.c Log Message: PyObject_SetAttr(): be more careful when raising an exception because there's no tp_getattr[o] slot. First, change this into a TypeError rather than an AttributeError (it was also a TypeError in 2.1 and before). Second, issue a different error message when the type has no tp_getattr[o] slot than when it does. Third, in all cases mention both the operation (assign to or del) and the attribute name. Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.124.4.23 retrieving revision 2.124.4.24 diff -C2 -r2.124.4.23 -r2.124.4.24 *** object.c 2001/07/07 22:55:30 2.124.4.23 --- object.c 2001/07/13 21:47:38 2.124.4.24 *************** *** 1104,1110 **** } Py_DECREF(name); ! PyErr_Format(PyExc_AttributeError, ! "'%.50s' object has no attribute '%.400s'", ! tp->tp_name, PyString_AS_STRING(name)); return -1; } --- 1104,1121 ---- } Py_DECREF(name); ! if (tp->tp_getattr == NULL && tp->tp_getattro == NULL) ! PyErr_Format(PyExc_TypeError, ! "'%.100s' object has no attributes " ! "(%s .%.100s)", ! tp->tp_name, ! value==NULL ? "del" : "assign to", ! PyString_AS_STRING(name)); ! else ! PyErr_Format(PyExc_TypeError, ! "'%.100s' object has only read-only attributes " ! "(%s .%.100s)", ! tp->tp_name, ! value==NULL ? "del" : "assign to", ! PyString_AS_STRING(name)); return -1; } From gvanrossum@users.sourceforge.net Fri Jul 13 22:48:11 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 13 Jul 2001 14:48:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.66,2.16.8.67 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv22282 Modified Files: Tag: descr-branch typeobject.c Log Message: Do not add a default __setattr__ implementation to the base object: this would be inherited by types that have no settable attributes. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.66 retrieving revision 2.16.8.67 diff -C2 -r2.16.8.66 -r2.16.8.67 *** typeobject.c 2001/07/11 00:57:09 2.16.8.66 --- typeobject.c 2001/07/13 21:48:09 2.16.8.67 *************** *** 874,878 **** 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ ! PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ --- 874,878 ---- 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ ! 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ From gvanrossum@users.sourceforge.net Fri Jul 13 22:49:35 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 13 Jul 2001 14:49:35 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,1.17.2.2,1.17.2.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv22862 Modified Files: Tag: descr-branch test_generators.py Log Message: Fix the expected output for assignment to a read-only attribute. Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.17.2.2 retrieving revision 1.17.2.3 diff -C2 -r1.17.2.2 -r1.17.2.3 *** test_generators.py 2001/07/08 04:30:29 1.17.2.2 --- test_generators.py 2001/07/13 21:49:33 1.17.2.3 *************** *** 406,410 **** Traceback (most recent call last): ... ! TypeError: readonly attribute >>> def g(): ... yield me.gi_running --- 406,410 ---- Traceback (most recent call last): ... ! TypeError: 'generator' object has only read-only attributes (assign to .gi_running) >>> def g(): ... yield me.gi_running From gvanrossum@users.sourceforge.net Fri Jul 13 22:50:50 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 13 Jul 2001 14:50:50 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0252.txt,1.12,1.13 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv23270 Modified Files: pep-0252.txt Log Message: Added a small example before I have to go. Index: pep-0252.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0252.txt,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -r1.12 -r1.13 *** pep-0252.txt 2001/07/13 21:04:00 1.12 --- pep-0252.txt 2001/07/13 21:50:48 1.13 *************** *** 596,600 **** Examples ! XXX --- 596,648 ---- Examples ! Let's look at lists. In classic Python, the method names of ! lists were available as the __methods__ attribute of list objects: ! ! >>> [].__methods__ ! ['append', 'count', 'extend', 'index', 'insert', 'pop', ! 'remove', 'reverse', 'sort'] ! >>> ! ! Under the new proposal, the __methods__ attribute no longer exists: ! ! >>> [].__methods__ ! Traceback (most recent call last): ! File "", line 1, in ? ! AttributeError: 'list' object has no attribute '__methods__' ! >>> ! ! Instead, you can get the same information from the list type: ! ! >>> T = [].__class__ ! >>> T ! ! >>> dir(T) # like T.__dict__.keys(), but sorted ! ['__add__', '__class__', '__contains__', '__eq__', '__ge__', ! '__getattr__', '__getitem__', '__getslice__', '__gt__', ! '__iadd__', '__imul__', '__init__', '__le__', '__len__', ! '__lt__', '__mul__', '__ne__', '__new__', '__radd__', ! '__repr__', '__rmul__', '__setitem__', '__setslice__', 'append', ! 'count', 'extend', 'index', 'insert', 'pop', 'remove', ! 'reverse', 'sort'] ! >>> ! ! The new introspection API gives more information than the old one: ! in addition to the regular methods, it also shows the methods that ! are normally invoked through special notations, e.g. __iadd__ ! (+=), __len__ (len), __ne__ (!=). You can invoke any method from ! this list directly: ! ! >>> a = ['tic', 'tac'] ! >>> T.__len__(a) # same as len(a) ! 2 ! >>> T.append(a, 'toe') # same as a.append('toe') ! >>> a ! ['tic', 'tac', 'toe'] ! >>> ! ! This is just like it is for user-defined classes. ! ! Notice a familiar yet surprising name in the list: __init__. This ! is the domain of PEP 253. From tim.one@home.com Fri Jul 13 22:59:49 2001 From: tim.one@home.com (Tim Peters) Date: Fri, 13 Jul 2001 17:59:49 -0400 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,1.17.2.2,1.17.2.3 In-Reply-To: Message-ID: > Modified Files: > Tag: descr-branch > test_generators.py > Log Message: > Fix the expected output for assignment to a read-only attribute. > > > Index: test_generators.py > =================================================================== > ! TypeError: readonly attribute > --- 406,410 ---- > ! TypeError: 'generator' object has only read-only attributes (assign to .gi_running) Thanks! That's a much more informative message. From jackjansen@users.sourceforge.net Fri Jul 13 23:27:10 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Fri, 13 Jul 2001 15:27:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/mlte Mltemodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/mlte In directory usw-pr-cvs1:/tmp/cvs-serv32192/Python/Mac/Modules/mlte Modified Files: Mltemodule.c Log Message: Fixed the mis-guessed parameters and added support for a few optional parameter types. There's a good chance that this is usable now (but there's no test code yet). Index: Mltemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/mlte/Mltemodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** Mltemodule.c 2001/07/13 20:56:43 1.1 --- Mltemodule.c 2001/07/13 22:27:07 1.2 *************** *** 39,44 **** /* ! ** Parse/generate ADD records */ --- 39,73 ---- /* ! ** Parse an optional fsspec */ + static int + OptFSSpecPtr_Convert(PyObject *v, FSSpec **p_itself) + { + static FSSpec fss; + if (v == Py_None) + { + *p_itself = NULL; + return 1; + } + *p_itself = &fss; + return PyMac_GetFSSpec(v, *p_itself); + } + + /* + ** Parse an optional rect + */ + static int + OptRectPtr_Convert(PyObject *v, Rect **p_itself) + { + static Rect r; + + if (v == Py_None) + { + *p_itself = NULL; + return 1; + } + *p_itself = &r; + return PyMac_GetRect(v, *p_itself); + } *************** *** 193,203 **** EventRecord iEvent; PyMac_PRECHECK(TXNTSMCheck); ! if (!PyArg_ParseTuple(_args, "")) return NULL; _rv = TXNTSMCheck(_self->ob_itself, &iEvent); ! _res = Py_BuildValue("bO&", ! _rv, ! PyMac_BuildEventRecord, &iEvent); return _res; } --- 222,232 ---- EventRecord iEvent; PyMac_PRECHECK(TXNTSMCheck); ! if (!PyArg_ParseTuple(_args, "O&", ! PyMac_GetEventRecord, &iEvent)) return NULL; _rv = TXNTSMCheck(_self->ob_itself, &iEvent); ! _res = Py_BuildValue("b", ! _rv); return _res; } *************** *** 666,673 **** SInt16 iResourceReference; PyMac_PRECHECK(TXNSave); ! if (!PyArg_ParseTuple(_args, "O&O&lhh", PyMac_GetOSType, &iType, PyMac_GetOSType, &iResType, &iPermanentEncoding, &iDataReference, &iResourceReference)) --- 695,703 ---- SInt16 iResourceReference; PyMac_PRECHECK(TXNSave); ! if (!PyArg_ParseTuple(_args, "O&O&lO&hh", PyMac_GetOSType, &iType, PyMac_GetOSType, &iResType, &iPermanentEncoding, + PyMac_GetFSSpec, &iFileSpecification, &iDataReference, &iResourceReference)) *************** *** 681,686 **** iResourceReference); if (_err != noErr) return PyMac_Error(_err); ! _res = Py_BuildValue("O&", ! PyMac_BuildFSSpec, iFileSpecification); return _res; } --- 711,716 ---- iResourceReference); if (_err != noErr) return PyMac_Error(_err); ! Py_INCREF(Py_None); ! _res = Py_None; return _res; } *************** *** 904,908 **** "(EventRecord iEvent) -> None"}, {"TXNTSMCheck", (PyCFunction)TXNObj_TXNTSMCheck, 1, ! "() -> (Boolean _rv, EventRecord iEvent)"}, {"TXNSelectAll", (PyCFunction)TXNObj_TXNSelectAll, 1, "() -> None"}, --- 934,938 ---- "(EventRecord iEvent) -> None"}, {"TXNTSMCheck", (PyCFunction)TXNObj_TXNTSMCheck, 1, ! "(EventRecord iEvent) -> (Boolean _rv)"}, {"TXNSelectAll", (PyCFunction)TXNObj_TXNSelectAll, 1, "() -> None"}, *************** *** 962,966 **** "() -> (ItemCount _rv)"}, {"TXNSave", (PyCFunction)TXNObj_TXNSave, 1, ! "(OSType iType, OSType iResType, TXNPermanentTextEncodingType iPermanentEncoding, SInt16 iDataReference, SInt16 iResourceReference) -> (FSSpec iFileSpecification)"}, {"TXNRevert", (PyCFunction)TXNObj_TXNRevert, 1, "() -> None"}, --- 992,996 ---- "() -> (ItemCount _rv)"}, {"TXNSave", (PyCFunction)TXNObj_TXNSave, 1, ! "(OSType iType, OSType iResType, TXNPermanentTextEncodingType iPermanentEncoding, FSSpec iFileSpecification, SInt16 iDataReference, SInt16 iResourceReference) -> None"}, {"TXNRevert", (PyCFunction)TXNObj_TXNRevert, 1, "() -> None"}, *************** *** 1141,1147 **** PyObject *_res = NULL; OSStatus _err; ! FSSpec iFileSpec; WindowPtr iWindow; ! Rect iFrame; TXNFrameOptions iFrameOptions; TXNFrameType iFrameType; --- 1171,1177 ---- PyObject *_res = NULL; OSStatus _err; ! FSSpec * iFileSpec; WindowPtr iWindow; ! Rect * iFrame; TXNFrameOptions iFrameOptions; TXNFrameType iFrameType; *************** *** 1151,1157 **** TXNFrameID oTXNFrameID; PyMac_PRECHECK(TXNNewObject); ! if (!PyArg_ParseTuple(_args, "O&O&llO&l", ! PyMac_GetFSSpec, &iFileSpec, WinObj_Convert, &iWindow, &iFrameOptions, &iFrameType, --- 1181,1188 ---- TXNFrameID oTXNFrameID; PyMac_PRECHECK(TXNNewObject); ! if (!PyArg_ParseTuple(_args, "O&O&O&llO&l", ! OptFSSpecPtr_Convert, &iFileSpec, WinObj_Convert, &iWindow, + OptRectPtr_Convert, &iFrame, &iFrameOptions, &iFrameType, *************** *** 1159,1165 **** &iPermanentEncoding)) return NULL; ! _err = TXNNewObject(&iFileSpec, iWindow, ! &iFrame, iFrameOptions, iFrameType, --- 1190,1196 ---- &iPermanentEncoding)) return NULL; ! _err = TXNNewObject(iFileSpec, iWindow, ! iFrame, iFrameOptions, iFrameType, *************** *** 1170,1175 **** (TXNObjectRefcon)0); if (_err != noErr) return PyMac_Error(_err); ! _res = Py_BuildValue("O&O&l", ! PyMac_BuildRect, &iFrame, TXNObj_New, oTXNObject, oTXNFrameID); --- 1201,1205 ---- (TXNObjectRefcon)0); if (_err != noErr) return PyMac_Error(_err); ! _res = Py_BuildValue("O&l", TXNObj_New, oTXNObject, oTXNFrameID); *************** *** 1269,1275 **** } static PyMethodDef Mlte_methods[] = { {"TXNNewObject", (PyCFunction)Mlte_TXNNewObject, 1, ! "(FSSpec iFileSpec, WindowPtr iWindow, TXNFrameOptions iFrameOptions, TXNFrameType iFrameType, TXNFileType iFileType, TXNPermanentTextEncodingType iPermanentEncoding) -> (Rect iFrame, TXNObject oTXNObject, TXNFrameID oTXNFrameID)"}, {"TXNTerminateTextension", (PyCFunction)Mlte_TXNTerminateTextension, 1, "() -> None"}, --- 1299,1326 ---- } + static PyObject *Mlte_TXNInitTextension(PyObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + + OSStatus _err; + TXNMacOSPreferredFontDescription * iDefaultFonts = NULL; + ItemCount iCountDefaultFonts = 0; + TXNInitOptions iUsageFlags; + PyMac_PRECHECK(TXNInitTextension); + if (!PyArg_ParseTuple(_args, "l", &iUsageFlags)) + return NULL; + _err = TXNInitTextension(iDefaultFonts, + iCountDefaultFonts, + iUsageFlags); + if (_err != noErr) return PyMac_Error(_err); + Py_INCREF(Py_None); + _res = Py_None; + return _res; + + } + static PyMethodDef Mlte_methods[] = { {"TXNNewObject", (PyCFunction)Mlte_TXNNewObject, 1, ! "(FSSpec * iFileSpec, WindowPtr iWindow, Rect * iFrame, TXNFrameOptions iFrameOptions, TXNFrameType iFrameType, TXNFileType iFileType, TXNPermanentTextEncodingType iPermanentEncoding) -> (TXNObject oTXNObject, TXNFrameID oTXNFrameID)"}, {"TXNTerminateTextension", (PyCFunction)Mlte_TXNTerminateTextension, 1, "() -> None"}, *************** *** 1284,1287 **** --- 1335,1340 ---- {"TXNVersionInformation", (PyCFunction)Mlte_TXNVersionInformation, 1, "() -> (TXNVersionValue _rv, TXNFeatureBits oFeatureFlags)"}, + {"TXNInitTextension", (PyCFunction)Mlte_TXNInitTextension, 1, + "(TXNInitOptions) -> None"}, {NULL, NULL, 0} }; From jackjansen@users.sourceforge.net Fri Jul 13 23:27:17 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Fri, 13 Jul 2001 15:27:17 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/mlte mltescan.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/mlte In directory usw-pr-cvs1:/tmp/cvs-serv32227/Python/Mac/Modules/mlte Modified Files: mltescan.py Log Message: Fixed the mis-guessed parameters and added support for a few optional parameter types. There's a good chance that this is usable now (but there's no test code yet). Index: mltescan.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/mlte/mltescan.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** mltescan.py 2001/07/13 20:56:48 1.1 --- mltescan.py 2001/07/13 22:27:14 1.2 *************** *** 42,45 **** --- 42,48 ---- def makeblacklistnames(self): return [ + "TXNGetFontDefaults", # Arg is too difficult + "TXNSetFontDefaults", # Arg is too difficult + "TXNInitTextension", # done manually ] *************** *** 64,67 **** --- 67,86 ---- def makerepairinstructions(self): return [ + # TXNNewObject has a lot of optional parameters + ([("FSSpec_ptr", "iFileSpec", "InMode")], + [("OptFSSpecPtr", "*", "*")]), + ([("Rect", "iFrame", "OutMode")], + [("OptRectPtr", "*", "InMode")]), + + # In UH 332 some of the "const" are missing for input parameters passed + # by reference. We fix that up here. + ([("EventRecord", "iEvent", "OutMode")], + [("EventRecord_ptr", "*", "InMode")]), + ([("FSSpec", "iFileSpecification", "OutMode")], + [("FSSpec_ptr", "*", "InMode")]), + ([("TXNMacOSPreferredFontDescription", "iFontDefaults", "OutMode")], + [("TXNMacOSPreferredFontDescription_ptr", "*", "InMode")]), + + # In buffers are passed as void * ([("void", "*", "OutMode"), ("ByteCount", "*", "InMode")], [("MlteInBuffer", "*", "InMode")]), From jackjansen@users.sourceforge.net Fri Jul 13 23:27:23 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Fri, 13 Jul 2001 15:27:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/mlte mltesupport.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/mlte In directory usw-pr-cvs1:/tmp/cvs-serv32267/Python/Mac/Modules/mlte Modified Files: mltesupport.py Log Message: Fixed the mis-guessed parameters and added support for a few optional parameter types. There's a good chance that this is usable now (but there's no test code yet). Index: mltesupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/mlte/mltesupport.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** mltesupport.py 2001/07/13 20:56:52 1.1 --- mltesupport.py 2001/07/13 22:27:20 1.2 *************** *** 43,49 **** /* ! ** Parse/generate ADD records */ """ --- 43,78 ---- /* ! ** Parse an optional fsspec */ + static int + OptFSSpecPtr_Convert(PyObject *v, FSSpec **p_itself) + { + static FSSpec fss; + if (v == Py_None) + { + *p_itself = NULL; + return 1; + } + *p_itself = &fss; + return PyMac_GetFSSpec(v, *p_itself); + } + /* + ** Parse an optional rect + */ + static int + OptRectPtr_Convert(PyObject *v, Rect **p_itself) + { + static Rect r; + + if (v == Py_None) + { + *p_itself = NULL; + return 1; + } + *p_itself = &r; + return PyMac_GetRect(v, *p_itself); + } + """ *************** *** 82,85 **** --- 111,116 ---- MlteInBuffer = VarInputBufferType('void *', 'ByteCount', 'l') + OptFSSpecPtr = OpaqueByValueType("FSSpec *", "OptFSSpecPtr") + OptRectPtr = OpaqueByValueType("Rect *", "OptRectPtr") # ADD object type here *************** *** 132,135 **** --- 163,186 ---- # ADD Manual generators here + inittextension_body = """ + OSStatus _err; + TXNMacOSPreferredFontDescription * iDefaultFonts = NULL; + ItemCount iCountDefaultFonts = 0; + TXNInitOptions iUsageFlags; + PyMac_PRECHECK(TXNInitTextension); + if (!PyArg_ParseTuple(_args, "l", &iUsageFlags)) + return NULL; + _err = TXNInitTextension(iDefaultFonts, + iCountDefaultFonts, + iUsageFlags); + if (_err != noErr) return PyMac_Error(_err); + Py_INCREF(Py_None); + _res = Py_None; + return _res; + """ + + f = ManualGenerator("TXNInitTextension", inittextension_body); + f.docstring = lambda: "(TXNInitOptions) -> None" + module.add(f) # generate output (open the output file as late as possible) From jackjansen@users.sourceforge.net Fri Jul 13 23:28:38 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Fri, 13 Jul 2001 15:28:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/bgen/bgen scantools.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/bgen/bgen In directory usw-pr-cvs1:/tmp/cvs-serv32616/Python/Tools/bgen/bgen Modified Files: scantools.py Log Message: Allow [] after a parameter name. We currently take this to be the same as * in front, which isn't 100% correct but good enough. Index: scantools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/scantools.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -r1.21 -r1.22 *** scantools.py 2001/06/26 21:53:25 1.21 --- scantools.py 2001/07/13 22:28:36 1.22 *************** *** 245,249 **** self.sym_pat = "^[ \t]*\([a-zA-Z0-9_]+\)[ \t]*=" + \ "[ \t]*\([-0-9_a-zA-Z'\"(][^\t\n,;}]*\),?" ! self.asplit_pat = "^\(.*[^a-zA-Z0-9_]\)\([a-zA-Z0-9_]+\)$" self.comment1_pat = "\(.*\)//.*" # note that the next pattern only removes comments that are wholly within one line --- 245,249 ---- self.sym_pat = "^[ \t]*\([a-zA-Z0-9_]+\)[ \t]*=" + \ "[ \t]*\([-0-9_a-zA-Z'\"(][^\t\n,;}]*\),?" ! self.asplit_pat = "^\(.*[^a-zA-Z0-9_]\)\([a-zA-Z0-9_]+\)\(\[\]\)?$" self.comment1_pat = "\(.*\)//.*" # note that the next pattern only removes comments that are wholly within one line *************** *** 471,476 **** if self.asplit.match(part) < 0: self.error("Indecipherable argument: %s", `part`) return ("unknown", part, mode) ! type, name = self.asplit.group('type', 'name') type = regsub.gsub("\*", " ptr ", type) type = string.strip(type) --- 471,480 ---- if self.asplit.match(part) < 0: self.error("Indecipherable argument: %s", `part`) + import pdb ; pdb.set_trace() return ("unknown", part, mode) ! type, name, array = self.asplit.group('type', 'name', 'array') ! if array: ! # array matches an optional [] after the argument name ! type = type + " ptr " type = regsub.gsub("\*", " ptr ", type) type = string.strip(type) *************** *** 574,581 **** Scanner.initpatterns(self) self.head_pat = "^extern pascal[ \t]+" # XXX Mac specific! - self.tail_pat = "[;={}]" self.type_pat = "pascal[ \t\n]+\([a-zA-Z0-9_ \t]*[a-zA-Z0-9_]\)[ \t\n]+" - self.name_pat = "\([a-zA-Z0-9_]+\)[ \t\n]*" - self.args_pat = "(\(\([^(;=)]+\|([^(;=)]*)\)*\))" self.whole_pat = self.type_pat + self.name_pat + self.args_pat self.sym_pat = "^[ \t]*\([a-zA-Z0-9_]+\)[ \t]*=" + \ --- 578,582 ---- *************** *** 586,605 **** """Scanner for modern (post UH3.3) Universal Headers """ def initpatterns(self): self.head_pat = "^EXTERN_API_C" - self.tail_pat = "[;={}]" self.type_pat = "EXTERN_API_C" + \ "[ \t\n]*([ \t\n]*" + \ "\([a-zA-Z0-9_* \t]*[a-zA-Z0-9_*]\)" + \ "[ \t\n]*)[ \t\n]*" - self.name_pat = "\([a-zA-Z0-9_]+\)[ \t\n]*" - self.args_pat = "(\(\([^(;=)]+\|([^(;=)]*)\)*\))" self.whole_pat = self.type_pat + self.name_pat + self.args_pat self.sym_pat = "^[ \t]*\([a-zA-Z0-9_]+\)[ \t]*=" + \ "[ \t]*\([-0-9_a-zA-Z'\"(][^\t\n,;}]*\),?" - self.asplit_pat = "^\(.*[^a-zA-Z0-9_]\)\([a-zA-Z0-9_]+\)$" - self.comment1_pat = "\(.*\)//.*" - # note that the next pattern only removes comments that are wholly within one line - self.comment2_pat = "\(.*\)/\*.*\*/\(.*\)" - def test(): --- 587,599 ---- """Scanner for modern (post UH3.3) Universal Headers """ def initpatterns(self): + Scanner.initpatterns(self) self.head_pat = "^EXTERN_API_C" self.type_pat = "EXTERN_API_C" + \ "[ \t\n]*([ \t\n]*" + \ "\([a-zA-Z0-9_* \t]*[a-zA-Z0-9_*]\)" + \ "[ \t\n]*)[ \t\n]*" self.whole_pat = self.type_pat + self.name_pat + self.args_pat self.sym_pat = "^[ \t]*\([a-zA-Z0-9_]+\)[ \t]*=" + \ "[ \t]*\([-0-9_a-zA-Z'\"(][^\t\n,;}]*\),?" def test(): From tim_one@users.sourceforge.net Sat Jul 14 02:38:58 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 13 Jul 2001 18:38:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.1.2.33,1.1.2.34 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv11694/descr/dist/src/Lib/test Modified Files: Tag: descr-branch test_descr.py Log Message: test_descr is failing because e.g. >>> a = object() >>> a.foo = 12 Traceback (most recent call last): File "", line 1, in ? TypeError: 'object' object has only read-only attributes (assign to .foo) >>> now but raised AttributeError before. I'm not sure which is better, but I want to merge the trunk into the branch again now so have a short-term but intense interest in just having all tests pass first. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_descr.py,v retrieving revision 1.1.2.33 retrieving revision 1.1.2.34 diff -C2 -r1.1.2.33 -r1.1.2.34 *** test_descr.py 2001/07/10 22:10:30 1.1.2.33 --- test_descr.py 2001/07/14 01:38:56 1.1.2.34 *************** *** 484,488 **** try: a.foo = 12 ! except AttributeError: pass else: --- 484,488 ---- try: a.foo = 12 ! except TypeError: pass else: From fdrake@users.sourceforge.net Sat Jul 14 03:07:48 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 13 Jul 2001 19:07:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/dist dist.tex,1.33,1.34 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/dist In directory usw-pr-cvs1:/tmp/cvs-serv17461/dist Modified Files: dist.tex Log Message: Minor changes to match the style guide. Index: dist.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/dist/dist.tex,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -r1.33 -r1.34 *** dist.tex 2001/03/01 18:35:43 1.33 --- dist.tex 2001/07/14 02:07:46 1.34 *************** *** 7,11 **** \author{Greg Ward} ! \authoraddress{E-mail: \email{gward@python.net}} \makeindex --- 7,11 ---- \author{Greg Ward} ! \authoraddress{Email: \email{gward@python.net}} \makeindex *************** *** 1238,1243 **** Executable Windows installers are the natural format for binary ! distributions on Windows. They display a nice GUI interface, display ! some information of the module distribution to be installed, taken from the meta-dada in the setup script, let the user select a few (currently maybe too few) options, and start or cancel the installation. --- 1238,1243 ---- Executable Windows installers are the natural format for binary ! distributions on Windows. They display a nice graphical user interface, ! display some information of the module distribution to be installed, taken from the meta-dada in the setup script, let the user select a few (currently maybe too few) options, and start or cancel the installation. From fdrake@users.sourceforge.net Sat Jul 14 03:07:48 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 13 Jul 2001 19:07:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/inst inst.tex,1.33,1.34 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/inst In directory usw-pr-cvs1:/tmp/cvs-serv17461/inst Modified Files: inst.tex Log Message: Minor changes to match the style guide. Index: inst.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/inst/inst.tex,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -r1.33 -r1.34 *** inst.tex 2001/07/06 22:46:52 1.33 --- inst.tex 2001/07/14 02:07:46 1.34 *************** *** 21,25 **** \author{Greg Ward} ! \authoraddress{E-mail: \email{gward@python.net}} \makeindex --- 21,25 ---- \author{Greg Ward} ! \authoraddress{Email: \email{gward@python.net}} \makeindex *************** *** 199,206 **** downloaded the archive file to \file{C:\textbackslash{}Temp}, then it would unpack into \file{C:\textbackslash{}Temp\textbackslash{}foo-1.0}; ! you can use either a GUI archive manipulator (such as WinZip) or a ! command-line tool (such as \program{unzip} or \program{pkunzip}) to ! unpack the archive. Then, open a command prompt window (``DOS box''), ! and run: \begin{verbatim} --- 199,206 ---- downloaded the archive file to \file{C:\textbackslash{}Temp}, then it would unpack into \file{C:\textbackslash{}Temp\textbackslash{}foo-1.0}; ! you can use either a archive manipulator with a grapical user interface ! (such as WinZip) or a command-line tool (such as \program{unzip} or ! \program{pkunzip}) to unpack the archive. Then, open a command prompt ! window (``DOS box''), and run: \begin{verbatim} *************** *** 443,447 **** First you have to know that the Borland's object file format(OMF) is different from what is used by the Python version you can download ! from the Python web site. (Python is built with Microsoft Visual \Cpp, which uses COFF as object file format.) For this reason you have to convert Python's library \file{python20.lib} into the Borland format. --- 443,447 ---- First you have to know that the Borland's object file format(OMF) is different from what is used by the Python version you can download ! from the Python Web site. (Python is built with Microsoft Visual \Cpp, which uses COFF as object file format.) For this reason you have to convert Python's library \file{python20.lib} into the Borland format. From fdrake@users.sourceforge.net Sat Jul 14 03:09:34 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 13 Jul 2001 19:09:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/mac undoc.tex,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/mac In directory usw-pr-cvs1:/tmp/cvs-serv17721/mac Modified Files: undoc.tex Log Message: Minor changes to match the style guide. Make the reference to the python-docs email address a hyperlink; we want to encourage responses to the plea for help! Index: undoc.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/mac/undoc.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** undoc.tex 2001/07/10 14:19:45 1.3 --- undoc.tex 2001/07/14 02:09:32 1.4 *************** *** 4,8 **** The modules in this chapter are poorly documented (if at all). If you wish to contribute documentation of any of these modules, please get in ! touch with \email{python-docs@python.org}. \localmoduletable --- 4,9 ---- The modules in this chapter are poorly documented (if at all). If you wish to contribute documentation of any of these modules, please get in ! touch with ! \ulink{\email{python-docs@python.org}}{mailto:python-docs@python.org}. \localmoduletable *************** *** 128,133 **** altogether, if set with \program{EditPythonPrefs}) until you try to read from stdin or disable the buffering, at which point all the saved output is ! sent to the window. Good for GUI programs that do want to display their ! output at a crash. --- 129,134 ---- altogether, if set with \program{EditPythonPrefs}) until you try to read from stdin or disable the buffering, at which point all the saved output is ! sent to the window. Good for programs with graphilcal user interfaces ! that do want to display their output at a crash. From fdrake@users.sourceforge.net Sat Jul 14 03:10:13 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 13 Jul 2001 19:10:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/mac libmacic.tex,1.15,1.16 libmacos.tex,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/mac In directory usw-pr-cvs1:/tmp/cvs-serv17856/mac Modified Files: libmacic.tex libmacos.tex Log Message: Minor changes to match the style guide. Index: libmacic.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/mac/libmacic.tex,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -r1.15 -r1.16 *** libmacic.tex 2000/10/14 04:45:22 1.15 --- libmacic.tex 2001/07/14 02:10:11 1.16 *************** *** 35,39 **** \begin{classdesc}{IC}{\optional{signature\optional{, ic}}} ! Create an internet config object. The signature is a 4-character creator code of the current application (default \code{'Pyth'}) which may influence some of ICs settings. The optional \var{ic} argument is a --- 35,39 ---- \begin{classdesc}{IC}{\optional{signature\optional{, ic}}} ! Create an Internet Config object. The signature is a 4-character creator code of the current application (default \code{'Pyth'}) which may influence some of ICs settings. The optional \var{ic} argument is a Index: libmacos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/mac/libmacos.tex,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -r1.14 -r1.15 *** libmacos.tex 1999/03/02 16:36:35 1.14 --- libmacos.tex 2001/07/14 02:10:11 1.15 *************** *** 52,56 **** value of this function is a tuple with the old values of these options. Initial defaults are that all processing is enabled, checking is done every ! quarter second and the CPU is given up for a quarter second when in the background. \end{funcdesc} --- 52,56 ---- value of this function is a tuple with the old values of these options. Initial defaults are that all processing is enabled, checking is done every ! quarter second and the processor is given up for a quarter second when in the background. \end{funcdesc} From fdrake@users.sourceforge.net Sat Jul 14 03:10:41 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 13 Jul 2001 19:10:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/templates howto.tex,1.5,1.6 manual.tex,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/templates In directory usw-pr-cvs1:/tmp/cvs-serv17930/templates Modified Files: howto.tex manual.tex Log Message: Minor changes to match the style guide. Index: howto.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/templates/howto.tex,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** howto.tex 2001/06/06 15:59:04 1.5 --- howto.tex 2001/07/14 02:10:39 1.6 *************** *** 20,24 **** \release{0.00} ! % At minimum, give your name and an e-mail address. You can include a % snail-mail address if you like. \author{Me, 'cause I wrote it} --- 20,24 ---- \release{0.00} ! % At minimum, give your name and an email address. You can include a % snail-mail address if you like. \author{Me, 'cause I wrote it} Index: manual.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/templates/manual.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** manual.tex 2001/06/06 15:59:04 1.3 --- manual.tex 2001/07/14 02:10:39 1.4 *************** *** 17,21 **** Organization name, if applicable \\ Street address, if you want to use it \\ ! E-mail: \email{your-email@your.domain} } --- 17,21 ---- Organization name, if applicable \\ Street address, if you want to use it \\ ! Email: \email{your-email@your.domain} } From fdrake@users.sourceforge.net Sat Jul 14 03:11:19 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 13 Jul 2001 19:11:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/texinputs boilerplate.tex,1.61,1.62 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory usw-pr-cvs1:/tmp/cvs-serv18036/texinputs Modified Files: boilerplate.tex Log Message: Minor change to match the style guide. Index: boilerplate.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/boilerplate.tex,v retrieving revision 1.61 retrieving revision 1.62 diff -C2 -r1.61 -r1.62 *** boilerplate.tex 2001/06/22 18:36:07 1.61 --- boilerplate.tex 2001/07/14 02:11:17 1.62 *************** *** 3,7 **** \authoraddress{ \strong{PythonLabs}\\ ! E-mail: \email{python-docs@python.org} } --- 3,7 ---- \authoraddress{ \strong{PythonLabs}\\ ! Email: \email{python-docs@python.org} } From fdrake@users.sourceforge.net Sat Jul 14 03:12:29 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 13 Jul 2001 19:12:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ref ref3.tex,1.68,1.69 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory usw-pr-cvs1:/tmp/cvs-serv18210/ref Modified Files: ref3.tex Log Message: Minor change to match the style guide. Index: ref3.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref3.tex,v retrieving revision 1.68 retrieving revision 1.69 diff -C2 -r1.68 -r1.69 *** ref3.tex 2001/06/23 05:27:20 1.68 --- ref3.tex 2001/07/14 02:12:27 1.69 *************** *** 211,215 **** \C{} implementation for the accepted range and handling of overflow. Python does not support single-precision floating point numbers; the ! savings in CPU and memory usage that are usually the reason for using these is dwarfed by the overhead of using objects in Python, so there is no reason to complicate the language with two kinds of floating --- 211,215 ---- \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 these is dwarfed by the overhead of using objects in Python, so there is no reason to complicate the language with two kinds of floating From fdrake@users.sourceforge.net Sat Jul 14 03:14:44 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 13 Jul 2001 19:14:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tut tut.tex,1.143,1.144 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tut In directory usw-pr-cvs1:/tmp/cvs-serv18409/tut Modified Files: tut.tex Log Message: Minor changes to match the style guide. Index: tut.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tut/tut.tex,v retrieving revision 1.143 retrieving revision 1.144 diff -C2 -r1.143 -r1.144 *** tut.tex 2001/07/06 17:28:39 1.143 --- tut.tex 2001/07/14 02:14:42 1.144 *************** *** 34,38 **** The Python interpreter and the extensive standard library are freely available in source or binary form for all major platforms from the ! Python web site, \url{http://www.python.org}, and can be freely distributed. The same site also contains distributions of and pointers to many free third party Python modules, programs and tools, --- 34,38 ---- The Python interpreter and the extensive standard library are freely available in source or binary form for all major platforms from the ! Python Web site, \url{http://www.python.org/}, and can be freely distributed. The same site also contains distributions of and pointers to many free third party Python modules, programs and tools, *************** *** 106,110 **** as examples to start learning to program in Python. There are also built-in modules that provide things like file I/O, system calls, ! sockets, and even interfaces to GUI toolkits like Tk. Python is an interpreted language, which can save you considerable time --- 106,110 ---- as examples to start learning to program in Python. There are also built-in modules that provide things like file I/O, system calls, ! sockets, and even interfaces to graphical user interface toolkits like Tk. Python is an interpreted language, which can save you considerable time *************** *** 746,750 **** Starting with Python 2.0 a new data type for storing text data is available to the programmer: the Unicode object. It can be used to ! store and manipulate Unicode data (see \url{http://www.unicode.org}) and integrates well with the existing string objects providing auto-conversions where necessary. --- 746,750 ---- Starting with Python 2.0 a new data type for storing text data is available to the programmer: the Unicode object. It can be used to ! store and manipulate Unicode data (see \url{http://www.unicode.org/}) and integrates well with the existing string objects providing auto-conversions where necessary. *************** *** 3937,3941 **** The major Python Web site is \url{http://www.python.org/}; it contains code, documentation, and pointers to Python-related pages around the ! Web. This web site is mirrored in various places around the world, such as Europe, Japan, and Australia; a mirror may be faster than the main site, depending on your geographical location. A more --- 3937,3941 ---- The major Python Web site is \url{http://www.python.org/}; it contains code, documentation, and pointers to Python-related pages around the ! Web. This Web site is mirrored in various places around the world, such as Europe, Japan, and Australia; a mirror may be faster than the main site, depending on your geographical location. A more From fdrake@users.sourceforge.net Sat Jul 14 03:27:24 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 13 Jul 2001 19:27:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ext ext.tex,1.98,1.99 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ext In directory usw-pr-cvs1:/tmp/cvs-serv19968/ext Modified Files: ext.tex Log Message: Minor change to match the style guide. Index: ext.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ext/ext.tex,v retrieving revision 1.98 retrieving revision 1.99 diff -C2 -r1.98 -r1.99 *** ext.tex 2001/07/06 06:47:15 1.98 --- ext.tex 2001/07/14 02:27:22 1.99 *************** *** 1440,1444 **** \code{Py_BEGIN_ALLOW_THREADS}, and to re-acquire it using \code{Py_END_ALLOW_THREADS}. This is common around blocking I/O ! calls, to let other threads use the CPU while waiting for the I/O to complete. Obviously, the following function has the same problem as the previous one: --- 1440,1444 ---- \code{Py_BEGIN_ALLOW_THREADS}, and to re-acquire it using \code{Py_END_ALLOW_THREADS}. This is common around blocking I/O ! calls, to let other threads use the processor while waiting for the I/O to complete. Obviously, the following function has the same problem as the previous one: From fdrake@users.sourceforge.net Sat Jul 14 03:34:15 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 13 Jul 2001 19:34:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/doc doc.tex,1.45,1.46 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/doc In directory usw-pr-cvs1:/tmp/cvs-serv20695/doc Modified Files: doc.tex Log Message: Add a little more information about the usage of some terms where the style guide can use a little clarification, and present some minor specific markup. Make a few adjustments to conform to the style guide. Index: doc.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/doc/doc.tex,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -r1.45 -r1.46 *** doc.tex 2001/07/12 02:08:29 1.45 --- doc.tex 2001/07/14 02:34:12 1.46 *************** *** 12,16 **** \authoraddress{ PythonLabs \\ ! E-mail: \email{fdrake@acm.org} } --- 12,16 ---- \authoraddress{ PythonLabs \\ ! Email: \email{fdrake@acm.org} } *************** *** 171,183 **** bodies, and the like. Many of these were assigned \LaTeX{} macros at some point in the distant past, and these macros lived on long ! past their usefulness. In the current markup, these entities are ! not assigned any special markup, but the preferred spellings are given here to aid authors in maintaining the consistency of presentation in the Python documentation. \begin{description} ! \item[POSIX] The name assigned to a particular group of standards. This is ! always uppercase. \item[Python] --- 171,195 ---- bodies, and the like. Many of these were assigned \LaTeX{} macros at some point in the distant past, and these macros lived on long ! past their usefulness. In the current markup, most of these entities ! are not assigned any special markup, but the preferred spellings are given here to aid authors in maintaining the consistency of presentation in the Python documentation. + Other terms and words deserve special mention as well; these conventions + should be used to ensure consistency throughout the documentation: + \begin{description} ! \item[CPU] ! For ``central processing unit.'' Many style guides say this ! should be spelled out on the first use (and if you must use it, ! do so!). For the Python documentation, this abbreviation should ! be avoided since there's no reasonable way to predict which occurance ! will be the first seen by the reader. It is better to use the ! word ``processor'' instead. ! ! \item[\POSIX] The name assigned to a particular group of standards. This is ! always uppercase. Use the macro \macro{POSIX} to represent this ! name. \item[Python] *************** *** 187,191 **** \item[Unicode] The name of a character set and matching encoding. This is ! always written capitalized. \end{description} --- 199,207 ---- \item[Unicode] The name of a character set and matching encoding. This is ! always written capitalized. ! ! \item[\UNIX] ! The name of the operating system developed at AT\&T Bell Labs ! in the early 1970s. Use the macro \macro{UNIX} to use this name. \end{description} *************** *** 829,833 **** \begin{macrodesc}{newsgroup}{\p{name}} ! The name of a USENET newsgroup. \end{macrodesc} --- 845,849 ---- \begin{macrodesc}{newsgroup}{\p{name}} ! The name of a Usenet newsgroup. \end{macrodesc} *************** *** 976,980 **** \declaremodule{extension}{spam} \platform{Unix} ! \modulesynopsis{Access to the SPAM facility of \UNIX{}.} \moduleauthor{Jane Doe}{jane.doe@frobnitz.org} \end{verbatim} --- 992,996 ---- \declaremodule{extension}{spam} \platform{Unix} ! \modulesynopsis{Access to the SPAM facility of \UNIX.} \moduleauthor{Jane Doe}{jane.doe@frobnitz.org} \end{verbatim} From fdrake@users.sourceforge.net Sat Jul 14 03:44:45 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 13 Jul 2001 19:44:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib netdata.tex,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv21844 Modified Files: netdata.tex Log Message: Remove comments about XML and HTML; those sections are no longer part of this chapter. Minor change to match the style guide. Index: netdata.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/netdata.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** netdata.tex 1998/08/07 15:56:52 1.1 --- netdata.tex 2001/07/14 02:44:43 1.2 *************** *** 2,7 **** This chapter describes modules which support handling data formats ! commonly used on the internet. Some, like SGML and XML, may be useful ! for other applications as well. \localmoduletable --- 2,6 ---- This chapter describes modules which support handling data formats ! commonly used on the Internet. \localmoduletable From fdrake@users.sourceforge.net Sat Jul 14 03:46:03 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 13 Jul 2001 19:46:03 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libxmlrpclib.tex,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv21987 Modified Files: libxmlrpclib.tex Log Message: Correct a couple of errors noted by Alex Martelli. Index: libxmlrpclib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libxmlrpclib.tex,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** libxmlrpclib.tex 2001/07/12 23:39:24 1.2 --- libxmlrpclib.tex 2001/07/14 02:46:01 1.3 *************** *** 18,23 **** objects and XML on the wire. ! \begin{classdesc}{Server}{\optional{uri\optional{, transport\optional{, ! encoding\optional{, verbose}}}}} A \class{Server} instance is a server proxy that manages communication with a remote XML-RPC server. The required first argument is a URI --- 18,23 ---- objects and XML on the wire. ! \begin{classdesc}{Server}{uri\optional{, transport\optional{, ! encoding\optional{, verbose}}}} A \class{Server} instance is a server proxy that manages communication with a remote XML-RPC server. The required first argument is a URI *************** *** 92,96 **** \end{methoddesc} ! \begin{methoddesc}{system.methodHelp}{name} This method takes one parameter, the name of a method implemented by the XML-RPC server.It returns an array of possible signatures for this --- 92,96 ---- \end{methoddesc} ! \begin{methoddesc}{system.methodSignature}{name} This method takes one parameter, the name of a method implemented by the XML-RPC server.It returns an array of possible signatures for this From fdrake@users.sourceforge.net Sat Jul 14 03:50:57 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 13 Jul 2001 19:50:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib internet.tex,1.3,1.4 lib.tex,1.188,1.189 libasyncore.tex,1.8,1.9 libbase64.tex,1.17,1.18 libbasehttp.tex,1.12,1.13 libcgi.tex,1.30,1.31 libfl.tex,1.18,1.19 libformatter.tex,1.20,1.21 libintro.tex,1.7,1.8 libos.tex,1.59,1.60 libpanel.tex,1.10,1.11 libresource.tex,1.13,1.14 librestricted.tex,1.6,1.7 librexec.tex,1.16,1.17 librobotparser.tex,1.2,1.3 libstdwin.tex,1.23,1.24 libtime.tex,1.40,1.41 libunittest.tex,1.4,1.5 liburllib.tex,1.35,1.36 liburlparse.tex,1.18,1.19 libxmllib.tex,1.31,1.32 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv22682 Modified Files: internet.tex lib.tex libasyncore.tex libbase64.tex libbasehttp.tex libcgi.tex libfl.tex libformatter.tex libintro.tex libos.tex libpanel.tex libresource.tex librestricted.tex librexec.tex librobotparser.tex libstdwin.tex libtime.tex libunittest.tex liburllib.tex liburlparse.tex libxmllib.tex Log Message: Minor changes to match the style guide. Index: internet.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/internet.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** internet.tex 2000/04/03 20:13:52 1.3 --- internet.tex 2001/07/14 02:50:55 1.4 *************** *** 3,7 **** \index{WWW} \index{Internet} ! \index{World-Wide Web} The modules described in this chapter implement Internet protocols and --- 3,7 ---- \index{WWW} \index{Internet} ! \index{World Wide Web} The modules described in this chapter implement Internet protocols and Index: lib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/lib.tex,v retrieving revision 1.188 retrieving revision 1.189 diff -C2 -r1.188 -r1.189 *** lib.tex 2001/07/12 23:40:13 1.188 --- lib.tex 2001/07/14 02:50:55 1.189 *************** *** 29,33 **** Python is an extensible, interpreted, object-oriented programming language. It supports a wide range of applications, from simple text ! processing scripts to interactive WWW browsers. While the \citetitle[../ref/ref.html]{Python Reference Manual} --- 29,33 ---- Python is an extensible, interpreted, object-oriented programming language. It supports a wide range of applications, from simple text ! processing scripts to interactive Web browsers. While the \citetitle[../ref/ref.html]{Python Reference Manual} Index: libasyncore.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libasyncore.tex,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** libasyncore.tex 2001/05/29 15:37:45 1.8 --- libasyncore.tex 2001/07/14 02:50:55 1.9 *************** *** 18,23 **** multi-threading, without actually using multiple threads. It's really only practical if your program is largely I/O bound. If your program ! is CPU bound, then pre-emptive scheduled threads are probably what ! you really need. Network servers are rarely CPU-bound, however. If your operating system supports the \cfunction{select()} system call --- 18,23 ---- multi-threading, without actually using multiple threads. It's really only practical if your program is largely I/O bound. If your program ! is processor bound, then pre-emptive scheduled threads are probably what ! you really need. Network servers are rarely processor bound, however. If your operating system supports the \cfunction{select()} system call Index: libbase64.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libbase64.tex,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -r1.17 -r1.18 *** libbase64.tex 2001/04/12 16:47:17 1.17 --- libbase64.tex 2001/07/14 02:50:55 1.18 *************** *** 10,14 **** This module performs base64 encoding and decoding of arbitrary binary ! strings into text strings that can be safely emailed or posted. The encoding scheme is defined in \rfc{1521} (\emph{MIME (Multipurpose Internet Mail Extensions) Part One: Mechanisms for --- 10,15 ---- This module performs base64 encoding and decoding of arbitrary binary ! strings into text strings that can be safely sent by email or included ! as part of an HTTP POST request. The encoding scheme is defined in \rfc{1521} (\emph{MIME (Multipurpose Internet Mail Extensions) Part One: Mechanisms for Index: libbasehttp.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libbasehttp.tex,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -r1.12 -r1.13 *** libbasehttp.tex 2000/10/10 16:56:41 1.12 --- libbasehttp.tex 2001/07/14 02:50:55 1.13 *************** *** 13,24 **** This module defines two classes for implementing HTTP servers ! (web servers). Usually, this module isn't used directly, but is used ! as a basis for building functioning web servers. See the \module{SimpleHTTPServer}\refstmodindex{SimpleHTTPServer} and \refmodule{CGIHTTPServer}\refstmodindex{CGIHTTPServer} modules. The first class, \class{HTTPServer}, is a ! \class{SocketServer.TCPServer} subclass. It creates and listens at the ! web socket, dispatching the requests to a handler. Code to create and run the server looks like this: --- 13,24 ---- This module defines two classes for implementing HTTP servers ! (Web servers). Usually, this module isn't used directly, but is used ! as a basis for building functioning Web servers. See the \module{SimpleHTTPServer}\refstmodindex{SimpleHTTPServer} and \refmodule{CGIHTTPServer}\refstmodindex{CGIHTTPServer} modules. The first class, \class{HTTPServer}, is a ! \class{SocketServer.TCPServer} subclass. It creates and listens at the ! HTTP socket, dispatching the requests to a handler. Code to create and run the server looks like this: Index: libcgi.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcgi.tex,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -r1.30 -r1.31 *** libcgi.tex 2001/07/06 19:28:48 1.30 --- libcgi.tex 2001/07/14 02:50:55 1.31 *************** *** 13,17 **** ! Support module for CGI (Common Gateway Interface) scripts.% \index{Common Gateway Interface} --- 13,17 ---- ! Support module for Common Gateway Interface (CGI) scripts.% \index{Common Gateway Interface} *************** *** 295,299 **** with similar functionality), make very sure you don't pass arbitrary strings received from the client to the shell. This is a well-known ! security hole whereby clever hackers anywhere on the web can exploit a gullible CGI script to invoke arbitrary shell commands. Even parts of the URL or field names cannot be trusted, since the request doesn't --- 295,299 ---- with similar functionality), make very sure you don't pass arbitrary strings received from the client to the shell. This is a well-known ! security hole whereby clever hackers anywhere on the Web can exploit a gullible CGI script to invoke arbitrary shell commands. Even parts of the URL or field names cannot be trusted, since the request doesn't *************** *** 331,335 **** current directory at execution time is also different (it is usually the server's cgi-bin directory) and the set of environment variables ! is also different from what you get at login. In particular, don't count on the shell's search path for executables (\envvar{PATH}) or the Python module search path (\envvar{PYTHONPATH}) to be set to --- 331,335 ---- current directory at execution time is also different (it is usually the server's cgi-bin directory) and the set of environment variables ! is also different from what you get when you log in. In particular, don't count on the shell's search path for executables (\envvar{PATH}) or the Python module search path (\envvar{PYTHONPATH}) to be set to Index: libfl.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfl.tex,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -r1.18 -r1.19 *** libfl.tex 1999/04/29 18:42:18 1.18 --- libfl.tex 2001/07/14 02:50:55 1.19 *************** *** 1,8 **** \section{\module{fl} --- ! FORMS library interface for GUI applications} \declaremodule{builtin}{fl} \platform{IRIX} ! \modulesynopsis{FORMS library interface for GUI applications.} --- 1,9 ---- \section{\module{fl} --- ! FORMS library for graphical user interfaces} \declaremodule{builtin}{fl} \platform{IRIX} ! \modulesynopsis{FORMS library for applications with graphical user ! interfaces.} Index: libformatter.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libformatter.tex,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -r1.20 -r1.21 *** libformatter.tex 2000/07/16 19:01:09 1.20 --- libformatter.tex 2001/07/14 02:50:55 1.21 *************** *** 201,205 **** applicability to many writers, and may be used directly in most circumstances. It has been used to implement a full-featured ! world-wide web browser. \end{classdesc} --- 201,205 ---- applicability to many writers, and may be used directly in most circumstances. It has been used to implement a full-featured ! World Wide Web browser. \end{classdesc} Index: libintro.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libintro.tex,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** libintro.tex 2000/07/16 19:01:09 1.7 --- libintro.tex 2001/07/14 02:50:55 1.8 *************** *** 25,29 **** operating systems, such as access to specific hardware; others provide interfaces that are ! specific to a particular application domain, like the World-Wide Web. Some modules are available in all versions and ports of Python; others are only available when the underlying system supports or requires --- 25,29 ---- operating systems, such as access to specific hardware; others provide interfaces that are ! specific to a particular application domain, like the World Wide Web. Some modules are available in all versions and ports of Python; others are only available when the underlying system supports or requires Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.59 retrieving revision 1.60 diff -C2 -r1.59 -r1.60 *** libos.tex 2001/07/06 20:30:11 1.59 --- libos.tex 2001/07/14 02:50:55 1.60 *************** *** 1,16 **** \section{\module{os} --- ! Miscellaneous OS interfaces} \declaremodule{standard}{os} ! \modulesynopsis{Miscellaneous OS interfaces.} This module provides a more portable way of using operating system ! (OS) dependent functionality than importing an OS dependent built-in ! module like \refmodule{posix} or \module{nt}. ! This module searches for an OS dependent built-in module like \module{mac} or \refmodule{posix} and exports the same functions and data ! as found there. The design of all Python's built-in OS dependent modules is such that as long as the same functionality is available, it uses the same interface; for example, the function --- 1,16 ---- \section{\module{os} --- ! Miscellaneous operating system interfaces} \declaremodule{standard}{os} ! \modulesynopsis{Miscellaneous operating system interfaces.} This module provides a more portable way of using operating system ! dependent functionality than importing a operating system dependent ! built-in module like \refmodule{posix} or \module{nt}. ! This module searches for an operating system dependent built-in module like \module{mac} or \refmodule{posix} and exports the same functions and data ! as found there. The design of all Python's built-in operating system dependent modules is such that as long as the same functionality is available, it uses the same interface; for example, the function *************** *** 19,30 **** \POSIX{} interface). ! Extensions peculiar to a particular OS are also available through the ! \module{os} module, but using them is of course a threat to ! portability! Note that after the first time \module{os} is imported, there is \emph{no} performance penalty in using functions from \module{os} ! instead of directly from the OS dependent built-in module, so there ! should be \emph{no} reason not to use \module{os}! --- 19,30 ---- \POSIX{} interface). ! Extensions peculiar to a particular operating system are also ! available through the \module{os} module, but using them is of course a ! threat to portability! Note that after the first time \module{os} is imported, there is \emph{no} performance penalty in using functions from \module{os} ! instead of directly from the operating system dependent built-in module, ! so there should be \emph{no} reason not to use \module{os}! *************** *** 66,76 **** \begin{datadesc}{name} ! The name of the OS dependent module imported. The following names ! have currently been registered: \code{'posix'}, \code{'nt'}, \code{'dos'}, \code{'mac'}, \code{'os2'}, \code{'ce'}, \code{'java'}. \end{datadesc} \begin{datadesc}{path} ! The corresponding OS dependent standard module for pathname operations, such as \module{posixpath} or \module{macpath}. Thus, given the proper imports, \code{os.path.split(\var{file})} is --- 66,76 ---- \begin{datadesc}{name} ! The name of the operating system dependent module imported. The ! following names have currently been registered: \code{'posix'}, \code{'nt'}, \code{'dos'}, \code{'mac'}, \code{'os2'}, \code{'ce'}, \code{'java'}. \end{datadesc} \begin{datadesc}{path} ! The corresponding operating system dependent standard module for pathname operations, such as \module{posixpath} or \module{macpath}. Thus, given the proper imports, \code{os.path.split(\var{file})} is *************** *** 637,641 **** \var{name} specifies the configuration value to retrieve; it may be a string which is the name of a defined system value; these names are ! specified in a number of standards (\POSIX.1, Unix95, Unix98, and others). Some platforms define additional names as well. The names known to the host operating system are given in the --- 637,641 ---- \var{name} specifies the configuration value to retrieve; it may be a string which is the name of a defined system value; these names are ! specified in a number of standards (\POSIX.1, \UNIX 95, \UNIX 98, and others). Some platforms define additional names as well. The names known to the host operating system are given in the *************** *** 738,744 **** \code{st_ctime}. More items may be added at the end by some implementations. Note that ! on the Macintosh, the time values are floating point values, like all ! time values on the Macintosh. ! (On MS Windows, some items are filled with dummy values.) Availability: Macintosh, \UNIX{}, Windows. --- 738,744 ---- \code{st_ctime}. More items may be added at the end by some implementations. Note that ! on the Mac OS, the time values are floating point values, like all ! time values on the Mac OS. ! (On Windows, some items are filled with dummy values.) Availability: Macintosh, \UNIX{}, Windows. *************** *** 984,989 **** Start a file with its associated application. This acts like double-clicking the file in Windows Explorer, or giving the file name ! as an argument to the DOS \program{start} command: the file is opened ! with whatever application (if any) its extension is associated. \function{startfile()} returns as soon as the associated application --- 984,990 ---- Start a file with its associated application. This acts like double-clicking the file in Windows Explorer, or giving the file name ! as an argument to the \program{start} command from the interactive ! command shell: the file is opened with whatever application (if any) ! its extension is associated. \function{startfile()} returns as soon as the associated application *************** *** 1013,1018 **** \begin{funcdesc}{times}{} ! Return a 5-tuple of floating point numbers indicating accumulated (CPU ! or other) times, in seconds. The items are: user time, system time, children's user time, children's system time, and elapsed real time since a fixed --- 1014,1019 ---- \begin{funcdesc}{times}{} ! Return a 5-tuple of floating point numbers indicating accumulated ! (processor or other) times, in seconds. The items are: user time, system time, children's user time, children's system time, and elapsed real time since a fixed *************** *** 1101,1105 **** \var{name} specifies the configuration value to retrieve; it may be a string which is the name of a defined system value; these names are ! specified in a number of standards (\POSIX, Unix95, Unix98, and others). Some platforms define additional names as well. The names known to the host operating system are given in the --- 1102,1106 ---- \var{name} specifies the configuration value to retrieve; it may be a string which is the name of a defined system value; these names are ! specified in a number of standards (\POSIX, \UNIX 95, \UNIX 98, and others). Some platforms define additional names as well. The names known to the host operating system are given in the *************** *** 1152,1166 **** \begin{datadesc}{curdir} ! The constant string used by the OS to refer to the current directory. For example: \code{'.'} for \POSIX{} or \code{':'} for the Macintosh. \end{datadesc} \begin{datadesc}{pardir} ! The constant string used by the OS to refer to the parent directory. For example: \code{'..'} for \POSIX{} or \code{'::'} for the Macintosh. \end{datadesc} \begin{datadesc}{sep} ! The character used by the OS to separate pathname components, for example, \character{/} for \POSIX{} or \character{:} for the Macintosh. Note that knowing this is not sufficient to be able to --- 1153,1169 ---- \begin{datadesc}{curdir} ! The constant string used by the operating system to refer to the current ! directory. For example: \code{'.'} for \POSIX{} or \code{':'} for the Macintosh. \end{datadesc} \begin{datadesc}{pardir} ! The constant string used by the operating system to refer to the parent ! directory. For example: \code{'..'} for \POSIX{} or \code{'::'} for the Macintosh. \end{datadesc} \begin{datadesc}{sep} ! The character used by the operating system to separate pathname components, for example, \character{/} for \POSIX{} or \character{:} for the Macintosh. Note that knowing this is not sufficient to be able to *************** *** 1170,1182 **** \begin{datadesc}{altsep} ! An alternative character used by the OS to separate pathname components, ! or \code{None} if only one separator character exists. This is set to ! \character{/} on DOS and Windows systems where \code{sep} is a backslash. \end{datadesc} \begin{datadesc}{pathsep} ! The character conventionally used by the OS to separate search patch ! components (as in \envvar{PATH}), such as \character{:} for \POSIX{} or ! \character{;} for DOS and Windows. \end{datadesc} --- 1173,1186 ---- \begin{datadesc}{altsep} ! An alternative character used by the operating system to separate pathname ! components, or \code{None} if only one separator character exists. This is ! set to \character{/} on DOS and Windows systems where \code{sep} is a ! backslash. \end{datadesc} \begin{datadesc}{pathsep} ! The character conventionally used by the operating system to separate ! search patch components (as in \envvar{PATH}), such as \character{:} for ! \POSIX{} or \character{;} for DOS and Windows. \end{datadesc} *************** *** 1189,1193 **** The string used to separate (or, rather, terminate) lines on the current platform. This may be a single character, such as \code{'\e ! n'} for \POSIX{} or \code{'\e r'} for MacOS, or multiple characters, ! for example, \code{'\e r\e n'} for MS-DOS and MS Windows. \end{datadesc} --- 1193,1197 ---- The string used to separate (or, rather, terminate) lines on the current platform. This may be a single character, such as \code{'\e ! n'} for \POSIX{} or \code{'\e r'} for the Mac OS, or multiple characters, ! for example, \code{'\e r\e n'} for DOS and Windows. \end{datadesc} Index: libpanel.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libpanel.tex,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -r1.10 -r1.11 *** libpanel.tex 2000/07/16 19:01:09 1.10 --- libpanel.tex 2001/07/14 02:50:55 1.11 *************** *** 61,65 **** This module provides access to the \emph{Panel Library} ! built by NASA Ames\index{NASA} (to get it, send e-mail to \code{panel-request@nas.nasa.gov}). All access to it should be done through the standard module --- 61,65 ---- This module provides access to the \emph{Panel Library} ! built by NASA Ames\index{NASA} (to get it, send email to \code{panel-request@nas.nasa.gov}). All access to it should be done through the standard module Index: libresource.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libresource.tex,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -r1.13 -r1.14 *** libresource.tex 1999/03/02 17:03:40 1.13 --- libresource.tex 2001/07/14 02:50:55 1.14 *************** *** 78,82 **** \begin{datadesc}{RLIMIT_CPU} ! The maximum amount of CPU time (in seconds) that a process can use. If this limit is exceeded, a \constant{SIGXCPU} signal is sent to the process. (See the \refmodule{signal} module documentation for --- 78,82 ---- \begin{datadesc}{RLIMIT_CPU} ! The maximum amount of processor time (in seconds) that a process can use. If this limit is exceeded, a \constant{SIGXCPU} signal is sent to the process. (See the \refmodule{signal} module documentation for Index: librestricted.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/librestricted.tex,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -r1.6 -r1.7 *** librestricted.tex 1999/04/23 17:26:24 1.6 --- librestricted.tex 2001/07/14 02:50:55 1.7 *************** *** 5,13 **** example, a Python program can open any file for reading and writing by using the \function{open()} built-in function (provided the underlying ! OS gives you permission!). This is exactly what you want for most ! applications. There exists a class of applications for which this ``openness'' is ! inappropriate. Take Grail: a web browser that accepts ``applets,'' snippets of Python code, from anywhere on the Internet for execution on the local system. This can be used to improve the user interface --- 5,13 ---- example, a Python program can open any file for reading and writing by using the \function{open()} built-in function (provided the underlying ! operating system gives you permission!). This is exactly what you want ! for most applications. There exists a class of applications for which this ``openness'' is ! inappropriate. Take Grail: a Web browser that accepts ``applets,'' snippets of Python code, from anywhere on the Internet for execution on the local system. This can be used to improve the user interface Index: librexec.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/librexec.tex,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -r1.16 -r1.17 *** librexec.tex 2001/07/06 20:30:11 1.16 --- librexec.tex 2001/07/14 02:50:55 1.17 *************** *** 19,23 **** unsafe operations like reading or writing disk files, or using TCP/IP sockets. However, it does not protect against code using extremely ! large amounts of memory or CPU time. \begin{classdesc}{RExec}{\optional{hooks\optional{, verbose}}} --- 19,23 ---- unsafe operations like reading or writing disk files, or using TCP/IP sockets. However, it does not protect against code using extremely ! large amounts of memory or processor time. \begin{classdesc}{RExec}{\optional{hooks\optional{, verbose}}} Index: librobotparser.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/librobotparser.tex,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** librobotparser.tex 2000/04/28 18:17:23 1.2 --- librobotparser.tex 2001/07/14 02:50:55 1.3 *************** *** 10,14 **** \index{WWW} ! \index{World-Wide Web} \index{URL} \index{robots.txt} --- 10,14 ---- \index{WWW} ! \index{World Wide Web} \index{URL} \index{robots.txt} *************** *** 16,20 **** This module provides a single class, \class{RobotFileParser}, which answers questions about whether or not a particular user agent can fetch a URL on ! the web site that published the \file{robots.txt} file. For more details on the structure of \file{robots.txt} files, see \url{http://info.webcrawler.com/mak/projects/robots/norobots.html}. --- 16,20 ---- This module provides a single class, \class{RobotFileParser}, which answers questions about whether or not a particular user agent can fetch a URL on ! the Web site that published the \file{robots.txt} file. For more details on the structure of \file{robots.txt} files, see \url{http://info.webcrawler.com/mak/projects/robots/norobots.html}. Index: libstdwin.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdwin.tex,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -r1.23 -r1.24 *** libstdwin.tex 2000/07/16 19:01:10 1.23 --- libstdwin.tex 2001/07/14 02:50:55 1.24 *************** *** 17,24 **** \section{\module{stdwin} --- ! Platform-independent GUI System} \declaremodule{builtin}{stdwin} ! \modulesynopsis{Older GUI system for X11 and Macintosh.} --- 17,24 ---- \section{\module{stdwin} --- ! Platform-independent Graphical User Interface System} \declaremodule{builtin}{stdwin} ! \modulesynopsis{Older graphical user interface system for X11 and Macintosh.} Index: libtime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libtime.tex,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -r1.40 -r1.41 *** libtime.tex 2001/07/06 20:30:11 1.40 --- libtime.tex 2001/07/14 02:50:55 1.41 *************** *** 127,135 **** \begin{funcdesc}{clock}{} ! Return the current CPU time as a floating point number expressed in seconds. The precision, and in fact the very definition of the meaning ! of ``CPU time''\index{CPU time}, depends on that of the C function ! of the same name, but in any case, this is the function to use for ! benchmarking\index{benchmarking} Python or timing algorithms. \end{funcdesc} --- 127,136 ---- \begin{funcdesc}{clock}{} ! Return the current processor time as a floating point number expressed in seconds. The precision, and in fact the very definition of the meaning ! of ``processor time''\index{CPU time}\index{processor time}, depends on ! that of the C function of the same name, but in any case, this is the ! function to use for benchmarking\index{benchmarking} Python or timing ! algorithms. \end{funcdesc} Index: libunittest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libunittest.tex,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** libunittest.tex 2001/04/12 19:34:38 1.4 --- libunittest.tex 2001/07/14 02:50:55 1.5 *************** *** 628,632 **** maintain the internal data structures, and mmay be extended in subclasses to support additional reporting requirements. This is ! particularly useful in building GUI tools which support interactive reporting while tests are being run. --- 628,632 ---- maintain the internal data structures, and mmay be extended in subclasses to support additional reporting requirements. This is ! particularly useful in building tools which support interactive reporting while tests are being run. *************** *** 668,673 **** additional tests. This is used by the \class{TextTestRunner} class to stop the test framework when the user signals an interrupt from ! the keyboard. GUI tools which provide runners can use this in a ! similar manner. \end{methoddesc} --- 668,673 ---- additional tests. This is used by the \class{TextTestRunner} class to stop the test framework when the user signals an interrupt from ! the keyboard. Interactive tools which provide runners can use this ! in a similar manner. \end{methoddesc} Index: liburllib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/liburllib.tex,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -r1.35 -r1.36 *** liburllib.tex 2001/04/12 20:26:49 1.35 --- liburllib.tex 2001/07/14 02:50:55 1.36 *************** *** 6,15 **** \index{WWW} ! \index{World-Wide Web} \index{URL} This module provides a high-level interface for fetching data across ! the World-Wide Web. In particular, the \function{urlopen()} function is similar to the built-in function \function{open()}, but accepts Universal Resource Locators (URLs) instead of filenames. Some --- 6,15 ---- \index{WWW} ! \index{World Wide Web} \index{URL} This module provides a high-level interface for fetching data across ! the World Wide Web. In particular, the \function{urlopen()} function is similar to the built-in function \function{open()}, but accepts Universal Resource Locators (URLs) instead of filenames. Some *************** *** 250,254 **** cause arbitrarily long delays while waiting for a network connection to be set up. This means that it is difficult to build an interactive ! web client using these functions without using threads. \item --- 250,254 ---- cause arbitrarily long delays while waiting for a network connection to be set up. This means that it is difficult to build an interactive ! Web client using these functions without using threads. \item Index: liburlparse.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/liburlparse.tex,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -r1.18 -r1.19 *** liburlparse.tex 2000/08/25 17:29:35 1.18 --- liburlparse.tex 2001/07/14 02:50:55 1.19 *************** *** 6,10 **** \index{WWW} ! \index{World-Wide Web} \index{URL} \indexii{URL}{parsing} --- 6,10 ---- \index{WWW} ! \index{World Wide Web} \index{URL} \indexii{URL}{parsing} Index: libxmllib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libxmllib.tex,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -r1.31 -r1.32 *** libxmllib.tex 2001/07/06 20:30:11 1.31 --- libxmllib.tex 2001/07/14 02:50:55 1.32 *************** *** 282,286 **** \begin{seealso} \seetitle[http://www.w3.org/TR/REC-xml-names/]{Namespaces in XML}{ ! This World-Wide Web Consortium recommendation describes the proper syntax and processing requirements for namespaces in XML.} --- 282,286 ---- \begin{seealso} \seetitle[http://www.w3.org/TR/REC-xml-names/]{Namespaces in XML}{ ! This World Wide Web Consortium recommendation describes the proper syntax and processing requirements for namespaces in XML.} From fdrake@users.sourceforge.net Sat Jul 14 04:01:51 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 13 Jul 2001 20:01:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.130,1.131 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv24015/api Modified Files: api.tex Log Message: Fix the markup of the caret charater in a couple of places; LaTeX's special character bite us again. ;-( This fixes SF bug #440911. Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.130 retrieving revision 1.131 diff -C2 -r1.130 -r1.131 *** api.tex 2001/07/11 20:35:37 1.130 --- api.tex 2001/07/14 03:01:48 1.131 *************** *** 1136,1140 **** values. ! \section{OS Utilities \label{os}} \begin{cfuncdesc}{int}{Py_FdIsInteractive}{FILE *fp, char *filename} --- 1136,1140 ---- values. ! \section{Operating System Utilities \label{os}} \begin{cfuncdesc}{int}{Py_FdIsInteractive}{FILE *fp, char *filename} *************** *** 1855,1859 **** \NULL{} on failure. The operation is done \emph{in-place} when \var{o1} supports it. This is the equivalent of the Python expression \samp{\var{o1} ! \^= \var{o2}}. \end{cfuncdesc} --- 1855,1859 ---- \NULL{} on failure. The operation is done \emph{in-place} when \var{o1} supports it. This is the equivalent of the Python expression \samp{\var{o1} ! \textasciicircum= \var{o2}}. \end{cfuncdesc} From fdrake@users.sourceforge.net Sat Jul 14 04:05:56 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 13 Jul 2001 20:05:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.131,1.132 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv24427/api Modified Files: api.tex Log Message: Oops, one more caret. Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.131 retrieving revision 1.132 diff -C2 -r1.131 -r1.132 *** api.tex 2001/07/14 03:01:48 1.131 --- api.tex 2001/07/14 03:05:53 1.132 *************** *** 1771,1775 **** Returns the ``bitwise exclusive or'' of \var{o1} by \var{o2} on success, or \NULL{} on failure. This is the equivalent of the Python ! expression \samp{\var{o1} \^{ }\var{o2}}. \end{cfuncdesc} --- 1771,1775 ---- Returns the ``bitwise exclusive or'' of \var{o1} by \var{o2} on success, or \NULL{} on failure. This is the equivalent of the Python ! expression \samp{\var{o1} \textasciicircum{} \var{o2}}. \end{cfuncdesc} From fdrake@users.sourceforge.net Sat Jul 14 04:07:58 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 13 Jul 2001 20:07:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.117.2.9,1.117.2.10 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv24716/api Modified Files: Tag: release21-maint api.tex Log Message: Fix the markup of the caret charater in a couple of places; LaTeX's special character bite us again. ;-( This fixes SF bug #440911. Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.117.2.9 retrieving revision 1.117.2.10 diff -C2 -r1.117.2.9 -r1.117.2.10 *** api.tex 2001/07/11 20:40:05 1.117.2.9 --- api.tex 2001/07/14 03:07:55 1.117.2.10 *************** *** 1771,1775 **** Returns the ``bitwise exclusive or'' of \var{o1} by \var{o2} on success, or \NULL{} on failure. This is the equivalent of the Python ! expression \samp{\var{o1} \^{ }\var{o2}}. \end{cfuncdesc} --- 1771,1775 ---- Returns the ``bitwise exclusive or'' of \var{o1} by \var{o2} on success, or \NULL{} on failure. This is the equivalent of the Python ! expression \samp{\var{o1} \textasciicircum{} \var{o2}}. \end{cfuncdesc} *************** *** 1855,1859 **** \NULL{} on failure. The operation is done \emph{in-place} when \var{o1} supports it. This is the equivalent of the Python expression \samp{\var{o1} ! \^= \var{o2}}. \end{cfuncdesc} --- 1855,1859 ---- \NULL{} on failure. The operation is done \emph{in-place} when \var{o1} supports it. This is the equivalent of the Python expression \samp{\var{o1} ! \textasciicircum= \var{o2}}. \end{cfuncdesc} From fdrake@users.sourceforge.net Sat Jul 14 04:09:32 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 13 Jul 2001 20:09:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc ACKS,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv24864 Modified Files: ACKS Log Message: Add another name. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ACKS,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -r1.21 -r1.22 *** ACKS 2001/07/06 22:27:04 1.21 --- ACKS 2001/07/14 03:09:29 1.22 *************** *** 114,117 **** --- 114,118 ---- Paolo Milani Skip Montanaro + Paul Moore Ross Moore Sjoerd Mullender From fdrake@users.sourceforge.net Sat Jul 14 04:10:23 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 13 Jul 2001 20:10:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools/sgmlconv conversion.xml,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools/sgmlconv In directory usw-pr-cvs1:/tmp/cvs-serv24992/tools/sgmlconv Modified Files: conversion.xml Log Message: Change the target name for \kbd. Index: conversion.xml =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/sgmlconv/conversion.xml,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -r1.16 -r1.17 *** conversion.xml 2001/07/09 15:00:42 1.16 --- conversion.xml 2001/07/14 03:10:20 1.17 *************** *** 677,681 **** ! --- 677,681 ---- ! From tim_one@users.sourceforge.net Sat Jul 14 04:31:37 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 13 Jul 2001 20:31:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild BUILDno.txt,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv27436/python/dist/src/pcbuild Modified Files: BUILDno.txt Log Message: Remove TENTATIVE from the 2.1.1c1 Windows buildno. Index: BUILDno.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/BUILDno.txt,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -r1.15 -r1.16 *** BUILDno.txt 2001/07/02 04:08:39 1.15 --- BUILDno.txt 2001/07/14 03:31:35 1.16 *************** *** 36,40 **** 20 2.1.1 TENTATIVE 20-Jul-2001 ! 19 2.1.1c1 TENTATIVE 13-Jul-2001 18 2.0.1 --- 36,40 ---- 20 2.1.1 TENTATIVE 20-Jul-2001 ! 19 2.1.1c1 13-Jul-2001 18 2.0.1 From tim_one@users.sourceforge.net Sat Jul 14 04:39:37 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 13 Jul 2001 20:39:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild BUILDno.txt,1.11.2.1,1.11.2.2 python20.wse,1.39.2.1,1.39.2.2 pythoncore.dsp,1.13.2.1,1.13.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv28539/2.1.1/dist/src/PCbuild Modified Files: Tag: release21-maint BUILDno.txt python20.wse pythoncore.dsp Log Message: Prepare Windows build for 2.1.1 final (buildno and installer screens). Index: BUILDno.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/BUILDno.txt,v retrieving revision 1.11.2.1 retrieving revision 1.11.2.2 diff -C2 -r1.11.2.1 -r1.11.2.2 *** BUILDno.txt 2001/07/02 04:31:28 1.11.2.1 --- BUILDno.txt 2001/07/14 03:39:35 1.11.2.2 *************** *** 36,40 **** 20 2.1.1 TENTATIVE 20-Jul-2001 ! 19 2.1.1c1 TENTATIVE 13-Jul-2001 15 2.1 --- 36,40 ---- 20 2.1.1 TENTATIVE 20-Jul-2001 ! 19 2.1.1c1 13-Jul-2001 15 2.1 Index: python20.wse =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/python20.wse,v retrieving revision 1.39.2.1 retrieving revision 1.39.2.2 diff -C2 -r1.39.2.1 -r1.39.2.2 *** python20.wse 2001/07/02 04:31:28 1.39.2.1 --- python20.wse 2001/07/14 03:39:35 1.39.2.2 *************** *** 2,6 **** item: Global Version=5.0 ! Title=Python 2.1.1c1 Flags=00010100 Languages=65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 --- 2,6 ---- item: Global Version=5.0 ! Title=Python 2.1.1 Flags=00010100 Languages=65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 *************** *** 67,71 **** item: Set Variable Variable=APPTITLE ! Value=Python 2.1.1c1 end item: Set Variable --- 67,71 ---- item: Set Variable Variable=APPTITLE ! Value=Python 2.1.1 end item: Set Variable Index: pythoncore.dsp =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/pythoncore.dsp,v retrieving revision 1.13.2.1 retrieving revision 1.13.2.2 diff -C2 -r1.13.2.1 -r1.13.2.2 *** pythoncore.dsp 2001/07/02 04:31:28 1.13.2.1 --- pythoncore.dsp 2001/07/14 03:39:35 1.13.2.2 *************** *** 740,748 **** !IF "$(CFG)" == "pythoncore - Win32 Release" ! # ADD CPP /D BUILD=19 !ELSEIF "$(CFG)" == "pythoncore - Win32 Debug" ! # ADD CPP /D BUILD=19 !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Debug" --- 740,748 ---- !IF "$(CFG)" == "pythoncore - Win32 Release" ! # ADD CPP /D BUILD=20 !ELSEIF "$(CFG)" == "pythoncore - Win32 Debug" ! # ADD CPP /D BUILD=20 !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Debug" From fdrake@users.sourceforge.net Sat Jul 14 06:50:35 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 13 Jul 2001 22:50:35 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib sgmllib.py,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv11413 Modified Files: sgmllib.py Log Message: Be more permissive in what is accepted as an attribute name; this makes this module slightly more resiliant in the face of XHTML input, or just colons in attribute names. Index: sgmllib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sgmllib.py,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -r1.32 -r1.33 *** sgmllib.py 2001/07/05 18:21:57 1.32 --- sgmllib.py 2001/07/14 05:50:33 1.33 *************** *** 37,41 **** tagfind = re.compile('[a-zA-Z][-_.a-zA-Z0-9]*') attrfind = re.compile( ! r'\s*([a-zA-Z_][-.a-zA-Z_0-9]*)(\s*=\s*' r'(\'[^\']*\'|"[^"]*"|[-a-zA-Z0-9./:;+*%?!&$\(\)_#=~\'"]*))?') --- 37,41 ---- tagfind = re.compile('[a-zA-Z][-_.a-zA-Z0-9]*') attrfind = re.compile( ! r'\s*([a-zA-Z_][-:.a-zA-Z_0-9]*)(\s*=\s*' r'(\'[^\']*\'|"[^"]*"|[-a-zA-Z0-9./:;+*%?!&$\(\)_#=~\'"]*))?') From tim_one@users.sourceforge.net Sat Jul 14 08:47:36 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 00:47:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include compile.h,2.29.4.1,2.29.4.2 rangeobject.h,2.15.8.1,2.15.8.2 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv29618/descr/dist/src/Include Modified Files: Tag: descr-branch compile.h rangeobject.h Log Message: Merge of trunk tag date2001-07-13 into descr-branch. See PLAN.txt. Index: compile.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/compile.h,v retrieving revision 2.29.4.1 retrieving revision 2.29.4.2 diff -C2 -r2.29.4.1 -r2.29.4.2 *** compile.h 2001/07/07 22:55:27 2.29.4.1 --- compile.h 2001/07/14 07:47:34 2.29.4.2 *************** *** 63,67 **** PyCompilerFlags *); ! #define NESTED_SCOPES_DEFAULT 0 #define FUTURE_NESTED_SCOPES "nested_scopes" --- 63,67 ---- PyCompilerFlags *); ! #define NESTED_SCOPES_DEFAULT 1 #define FUTURE_NESTED_SCOPES "nested_scopes" Index: rangeobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/rangeobject.h,v retrieving revision 2.15.8.1 retrieving revision 2.15.8.2 diff -C2 -r2.15.8.1 -r2.15.8.2 *** rangeobject.h 2001/07/07 22:55:27 2.15.8.1 --- rangeobject.h 2001/07/14 07:47:34 2.15.8.2 *************** *** 20,24 **** #define PyRange_Check(op) ((op)->ob_type == &PyRange_Type) ! extern DL_IMPORT(PyObject *) PyRange_New(long, long, long); #ifdef __cplusplus --- 20,24 ---- #define PyRange_Check(op) ((op)->ob_type == &PyRange_Type) ! extern DL_IMPORT(PyObject *) PyRange_New(long, long, long, int); #ifdef __cplusplus From tim_one@users.sourceforge.net Sat Jul 14 08:47:37 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 00:47:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _sre.c,2.55.4.1,2.55.4.2 posixmodule.c,2.187.4.1,2.187.4.2 readline.c,2.35,2.35.4.1 regexmodule.c,1.42,1.42.6.1 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv29618/descr/dist/src/Modules Modified Files: Tag: descr-branch _sre.c posixmodule.c readline.c regexmodule.c Log Message: Merge of trunk tag date2001-07-13 into descr-branch. See PLAN.txt. Index: _sre.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_sre.c,v retrieving revision 2.55.4.1 retrieving revision 2.55.4.2 diff -C2 -r2.55.4.1 -r2.55.4.2 *** _sre.c 2001/07/07 22:55:29 2.55.4.1 --- _sre.c 2001/07/14 07:47:34 2.55.4.2 *************** *** 1956,1959 **** --- 1956,1981 ---- } + static PyObject* + pattern_isliteral(PatternObject* self, PyObject* args) + { + /* internal: return true if pattern consists of literal text only */ + + SRE_CODE* code; + PyObject* isliteral; + + if (!PyArg_ParseTuple(args, ":_isliteral")) + return NULL; + + code = PatternObject_GetCode(self); + + if (code[0] == SRE_OP_INFO && code[2] & SRE_INFO_LITERAL) + isliteral = Py_True; + else + isliteral = Py_False; + + Py_INCREF(isliteral); + return isliteral; + } + static PyMethodDef pattern_methods[] = { {"match", (PyCFunction) pattern_match, METH_VARARGS|METH_KEYWORDS}, *************** *** 1966,1969 **** --- 1988,1992 ---- {"__copy__", (PyCFunction) pattern_copy, METH_VARARGS}, {"__deepcopy__", (PyCFunction) pattern_deepcopy, METH_VARARGS}, + {"_isliteral", (PyCFunction) pattern_isliteral, METH_VARARGS}, {NULL, NULL} }; Index: posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.187.4.1 retrieving revision 2.187.4.2 diff -C2 -r2.187.4.1 -r2.187.4.2 *** posixmodule.c 2001/07/07 22:55:29 2.187.4.1 --- posixmodule.c 2001/07/14 07:47:34 2.187.4.2 *************** *** 1111,1114 **** --- 1111,1120 ---- #ifdef HAVE_NICE + #if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H) + #if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS) + #include + #endif + #endif + static char posix_nice__doc__[] = "nice(inc) -> new_priority\n\ *************** *** 1122,1127 **** if (!PyArg_ParseTuple(args, "i:nice", &increment)) return NULL; value = nice(increment); ! if (value == -1) return posix_error(); return PyInt_FromLong((long) value); --- 1128,1150 ---- if (!PyArg_ParseTuple(args, "i:nice", &increment)) return NULL; + + /* There are two flavours of 'nice': one that returns the new + priority (as required by almost all standards out there) and the + Linux/FreeBSD/BSDI one, which returns '0' on success and advices + the use of getpriority() to get the new priority. + + If we are of the nice family that returns the new priority, we + need to clear errno before the call, and check if errno is filled + before calling posix_error() on a returnvalue of -1, because the + -1 may be the actual new priority! */ + + errno = 0; value = nice(increment); ! #if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY) ! if (value == 0) ! value = getpriority(PRIO_PROCESS, 0); ! #endif ! if (value == -1 && errno != 0) ! /* either nice() or getpriority() returned an error */ return posix_error(); return PyInt_FromLong((long) value); Index: readline.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/readline.c,v retrieving revision 2.35 retrieving revision 2.35.4.1 diff -C2 -r2.35 -r2.35.4.1 *** readline.c 2001/04/13 18:14:27 2.35 --- readline.c 2001/07/14 07:47:35 2.35.4.1 *************** *** 22,25 **** --- 22,29 ---- #include + #ifdef HAVE_RL_COMPLETION_MATCHES + #define completion_matches(x, y) rl_completion_matches((x), ((rl_compentry_func_t *)(y))) + #endif + /* Pointers needed from outside (but not declared in a header file). */ extern DL_IMPORT(int) (*PyOS_InputHook)(void); Index: regexmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/regexmodule.c,v retrieving revision 1.42 retrieving revision 1.42.6.1 diff -C2 -r1.42 -r1.42.6.1 *** regexmodule.c 2001/01/22 15:29:14 1.42 --- regexmodule.c 2001/07/14 07:47:35 1.42.6.1 *************** *** 661,666 **** d = PyModule_GetDict(m); ! PyErr_Warn(PyExc_DeprecationWarning, ! "the regex module is deprecated; please use the re module"); /* Initialize regex.error exception */ --- 661,668 ---- d = PyModule_GetDict(m); ! if (PyErr_Warn(PyExc_DeprecationWarning, ! "the regex module is deprecated; " ! "please use the re module") < 0) ! return; /* Initialize regex.error exception */ From tim_one@users.sourceforge.net Sat Jul 14 08:47:37 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 00:47:37 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.1.2.26,1.1.2.27 acconfig.h,1.46.4.1,1.46.4.2 config.h.in,2.92.2.1,2.92.2.2 configure,1.209.2.1,1.209.2.2 configure.in,1.217.2.1,1.217.2.2 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv29618/descr/dist/src Modified Files: Tag: descr-branch PLAN.txt acconfig.h config.h.in configure configure.in Log Message: Merge of trunk tag date2001-07-13 into descr-branch. See PLAN.txt. Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Attic/PLAN.txt,v retrieving revision 1.1.2.26 retrieving revision 1.1.2.27 diff -C2 -r1.1.2.26 -r1.1.2.27 *** PLAN.txt 2001/07/09 01:32:28 1.1.2.26 --- PLAN.txt 2001/07/14 07:47:33 1.1.2.27 *************** *** 269,272 **** --- 269,289 ---- ---------------------------------------------------------------------------- + 2001-07-13 + + Tagged trunk about 22:13 EDT, like so: + cvs tag date2001-07-13 python + + Merged trunk delta into branch via: + cvs -q -z3 up -j date2001-07-06 -j date2001-07-13 descr + + Six(!) files with conflicts, mostly related to NeilS's generator gc patches. + Unsure why, but CVS seems always to think there are conflicts whenever a + line in a type object decl gets changed, and the conflict marking seems + maximally confused in these cases. Anyway, since I reviewed those patches + on the trunk, good thing I'm merging them, and darned glad it's still fresh + on my mind. + + Resolved the conflicts, and committed the changes in a few hours total. + ---------------------------------------------------------------------------- 2001-07-07 Index: acconfig.h =================================================================== RCS file: /cvsroot/python/python/dist/src/acconfig.h,v retrieving revision 1.46.4.1 retrieving revision 1.46.4.2 diff -C2 -r1.46.4.1 -r1.46.4.2 *** acconfig.h 2001/07/07 22:55:27 1.46.4.1 --- acconfig.h 2001/07/14 07:47:33 1.46.4.2 *************** *** 87,90 **** --- 87,93 ---- #undef HAVE_PTH + /* Define if you have readline 4.2 */ + #undef HAVE_RL_COMPLETION_MATCHES + /* Define if your compiler supports variable length function prototypes (e.g. void fprintf(FILE *, char *, ...);) *and* */ *************** *** 113,116 **** --- 116,122 ---- /* Define as the size of the unicode type. */ #undef Py_UNICODE_SIZE + + /* Define if nice() returns success/failure instead of the new priority. */ + #undef HAVE_BROKEN_NICE /* Define if malloc(0) returns a NULL pointer */ Index: config.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/config.h.in,v retrieving revision 2.92.2.1 retrieving revision 2.92.2.2 diff -C2 -r2.92.2.1 -r2.92.2.2 *** config.h.in 2001/07/07 22:55:27 2.92.2.1 --- config.h.in 2001/07/14 07:47:33 2.92.2.2 *************** *** 1,3 **** ! /* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define if on AIX 3. --- 1,3 ---- ! /* config.h.in. Generated automatically from configure.in by autoheader 2.13. */ /* Define if on AIX 3. *************** *** 149,152 **** --- 149,155 ---- #undef HAVE_PTH + /* Define if you have readline 4.2 */ + #undef HAVE_RL_COMPLETION_MATCHES + /* Define if your compiler supports variable length function prototypes (e.g. void fprintf(FILE *, char *, ...);) *and* */ *************** *** 173,176 **** --- 176,182 ---- #undef Py_UNICODE_SIZE + /* Define if nice() returns success/failure instead of the new priority. */ + #undef HAVE_BROKEN_NICE + /* Define if malloc(0) returns a NULL pointer */ #undef MALLOC_ZERO_RETURNS_NULL *************** *** 393,396 **** --- 399,405 ---- #undef HAVE_GETPID + /* Define if you have the getpriority function. */ + #undef HAVE_GETPRIORITY + /* Define if you have the getpwent function. */ #undef HAVE_GETPWENT *************** *** 635,638 **** --- 644,650 ---- /* Define if you have the header file. */ #undef HAVE_SYS_PARAM_H + + /* Define if you have the header file. */ + #undef HAVE_SYS_RESOURCE_H /* Define if you have the header file. */ Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.209.2.1 retrieving revision 1.209.2.2 diff -C2 -r1.209.2.1 -r1.209.2.2 *** configure 2001/07/07 22:55:27 1.209.2.1 --- configure 2001/07/14 07:47:33 1.209.2.2 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.222 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.226 [...4338 lines suppressed...] if eval "test \"`echo '$''{'ac_cv_type_socklen_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < *************** *** 6877,6881 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6880: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then --- 6984,6988 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6987: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.217.2.1 retrieving revision 1.217.2.2 diff -C2 -r1.217.2.1 -r1.217.2.2 *** configure.in 2001/07/07 22:55:27 1.217.2.1 --- configure.in 2001/07/14 07:47:34 1.217.2.2 *************** *** 304,307 **** --- 304,317 ---- fi + # Check for --with-pydebug + AC_MSG_CHECKING(for --with-pydebug) + AC_ARG_WITH(pydebug, + [ --with-pydebug build with Py_DEBUG defined], [ + if test "$withval" != no + then AC_DEFINE(Py_DEBUG) AC_MSG_RESULT(yes); Py_DEBUG='true' + else AC_MSG_RESULT(no); Py_DEBUG='false' + fi], + [AC_MSG_RESULT(no)]) + # Optimizer/debugger flags AC_SUBST(OPT) *************** *** 312,320 **** case $ac_cv_prog_cc_g in yes) ! OPT="-g -O2 -Wall -Wstrict-prototypes";; *) ! OPT="-O2 -Wall -Wstrict-prototypes";; ! esac ! ;; *) case $ac_sys_system in --- 322,336 ---- case $ac_cv_prog_cc_g in yes) ! if test "$Py_DEBUG" = 'true' ; then ! # Optimization messes up debuggers, so turn it off for ! # debug builds. ! OPT="-g -Wall -Wstrict-prototypes" ! else ! OPT="-g -O3 -Wall -Wstrict-prototypes" ! fi;; *) ! OPT="-O3 -Wall -Wstrict-prototypes";; ! esac ! ;; *) case $ac_sys_system in *************** *** 386,390 **** esac ], ! AC_TRY_RUN([ /* AF_INET6 avalable check */ #include #include --- 402,406 ---- esac ], ! AC_TRY_RUN([ /* AF_INET6 available check */ #include #include *************** *** 530,534 **** sys/param.h sys/select.h sys/socket.h sys/time.h sys/times.h \ sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ ! ndbm.h db1/ndbm.h gdbm/ndbm.h) AC_HEADER_DIRENT --- 546,550 ---- sys/param.h sys/select.h sys/socket.h sys/time.h sys/times.h \ sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ ! ndbm.h db1/ndbm.h gdbm/ndbm.h sys/resource.h) AC_HEADER_DIRENT *************** *** 862,875 **** AC_CHECK_LIB(dld, shl_load) # Dynamic linking for HP-UX - # Check for --with-pydebug - AC_MSG_CHECKING(for --with-pydebug) - AC_ARG_WITH(pydebug, - [ --with-pydebug build with Py_DEBUG defined], [ - if test "$withval" != no - then AC_DEFINE(Py_DEBUG) AC_MSG_RESULT(yes) - else AC_MSG_RESULT(no) - fi], - [AC_MSG_RESULT(no)]) - # checks for system dependent C++ extensions support case "$ac_sys_system" in --- 878,881 ---- *************** *** 1170,1174 **** sigaction siginterrupt sigrelse strftime strptime symlink sysconf \ tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ ! truncate uname waitpid _getpty) # check for openpty and forkpty --- 1176,1180 ---- sigaction siginterrupt sigrelse strftime strptime symlink sysconf \ tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ ! truncate uname waitpid _getpty getpriority) # check for openpty and forkpty *************** *** 1660,1663 **** --- 1666,1690 ---- then AC_DEFINE(HAVE_GETC_UNLOCKED) + fi + + # check for readline 4.2 + AC_CHECK_LIB(readline, rl_completion_matches, + AC_DEFINE(HAVE_RL_COMPLETION_MATCHES), , -ltermcap) + + AC_MSG_CHECKING(for broken nice()) + AC_CACHE_VAL(ac_cv_broken_nice, [ + AC_TRY_RUN([ + int main() + { + int val1 = nice(1); + if (val1 != -1 && val1 == nice(2)) + exit(0); + exit(1); + } + ],ac_cv_broken_nice=yes, ac_cv_broken_nice=no)]) + AC_MSG_RESULT($ac_cv_broken_nice) + if test "$ac_cv_broken_nice" = yes + then + AC_DEFINE(HAVE_BROKEN_NICE) fi From tim_one@users.sourceforge.net Sat Jul 14 08:47:37 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 00:47:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_fileinput.py,NONE,1.1.2.1 test_socketserver.py,NONE,1.3.2.1 test_uu.py,NONE,1.1.2.1 test_cfgparser.py,1.7,1.7.6.1 test_gc.py,1.7,1.7.6.1 test_generators.py,1.17.2.3,1.17.2.4 test_pow.py,1.7,1.7.6.1 test_scope.py,1.14.4.1,1.14.4.2 test_sundry.py,1.4,1.4.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv29618/descr/dist/src/Lib/test Modified Files: Tag: descr-branch test_cfgparser.py test_gc.py test_generators.py test_pow.py test_scope.py test_sundry.py Added Files: Tag: descr-branch test_fileinput.py test_socketserver.py test_uu.py Log Message: Merge of trunk tag date2001-07-13 into descr-branch. See PLAN.txt. --- NEW FILE: test_fileinput.py --- ''' Tests for fileinput module. Nick Mathewson ''' from test_support import verify, verbose, TESTFN import sys, os, re from StringIO import StringIO from fileinput import FileInput # The fileinput module has 2 interfaces: the FileInput class which does # all the work, and a few functions (input, etc.) that use a global _state # variable. We only test the FileInput class, since the other functions # only provide a thin facade over FileInput. # Write lines (a list of lines) to temp file number i, and return the # temp file's name. def writeTmp(i, lines): name = TESTFN + str(i) f = open(name, 'w') f.writelines(lines) f.close() return name pat = re.compile(r'LINE (\d+) OF FILE (\d+)') def remove_tempfiles(*names): for name in names: try: os.unlink(name) except: pass def runTests(t1, t2, t3, t4, bs=0, round=0): start = 1 + round*6 if verbose: print '%s. Simple iteration (bs=%s)' % (start+0, bs) fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs) lines = list(fi) fi.close() verify(len(lines) == 31) verify(lines[4] == 'Line 5 of file 1\n') verify(lines[30] == 'Line 1 of file 4\n') verify(fi.lineno() == 31) verify(fi.filename() == t4) if verbose: print '%s. Status variables (bs=%s)' % (start+1, bs) fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs) s = "x" while s and s != 'Line 6 of file 2\n': s = fi.readline() verify(fi.filename() == t2) verify(fi.lineno() == 21) verify(fi.filelineno() == 6) verify(not fi.isfirstline()) verify(not fi.isstdin()) if verbose: print '%s. Nextfile (bs=%s)' % (start+2, bs) fi.nextfile() verify(fi.readline() == 'Line 1 of file 3\n') verify(fi.lineno() == 22) fi.close() if verbose: print '%s. Stdin (bs=%s)' % (start+3, bs) fi = FileInput(files=(t1, t2, t3, t4, '-'), bufsize=bs) savestdin = sys.stdin try: sys.stdin = StringIO("Line 1 of stdin\nLine 2 of stdin\n") lines = list(fi) verify(len(lines) == 33) verify(lines[32] == 'Line 2 of stdin\n') verify(fi.filename() == '') fi.nextfile() finally: sys.stdin = savestdin if verbose: print '%s. Boundary conditions (bs=%s)' % (start+4, bs) fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs) verify(fi.lineno() == 0) verify(fi.filename() == None) fi.nextfile() verify(fi.lineno() == 0) verify(fi.filename() == None) if verbose: print '%s. Inplace (bs=%s)' % (start+5, bs) savestdout = sys.stdout try: fi = FileInput(files=(t1, t2, t3, t4), inplace=1, bufsize=bs) for line in fi: line = line[:-1].upper() print line fi.close() finally: sys.stdout = savestdout fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs) for line in fi: verify(line[-1] == '\n') m = pat.match(line[:-1]) verify(m != None) verify(int(m.group(1)) == fi.filelineno()) fi.close() def writeFiles(): global t1, t2, t3, t4 t1 = writeTmp(1, ["Line %s of file 1\n" % (i+1) for i in range(15)]) t2 = writeTmp(2, ["Line %s of file 2\n" % (i+1) for i in range(10)]) t3 = writeTmp(3, ["Line %s of file 3\n" % (i+1) for i in range(5)]) t4 = writeTmp(4, ["Line %s of file 4\n" % (i+1) for i in range(1)]) # First, run the tests with default and teeny buffer size. for round, bs in (0, 0), (1, 30): try: writeFiles() runTests(t1, t2, t3, t4, bs, round) finally: remove_tempfiles(t1, t2, t3, t4) # Next, check for proper behavior with 0-byte files. if verbose: print "13. 0-byte files" try: t1 = writeTmp(1, [""]) t2 = writeTmp(2, [""]) t3 = writeTmp(3, ["The only line there is.\n"]) t4 = writeTmp(4, [""]) fi = FileInput(files=(t1, t2, t3, t4)) line = fi.readline() verify(line == 'The only line there is.\n') verify(fi.lineno() == 1) verify(fi.filelineno() == 1) verify(fi.filename() == t3) line = fi.readline() verify(not line) verify(fi.lineno() == 1) verify(fi.filelineno() == 0) verify(fi.filename() == t4) fi.close() finally: remove_tempfiles(t1, t2, t3, t4) if verbose: print "14. Files that don't end with newline" try: t1 = writeTmp(1, ["A\nB\nC"]) t2 = writeTmp(2, ["D\nE\nF"]) fi = FileInput(files=(t1, t2)) lines = list(fi) verify(lines == ["A\n", "B\n", "C", "D\n", "E\n", "F"]) verify(fi.filelineno() == 3) verify(fi.lineno() == 6) finally: remove_tempfiles(t1, t2) --- NEW FILE: test_socketserver.py --- # Test suite for SocketServer.py # XXX This must be run manually -- somehow the I/O redirection of the # regression test breaks the test. from test_support import verbose, verify, TESTFN, TestSkipped if not verbose: raise TestSkipped, "test_socketserver can only be run manually" from SocketServer import * import socket import select import time import threading import os NREQ = 3 DELAY = 0.5 class MyMixinHandler: def handle(self): time.sleep(DELAY) line = self.rfile.readline() time.sleep(DELAY) self.wfile.write(line) class MyStreamHandler(MyMixinHandler, StreamRequestHandler): pass class MyDatagramHandler(MyMixinHandler, DatagramRequestHandler): pass class MyMixinServer: def serve_a_few(self): for i in range(NREQ): self.handle_request() def handle_error(self, request, client_address): self.close_request(request) self.server_close() raise teststring = "hello world\n" def receive(sock, n, timeout=20): r, w, x = select.select([sock], [], [], timeout) if sock in r: return sock.recv(n) else: raise RuntimeError, "timed out on %s" % `sock` def testdgram(proto, addr): s = socket.socket(proto, socket.SOCK_DGRAM) s.sendto(teststring, addr) buf = data = receive(s, 100) while data and '\n' not in buf: data = receive(s, 100) buf += data verify(buf == teststring) s.close() def teststream(proto, addr): s = socket.socket(proto, socket.SOCK_STREAM) s.connect(addr) s.send(teststring) buf = data = receive(s, 100) while data and '\n' not in buf: data = receive(s, 100) buf += data verify(buf == teststring) s.close() class ServerThread(threading.Thread): def __init__(self, addr, svrcls, hdlrcls): threading.Thread.__init__(self) self.__addr = addr self.__svrcls = svrcls self.__hdlrcls = hdlrcls def run(self): class svrcls(MyMixinServer, self.__svrcls): pass if verbose: print "thread: creating server" svr = svrcls(self.__addr, self.__hdlrcls) if verbose: print "thread: serving three times" svr.serve_a_few() if verbose: print "thread: done" seed = 0 def pickport(): global seed seed += 1 return 10000 + (os.getpid() % 1000)*10 + seed host = "localhost" testfiles = [] def pickaddr(proto): if proto == socket.AF_INET: return (host, pickport()) else: fn = TESTFN + str(pickport()) testfiles.append(fn) return fn def cleanup(): for fn in testfiles: try: os.remove(fn) except os.error: pass testfiles[:] = [] def testloop(proto, servers, hdlrcls, testfunc): for svrcls in servers: addr = pickaddr(proto) if verbose: print "ADDR =", addr print "CLASS =", svrcls t = ServerThread(addr, svrcls, hdlrcls) if verbose: print "server created" t.start() if verbose: print "server running" for i in range(NREQ): time.sleep(DELAY) if verbose: print "test client", i testfunc(proto, addr) if verbose: print "waiting for server" t.join() if verbose: print "done" tcpservers = [TCPServer, ThreadingTCPServer] if hasattr(os, 'fork'): tcpservers.append(ForkingTCPServer) udpservers = [UDPServer, ThreadingUDPServer] if hasattr(os, 'fork'): udpservers.append(ForkingUDPServer) if not hasattr(socket, 'AF_UNIX'): streamservers = [] dgramservers = [] else: class ForkingUnixStreamServer(ForkingMixIn, UnixStreamServer): pass streamservers = [UnixStreamServer, ThreadingUnixStreamServer, ForkingUnixStreamServer] class ForkingUnixDatagramServer(ForkingMixIn, UnixDatagramServer): pass dgramservers = [UnixDatagramServer, ThreadingUnixDatagramServer, ForkingUnixDatagramServer] def testall(): testloop(socket.AF_INET, tcpservers, MyStreamHandler, teststream) testloop(socket.AF_INET, udpservers, MyDatagramHandler, testdgram) if hasattr(socket, 'AF_UNIX'): testloop(socket.AF_UNIX, streamservers, MyStreamHandler, teststream) # Alas, on Linux (at least) recvfrom() doesn't return a meaningful # client address so this cannot work: ##testloop(socket.AF_UNIX, dgramservers, MyDatagramHandler, testdgram) def main(): try: testall() finally: cleanup() main() --- NEW FILE: test_uu.py --- """ Tests for uu module. Nick Mathewson """ from test_support import verify, TestFailed, verbose, TESTFN import sys, os import uu from StringIO import StringIO teststr = "The smooth-scaled python crept over the sleeping dog\n" expected = """\ M5&AE('-M;V]T:\"US8V%L960@<'ET:&]N(&-R97!T(&]V97(@=&AE('-L965P (:6YG(&1O9PH """ encoded1 = "begin 666 t1\n"+expected+"\n \nend\n" if verbose: print '1. encode file->file' inp = StringIO(teststr) out = StringIO() uu.encode(inp, out, "t1") verify(out.getvalue() == encoded1) inp = StringIO(teststr) out = StringIO() uu.encode(inp, out, "t1", 0644) verify(out.getvalue() == "begin 644 t1\n"+expected+"\n \nend\n") if verbose: print '2. decode file->file' inp = StringIO(encoded1) out = StringIO() uu.decode(inp, out) verify(out.getvalue() == teststr) inp = StringIO("""UUencoded files may contain many lines, even some that have 'begin' in them.\n"""+encoded1) out = StringIO() uu.decode(inp, out) verify(out.getvalue() == teststr) stdinsave = sys.stdin stdoutsave = sys.stdout try: if verbose: print '3. encode stdin->stdout' sys.stdin = StringIO(teststr) sys.stdout = StringIO() uu.encode("-", "-", "t1", 0666) verify(sys.stdout.getvalue() == encoded1) if verbose: print >>stdoutsave, '4. decode stdin->stdout' sys.stdin = StringIO(encoded1) sys.stdout = StringIO() uu.decode("-", "-") verify(sys.stdout.getvalue() == teststr) finally: sys.stdin = stdinsave sys.stdout = stdoutsave if verbose: print '5. encode file->file' tmpIn = TESTFN + "i" tmpOut = TESTFN + "o" try: fin = open(tmpIn, 'w') fin.write(teststr) fin.close() fin = open(tmpIn, 'r') fout = open(tmpOut, 'w') uu.encode(fin, fout, tmpIn, mode=0644) fin.close() fout.close() fout = open(tmpOut, 'r') s = fout.read() fout.close() verify(s == 'begin 644 ' + tmpIn + '\n' + expected + '\n \nend\n') os.unlink(tmpIn) if verbose: print '6. decode file-> file' uu.decode(tmpOut) fin = open(tmpIn, 'r') s = fin.read() fin.close() verify(s == teststr) # XXX is there an xp way to verify the mode? finally: try: fin.close() except: pass try: fout.close() except: pass try: os.unlink(tmpIn) except: pass try: os.unlink(tmpOut) except: pass if verbose: print '7. error: truncated input' inp = StringIO("begin 644 t1\n"+expected) out = StringIO() try: uu.decode(inp, out) raise TestFailed("No exception thrown") except uu.Error, e: verify(str(e) == 'Truncated input file') if verbose: print '8. error: missing begin' inp = StringIO("") out = StringIO() try: uu.decode(inp, out) raise TestFailed("No exception thrown") except uu.Error, e: verify(str(e) == 'No valid begin line found in input file') Index: test_cfgparser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_cfgparser.py,v retrieving revision 1.7 retrieving revision 1.7.6.1 diff -C2 -r1.7 -r1.7.6.1 *** test_cfgparser.py 2001/02/26 21:55:34 1.7 --- test_cfgparser.py 2001/07/14 07:47:34 1.7.6.1 *************** *** 71,74 **** --- 71,81 ---- verify(cf.options("a") == []) + # SF bug #432369: + cf = ConfigParser.ConfigParser() + sio = StringIO.StringIO("[MySection]\nOption: first line\n\tsecond line\n") + cf.readfp(sio) + verify(cf.options("MySection") == ["option"]) + verify(cf.get("MySection", "Option") == "first line\nsecond line") + def interpolation(src): Index: test_gc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_gc.py,v retrieving revision 1.7 retrieving revision 1.7.6.1 diff -C2 -r1.7 -r1.7.6.1 *** test_gc.py 2001/01/17 19:11:13 1.7 --- test_gc.py 2001/07/14 07:47:34 1.7.6.1 *************** *** 1,3 **** --- 1,4 ---- from test_support import verify, verbose, TestFailed + import sys import gc *************** *** 108,111 **** --- 109,121 ---- raise TestFailed + def test_frame(): + def f(): + frame = sys._getframe() + gc.collect() + f() + if gc.collect() != 1: + raise TestFailed + + def test_saveall(): # Verify that cyclic garbage like lists show up in gc.garbage if the *************** *** 153,156 **** --- 163,167 ---- run_test("methods", test_method) run_test("functions", test_function) + run_test("frames", test_frame) run_test("finalizers", test_finalizer) run_test("__del__", test_del) Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.17.2.3 retrieving revision 1.17.2.4 diff -C2 -r1.17.2.3 -r1.17.2.4 *** test_generators.py 2001/07/13 21:49:33 1.17.2.3 --- test_generators.py 2001/07/14 07:47:34 1.17.2.4 *************** *** 1,4 **** - from __future__ import nested_scopes - tutorial_tests = """ Let's try a simple generator: --- 1,2 ---- *************** *** 50,54 **** >>> def f(): ... yield 1 ! ... return ... yield 2 # never reached ... --- 48,52 ---- >>> def f(): ... yield 1 ! ... raise StopIteration ... yield 2 # never reached ... *************** *** 444,450 **** ... def __str__(self): ... return self.name - ... - ... def clear(self): - ... self.__dict__.clear() >>> names = "ABCDEFGHIJKLM" --- 442,445 ---- *************** *** 491,496 **** merged A into G A->G B->G C->G D->G E->G F->G G->G H->G I->G J->G K->G L->G M->G - >>> for s in sets: # XXX memory leak without this - ... s.clear() """ --- 486,489 ---- *************** *** 605,611 **** ... sofar.append(fetch()) ... return sofar[i] - ... - ... def clear(self): - ... self.__dict__.clear() >>> def m235(): --- 598,601 ---- *************** *** 621,625 **** Print as many of these as you like -- *this* implementation is memory- ! efficient. XXX Except that it leaks unless you clear the dict! >>> m235 = LazyList(m235()) --- 611,615 ---- Print as many of these as you like -- *this* implementation is memory- ! efficient. >>> m235 = LazyList(m235()) *************** *** 632,638 **** [400, 405, 432, 450, 480, 486, 500, 512, 540, 576, 600, 625, 640, 648, 675] - >>> m235.clear() # XXX memory leak without this - Ye olde Fibonacci generator, LazyList style. --- 622,626 ---- *************** *** 657,662 **** >>> firstn(iter(fib), 17) [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584] - - >>> fib.clear() # XXX memory leak without this """ --- 645,648 ---- *************** *** 924,928 **** # NOTE WELL: This allows large problems to be solved with only trivial # demands on stack space. Without explicitly resumable generators, this is ! # much harder to achieve. def flat_conjoin(gs): # rename to conjoin to run tests with this instead --- 910,915 ---- # NOTE WELL: This allows large problems to be solved with only trivial # demands on stack space. Without explicitly resumable generators, this is ! # much harder to achieve. OTOH, this is much slower (up to a factor of 2) ! # than the fancy unrolled recursive conjoin. def flat_conjoin(gs): # rename to conjoin to run tests with this instead *************** *** 930,954 **** values = [None] * n iters = [None] * n i = 0 ! while i >= 0: ! # Need a fresh iterator. ! if i >= n: ! yield values ! # Backtrack. ! i -= 1 else: ! iters[i] = gs[i]().next ! # Need next value from current iterator. while i >= 0: try: values[i] = iters[i]() ! except StopIteration: ! # Backtrack. ! i -= 1 ! else: ! # Start fresh at next level. i += 1 break # A conjoin-based N-Queens solver. --- 917,949 ---- values = [None] * n iters = [None] * n + _StopIteration = StopIteration # make local because caught a *lot* i = 0 ! while 1: ! # Descend. ! try: ! while i < n: ! it = iters[i] = gs[i]().next ! values[i] = it() ! i += 1 ! except _StopIteration: ! pass else: ! assert i == n ! yield values ! # Backtrack until an older iterator can be resumed. ! i -= 1 while i >= 0: try: values[i] = iters[i]() ! # Success! Start fresh at next level. i += 1 break + except _StopIteration: + # Continue backtracking. + i -= 1 + else: + assert i < 0 + break # A conjoin-based N-Queens solver. *************** *** 1007,1035 **** # (e.g., when used with flat_conjoin above, and passing hard=1 to the # constructor, a 200x200 Knight's Tour was found quickly -- note that we're ! # creating 10s of thousands of generators then!), so goes on at some length class Knights: ! def __init__(self, n, hard=0): ! self.n = n ! ! def coords2index(i, j): ! return i*n + j ! offsets = [( 1, 2), ( 2, 1), ( 2, -1), ( 1, -2), ! (-1, -2), (-2, -1), (-2, 1), (-1, 2)] ! succs = [] ! for i in range(n): ! for j in range(n): ! s = [coords2index(i+io, j+jo) for io, jo in offsets ! if 0 <= i+io < n and ! 0 <= j+jo < n] ! succs.append(s) ! del s ! del offsets ! free = [0] * n**2 # 0 if occupied, 1 if visited ! nexits = free[:] # number of free successors ! ! def decrexits(i0): # If we remove all exits from a free square, we're dead: # even if we move to it next, we can't leave it again. --- 1002,1020 ---- # (e.g., when used with flat_conjoin above, and passing hard=1 to the # constructor, a 200x200 Knight's Tour was found quickly -- note that we're ! # creating 10s of thousands of generators then!), and is lengthy. class Knights: ! def __init__(self, m, n, hard=0): ! self.m, self.n = m, n ! # solve() will set up succs[i] to be a list of square #i's ! # successors. ! succs = self.succs = [] ! ! # Remove i0 from each of its successor's successor lists, i.e. ! # successors can't go back to i0 again. Return 0 if we can ! # detect this makes a solution impossible, else return 1. ! def remove_from_successors(i0, len=len): # If we remove all exits from a free square, we're dead: # even if we move to it next, we can't leave it again. *************** *** 1042,1120 **** ne0 = ne1 = 0 for i in succs[i0]: ! if free[i]: ! e = nexits[i] - 1 ! nexits[i] = e ! if e == 0: ! ne0 += 1 ! elif e == 1: ! ne1 += 1 return ne0 == 0 and ne1 < 2 ! def increxits(i0): for i in succs[i0]: ! if free[i]: ! nexits[i] += 1 # Generate the first move. def first(): ! if n < 1: return - # Initialize board structures. - for i in xrange(n**2): - free[i] = 1 - nexits[i] = len(succs[i]) - # Since we're looking for a cycle, it doesn't matter where we # start. Starting in a corner makes the 2nd move easy. ! corner = coords2index(0, 0) ! free[corner] = 0 ! decrexits(corner) self.lastij = corner yield corner ! increxits(corner) ! free[corner] = 1 # Generate the second moves. def second(): ! corner = coords2index(0, 0) assert self.lastij == corner # i.e., we started in the corner ! if n < 3: return ! assert nexits[corner] == len(succs[corner]) == 2 ! assert coords2index(1, 2) in succs[corner] ! assert coords2index(2, 1) in succs[corner] # Only two choices. Whichever we pick, the other must be the ! # square picked on move n**2, as it's the only way to get back # to (0, 0). Save its index in self.final so that moves before # the last know it must be kept free. for i, j in (1, 2), (2, 1): ! this, final = coords2index(i, j), coords2index(3-i, 3-j) ! assert free[this] and free[final] self.final = final - nexits[final] += 1 # it has an exit back to 0,0 ! free[this] = 0 ! decrexits(this) self.lastij = this yield this ! increxits(this) ! free[this] = 1 ! ! nexits[final] -= 1 ! # Generate moves 3 thru n**2-1. ! def advance(): # If some successor has only one exit, must take it. # Else favor successors with fewer exits. candidates = [] for i in succs[self.lastij]: ! if free[i]: ! e = nexits[i] ! assert e > 0, "else decrexits() pruning flawed" ! if e == 1: ! candidates = [(e, i)] ! break ! candidates.append((e, i)) else: candidates.sort() --- 1027,1095 ---- ne0 = ne1 = 0 for i in succs[i0]: ! s = succs[i] ! s.remove(i0) ! e = len(s) ! if e == 0: ! ne0 += 1 ! elif e == 1: ! ne1 += 1 return ne0 == 0 and ne1 < 2 + + # Put i0 back in each of its successor's successor lists. ! def add_to_successors(i0): for i in succs[i0]: ! succs[i].append(i0) # Generate the first move. def first(): ! if m < 1 or n < 1: return # Since we're looking for a cycle, it doesn't matter where we # start. Starting in a corner makes the 2nd move easy. ! corner = self.coords2index(0, 0) ! remove_from_successors(corner) self.lastij = corner yield corner ! add_to_successors(corner) # Generate the second moves. def second(): ! corner = self.coords2index(0, 0) assert self.lastij == corner # i.e., we started in the corner ! if m < 3 or n < 3: return ! assert len(succs[corner]) == 2 ! assert self.coords2index(1, 2) in succs[corner] ! assert self.coords2index(2, 1) in succs[corner] # Only two choices. Whichever we pick, the other must be the ! # square picked on move m*n, as it's the only way to get back # to (0, 0). Save its index in self.final so that moves before # the last know it must be kept free. for i, j in (1, 2), (2, 1): ! this = self.coords2index(i, j) ! final = self.coords2index(3-i, 3-j) self.final = final ! remove_from_successors(this) ! succs[final].append(corner) self.lastij = this yield this ! succs[final].remove(corner) ! add_to_successors(this) ! # Generate moves 3 thru m*n-1. ! def advance(len=len): # If some successor has only one exit, must take it. # Else favor successors with fewer exits. candidates = [] for i in succs[self.lastij]: ! e = len(succs[i]) ! assert e > 0, "else remove_from_successors() pruning flawed" ! if e == 1: ! candidates = [(e, i)] ! break ! candidates.append((e, i)) else: candidates.sort() *************** *** 1122,1138 **** for e, i in candidates: if i != self.final: ! if decrexits(i): ! free[i] = 0 self.lastij = i yield i ! free[i] = 1 ! increxits(i) ! # Generate moves 3 thru n**2-1. Alternative version using a # stronger (but more expensive) heuristic to order successors. ! # Since the # of backtracking levels is n**2, a poor move early on ! # can take eons to undo. Smallest n for which this matters a lot is ! # n==52. ! def advance_hard(midpoint=(n-1)/2.0): # If some successor has only one exit, must take it. # Else favor successors with fewer exits. --- 1097,1111 ---- for e, i in candidates: if i != self.final: ! if remove_from_successors(i): self.lastij = i yield i ! add_to_successors(i) ! # Generate moves 3 thru m*n-1. Alternative version using a # stronger (but more expensive) heuristic to order successors. ! # Since the # of backtracking levels is m*n, a poor move early on ! # can take eons to undo. Smallest square board for which this ! # matters a lot is 52x52. ! def advance_hard(vmid=(m-1)/2.0, hmid=(n-1)/2.0, len=len): # If some successor has only one exit, must take it. # Else favor successors with fewer exits. *************** *** 1141,1153 **** candidates = [] for i in succs[self.lastij]: ! if free[i]: ! e = nexits[i] ! assert e > 0, "else decrexits() pruning flawed" ! if e == 1: ! candidates = [(e, 0, i)] ! break ! i1, j1 = divmod(i, n) ! d = (i1 - midpoint)**2 + (j1 - midpoint)**2 ! candidates.append((e, -d, i)) else: candidates.sort() --- 1114,1125 ---- candidates = [] for i in succs[self.lastij]: ! e = len(succs[i]) ! assert e > 0, "else remove_from_successors() pruning flawed" ! if e == 1: ! candidates = [(e, 0, i)] ! break ! i1, j1 = self.index2coords(i) ! d = (i1 - vmid)**2 + (j1 - hmid)**2 ! candidates.append((e, -d, i)) else: candidates.sort() *************** *** 1155,1164 **** for e, d, i in candidates: if i != self.final: ! if decrexits(i): ! free[i] = 0 self.lastij = i yield i ! free[i] = 1 ! increxits(i) # Generate the last move. --- 1127,1134 ---- for e, d, i in candidates: if i != self.final: ! if remove_from_successors(i): self.lastij = i yield i ! add_to_successors(i) # Generate the last move. *************** *** 1167,1192 **** yield self.final ! if n <= 1: ! self.rowgenerators = [first] else: ! self.rowgenerators = [first, second] + \ ! [hard and advance_hard or advance] * (n**2 - 3) + \ [last] # Generate solutions. def solve(self): ! for x in conjoin(self.rowgenerators): yield x def printsolution(self, x): ! n = self.n ! assert len(x) == n**2 ! w = len(str(n**2 + 1)) format = "%" + str(w) + "d" ! squares = [[None] * n for i in range(n)] k = 1 for i in x: ! i1, j1 = divmod(i, n) squares[i1][j1] = format % k k += 1 --- 1137,1188 ---- yield self.final ! if m*n < 4: ! self.squaregenerators = [first] else: ! self.squaregenerators = [first, second] + \ ! [hard and advance_hard or advance] * (m*n - 3) + \ [last] + def coords2index(self, i, j): + assert 0 <= i < self.m + assert 0 <= j < self.n + return i * self.n + j + + def index2coords(self, index): + assert 0 <= index < self.m * self.n + return divmod(index, self.n) + + def _init_board(self): + succs = self.succs + del succs[:] + m, n = self.m, self.n + c2i = self.coords2index + + offsets = [( 1, 2), ( 2, 1), ( 2, -1), ( 1, -2), + (-1, -2), (-2, -1), (-2, 1), (-1, 2)] + rangen = range(n) + for i in range(m): + for j in rangen: + s = [c2i(i+io, j+jo) for io, jo in offsets + if 0 <= i+io < m and + 0 <= j+jo < n] + succs.append(s) + # Generate solutions. def solve(self): ! self._init_board() ! for x in conjoin(self.squaregenerators): yield x def printsolution(self, x): ! m, n = self.m, self.n ! assert len(x) == m*n ! w = len(str(m*n)) format = "%" + str(w) + "d" ! squares = [[None] * n for i in range(m)] k = 1 for i in x: ! i1, j1 = self.index2coords(i) squares[i1][j1] = format % k k += 1 *************** *** 1194,1198 **** sep = "+" + ("-" * w + "+") * n print sep ! for i in range(n): row = squares[i] print "|" + "|".join(row) + "|" --- 1190,1194 ---- sep = "+" + ("-" * w + "+") * n print sep ! for i in range(m): row = squares[i] print "|" + "|".join(row) + "|" *************** *** 1290,1294 **** 20,000 solutions even on a 6x6 board, so don't dare run this to exhaustion. ! >>> k = Knights(10) >>> LIMIT = 2 >>> count = 0 --- 1286,1290 ---- 20,000 solutions even on a 6x6 board, so don't dare run this to exhaustion. ! >>> k = Knights(10, 10) >>> LIMIT = 2 >>> count = 0 *************** *** 1359,1370 **** def test_main(): import doctest, test_generators ! if 0: ! # Temporary block to help track down leaks. So far, the blame ! # fell mostly on doctest. Later: the only leaks remaining are ! # in fun_tests, and only if you comment out the two LazyList.clear() ! # calls. ! for i in range(10000): doctest.master = None doctest.testmod(test_generators) else: doctest.testmod(test_generators) --- 1355,1363 ---- def test_main(): import doctest, test_generators ! if 0: # change to 1 to run forever (to check for leaks) ! while 1: doctest.master = None doctest.testmod(test_generators) + print ".", else: doctest.testmod(test_generators) Index: test_pow.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pow.py,v retrieving revision 1.7 retrieving revision 1.7.6.1 diff -C2 -r1.7 -r1.7.6.1 *** test_pow.py 2000/12/12 23:11:42 1.7 --- test_pow.py 2001/07/14 07:47:34 1.7.6.1 *************** *** 33,39 **** pow(ii, jj) except ValueError: ! pass # taking an int to a neg int power should fail ! else: ! raise ValueError, "pow(%s, %s) did not fail" % (ii, jj) for othertype in int, long, float: --- 33,37 ---- pow(ii, jj) except ValueError: ! raise ValueError, "pow(%s, %s) failed" % (ii, jj) for othertype in int, long, float: Index: test_scope.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_scope.py,v retrieving revision 1.14.4.1 retrieving revision 1.14.4.2 diff -C2 -r1.14.4.1 -r1.14.4.2 *** test_scope.py 2001/07/07 22:55:29 1.14.4.1 --- test_scope.py 2001/07/14 07:47:34 1.14.4.2 *************** *** 1,4 **** - from __future__ import nested_scopes - from test.test_support import verify, TestFailed, check_syntax --- 1,2 ---- *************** *** 180,184 **** print "11. unoptimized namespaces" ! check_syntax("""from __future__ import nested_scopes def unoptimized_clash1(strip): def f(s): --- 178,182 ---- print "11. unoptimized namespaces" ! check_syntax("""\ def unoptimized_clash1(strip): def f(s): *************** *** 188,192 **** """) ! check_syntax("""from __future__ import nested_scopes def unoptimized_clash2(): from string import * --- 186,190 ---- """) ! check_syntax("""\ def unoptimized_clash2(): from string import * *************** *** 196,200 **** """) ! check_syntax("""from __future__ import nested_scopes def unoptimized_clash2(): from string import * --- 194,198 ---- """) ! check_syntax("""\ def unoptimized_clash2(): from string import * *************** *** 206,210 **** # XXX could allow this for exec with const argument, but what's the point ! check_syntax("""from __future__ import nested_scopes def error(y): exec "a = 1" --- 204,208 ---- # XXX could allow this for exec with const argument, but what's the point ! check_syntax("""\ def error(y): exec "a = 1" *************** *** 214,218 **** """) ! check_syntax("""from __future__ import nested_scopes def f(x): def g(): --- 212,216 ---- """) ! check_syntax("""\ def f(x): def g(): *************** *** 221,225 **** """) ! check_syntax("""from __future__ import nested_scopes def f(): def g(): --- 219,223 ---- """) ! check_syntax("""\ def f(): def g(): Index: test_sundry.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sundry.py,v retrieving revision 1.4 retrieving revision 1.4.4.1 diff -C2 -r1.4 -r1.4.4.1 *** test_sundry.py 2001/04/06 18:59:17 1.4 --- test_sundry.py 2001/07/14 07:47:34 1.4.4.1 *************** *** 31,35 **** import encodings import filecmp - import fileinput import fnmatch import formatter --- 31,34 ---- *************** *** 97,101 **** # can screw up all sorts of things (esp. if it prints!). #import user - import uu import webbrowser import whichdb --- 96,99 ---- From tim_one@users.sourceforge.net Sat Jul 14 08:47:37 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 00:47:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild python20.wse,1.40,1.40.2.1 rmpyc.py,1.2,1.2.6.1 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv29618/descr/dist/src/PCbuild Modified Files: Tag: descr-branch python20.wse rmpyc.py Log Message: Merge of trunk tag date2001-07-13 into descr-branch. See PLAN.txt. Index: python20.wse =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/python20.wse,v retrieving revision 1.40 retrieving revision 1.40.2.1 diff -C2 -r1.40 -r1.40.2.1 *** python20.wse 2001/04/18 21:12:25 1.40 --- python20.wse 2001/07/14 07:47:35 1.40.2.1 *************** *** 910,913 **** --- 910,919 ---- Flags=0000000000000010 end + item: Install File + Source=%_SRC_%\Lib\site-packages\README + Destination=%MAINDIR%\Lib\site-packages\README.txt + Description=Site packages + Flags=0000000000000010 + end item: Remark Text=*** Other *** Index: rmpyc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/rmpyc.py,v retrieving revision 1.2 retrieving revision 1.2.6.1 diff -C2 -r1.2 -r1.2.6.1 *** rmpyc.py 2001/02/27 21:11:46 1.2 --- rmpyc.py 2001/07/14 07:47:35 1.2.6.1 *************** *** 1,6 **** # Remove all the .pyc and .pyo files under ../Lib. - from __future__ import nested_scopes - def deltree(root): import os --- 1,4 ---- From tim_one@users.sourceforge.net Sat Jul 14 08:47:37 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 00:47:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects frameobject.c,2.49.4.5,2.49.4.6 intobject.c,2.56.6.6,2.56.6.7 iterobject.c,1.3.2.3,1.3.2.4 listobject.c,2.92.6.10,2.92.6.11 longobject.c,1.71.6.4,1.71.6.5 methodobject.c,2.33.8.5,2.33.8.6 rangeobject.c,2.24.6.4,2.24.6.5 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv29618/descr/dist/src/Objects Modified Files: Tag: descr-branch frameobject.c intobject.c iterobject.c listobject.c longobject.c methodobject.c rangeobject.c Log Message: Merge of trunk tag date2001-07-13 into descr-branch. See PLAN.txt. Index: frameobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/frameobject.c,v retrieving revision 2.49.4.5 retrieving revision 2.49.4.6 diff -C2 -r2.49.4.5 -r2.49.4.6 *** frameobject.c 2001/07/07 22:55:30 2.49.4.5 --- frameobject.c 2001/07/14 07:47:35 2.49.4.6 *************** *** 69,72 **** --- 69,73 ---- Py_TRASHCAN_SAFE_BEGIN(f) + PyObject_GC_Fini(f); /* Kill all local variables */ slots = f->f_nlocals + f->f_ncells + f->f_nfreevars; *************** *** 96,114 **** } PyTypeObject PyFrame_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, "frame", ! sizeof(PyFrameObject), 0, ! (destructor)frame_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 */ --- 97,186 ---- } + static int + frame_traverse(PyFrameObject *f, visitproc visit, void *arg) + { + PyObject **fastlocals, **p; + int i, err, slots; + #define VISIT(o) if (o) {if ((err = visit((PyObject *)(o), arg))) return err;} + + VISIT(f->f_back); + VISIT(f->f_code); + VISIT(f->f_builtins); + VISIT(f->f_globals); + VISIT(f->f_locals); + VISIT(f->f_trace); + VISIT(f->f_exc_type); + VISIT(f->f_exc_value); + VISIT(f->f_exc_traceback); + + /* locals */ + slots = f->f_nlocals + f->f_ncells + f->f_nfreevars; + fastlocals = f->f_localsplus; + for (i = slots; --i >= 0; ++fastlocals) { + VISIT(*fastlocals); + } + + /* stack */ + if (f->f_stacktop != NULL) { + for (p = f->f_valuestack; p < f->f_stacktop; p++) + VISIT(*p); + } + + return 0; + } + + static void + frame_clear(PyFrameObject *f) + { + PyObject **fastlocals, **p; + int i, slots; + + Py_XDECREF(f->f_exc_type); + f->f_exc_type = NULL; + + Py_XDECREF(f->f_exc_value); + f->f_exc_value = NULL; + + Py_XDECREF(f->f_exc_traceback); + f->f_exc_traceback = NULL; + + Py_XDECREF(f->f_trace); + f->f_trace = NULL; + + /* locals */ + slots = f->f_nlocals + f->f_ncells + f->f_nfreevars; + fastlocals = f->f_localsplus; + for (i = slots; --i >= 0; ++fastlocals) { + if (*fastlocals != NULL) { + Py_XDECREF(*fastlocals); + *fastlocals = NULL; + } + } + + /* stack */ + if (f->f_stacktop != NULL) { + for (p = f->f_valuestack; p < f->f_stacktop; p++) { + Py_XDECREF(*p); + *p = NULL; + } + } + } + + PyTypeObject PyFrame_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, "frame", ! sizeof(PyFrameObject) + PyGC_HEAD_SIZE, 0, ! (destructor)frame_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 */ *************** *** 117,124 **** PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ ! 0, /* tp_doc */ ! 0, /* tp_traverse */ ! 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ --- 189,196 ---- PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */ ! 0, /* tp_doc */ ! (traverseproc)frame_traverse, /* tp_traverse */ ! (inquiry)frame_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ *************** *** 173,179 **** f = (PyFrameObject *) PyObject_MALLOC(sizeof(PyFrameObject) + ! extras*sizeof(PyObject *)); if (f == NULL) return (PyFrameObject *)PyErr_NoMemory(); PyObject_INIT(f, &PyFrame_Type); f->f_size = extras; --- 245,253 ---- f = (PyFrameObject *) PyObject_MALLOC(sizeof(PyFrameObject) + ! extras*sizeof(PyObject *) + ! PyGC_HEAD_SIZE); if (f == NULL) return (PyFrameObject *)PyErr_NoMemory(); + f = (PyFrameObject *) PyObject_FROM_GC(f); PyObject_INIT(f, &PyFrame_Type); f->f_size = extras; *************** *** 183,191 **** free_list = free_list->f_back; if (f->f_size < extras) { f = (PyFrameObject *) PyObject_REALLOC(f, sizeof(PyFrameObject) + ! extras*sizeof(PyObject *)); if (f == NULL) return (PyFrameObject *)PyErr_NoMemory(); f->f_size = extras; } --- 257,268 ---- free_list = free_list->f_back; if (f->f_size < extras) { + f = (PyFrameObject *) PyObject_AS_GC(f); f = (PyFrameObject *) PyObject_REALLOC(f, sizeof(PyFrameObject) + ! extras*sizeof(PyObject *) + ! PyGC_HEAD_SIZE); if (f == NULL) return (PyFrameObject *)PyErr_NoMemory(); + f = (PyFrameObject *) PyObject_FROM_GC(f); f->f_size = extras; } *************** *** 248,251 **** --- 325,329 ---- f->f_stacktop = f->f_valuestack; + PyObject_GC_Init(f); return f; } *************** *** 409,412 **** --- 487,491 ---- PyFrameObject *f = free_list; free_list = free_list->f_back; + f = (PyFrameObject *) PyObject_AS_GC(f); PyObject_DEL(f); } Index: intobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v retrieving revision 2.56.6.6 retrieving revision 2.56.6.7 diff -C2 -r2.56.6.6 -r2.56.6.7 *** intobject.c 2001/07/07 22:55:30 2.56.6.6 --- intobject.c 2001/07/14 07:47:35 2.56.6.7 *************** *** 511,521 **** CONVERT_TO_LONG(w, iw); if (iw < 0) { ! if (iv) ! PyErr_SetString(PyExc_ValueError, ! "cannot raise integer to a negative power"); ! else ! PyErr_SetString(PyExc_ZeroDivisionError, ! "cannot raise 0 to a negative power"); ! return NULL; } if ((PyObject *)z != Py_None) { --- 511,519 ---- CONVERT_TO_LONG(w, iw); if (iw < 0) { ! /* Return a float. This works because we know that ! this calls float_pow() which converts its ! arguments to double. */ ! return PyFloat_Type.tp_as_number->nb_power( ! (PyObject *)v, (PyObject *)w, (PyObject *)z); } if ((PyObject *)z != Py_None) { Index: iterobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/iterobject.c,v retrieving revision 1.3.2.3 retrieving revision 1.3.2.4 diff -C2 -r1.3.2.3 -r1.3.2.4 *** iterobject.c 2001/07/07 22:55:30 1.3.2.3 --- iterobject.c 2001/07/14 07:47:35 1.3.2.4 *************** *** 19,22 **** --- 19,23 ---- Py_INCREF(seq); it->it_seq = seq; + PyObject_GC_Init(it); return (PyObject *)it; } *************** *** 24,31 **** --- 25,40 ---- iter_dealloc(seqiterobject *it) { + PyObject_GC_Fini(it); Py_DECREF(it->it_seq); + it = (seqiterobject *) PyObject_AS_GC(it); PyObject_DEL(it); } + static int + iter_traverse(seqiterobject *it, visitproc visit, void *arg) + { + return visit(it->it_seq, arg); + } + static PyObject * iter_next(seqiterobject *it, PyObject *args) *************** *** 92,96 **** 0, /* ob_size */ "iterator", /* tp_name */ ! sizeof(seqiterobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ --- 101,105 ---- 0, /* ob_size */ "iterator", /* tp_name */ ! sizeof(seqiterobject) + PyGC_HEAD_SIZE, /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ *************** *** 110,116 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ 0, /* tp_doc */ ! 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ --- 119,125 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */ 0, /* tp_doc */ ! (traverseproc)iter_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ *************** *** 146,149 **** --- 155,159 ---- Py_INCREF(sentinel); it->it_sentinel = sentinel; + PyObject_GC_Init(it); return (PyObject *)it; } *************** *** 151,159 **** --- 161,182 ---- calliter_dealloc(calliterobject *it) { + PyObject_GC_Fini(it); Py_DECREF(it->it_callable); Py_DECREF(it->it_sentinel); + it = (calliterobject *) PyObject_AS_GC(it); PyObject_DEL(it); } + static int + calliter_traverse(calliterobject *it, visitproc visit, void *arg) + { + int err; + if ((err = visit(it->it_callable, arg))) + return err; + if ((err = visit(it->it_sentinel, arg))) + return err; + return 0; + } + static PyObject * calliter_next(calliterobject *it, PyObject *args) *************** *** 196,200 **** 0, /* ob_size */ "callable-iterator", /* tp_name */ ! sizeof(calliterobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ --- 219,223 ---- 0, /* ob_size */ "callable-iterator", /* tp_name */ ! sizeof(calliterobject) + PyGC_HEAD_SIZE,/* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ *************** *** 214,220 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ 0, /* tp_doc */ ! 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ --- 237,243 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */ 0, /* tp_doc */ ! (traverseproc)calliter_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ Index: listobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v retrieving revision 2.92.6.10 retrieving revision 2.92.6.11 diff -C2 -r2.92.6.10 -r2.92.6.11 *** listobject.c 2001/07/07 22:55:30 2.92.6.10 --- listobject.c 2001/07/14 07:47:35 2.92.6.11 *************** *** 1519,1523 **** switch (op) { case Py_LT: cmp = vs < ws; break; ! case Py_LE: cmp = ws <= ws; break; case Py_EQ: cmp = vs == ws; break; case Py_NE: cmp = vs != ws; break; --- 1519,1523 ---- switch (op) { case Py_LT: cmp = vs < ws; break; ! case Py_LE: cmp = vs <= ws; break; case Py_EQ: cmp = vs == ws; break; case Py_NE: cmp = vs != ws; break; Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.71.6.4 retrieving revision 1.71.6.5 diff -C2 -r1.71.6.4 -r1.71.6.5 *** longobject.c 2001/07/07 22:55:30 1.71.6.4 --- longobject.c 2001/07/14 07:47:35 1.71.6.5 *************** *** 812,831 **** } else { Py_INCREF(a); do { digit rem; ! PyLongObject *temp = divrem1(a, (digit)base, &rem); if (temp == NULL) { - Py_DECREF(a); Py_DECREF(str); return NULL; } - if (rem < 10) - rem += '0'; - else - rem += 'A'-10; - assert(p > PyString_AS_STRING(str)); - *--p = (char) rem; - Py_DECREF(a); a = temp; SIGCHECK({ --- 812,838 ---- } else { + /* Not 0, and base not a power of 2. Divide repeatedly by + base, but for speed use the highest power of base that + fits in a digit. */ + digit powbase = base; /* powbase == base ** power */ + int power = 1; + for (;;) { + unsigned long newpow = powbase * (unsigned long)base; + if (newpow >> SHIFT) /* doesn't fit in a digit */ + break; + powbase = (digit)newpow; + ++power; + } + Py_INCREF(a); do { + int ntostore = power; digit rem; ! PyLongObject *temp = divrem1(a, powbase, &rem); ! Py_DECREF(a); if (temp == NULL) { Py_DECREF(str); return NULL; } a = temp; SIGCHECK({ *************** *** 834,837 **** --- 841,854 ---- return NULL; }) + while (--ntostore >= 0) { + digit nextrem = (digit)(rem / base); + char c = (char)(rem - nextrem * base); + assert(p > PyString_AS_STRING(str)); + c += (c < 10) ? '0' : 'A'-10; + *--p = c; + rem = nextrem; + if (a->ob_size == 0 && rem == 0) + break; /* skip leading zeroes */ + } } while (ABS(a->ob_size) != 0); Py_DECREF(a); *************** *** 1544,1555 **** size_b = b->ob_size; if (size_b < 0) { ! if (a->ob_size) ! PyErr_SetString(PyExc_ValueError, ! "long integer to a negative power"); ! else ! PyErr_SetString(PyExc_ZeroDivisionError, ! "zero to a negative power"); ! z = NULL; ! goto error; } z = (PyLongObject *)PyLong_FromLong(1L); --- 1561,1571 ---- size_b = b->ob_size; if (size_b < 0) { ! /* Return a float. This works because we know that ! this calls float_pow() which converts its ! arguments to double. */ ! Py_DECREF(a); ! Py_DECREF(b); ! Py_DECREF(c); ! return PyFloat_Type.tp_as_number->nb_power(v, w, x); } z = (PyLongObject *)PyLong_FromLong(1L); Index: methodobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/methodobject.c,v retrieving revision 2.33.8.5 retrieving revision 2.33.8.6 diff -C2 -r2.33.8.5 -r2.33.8.6 *** methodobject.c 2001/06/06 14:27:54 2.33.8.5 --- methodobject.c 2001/07/14 07:47:35 2.33.8.6 *************** *** 23,26 **** --- 23,27 ---- Py_XINCREF(self); op->m_self = self; + PyObject_GC_Init(op); return (PyObject *)op; } *************** *** 61,64 **** --- 62,66 ---- meth_dealloc(PyCFunctionObject *m) { + PyObject_GC_Fini(m); Py_XDECREF(m->m_self); m->m_self = (PyObject *)free_list; *************** *** 83,86 **** --- 85,97 ---- } + static int + meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg) + { + if (m->m_self != NULL) + return visit(m->m_self, arg); + else + return 0; + } + static PyObject * meth_get__self__(PyCFunctionObject *m, void *closure) *************** *** 192,203 **** 0, "builtin_function_or_method", ! sizeof(PyCFunctionObject), 0, ! (destructor)meth_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ (cmpfunc)meth_compare, /* tp_compare */ ! (reprfunc)meth_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ --- 203,214 ---- 0, "builtin_function_or_method", ! sizeof(PyCFunctionObject) + PyGC_HEAD_SIZE, 0, ! (destructor)meth_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ (cmpfunc)meth_compare, /* tp_compare */ ! (reprfunc)meth_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ *************** *** 209,215 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ ! 0, /* tp_doc */ ! 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ --- 220,226 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */ ! 0, /* tp_doc */ ! (traverseproc)meth_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ *************** *** 303,306 **** --- 314,318 ---- PyCFunctionObject *v = free_list; free_list = (PyCFunctionObject *)(v->m_self); + v = (PyCFunctionObject *) PyObject_AS_GC(v); PyObject_DEL(v); } Index: rangeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/rangeobject.c,v retrieving revision 2.24.6.4 retrieving revision 2.24.6.5 diff -C2 -r2.24.6.4 -r2.24.6.5 *** rangeobject.c 2001/07/07 22:55:30 2.24.6.4 --- rangeobject.c 2001/07/14 07:47:35 2.24.6.5 *************** *** 6,9 **** --- 6,12 ---- #include + #define WARN(msg) if (PyErr_Warn(PyExc_DeprecationWarning, msg) < 0) \ + return NULL; + typedef struct { PyObject_HEAD *************** *** 11,37 **** long step; long len; } rangeobject; PyObject * ! PyRange_New(long start, long len, long step) { rangeobject *obj = PyObject_NEW(rangeobject, &PyRange_Type); if (obj == NULL) return NULL; ! if (len == 0) { start = 0; len = 0; step = 1; } else { long last = start + (len - 1) * step; if ((step > 0) ? ! (last > (PyInt_GetMax() - step)) ! :(last < (-1 - PyInt_GetMax() - step))) { PyErr_SetString(PyExc_OverflowError, "integer addition"); return NULL; } } --- 14,87 ---- long step; long len; + int reps; + long totlen; } rangeobject; + static int + long_mul(long i, long j, long *kk) + { + PyObject *a; + PyObject *b; + PyObject *c; + + if ((a = PyInt_FromLong(i)) == NULL) + return 0; + + if ((b = PyInt_FromLong(j)) == NULL) + return 0; + + c = PyNumber_Multiply(a, b); + + Py_DECREF(a); + Py_DECREF(b); + + if (c == NULL) + return 0; + + *kk = PyInt_AS_LONG(c); + Py_DECREF(c); + + if (*kk > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "integer multiplication"); + return 0; + } + else + return 1; + } + PyObject * ! PyRange_New(long start, long len, long step, int reps) { + long totlen = -1; rangeobject *obj = PyObject_NEW(rangeobject, &PyRange_Type); if (obj == NULL) return NULL; + + if (reps != 1) + WARN("PyRange_New's 'repetitions' argument is deprecated"); ! if (len == 0 || reps <= 0) { start = 0; len = 0; step = 1; + reps = 1; + totlen = 0; } else { long last = start + (len - 1) * step; if ((step > 0) ? ! (last > (PyInt_GetMax() - step)) : ! (last < (-1 - PyInt_GetMax() - step))) { PyErr_SetString(PyExc_OverflowError, "integer addition"); return NULL; + } + if (! long_mul(len, (long) reps, &totlen)) { + if(!PyErr_ExceptionMatches(PyExc_OverflowError)) + return NULL; + PyErr_Clear(); + totlen = -1; } } *************** *** 40,43 **** --- 90,95 ---- obj->len = len; obj->step = step; + obj->reps = reps; + obj->totlen = totlen; return (PyObject *) obj; *************** *** 53,61 **** range_item(rangeobject *r, int i) { ! if (i < 0 || i >= r->len) { ! PyErr_SetString(PyExc_IndexError, "xrange object index out of range"); ! return NULL; ! } return PyInt_FromLong(r->start + (i % r->len) * r->step); --- 105,114 ---- range_item(rangeobject *r, int i) { ! if (i < 0 || i >= r->totlen) ! if (r->totlen!=-1) { ! PyErr_SetString(PyExc_IndexError, "xrange object index out of range"); ! return NULL; ! } return PyInt_FromLong(r->start + (i % r->len) * r->step); *************** *** 65,69 **** range_length(rangeobject *r) { ! return r->len; } --- 118,125 ---- range_length(rangeobject *r) { ! if (r->totlen == -1) ! PyErr_SetString(PyExc_OverflowError, ! "xrange object has too many items"); ! return r->totlen; } *************** *** 75,78 **** --- 131,135 ---- */ char buf1[250]; + char buf2[250]; if (r->start == 0 && r->step == 1) *************** *** 89,105 **** r->start + r->len * r->step, r->step); ! return PyString_FromString(buf1); } static PySequenceMethods range_as_sequence = { (inquiry)range_length, /*sq_length*/ 0, /*sq_concat*/ ! 0, /*sq_repeat*/ ! (intargfunc)range_item, /*sq_item*/ ! 0, /*sq_slice*/ 0, /*sq_ass_item*/ 0, /*sq_ass_slice*/ ! 0, /*sq_contains*/ }; --- 146,306 ---- r->start + r->len * r->step, r->step); + + if (r->reps != 1) + sprintf(buf2, "(%s * %d)", buf1, r->reps); + + return PyString_FromString(r->reps == 1 ? buf1 : buf2); + } + + static PyObject * + range_repeat(rangeobject *r, int n) + { + long lreps = 0; + + WARN("xrange object multiplication is deprecated; " + "convert to list instead"); + + if (n <= 0) + return (PyObject *) PyRange_New(0, 0, 1, 1); ! else if (n == 1) { ! Py_INCREF(r); ! return (PyObject *) r; ! } ! ! else if (! long_mul((long) r->reps, (long) n, &lreps)) ! return NULL; ! ! else ! return (PyObject *) PyRange_New( ! r->start, ! r->len, ! r->step, ! (int) lreps); } + static int + range_compare(rangeobject *r1, rangeobject *r2) + { + + if (PyErr_Warn(PyExc_DeprecationWarning, + "xrange object comparision is deprecated; " + "convert to list instead") < 0) + return -1; + + if (r1->start != r2->start) + return r1->start - r2->start; + + else if (r1->step != r2->step) + return r1->step - r2->step; + + else if (r1->len != r2->len) + return r1->len - r2->len; + + else + return r1->reps - r2->reps; + } + + static PyObject * + range_slice(rangeobject *r, int low, int high) + { + WARN("xrange object slicing is deprecated; " + "convert to list instead"); + + if (r->reps != 1) { + PyErr_SetString(PyExc_TypeError, + "cannot slice a replicated xrange"); + return NULL; + } + if (low < 0) + low = 0; + else if (low > r->len) + low = r->len; + if (high < 0) + high = 0; + if (high < low) + high = low; + else if (high > r->len) + high = r->len; + + if (low == 0 && high == r->len) { + Py_INCREF(r); + return (PyObject *) r; + } + + return (PyObject *) PyRange_New( + low * r->step + r->start, + high - low, + r->step, + 1); + } + + static PyObject * + range_tolist(rangeobject *self, PyObject *args) + { + PyObject *thelist; + int j; + + WARN("xrange.tolist() is deprecated; use list(xrange) instead"); + + if (! PyArg_ParseTuple(args, ":tolist")) + return NULL; + + if (self->totlen == -1) + return PyErr_NoMemory(); + + if ((thelist = PyList_New(self->totlen)) == NULL) + return NULL; + + for (j = 0; j < self->totlen; ++j) + if ((PyList_SetItem(thelist, j, (PyObject *) PyInt_FromLong( + self->start + (j % self->len) * self->step))) < 0) + return NULL; + + return thelist; + } + + static PyObject * + range_getattr(rangeobject *r, char *name) + { + PyObject *result; + + static PyMethodDef range_methods[] = { + {"tolist", (PyCFunction)range_tolist, METH_VARARGS, + "tolist() -> list\n" + "Return a list object with the same values.\n" + "(This method is deprecated; use list() instead.)"}, + {NULL, NULL} + }; + static struct memberlist range_members[] = { + {"step", T_LONG, offsetof(rangeobject, step), RO}, + {"start", T_LONG, offsetof(rangeobject, start), RO}, + {"stop", T_LONG, 0, RO}, + {NULL, 0, 0, 0} + }; + + result = Py_FindMethod(range_methods, (PyObject *) r, name); + if (result == NULL) { + PyErr_Clear(); + if (strcmp("stop", name) == 0) + result = PyInt_FromLong(r->start + (r->len * r->step)); + else + result = PyMember_Get((char *)r, range_members, name); + if (result) + WARN("xrange object's 'start', 'stop' and 'step' " + "attributes are deprecated"); + } + return result; + } + static PySequenceMethods range_as_sequence = { (inquiry)range_length, /*sq_length*/ 0, /*sq_concat*/ ! (intargfunc)range_repeat, /*sq_repeat*/ ! (intargfunc)range_item, /*sq_item*/ ! (intintargfunc)range_slice, /*sq_slice*/ 0, /*sq_ass_item*/ 0, /*sq_ass_slice*/ ! 0, /*sq_contains*/ }; *************** *** 110,129 **** sizeof(rangeobject), /* Basic object size */ 0, /* Item size for varobject */ ! (destructor)range_dealloc, /* tp_dealloc */ ! 0, /* tp_print */ ! 0, /* tp_getattr */ ! 0, /* tp_setattr */ ! 0, /* tp_compare */ ! (reprfunc)range_repr, /* tp_repr */ ! 0, /* tp_as_number */ ! &range_as_sequence, /* 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 */ 0, /* tp_doc */ 0, /* tp_traverse */ --- 311,330 ---- sizeof(rangeobject), /* Basic object size */ 0, /* Item size for varobject */ ! (destructor)range_dealloc, /*tp_dealloc*/ ! 0, /*tp_print*/ ! (getattrfunc)range_getattr, /*tp_getattr*/ ! 0, /*tp_setattr*/ ! (cmpfunc)range_compare, /*tp_compare*/ ! (reprfunc)range_repr, /*tp_repr*/ ! 0, /*tp_as_number*/ ! &range_as_sequence, /*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*/ 0, /* tp_doc */ 0, /* tp_traverse */ *************** *** 139,140 **** --- 340,343 ---- 0, /* tp_dict */ }; + + #undef WARN From tim_one@users.sourceforge.net Sat Jul 14 08:47:37 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 00:47:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib xmlrpclib.py,NONE,1.1.2.1 ConfigParser.py,1.32,1.32.6.1 SocketServer.py,1.24,1.24.4.1 __future__.py,1.5,1.5.4.1 site.py,1.26.4.1,1.26.4.2 sre.py,1.31,1.31.4.1 symbol.py,1.12,1.12.8.1 symtable.py,1.4,1.4.4.1 uu.py,1.16,1.16.6.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv29618/descr/dist/src/Lib Modified Files: Tag: descr-branch ConfigParser.py SocketServer.py __future__.py site.py sre.py symbol.py symtable.py uu.py Added Files: Tag: descr-branch xmlrpclib.py Log Message: Merge of trunk tag date2001-07-13 into descr-branch. See PLAN.txt. --- NEW FILE: xmlrpclib.py --- # # XML-RPC CLIENT LIBRARY # $Id: xmlrpclib.py,v 1.1.2.1 2001/07/14 07:47:34 tim_one Exp $ # # an XML-RPC client interface for Python. # # the marshalling and response parser code can also be used to # implement XML-RPC servers. # # Notes: # this version is designed to work with Python 1.5.2 or newer. # unicode encoding support requires at least Python 1.6. # experimental HTTPS requires Python 2.0 built with SSL sockets. # expat parser support requires Python 2.0 with pyexpat support. # # History: # 1999-01-14 fl Created # 1999-01-15 fl Changed dateTime to use localtime # 1999-01-16 fl Added Binary/base64 element, default to RPC2 service # 1999-01-19 fl Fixed array data element (from Skip Montanaro) # 1999-01-21 fl Fixed dateTime constructor, etc. # 1999-02-02 fl Added fault handling, handle empty sequences, etc. # 1999-02-10 fl Fixed problem with empty responses (from Skip Montanaro) # 1999-06-20 fl Speed improvements, pluggable parsers/transports (0.9.8) # 2000-11-28 fl Changed boolean to check the truth value of its argument # 2001-02-24 fl Added encoding/Unicode/SafeTransport patches # 2001-02-26 fl Added compare support to wrappers (0.9.9/1.0b1) # 2001-03-28 fl Make sure response tuple is a singleton # 2001-03-29 fl Don't require empty params element (from Nicholas Riley) # 2001-06-10 fl Folded in _xmlrpclib accelerator support # # Copyright (c) 1999-2001 by Secret Labs AB. # Copyright (c) 1999-2001 by Fredrik Lundh. # # info@pythonware.com # http://www.pythonware.com # # -------------------------------------------------------------------- # The XML-RPC client interface is # # Copyright (c) 1999-2001 by Secret Labs AB # Copyright (c) 1999-2001 by Fredrik Lundh # # By obtaining, using, and/or copying this software and/or its # associated documentation, you agree that you have read, understood, # and will comply with the following terms and conditions: # # Permission to use, copy, modify, and distribute this software and # its associated documentation for any purpose and without fee is # hereby granted, provided that the above copyright notice appears in # all copies, and that both that copyright notice and this permission # notice appear in supporting documentation, and that the name of # Secret Labs AB or the author not be used in advertising or publicity # pertaining to distribution of the software without specific, written # prior permission. # # SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD # TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- # ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR # 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. # -------------------------------------------------------------------- # # things to look into before 1.0 final: # TODO: unicode marshalling -DONE # TODO: ascii-compatible encoding support -DONE # TODO: safe transport -DONE (but mostly untested) # TODO: sgmlop memory leak -DONE # TODO: sgmlop xml parsing -DONE # TODO: support unicode method names -DONE # TODO: update selftest -DONE # TODO: add docstrings -DONE # TODO: clean up parser encoding (trust the parser) -DONE # TODO: expat support -DONE # TODO: _xmlrpclib accelerator support -DONE # TODO: use smarter/faster escape from effdom # TODO: support basic authentication (see robin's patch) # TODO: fix host tuple handling in the server constructor # TODO: let transport verify schemes # TODO: update documentation # TODO: authentication plugins # TODO: memo problem (see HP's mail) import re, string, time, operator import urllib, xmllib from types import * from cgi import escape try: unicode except NameError: unicode = None # unicode support not available def _decode(data, encoding, is8bit=re.compile("[\x80-\xff]").search): # decode non-ascii string (if possible) if unicode and encoding and is8bit(data): data = unicode(data, encoding) return data if unicode: def _stringify(string): # convert to 7-bit ascii if possible try: return str(string) except UnicodeError: return string else: def _stringify(string): return string __version__ = "1.0b2" # -------------------------------------------------------------------- # Exceptions class Error: # base class for client errors pass class ProtocolError(Error): # indicates an HTTP protocol error def __init__(self, url, errcode, errmsg, headers): self.url = url self.errcode = errcode self.errmsg = errmsg self.headers = headers def __repr__(self): return ( "" % (self.url, self.errcode, self.errmsg) ) class ResponseError(Error): # indicates a broken response package pass class Fault(Error): # indicates a XML-RPC fault package def __init__(self, faultCode, faultString, **extra): self.faultCode = faultCode self.faultString = faultString def __repr__(self): return ( "" % (self.faultCode, repr(self.faultString)) ) # -------------------------------------------------------------------- # Special values # boolean wrapper # use True or False to generate a "boolean" XML-RPC value class Boolean: 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) def boolean(value, truefalse=(False, True)): # convert any Python value to XML-RPC boolean return truefalse[operator.truth(value)] # # dateTime wrapper # wrap your iso8601 string or time tuple or localtime integer value # in this class to generate a "dateTime.iso8601" XML-RPC value class DateTime: def __init__(self, value=0): t = type(value) if not isinstance(t, StringType): if not isinstance(t, TupleType): if value == 0: value = time.time() value = time.localtime(value) value = time.strftime("%Y%m%dT%H:%M:%S", value) self.value = value def __cmp__(self, other): if isinstance(other, DateTime): other = other.value return cmp(self.value, other) def __repr__(self): return "" % (self.value, id(self)) def decode(self, data): self.value = string.strip(data) def encode(self, out): out.write("") out.write(self.value) out.write("\n") def datetime(data): value = DateTime() value.decode(data) return value # # binary data wrapper class Binary: def __init__(self, data=None): self.data = data def __cmp__(self, other): if isinstance(other, Binary): other = other.data return cmp(self.data, other) def decode(self, data): import base64 self.data = base64.decodestring(data) def encode(self, out): import base64, StringIO out.write("\n") base64.encode(StringIO.StringIO(self.data), out) out.write("\n") def binary(data): value = Binary() value.decode(data) return value WRAPPERS = DateTime, Binary, Boolean # -------------------------------------------------------------------- # XML parsers try: # optional xmlrpclib accelerator. for more information on this # component, contact info@pythonware.com import _xmlrpclib FastParser = _xmlrpclib.Parser FastUnmarshaller = _xmlrpclib.Unmarshaller except (AttributeError, ImportError): FastParser = FastUnmarshaller = None # # the SGMLOP parser is about 15x faster than Python's builtin # XML parser. SGMLOP sources can be downloaded from: # # http://www.pythonware.com/products/xml/sgmlop.htm # try: import sgmlop if not hasattr(sgmlop, "XMLParser"): raise ImportError except ImportError: SgmlopParser = None # sgmlop accelerator not available else: class SgmlopParser: def __init__(self, target): # setup callbacks self.finish_starttag = target.start self.finish_endtag = target.end self.handle_data = target.data self.handle_xml = target.xml # activate parser self.parser = sgmlop.XMLParser() self.parser.register(self) self.feed = self.parser.feed self.entity = { "amp": "&", "gt": ">", "lt": "<", "apos": "'", "quot": '"' } def close(self): try: self.parser.close() finally: self.parser = self.feed = None # nuke circular reference def handle_proc(self, tag, attr): m = re.search("encoding\s*=\s*['\"]([^\"']+)[\"']", attr) if m: self.handle_xml(m.group(1), 1) def handle_entityref(self, entity): # entity try: self.handle_data(self.entity[entity]) except KeyError: self.handle_data("&%s;" % entity) try: from xml.parsers import expat except ImportError: ExpatParser = None else: class ExpatParser: # fast expat parser for Python 2.0. this is about 50% # slower than sgmlop, on roundtrip testing def __init__(self, target): self._parser = parser = expat.ParserCreate(None, None) self._target = target parser.StartElementHandler = target.start parser.EndElementHandler = target.end parser.CharacterDataHandler = target.data encoding = None if not parser.returns_unicode: encoding = "utf-8" target.xml(encoding, None) def feed(self, data): self._parser.Parse(data, 0) def close(self): self._parser.Parse("", 1) # end of data del self._target, self._parser # get rid of circular references class SlowParser(xmllib.XMLParser): # slow but safe standard parser, based on the XML parser in # Python's standard library. this is about 10 times slower # than sgmlop, on roundtrip testing. def __init__(self, target): self.handle_xml = target.xml self.unknown_starttag = target.start self.handle_data = target.data self.unknown_endtag = target.end xmllib.XMLParser.__init__(self) # -------------------------------------------------------------------- # XML-RPC marshalling and unmarshalling code class Marshaller: """Generate an XML-RPC params chunk from a Python data structure""" # USAGE: create a marshaller instance for each set of parameters, # and use "dumps" to convert your data (represented as a tuple) to # a XML-RPC params chunk. to write a fault response, pass a Fault # instance instead. you may prefer to use the "dumps" convenience # function for this purpose (see below). # by the way, if you don't understand what's going on in here, # that's perfectly ok. def __init__(self, encoding=None): self.memo = {} self.data = None self.encoding = encoding dispatch = {} def dumps(self, values): self.__out = [] self.write = write = self.__out.append if isinstance(values, Fault): # fault instance write("\n") self.__dump(vars(values)) write("\n") else: # parameter block write("\n") for v in values: write("\n") self.__dump(v) write("\n") write("\n") result = string.join(self.__out, "") del self.__out, self.write # don't need this any more return result def __dump(self, value): try: f = self.dispatch[type(value)] except KeyError: raise TypeError, "cannot marshal %s objects" % type(value) else: f(self, value) def dump_int(self, value): self.write("%s\n" % value) dispatch[IntType] = dump_int def dump_double(self, value): self.write("%s\n" % value) dispatch[FloatType] = dump_double def dump_string(self, value): self.write("%s\n" % escape(value)) dispatch[StringType] = dump_string if unicode: def dump_unicode(self, value): value = value.encode(self.encoding) self.write("%s\n" % escape(value)) dispatch[UnicodeType] = dump_unicode def container(self, value): if value: i = id(value) if self.memo.has_key(i): raise TypeError, "cannot marshal recursive data structures" self.memo[i] = None def dump_array(self, value): self.container(value) write = self.write write("\n") for v in value: self.__dump(v) write("\n") dispatch[TupleType] = dump_array dispatch[ListType] = dump_array def dump_struct(self, value): self.container(value) write = self.write write("\n") for k, v in value.items(): write("\n") if type(k) is not StringType: raise TypeError, "dictionary key must be string" write("%s\n" % escape(k)) self.__dump(v) write("\n") write("\n") dispatch[DictType] = dump_struct def dump_instance(self, value): # check for special wrappers if value.__class__ in WRAPPERS: value.encode(self) else: # store instance attributes as a struct (really?) self.dump_struct(value.__dict__) dispatch[InstanceType] = dump_instance class Unmarshaller: # unmarshal an XML-RPC response, based on incoming XML event # messages (start, data, end). call close to get the resulting # data structure # note that this reader is fairly tolerant, and gladly accepts # bogus XML-RPC data without complaining (but not bogus XML). # and again, if you don't understand what's going on in here, # that's perfectly ok. def __init__(self): self._type = None self._stack = [] self._marks = [] self._data = [] self._methodname = None self._encoding = "utf-8" self.append = self._stack.append def close(self): # return response tuple and target method if self._type is None or self._marks: raise ResponseError() if self._type == "fault": raise apply(Fault, (), self._stack[0]) return tuple(self._stack) def getmethodname(self): return self._methodname # # event handlers def xml(self, encoding, standalone): self._encoding = encoding # FIXME: assert standalone == 1 ??? def start(self, tag, attrs): # prepare to handle this element if tag == "array" or tag == "struct": self._marks.append(len(self._stack)) self._data = [] self._value = (tag == "value") def data(self, text): self._data.append(text) def end(self, tag): # call the appropriate end tag handler try: f = self.dispatch[tag] except KeyError: pass # unknown tag ? else: return f(self, self._data) # # accelerator support def end_dispatch(self, tag, data): # dispatch data try: f = self.dispatch[tag] except KeyError: pass # unknown tag ? else: return f(self, data) # # element decoders dispatch = {} def end_boolean(self, data, join=string.join): data = join(data, "") if data == "0": self.append(False) elif data == "1": self.append(True) else: raise TypeError, "bad boolean value" self._value = 0 dispatch["boolean"] = end_boolean def end_int(self, data, join=string.join): self.append(int(join(data, ""))) self._value = 0 dispatch["i4"] = end_int dispatch["int"] = end_int def end_double(self, data, join=string.join): self.append(float(join(data, ""))) self._value = 0 dispatch["double"] = end_double def end_string(self, data, join=string.join): data = join(data, "") if self._encoding: data = _decode(data, self._encoding) self.append(_stringify(data)) self._value = 0 dispatch["string"] = end_string dispatch["name"] = end_string # struct keys are always strings def end_array(self, data): mark = self._marks[-1] del self._marks[-1] # map arrays to Python lists self._stack[mark:] = [self._stack[mark:]] self._value = 0 dispatch["array"] = end_array def end_struct(self, data): mark = self._marks[-1] del self._marks[-1] # map structs to Python dictionaries dict = {} items = self._stack[mark:] for i in range(0, len(items), 2): dict[_stringify(items[i])] = items[i+1] self._stack[mark:] = [dict] self._value = 0 dispatch["struct"] = end_struct def end_base64(self, data, join=string.join): value = Binary() value.decode(join(data, "")) self.append(value) self._value = 0 dispatch["base64"] = end_base64 def end_dateTime(self, data, join=string.join): value = DateTime() value.decode(join(data, "")) self.append(value) dispatch["dateTime.iso8601"] = end_dateTime def end_value(self, data): # if we stumble upon an value element with no internal # elements, treat it as a string element if self._value: self.end_string(data) dispatch["value"] = end_value def end_params(self, data): self._type = "params" dispatch["params"] = end_params def end_fault(self, data): self._type = "fault" dispatch["fault"] = end_fault def end_methodName(self, data, join=string.join): data = join(data, "") if self._encoding: data = _decode(data, self._encoding) self._methodname = data self._type = "methodName" # no params dispatch["methodName"] = end_methodName # -------------------------------------------------------------------- # convenience functions def getparser(): """getparser() -> parser, unmarshaller Create an instance of the fastest available parser, and attach it to an unmarshalling object. Return both objects. """ if FastParser and FastUnmarshaller: target = FastUnmarshaller(True, False, binary, datetime) parser = FastParser(target) else: target = Unmarshaller() if FastParser: parser = FastParser(target) elif SgmlopParser: parser = SgmlopParser(target) elif ExpatParser: parser = ExpatParser(target) else: parser = SlowParser(target) return parser, target def dumps(params, methodname=None, methodresponse=None, encoding=None): """data [,options] -> marshalled data Convert an argument tuple or a Fault instance to an XML-RPC request (or response, if the methodresponse option is used). In addition to the data object, the following options can be given as keyword arguments: methodname: the method name for a methodCall packet methodresponse: true to create a methodResponse packet. If this option is used with a tuple, the tuple must be a singleton (i.e. it can contain only one element). encoding: the packet encoding (default is UTF-8) All 8-bit strings in the data structure are assumed to use the packet encoding. Unicode strings are automatically converted, as necessary. """ assert isinstance(params, TupleType) or isinstance(params, Fault),\ "argument must be tuple or Fault instance" if isinstance(params, Fault): methodresponse = 1 elif methodresponse and isinstance(params, TupleType): assert len(params) == 1, "response tuple must be a singleton" if not encoding: encoding = "utf-8" m = Marshaller(encoding) data = m.dumps(params) if encoding != "utf-8": xmlheader = "\n" % repr(encoding) else: xmlheader = "\n" # utf-8 is default # standard XML-RPC wrappings if methodname: # a method call if not isinstance(methodname, StringType): methodname = methodname.encode(encoding) data = ( xmlheader, "\n" "", methodname, "\n", data, "\n" ) elif methodresponse: # a method response, or a fault structure data = ( xmlheader, "\n", data, "\n" ) else: return data # return as is return string.join(data, "") def loads(data): """data -> unmarshalled data, method name Convert an XML-RPC packet to unmarshalled data plus a method name (None if not present). If the XML-RPC packet represents a fault condition, this function raises a Fault exception. """ p, u = getparser() p.feed(data) p.close() return u.close(), u.getmethodname() # -------------------------------------------------------------------- # request dispatcher class _Method: # some magic to bind an XML-RPC method to an RPC server. # supports "nested" methods (e.g. examples.getStateName) def __init__(self, send, name): self.__send = send self.__name = name def __getattr__(self, name): return _Method(self.__send, "%s.%s" % (self.__name, name)) def __call__(self, *args): return self.__send(self.__name, args) class Transport: """Handles an HTTP transaction to an XML-RPC server""" # client identifier (may be overridden) user_agent = "xmlrpclib.py/%s (by www.pythonware.com)" % __version__ def request(self, host, handler, request_body, verbose=0): # issue XML-RPC request h = self.make_connection(host) if verbose: h.set_debuglevel(1) self.send_request(h, handler, request_body) self.send_host(h, host) self.send_user_agent(h) self.send_content(h, request_body) errcode, errmsg, headers = h.getreply() if errcode != 200: raise ProtocolError( host + handler, errcode, errmsg, headers ) self.verbose = verbose return self.parse_response(h.getfile()) def make_connection(self, host): # create a HTTP connection object from a host descriptor import httplib return httplib.HTTP(host) def send_request(self, connection, handler, request_body): connection.putrequest("POST", handler) def send_host(self, connection, host): connection.putheader("Host", host) def send_user_agent(self, connection): connection.putheader("User-Agent", self.user_agent) def send_content(self, connection, request_body): connection.putheader("Content-Type", "text/xml") connection.putheader("Content-Length", str(len(request_body))) connection.endheaders() if request_body: connection.send(request_body) def parse_response(self, f): # read response from input file, and parse it p, u = getparser() while 1: response = f.read(1024) if not response: break if self.verbose: print "body:", repr(response) p.feed(response) f.close() p.close() return u.close() class SafeTransport(Transport): """Handles an HTTPS transaction to an XML-RPC server""" def make_connection(self, host): # create a HTTPS connection object from a host descriptor # host may be a string, or a (host, x509-dict) tuple import httplib if isinstance(host, TupleType): host, x509 = host else: x509 = {} try: HTTPS = httplib.HTTPS except AttributeError: raise NotImplementedError,\ "your version of httplib doesn't support HTTPS" else: return apply(HTTPS, (host, None), x509) def send_host(self, connection, host): if isinstance(host, TupleType): host, x509 = host connection.putheader("Host", host) class ServerProxy: """uri [,options] -> a logical connection to an XML-RPC server uri is the connection point on the server, given as scheme://host/target. The standard implementation always supports the "http" scheme. If SSL socket support is available (Python 2.0), it also supports "https". If the target part and the slash preceding it are both omitted, "/RPC2" is assumed. The following options can be given as keyword arguments: transport: a transport factory encoding: the request encoding (default is UTF-8) All 8-bit strings passed to the server proxy are assumed to use the given encoding. """ def __init__(self, uri, transport=None, encoding=None, verbose=0): # establish a "logical" server connection # get the url type, uri = urllib.splittype(uri) if type not in ("http", "https"): raise IOError, "unsupported XML-RPC protocol" self.__host, self.__handler = urllib.splithost(uri) if not self.__handler: self.__handler = "/RPC2" if transport is None: if type == "https": transport = SafeTransport() else: transport = Transport() self.__transport = transport self.__encoding = encoding self.__verbose = verbose def __request(self, methodname, params): # call a method on the remote server request = dumps(params, methodname, encoding=self.__encoding) response = self.__transport.request( self.__host, self.__handler, request, verbose=self.__verbose ) if len(response) == 1: response = response[0] return response def __repr__(self): return ( "" % (self.__host, self.__handler) ) __str__ = __repr__ def __getattr__(self, name): # magic method dispatcher return _Method(self.__request, name) # note: to call a remote object with an non-standard name, use # result getattr(server, "strange-python-name")(args) Server = ServerProxy # -------------------------------------------------------------------- # test code if __name__ == "__main__": # simple test program (from the XML-RPC specification) # server = Server("http://localhost:8000") # local server server = Server("http://betty.userland.com") print server try: print server.examples.getStateName(41) except Error, v: print "ERROR", v Index: ConfigParser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/ConfigParser.py,v retrieving revision 1.32 retrieving revision 1.32.6.1 diff -C2 -r1.32 -r1.32.6.1 *** ConfigParser.py 2001/02/26 21:55:34 1.32 --- ConfigParser.py 2001/07/14 07:47:34 1.32.6.1 *************** *** 432,436 **** value = line.strip() if value: ! cursect[optname] = cursect[optname] + '\n ' + value # a section header or option header? else: --- 432,437 ---- value = line.strip() if value: ! k = self.optionxform(optname) ! cursect[k] = "%s\n%s" % (cursect[k], value) # a section header or option header? else: Index: SocketServer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/SocketServer.py,v retrieving revision 1.24 retrieving revision 1.24.4.1 diff -C2 -r1.24 -r1.24.4.1 *** SocketServer.py 2001/04/11 04:02:05 1.24 --- SocketServer.py 2001/07/14 07:47:34 1.24.4.1 *************** *** 121,127 **** # Author of the BaseServer patch: Luke Kenneth Casson Leighton ! __version__ = "0.3" import socket import sys --- 121,132 ---- # Author of the BaseServer patch: Luke Kenneth Casson Leighton ! # XXX Warning! ! # There is a test suite for this module, but it cannot be run by the ! # standard regression test. ! # To run it manually, run Lib/test/test_socketserver.py. + __version__ = "0.4" + import socket import sys *************** *** 130,134 **** __all__ = ["TCPServer","UDPServer","ForkingUDPServer","ForkingTCPServer", "ThreadingUDPServer","ThreadingTCPServer","BaseRequestHandler", ! "StreamRequestHandler","DatagramRequestHandler"] if hasattr(socket, "AF_UNIX"): __all__.extend(["UnixStreamServer","UnixDatagramServer", --- 135,140 ---- __all__ = ["TCPServer","UDPServer","ForkingUDPServer","ForkingTCPServer", "ThreadingUDPServer","ThreadingTCPServer","BaseRequestHandler", ! "StreamRequestHandler","DatagramRequestHandler", ! "ThreadingMixIn", "ForkingMixIn"] if hasattr(socket, "AF_UNIX"): __all__.extend(["UnixStreamServer","UnixDatagramServer", *************** *** 216,220 **** except: self.handle_error(request, client_address) ! self.close_request(request) def verify_request(self, request, client_address): --- 222,226 ---- except: self.handle_error(request, client_address) ! self.close_request(request) def verify_request(self, request, client_address): *************** *** 233,236 **** --- 239,243 ---- """ self.finish_request(request, client_address) + self.close_request(request) def server_close(self): *************** *** 424,427 **** --- 431,435 ---- self.active_children = [] self.active_children.append(pid) + self.close_request(request) return else: *************** *** 429,439 **** # This must never return, hence os._exit()! try: - self.server_close() self.finish_request(request, client_address) os._exit(0) except: try: ! self.handle_error(request, ! client_address) finally: os._exit(1) --- 437,445 ---- # This must never return, hence os._exit()! try: self.finish_request(request, client_address) os._exit(0) except: try: ! self.handle_error(request, client_address) finally: os._exit(1) *************** *** 545,548 **** --- 551,557 ---- class DatagramRequestHandler(BaseRequestHandler): + + # XXX Regrettably, I cannot get this working on Linux; + # s.recvfrom() doesn't return a meaningful client address. """Define self.rfile and self.wfile for datagram sockets.""" Index: __future__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/__future__.py,v retrieving revision 1.5 retrieving revision 1.5.4.1 diff -C2 -r1.5 -r1.5.4.1 *** __future__.py 2001/03/15 10:45:44 1.5 --- __future__.py 2001/07/14 07:47:34 1.5.4.1 *************** *** 67,69 **** `self.getMandatoryRelease()` + ")" ! nested_scopes = _Feature((2, 1, 0, "beta", 1), (2, 2, 0, "final", 0)) --- 67,69 ---- `self.getMandatoryRelease()` + ")" ! nested_scopes = _Feature((2, 1, 0, "beta", 1), (2, 2, 0, "alpha", 0)) Index: site.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/site.py,v retrieving revision 1.26.4.1 retrieving revision 1.26.4.2 diff -C2 -r1.26.4.1 -r1.26.4.2 *** site.py 2001/07/07 22:55:28 1.26.4.1 --- site.py 2001/07/14 07:47:34 1.26.4.2 *************** *** 80,83 **** --- 80,87 ---- dirs_in_sys_path = {} for dir in sys.path: + # Filter out paths that don't exist, but leave in the empty string + # since it's a special case. + if dir and not os.path.isdir(dir): + continue dir, dircase = makepath(dir) if not dirs_in_sys_path.has_key(dircase): *************** *** 142,149 **** "site-packages"), os.path.join(prefix, "lib", "site-python")] - elif os.sep == ':': - sitedirs = [os.path.join(prefix, "lib", "site-packages")] else: ! sitedirs = [prefix] for sitedir in sitedirs: if os.path.isdir(sitedir): --- 146,151 ---- "site-packages"), os.path.join(prefix, "lib", "site-python")] else: ! sitedirs = [prefix, os.path.join(prefix, "lib", "site-packages")] for sitedir in sitedirs: if os.path.isdir(sitedir): Index: sre.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre.py,v retrieving revision 1.31 retrieving revision 1.31.4.1 diff -C2 -r1.31 -r1.31.4.1 *** sre.py 2001/03/22 15:50:10 1.31 --- sre.py 2001/07/14 07:47:34 1.31.4.1 *************** *** 76,80 **** return _compile(pattern, 0).split(string, maxsplit) ! def findall(pattern, string, maxsplit=0): """Return a list of all non-overlapping matches in the string. --- 76,80 ---- return _compile(pattern, 0).split(string, maxsplit) ! def findall(pattern, string): """Return a list of all non-overlapping matches in the string. *************** *** 84,88 **** Empty matches are included in the result.""" ! return _compile(pattern, 0).findall(string, maxsplit) def compile(pattern, flags=0): --- 84,88 ---- Empty matches are included in the result.""" ! return _compile(pattern, 0).findall(string) def compile(pattern, flags=0): *************** *** 160,168 **** return sre_parse.expand_template(template, match) ! def _sub(pattern, template, string, count=0): # internal: pattern.sub implementation hook ! return _subn(pattern, template, string, count)[0] ! def _subn(pattern, template, string, count=0): # internal: pattern.subn implementation hook if callable(template): --- 160,168 ---- return sre_parse.expand_template(template, match) ! def _sub(pattern, template, text, count=0): # internal: pattern.sub implementation hook ! return _subn(pattern, template, text, count, 1)[0] ! def _subn(pattern, template, text, count=0, sub=0): # internal: pattern.subn implementation hook if callable(template): *************** *** 170,173 **** --- 170,178 ---- else: template = _compile_repl(template, pattern) + literals = template[1] + if (sub and not count and pattern._isliteral() and + len(literals) == 1 and literals[0]): + # shortcut: both pattern and string are literals + return string.replace(text, pattern.pattern, literals[0]), 0 def filter(match, template=template): return sre_parse.expand_template(template, match) *************** *** 175,179 **** s = [] append = s.append ! c = pattern.scanner(string) while not count or n < count: m = c.search() --- 180,184 ---- s = [] append = s.append ! c = pattern.scanner(text) while not count or n < count: m = c.search() *************** *** 182,193 **** b, e = m.span() if i < b: ! append(string[i:b]) append(filter(m)) i = e n = n + 1 ! append(string[i:]) ! return _join(s, string[:0]), n ! def _split(pattern, string, maxsplit=0): # internal: pattern.split implementation hook n = i = 0 --- 187,198 ---- b, e = m.span() if i < b: ! append(text[i:b]) append(filter(m)) i = e n = n + 1 ! append(text[i:]) ! return _join(s, text[:0]), n ! def _split(pattern, text, maxsplit=0): # internal: pattern.split implementation hook n = i = 0 *************** *** 195,199 **** append = s.append extend = s.extend ! c = pattern.scanner(string) g = pattern.groups while not maxsplit or n < maxsplit: --- 200,204 ---- append = s.append extend = s.extend ! c = pattern.scanner(text) g = pattern.groups while not maxsplit or n < maxsplit: *************** *** 203,215 **** b, e = m.span() if b == e: ! if i >= len(string): break continue ! append(string[i:b]) if g and b != e: extend(list(m.groups())) i = e n = n + 1 ! append(string[i:]) return s --- 208,220 ---- b, e = m.span() if b == e: ! if i >= len(text): break continue ! append(text[i:b]) if g and b != e: extend(list(m.groups())) i = e n = n + 1 ! append(text[i:]) return s Index: symbol.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/symbol.py,v retrieving revision 1.12 retrieving revision 1.12.8.1 diff -C2 -r1.12 -r1.12.8.1 *** symbol.py 2000/08/24 21:08:39 1.12 --- symbol.py 2001/07/14 07:47:34 1.12.8.1 *************** *** 31,78 **** continue_stmt = 274 return_stmt = 275 ! raise_stmt = 276 ! import_stmt = 277 ! import_as_name = 278 ! dotted_as_name = 279 ! dotted_name = 280 ! global_stmt = 281 ! exec_stmt = 282 ! assert_stmt = 283 ! compound_stmt = 284 ! if_stmt = 285 ! while_stmt = 286 ! for_stmt = 287 ! try_stmt = 288 ! except_clause = 289 ! suite = 290 ! test = 291 ! and_test = 292 ! not_test = 293 ! comparison = 294 ! comp_op = 295 ! expr = 296 ! xor_expr = 297 ! and_expr = 298 ! shift_expr = 299 ! arith_expr = 300 ! term = 301 ! factor = 302 ! power = 303 ! atom = 304 ! listmaker = 305 ! lambdef = 306 ! trailer = 307 ! subscriptlist = 308 ! subscript = 309 ! sliceop = 310 ! exprlist = 311 ! testlist = 312 ! dictmaker = 313 ! classdef = 314 ! arglist = 315 ! argument = 316 ! list_iter = 317 ! list_for = 318 ! list_if = 319 #--end constants-- --- 31,79 ---- continue_stmt = 274 return_stmt = 275 ! yield_stmt = 276 ! raise_stmt = 277 ! import_stmt = 278 ! import_as_name = 279 ! dotted_as_name = 280 ! dotted_name = 281 ! global_stmt = 282 ! exec_stmt = 283 ! assert_stmt = 284 ! compound_stmt = 285 ! if_stmt = 286 ! while_stmt = 287 ! for_stmt = 288 ! try_stmt = 289 ! except_clause = 290 ! suite = 291 ! test = 292 ! and_test = 293 ! not_test = 294 ! comparison = 295 ! comp_op = 296 ! expr = 297 ! xor_expr = 298 ! and_expr = 299 ! shift_expr = 300 ! arith_expr = 301 ! term = 302 ! factor = 303 ! power = 304 ! atom = 305 ! listmaker = 306 ! lambdef = 307 ! trailer = 308 ! subscriptlist = 309 ! subscript = 310 ! sliceop = 311 ! exprlist = 312 ! testlist = 313 ! dictmaker = 314 ! classdef = 315 ! arglist = 316 ! argument = 317 ! list_iter = 318 ! list_for = 319 ! list_if = 320 #--end constants-- Index: symtable.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/symtable.py,v retrieving revision 1.4 retrieving revision 1.4.4.1 diff -C2 -r1.4 -r1.4.4.1 *** symtable.py 2001/04/16 18:43:18 1.4 --- symtable.py 2001/07/14 07:47:34 1.4.4.1 *************** *** 1,4 **** """Interface to the compiler's internal symbol tables""" - from __future__ import nested_scopes import _symtable --- 1,3 ---- Index: uu.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/uu.py,v retrieving revision 1.16 retrieving revision 1.16.6.1 diff -C2 -r1.16 -r1.16.6.1 *** uu.py 2001/03/01 04:27:19 1.16 --- uu.py 2001/07/14 07:47:34 1.16.6.1 *************** *** 136,140 **** out_file.write(data) s = in_file.readline() ! if not str: raise Error, 'Truncated input file' --- 136,140 ---- out_file.write(data) s = in_file.readline() ! if not s: raise Error, 'Truncated input file' From tim_one@users.sourceforge.net Sat Jul 14 08:47:37 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 00:47:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.198.2.7,2.198.2.8 ceval.c,2.241.2.7,2.241.2.8 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv29618/descr/dist/src/Python Modified Files: Tag: descr-branch bltinmodule.c ceval.c Log Message: Merge of trunk tag date2001-07-13 into descr-branch. See PLAN.txt. Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.198.2.7 retrieving revision 2.198.2.8 diff -C2 -r2.198.2.7 -r2.198.2.8 *** bltinmodule.c 2001/07/07 22:55:30 2.198.2.7 --- bltinmodule.c 2001/07/14 07:47:35 2.198.2.8 *************** *** 1392,1396 **** return NULL; } ! return PyRange_New(ilow, n, istep); } --- 1392,1396 ---- return NULL; } ! return PyRange_New(ilow, n, istep, 1); } Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.241.2.7 retrieving revision 2.241.2.8 diff -C2 -r2.241.2.7 -r2.241.2.8 *** ceval.c 2001/07/08 11:51:54 2.241.2.7 --- ceval.c 2001/07/14 07:47:35 2.241.2.8 *************** *** 113,124 **** gen->gi_frame = f; gen->gi_running = 0; return (PyObject *)gen; } static void gen_dealloc(genobject *gen) { Py_DECREF(gen->gi_frame); ! PyObject_DEL(gen); } --- 113,132 ---- gen->gi_frame = f; gen->gi_running = 0; + PyObject_GC_Init(gen); return (PyObject *)gen; } + static int + gen_traverse(genobject *gen, visitproc visit, void *arg) + { + return visit((PyObject *)gen->gi_frame, arg); + } + static void gen_dealloc(genobject *gen) { + PyObject_GC_Fini(gen); Py_DECREF(gen->gi_frame); ! PyObject_Del(gen); } *************** *** 203,211 **** statichere PyTypeObject gentype = { PyObject_HEAD_INIT(&PyType_Type) ! 0, /* Number of items for varobject */ ! "generator", /* Name of this type */ ! sizeof(genobject), /* Basic object size */ ! 0, /* Item size for varobject */ ! (destructor)gen_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ --- 211,220 ---- statichere PyTypeObject gentype = { PyObject_HEAD_INIT(&PyType_Type) ! 0, /* ob_size */ ! "generator", /* tp_name */ ! sizeof(genobject) + PyGC_HEAD_SIZE, /* tp_basicsize */ ! 0, /* tp_itemsize */ ! /* methods */ ! (destructor)gen_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ *************** *** 222,229 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ ! 0, /* tp_doc */ ! 0, /* tp_traverse */ ! 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ --- 231,238 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */ ! 0, /* tp_doc */ ! (traverseproc)gen_traverse, /* tp_traverse */ ! 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ From tim_one@users.sourceforge.net Sat Jul 14 12:01:30 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 04:01:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.85,1.86 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv22122/python/dist/src/Objects Modified Files: longobject.c Log Message: long_format(): Simplify new code a bit. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.85 retrieving revision 1.86 diff -C2 -r1.85 -r1.86 *** longobject.c 2001/07/13 02:59:26 1.85 --- longobject.c 2001/07/14 11:01:28 1.86 *************** *** 841,845 **** return NULL; }) ! while (--ntostore >= 0) { digit nextrem = (digit)(rem / base); char c = (char)(rem - nextrem * base); --- 841,846 ---- return NULL; }) ! assert(ntostore > 0); ! do { digit nextrem = (digit)(rem / base); char c = (char)(rem - nextrem * base); *************** *** 848,855 **** *--p = c; rem = nextrem; ! if (a->ob_size == 0 && rem == 0) ! break; /* skip leading zeroes */ ! } ! } while (ABS(a->ob_size) != 0); Py_DECREF(a); } --- 849,858 ---- *--p = c; rem = nextrem; ! --ntostore; ! /* Termination is a bit delicate: must not ! store leading zeroes, so must get out if ! a and rem are both 0 now. */ ! } while (ntostore && (a->ob_size || rem)); ! } while (a->ob_size != 0); Py_DECREF(a); } From tim_one@users.sourceforge.net Sat Jul 14 13:23:21 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 05:23:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.86,1.87 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv30461/python/dist/src/Objects Modified Files: longobject.c Log Message: divrem1 & long_format: found a clean way to factor divrem1 so that long_format can reuse a scratch area for its repeated divisions (instead of malloc/free for every digit produced); speeds str(long)/repr(long). Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.86 retrieving revision 1.87 diff -C2 -r1.86 -r1.87 *** longobject.c 2001/07/14 11:01:28 1.86 --- longobject.c 2001/07/14 12:23:19 1.87 *************** *** 16,20 **** static PyLongObject *mul1(PyLongObject *, wdigit); static PyLongObject *muladd1(PyLongObject *, wdigit, wdigit); ! static PyLongObject *divrem1(PyLongObject *, wdigit, digit *); static PyObject *long_format(PyObject *aa, int base, int addL); --- 16,20 ---- static PyLongObject *mul1(PyLongObject *, wdigit); static PyLongObject *muladd1(PyLongObject *, wdigit, wdigit); ! static PyLongObject *divrem1(PyLongObject *, digit, digit *); static PyObject *long_format(PyObject *aa, int base, int addL); *************** *** 708,711 **** --- 708,734 ---- } + /* Divide long pin, w/ size digits, by non-zero digit n, storing quotient + in pout, and returning the remainder. pin and pout point at the LSD. + It's OK for pin == pout on entry, which saves oodles of mallocs/frees in + long_format, but that should be done with great care since longs are + immutable. */ + + static digit + inplace_divrem1(digit *pout, digit *pin, int size, digit n) + { + twodigits rem = 0; + + assert(n > 0 && n <= MASK); + pin += size; + pout += size; + while (--size >= 0) { + digit hi; + rem = (rem << SHIFT) + *--pin; + *--pout = hi = (digit)(rem / n); + rem -= hi * n; + } + return (digit)rem; + } + /* Divide a long integer by a digit, returning both the quotient (as function result) and the remainder (through *prem). *************** *** 713,722 **** static PyLongObject * ! divrem1(PyLongObject *a, wdigit n, digit *prem) { ! int size = ABS(a->ob_size); PyLongObject *z; - int i; - twodigits rem = 0; assert(n > 0 && n <= MASK); --- 736,743 ---- static PyLongObject * ! divrem1(PyLongObject *a, digit n, digit *prem) { ! const int size = ABS(a->ob_size); PyLongObject *z; assert(n > 0 && n <= MASK); *************** *** 724,733 **** if (z == NULL) return NULL; ! for (i = size; --i >= 0; ) { ! rem = (rem << SHIFT) + a->ob_digit[i]; ! z->ob_digit[i] = (digit) (rem/n); ! rem %= n; ! } ! *prem = (digit) rem; return long_normalize(z); } --- 745,749 ---- if (z == NULL) return NULL; ! *prem = inplace_divrem1(z->ob_digit, a->ob_digit, size, n); return long_normalize(z); } *************** *** 743,747 **** PyStringObject *str; int i; ! int size_a = ABS(a->ob_size); char *p; int bits; --- 759,763 ---- PyStringObject *str; int i; ! const int size_a = ABS(a->ob_size); char *p; int bits; *************** *** 780,784 **** int bitsleft = SHIFT; int rem; ! int last = abs(a->ob_size); int basebits = 1; i = base; --- 796,800 ---- int bitsleft = SHIFT; int rem; ! int last = size_a; int basebits = 1; i = base; *************** *** 815,818 **** --- 831,838 ---- base, but for speed use the highest power of base that fits in a digit. */ + int size = size_a; + digit *pin = a->ob_digit; + PyLongObject *scratch; + /* powbasw <- largest power of base that fits in a digit. */ digit powbase = base; /* powbase == base ** power */ int power = 1; *************** *** 824,844 **** ++power; } ! ! Py_INCREF(a); do { int ntostore = power; ! digit rem; ! PyLongObject *temp = divrem1(a, powbase, &rem); ! Py_DECREF(a); ! if (temp == NULL) { ! Py_DECREF(str); ! return NULL; ! } ! a = temp; SIGCHECK({ ! Py_DECREF(a); Py_DECREF(str); return NULL; }) assert(ntostore > 0); do { --- 844,870 ---- ++power; } ! ! /* Get a scratch area for repeated division. */ ! scratch = _PyLong_New(size); ! if (scratch == NULL) { ! Py_DECREF(str); ! return NULL; ! } ! ! /* Repeatedly divide by powbase. */ do { int ntostore = power; ! digit rem = inplace_divrem1(scratch->ob_digit, ! pin, size, powbase); ! pin = scratch->ob_digit; /* no need to use a again */ ! if (pin[size - 1] == 0) ! --size; SIGCHECK({ ! Py_DECREF(scratch); Py_DECREF(str); return NULL; }) + + /* Break rem into digits. */ assert(ntostore > 0); do { *************** *** 852,859 **** /* Termination is a bit delicate: must not store leading zeroes, so must get out if ! a and rem are both 0 now. */ ! } while (ntostore && (a->ob_size || rem)); ! } while (a->ob_size != 0); ! Py_DECREF(a); } --- 878,885 ---- /* Termination is a bit delicate: must not store leading zeroes, so must get out if ! remaining quotient and rem are both 0. */ ! } while (ntostore && (size || rem)); ! } while (size != 0); ! Py_DECREF(scratch); } From jackjansen@users.sourceforge.net Sat Jul 14 14:59:49 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 14 Jul 2001 06:59:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Lib/lib-toolbox MacTextEditor.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Lib/lib-toolbox In directory usw-pr-cvs1:/tmp/cvs-serv17790/Python/Mac/Lib/lib-toolbox Added Files: MacTextEditor.py Log Message: The constants for MLTE. --- NEW FILE: MacTextEditor.py --- # Generated from 'MacTextEditor.h' def FOUR_CHAR_CODE(x): return x false = 0 true = 1 kTXNClearThisControl = 0xFFFFFFFF kTXNClearTheseFontFeatures = 0x80000000 kTXNDontCareTypeSize = 0xFFFFFFFF kTXNDecrementTypeSize = 0x80000000 kTXNUseCurrentSelection = 0xFFFFFFFF kTXNStartOffset = 0 kTXNEndOffset = 0x7FFFFFFF MovieFileType = FOUR_CHAR_CODE('moov') kTXNWillDefaultToATSUIBit = 0 kTXNWillDefaultToATSUIMask = 1L << kTXNWillDefaultToATSUIBit kTXNWantMoviesBit = 0 kTXNWantSoundBit = 1 kTXNWantGraphicsBit = 2 kTXNAlwaysUseQuickDrawTextBit = 3 kTXNUseTemporaryMemoryBit = 4 kTXNWantMoviesMask = 1L << kTXNWantMoviesBit kTXNWantSoundMask = 1L << kTXNWantSoundBit kTXNWantGraphicsMask = 1L << kTXNWantGraphicsBit kTXNAlwaysUseQuickDrawTextMask = 1L << kTXNAlwaysUseQuickDrawTextBit kTXNUseTemporaryMemoryMask = 1L << kTXNUseTemporaryMemoryBit kTXNDrawGrowIconBit = 0 kTXNShowWindowBit = 1 kTXNWantHScrollBarBit = 2 kTXNWantVScrollBarBit = 3 kTXNNoTSMEverBit = 4 kTXNReadOnlyBit = 5 kTXNNoKeyboardSyncBit = 6 kTXNNoSelectionBit = 7 kTXNSaveStylesAsSTYLResourceBit = 8 kOutputTextInUnicodeEncodingBit = 9 kTXNDoNotInstallDragProcsBit = 10 kTXNAlwaysWrapAtViewEdgeBit = 11 kTXNDrawGrowIconMask = 1L << kTXNDrawGrowIconBit kTXNShowWindowMask = 1L << kTXNShowWindowBit kTXNWantHScrollBarMask = 1L << kTXNWantHScrollBarBit kTXNWantVScrollBarMask = 1L << kTXNWantVScrollBarBit kTXNNoTSMEverMask = 1L << kTXNNoTSMEverBit kTXNReadOnlyMask = 1L << kTXNReadOnlyBit kTXNNoKeyboardSyncMask = 1L << kTXNNoKeyboardSyncBit kTXNNoSelectionMask = 1L << kTXNNoSelectionBit kTXNSaveStylesAsSTYLResourceMask = 1L << kTXNSaveStylesAsSTYLResourceBit kOutputTextInUnicodeEncodingMask = 1L << kOutputTextInUnicodeEncodingBit kTXNDoNotInstallDragProcsMask = 1L << kTXNDoNotInstallDragProcsBit kTXNAlwaysWrapAtViewEdgeMask = 1L << kTXNAlwaysWrapAtViewEdgeBit kTXNFontContinuousBit = 0 kTXNSizeContinuousBit = 1 kTXNStyleContinuousBit = 2 kTXNColorContinuousBit = 3 kTXNFontContinuousMask = 1L << kTXNFontContinuousBit kTXNSizeContinuousMask = 1L << kTXNSizeContinuousBit kTXNStyleContinuousMask = 1L << kTXNStyleContinuousBit kTXNColorContinuousMask = 1L << kTXNColorContinuousBit kTXNIgnoreCaseBit = 0 kTXNEntireWordBit = 1 kTXNUseEncodingWordRulesBit = 31 kTXNIgnoreCaseMask = 1L << kTXNIgnoreCaseBit kTXNEntireWordMask = 1L << kTXNEntireWordBit kTXNUseEncodingWordRulesMask = 1L << kTXNUseEncodingWordRulesBit kTXNTextensionFile = FOUR_CHAR_CODE('txtn') kTXNTextFile = FOUR_CHAR_CODE('TEXT') kTXNPictureFile = FOUR_CHAR_CODE('PICT') kTXNMovieFile = MovieFileType kTXNSoundFile = FOUR_CHAR_CODE('sfil') kTXNAIFFFile = FOUR_CHAR_CODE('AIFF') kTXNTextEditStyleFrameType = 1 kTXNPageFrameType = 2 kTXNMultipleFrameType = 3 kTXNTextData = FOUR_CHAR_CODE('TEXT') kTXNPictureData = FOUR_CHAR_CODE('PICT') kTXNMovieData = FOUR_CHAR_CODE('moov') kTXNSoundData = FOUR_CHAR_CODE('snd ') kTXNUnicodeTextData = FOUR_CHAR_CODE('utxt') kTXNLineDirectionTag = FOUR_CHAR_CODE('lndr') kTXNJustificationTag = FOUR_CHAR_CODE('just') kTXNIOPrivilegesTag = FOUR_CHAR_CODE('iopv') kTXNSelectionStateTag = FOUR_CHAR_CODE('slst') kTXNInlineStateTag = FOUR_CHAR_CODE('inst') kTXNWordWrapStateTag = FOUR_CHAR_CODE('wwrs') kTXNKeyboardSyncStateTag = FOUR_CHAR_CODE('kbsy') kTXNAutoIndentStateTag = FOUR_CHAR_CODE('auin') kTXNTabSettingsTag = FOUR_CHAR_CODE('tabs') kTXNRefConTag = FOUR_CHAR_CODE('rfcn') kTXNMarginsTag = FOUR_CHAR_CODE('marg') kTXNNoUserIOTag = FOUR_CHAR_CODE('nuio') kTXNTypingAction = 0 kTXNCutAction = 1 kTXNPasteAction = 2 kTXNClearAction = 3 kTXNChangeFontAction = 4 kTXNChangeFontColorAction = 5 kTXNChangeFontSizeAction = 6 kTXNChangeStyleAction = 7 kTXNAlignLeftAction = 8 kTXNAlignCenterAction = 9 kTXNAlignRightAction = 10 kTXNDropAction = 11 kTXNMoveAction = 12 kTXNFontFeatureAction = 13 kTXNFontVariationAction = 14 kTXNUndoLastAction = 1024 # kTXNClearThisControl = (long)0xFFFFFFFF # kTXNClearTheseFontFeatures = (long)0x80000000 kTXNReadWrite = false kTXNReadOnly = true kTXNSelectionOn = true kTXNSelectionOff = false kTXNUseInline = false kTXNUseBottomline = true kTXNAutoWrap = false kTXNNoAutoWrap = true kTXNSyncKeyboard = false kTXNNoSyncKeyboard = true kTXNAutoIndentOff = false kTXNAutoIndentOn = true kTXNRightTab = -1 kTXNLeftTab = 0 kTXNCenterTab = 1 kTXNLeftToRight = 0 kTXNRightToLeft = 1 kTXNFlushDefault = 0 kTXNFlushLeft = 1 kTXNFlushRight = 2 kTXNCenter = 4 kTXNFullJust = 8 kTXNForceFullJust = 16 kScrollBarsAlwaysActive = true kScrollBarsSyncWithFocus = false # kTXNDontCareTypeSize = (long)0xFFFFFFFF kTXNDontCareTypeStyle = 0xFF kTXNIncrementTypeSize = 0x00000001 # kTXNDecrementTypeSize = (long)0x80000000 # kTXNUseCurrentSelection = 0xFFFFFFFFUL # kTXNStartOffset = 0UL # kTXNEndOffset = 0x7FFFFFFFUL kTXNSingleStylePerTextDocumentResType = FOUR_CHAR_CODE('MPSR') kTXNMultipleStylesPerTextDocumentResType = FOUR_CHAR_CODE('styl') kTXNShowStart = false kTXNShowEnd = true kTXNQDFontNameAttribute = FOUR_CHAR_CODE('fntn') kTXNQDFontFamilyIDAttribute = FOUR_CHAR_CODE('font') kTXNQDFontSizeAttribute = FOUR_CHAR_CODE('size') kTXNQDFontStyleAttribute = FOUR_CHAR_CODE('face') kTXNQDFontColorAttribute = FOUR_CHAR_CODE('klor') kTXNTextEncodingAttribute = FOUR_CHAR_CODE('encd') kTXNATSUIFontFeaturesAttribute = FOUR_CHAR_CODE('atfe') kTXNATSUIFontVariationsAttribute = FOUR_CHAR_CODE('atva') # kTXNQDFontNameAttributeSize = sizeof(Str255) # kTXNQDFontFamilyIDAttributeSize = sizeof(SInt16) # kTXNQDFontSizeAttributeSize = sizeof(SInt16) # kTXNQDFontStyleAttributeSize = sizeof(Style) # kTXNQDFontColorAttributeSize = sizeof(RGBColor) # kTXNTextEncodingAttributeSize = sizeof(TextEncoding) kTXNSystemDefaultEncoding = 0 kTXNMacOSEncoding = 1 kTXNUnicodeEncoding = 2 kTXNBackgroundTypeRGB = 1 # status = TXNInitTextension( &defaults # justification = LMTESysJust From jackjansen@users.sourceforge.net Sat Jul 14 15:00:43 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 14 Jul 2001 07:00:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/mlte Mltemodule.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/mlte In directory usw-pr-cvs1:/tmp/cvs-serv18088/Python/Mac/Modules/mlte Modified Files: Mltemodule.c Log Message: Various small fixes. The demo now starts to limp along. Index: Mltemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/mlte/Mltemodule.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** Mltemodule.c 2001/07/13 22:27:07 1.2 --- Mltemodule.c 2001/07/14 14:00:41 1.3 *************** *** 192,196 **** PyMac_PRECHECK(TXNAdjustCursor); if (!PyArg_ParseTuple(_args, "O&", ! ResObj_Convert, &ioCursorRgn)) return NULL; TXNAdjustCursor(_self->ob_itself, --- 192,196 ---- PyMac_PRECHECK(TXNAdjustCursor); if (!PyArg_ParseTuple(_args, "O&", ! OptResObj_Convert, &ioCursorRgn)) return NULL; TXNAdjustCursor(_self->ob_itself, From jackjansen@users.sourceforge.net Sat Jul 14 15:00:48 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 14 Jul 2001 07:00:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/mlte mltescan.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/mlte In directory usw-pr-cvs1:/tmp/cvs-serv18126/Python/Mac/Modules/mlte Modified Files: mltescan.py Log Message: Various small fixes. The demo now starts to limp along. Index: mltescan.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/mlte/mltescan.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** mltescan.py 2001/07/13 22:27:14 1.2 --- mltescan.py 2001/07/14 14:00:45 1.3 *************** *** 38,42 **** def writeinitialdefs(self): ! self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n") def makeblacklistnames(self): --- 38,54 ---- def writeinitialdefs(self): ! self.defsfile.write(""" ! def FOUR_CHAR_CODE(x): return x ! false = 0 ! true = 1 ! kTXNClearThisControl = 0xFFFFFFFF ! kTXNClearTheseFontFeatures = 0x80000000 ! kTXNDontCareTypeSize = 0xFFFFFFFF ! kTXNDecrementTypeSize = 0x80000000 ! kTXNUseCurrentSelection = 0xFFFFFFFF ! kTXNStartOffset = 0 ! kTXNEndOffset = 0x7FFFFFFF ! MovieFileType = FOUR_CHAR_CODE('moov') ! """) def makeblacklistnames(self): *************** *** 45,48 **** --- 57,77 ---- "TXNSetFontDefaults", # Arg is too difficult "TXNInitTextension", # done manually + + # Constants with funny definitions + "kTXNClearThisControl", + "kTXNClearTheseFontFeatures", + "kTXNDontCareTypeSize", + "kTXNDecrementTypeSize", + "kTXNUseCurrentSelection", + "kTXNStartOffset", + "kTXNEndOffset", + "kTXNQDFontNameAttributeSize", + "kTXNQDFontFamilyIDAttributeSize", + "kTXNQDFontSizeAttributeSize", + "kTXNQDFontStyleAttributeSize", + "kTXNQDFontColorAttributeSize", + "kTXNTextEncodingAttributeSize", + "status", + "justification", ] *************** *** 85,88 **** --- 114,121 ---- ([("void", "*", "OutMode"), ("ByteCount", "*", "InMode")], [("MlteInBuffer", "*", "InMode")]), + + # The AdjustCursor region handle is optional + ([("RgnHandle", "ioCursorRgn", "InMode")], + [("OptRgnHandle", "*", "*")]) ] From jackjansen@users.sourceforge.net Sat Jul 14 15:00:52 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 14 Jul 2001 07:00:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/mlte mltesupport.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/mlte In directory usw-pr-cvs1:/tmp/cvs-serv18153/Python/Mac/Modules/mlte Modified Files: mltesupport.py Log Message: Various small fixes. The demo now starts to limp along. Index: mltesupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/mlte/mltesupport.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** mltesupport.py 2001/07/13 22:27:20 1.2 --- mltesupport.py 2001/07/14 14:00:50 1.3 *************** *** 108,111 **** --- 108,112 ---- DragTrackingMessage = Type("DragTrackingMessage", "h") RgnHandle = OpaqueByValueType("RgnHandle", "ResObj") + OptRgnHandle = OpaqueByValueType("RgnHandle", "OptResObj") GWorldPtr = OpaqueByValueType("GWorldPtr", "GWorldObj") MlteInBuffer = VarInputBufferType('void *', 'ByteCount', 'l') From jackjansen@users.sourceforge.net Sat Jul 14 15:01:21 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 14 Jul 2001 07:01:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Demo/mlte - New directory Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Demo/mlte In directory usw-pr-cvs1:/tmp/cvs-serv18322/mlte Log Message: Directory /cvsroot/python/python/dist/src/Mac/Demo/mlte added to the repository From jackjansen@users.sourceforge.net Sat Jul 14 15:02:23 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 14 Jul 2001 07:02:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Demo/mlte mlted.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Demo/mlte In directory usw-pr-cvs1:/tmp/cvs-serv18647/Python/Mac/Demo/mlte Added Files: mlted.py Log Message: Minimal text editor using MLTE (code based on wed.py, the waste demo). It's sort-of starting to work, but there's still problems with redraws and with resizing the window. --- NEW FILE: mlted.py --- # A minimal text editor using MLTE. Based on wed.py. # # To be done: # - Functionality: find, etc. from Menu import DrawMenuBar from FrameWork import * import Win import Qd import Res import Scrap import os import macfs import MacTextEditor import Mlte UNDOLABELS = [ # Indexed by MLTECanUndo() value "Typing", "Cut", "Paste", "Clear", "Font Change", "Color Change", "Size Change", "Style Change", "Align Left", "Align Center", "Align Right", "Drop", "Move"] class WasteWindow(Window): def open(self, path, name, data): self.path = path self.name = name r = windowbounds(400, 400) w = Win.NewWindow(r, name, 1, 0, -1, 1, 0x55555555) self.wid = w ## vr = 0, 0, r[2]-r[0]-15, r[3]-r[1]-15 ## dr = (0, 0, 10240, 0) ## Qd.SetPort(w) ## Qd.TextFont(4) ## Qd.TextSize(9) ## self.ted = waste.WENew(dr, vr, flags) flags = MacTextEditor.kTXNDrawGrowIconMask|MacTextEditor.kTXNShowWindowMask|MacTextEditor.kTXNWantHScrollBarMask| \ MacTextEditor.kTXNWantVScrollBarMask self.ted, self.frameid = Mlte.TXNNewObject(None, w, None, flags, MacTextEditor.kTXNTextEditStyleFrameType, MacTextEditor.kTXNTextFile, MacTextEditor.kTXNMacOSEncoding) ## self.tedtexthandle = Res.Resource(data) ## self.ted.WEUseText(self.tedtexthandle) self.ted.TXNSetData(MacTextEditor.kTXNTextData, data, 0, 0x7fffffff) ## self.ted.WECalText() ## w.DrawGrowIcon() ## self.scrollbars() self.changed = 0 self.do_postopen() self.do_activate(1, None) def do_idle(self, event): ## (what, message, when, where, modifiers) = event ## Qd.SetPort(self.wid) self.ted.TXNIdle() self.ted.TXNAdjustCursor(None) ## def getscrollbarvalues(self): ## dr = self.ted.WEGetDestRect() ## vr = self.ted.WEGetViewRect() ## vx = self.scalebarvalue(dr[0], dr[2], vr[0], vr[2]) ## vy = self.scalebarvalue(dr[1], dr[3], vr[1], vr[3]) #### print dr, vr, vx, vy ## return vx, vy ## ## def scrollbar_callback(self, which, what, value): ## if which == 'y': ## if what == 'set': ## height = self.ted.WEGetHeight(0, 0x3fffffff) ## cur = self.getscrollbarvalues()[1] ## delta = (cur-value)*height/32767 ## if what == '-': ## topline_off,dummy = self.ted.WEGetOffset((1,1)) ## topline_num = self.ted.WEOffsetToLine(topline_off) ## delta = self.ted.WEGetHeight(topline_num, topline_num+1) ## elif what == '--': ## delta = (self.ted.WEGetViewRect()[3]-10) ## if delta <= 0: ## delta = 10 # Random value ## elif what == '+': ## # XXXX Wrong: should be bottom line size ## topline_off,dummy = self.ted.WEGetOffset((1,1)) ## topline_num = self.ted.WEOffsetToLine(topline_off) ## delta = -self.ted.WEGetHeight(topline_num, topline_num+1) ## elif what == '++': ## delta = -(self.ted.WEGetViewRect()[3]-10) ## if delta >= 0: ## delta = -10 ## self.ted.WEScroll(0, delta) #### print 'SCROLL Y', delta ## else: ## if what == 'set': ## return # XXXX ## vr = self.ted.WEGetViewRect() ## winwidth = vr[2]-vr[0] ## if what == '-': ## delta = winwidth/10 ## elif what == '--': ## delta = winwidth/2 ## elif what == '+': ## delta = -winwidth/10 ## elif what == '++': ## delta = -winwidth/2 ## self.ted.WEScroll(delta, 0) ## # Pin the scroll ## l, t, r, b = self.ted.WEGetDestRect() ## vl, vt, vr, vb = self.ted.WEGetViewRect() ## if t > 0 or l > 0: ## dx = dy = 0 ## if t > 0: dy = -t ## if l > 0: dx = -l #### print 'Extra scroll', dx, dy ## self.ted.WEScroll(dx, dy) ## elif b < vb: #### print 'Extra downscroll', b-vb ## self.ted.WEScroll(0, b-vb) def do_activate(self, onoff, evt): ## print "ACTIVATE", onoff Qd.SetPort(self.wid) Window.do_activate(self, onoff, evt) if onoff: self.ted.TXNFocus(1) self.parent.active = self self.parent.updatemenubar() else: self.ted.TXNFocus(0) def do_update(self, wid, event): Qd.SetPort(self.wid) ## region = wid.GetWindowPort().visRgn ## if Qd.EmptyRgn(region): ## return ## Qd.EraseRgn(region) self.ted.TXNUpdate() ## self.updatescrollbars() ## def do_postresize(self, width, height, window): ## l, t, r, b = self.ted.WEGetViewRect() ## vr = (l, t, l+width-15, t+height-15) ## self.ted.WESetViewRect(vr) ## self.wid.InvalWindowRect(vr) ## ScrolledWindow.do_postresize(self, width, height, window) def do_contentclick(self, local, modifiers, evt): ## (what, message, when, where, modifiers) = evt self.ted.TXNClick(evt) ## self.updatescrollbars() self.parent.updatemenubar() def do_char(self, ch, event): self.ted.TXNKeyDown(event) ## self.ted.WESelView() ## (what, message, when, where, modifiers) = event ## self.ted.WEKey(ord(ch), modifiers) ## self.changed = 1 ## self.updatescrollbars() ## self.parent.updatemenubar() def close(self): if self.changed: save = EasyDialogs.AskYesNoCancel('Save window "%s" before closing?'%self.name, 1) if save > 0: self.menu_save() elif save < 0: return if self.parent.active == self: self.parent.active = None ## self.parent.updatemenubar() del self.ted ## del self.tedtexthandle self.do_postclose() def menu_save(self): if not self.path: self.menu_save_as() return # Will call us recursively print 'Saving to ', self.path dhandle = self.ted.TXNGetData(0, 0x7fffffff) data = dhandle.data fp = open(self.path, 'wb') # NOTE: wb, because data has CR for end-of-line fp.write(data) if data[-1] <> '\r': fp.write('\r') fp.close() self.changed = 0 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) self.menu_save() def menu_cut(self): ## self.ted.WESelView() self.ted.TXNCut() ### Mlte.ConvertToPublicScrap() ## Scrap.ZeroScrap() ## self.ted.WECut() ## self.updatescrollbars() self.parent.updatemenubar() self.changed = 1 def menu_copy(self): ## Scrap.ZeroScrap() self.ted.TXNCopy() ### Mlte.ConvertToPublicScrap() ## self.updatescrollbars() self.parent.updatemenubar() def menu_paste(self): ### Mlte.ConvertFromPublicScrap() self.ted.TXNPaste() ## self.updatescrollbars() self.parent.updatemenubar() self.changed = 1 def menu_clear(self): ## self.ted.WESelView() self.ted.TXNClear() ## self.updatescrollbars() self.parent.updatemenubar() self.changed = 1 def menu_undo(self): self.ted.TXNUndo() ## self.updatescrollbars() self.parent.updatemenubar() def menu_redo(self): self.ted.TXNRedo() ## self.updatescrollbars() self.parent.updatemenubar() def have_selection(self): start, stop = self.ted.TXNGetSelection() return start < stop def can_paste(self): return Mlte.TXNIsScrapPastable() def can_undo(self): can, which = self.ted.TXNCanUndo() if not can: return None if which >= len(UNDOLABELS): # Unspecified undo return "Undo" which = UNDOLABELS[which] return "Undo "+which def can_redo(self): can, which = self.ted.TXNCanRedo() if not can: return None if which >= len(UNDOLABELS): # Unspecified undo return "Redo" which = UNDOLABELS[which] return "Redo "+which class Mlted(Application): def __init__(self): Application.__init__(self) self.num = 0 self.active = None self.updatemenubar() def makeusermenus(self): self.filemenu = m = Menu(self.menubar, "File") self.newitem = MenuItem(m, "New window", "N", self.open) self.openitem = MenuItem(m, "Open...", "O", self.openfile) self.closeitem = MenuItem(m, "Close", "W", self.closewin) m.addseparator() self.saveitem = MenuItem(m, "Save", "S", self.save) self.saveasitem = MenuItem(m, "Save as...", "", self.saveas) m.addseparator() self.quititem = MenuItem(m, "Quit", "Q", self.quit) self.editmenu = m = Menu(self.menubar, "Edit") self.undoitem = MenuItem(m, "Undo", "Z", self.undo) self.redoitem = MenuItem(m, "Undo", None, self.redo) self.cutitem = MenuItem(m, "Cut", "X", self.cut) self.copyitem = MenuItem(m, "Copy", "C", self.copy) self.pasteitem = MenuItem(m, "Paste", "V", self.paste) self.clearitem = MenuItem(m, "Clear", "", self.clear) # Groups of items enabled together: self.windowgroup = [self.closeitem, self.saveitem, self.saveasitem, self.editmenu] self.focusgroup = [self.cutitem, self.copyitem, self.clearitem] self.windowgroup_on = -1 self.focusgroup_on = -1 self.pastegroup_on = -1 self.undo_label = "never" self.redo_label = "never" def updatemenubar(self): changed = 0 on = (self.active <> None) if on <> self.windowgroup_on: for m in self.windowgroup: m.enable(on) self.windowgroup_on = on changed = 1 if on: # only if we have an edit menu on = self.active.have_selection() if on <> self.focusgroup_on: for m in self.focusgroup: m.enable(on) self.focusgroup_on = on changed = 1 on = self.active.can_paste() if on <> self.pastegroup_on: self.pasteitem.enable(on) self.pastegroup_on = on changed = 1 on = self.active.can_undo() if on <> self.undo_label: if on: self.undoitem.enable(1) self.undoitem.settext(on) self.undo_label = on else: self.undoitem.settext("Nothing to undo") self.undoitem.enable(0) changed = 1 on = self.active.can_redo() if on <> self.redo_label: if on: self.redoitem.enable(1) self.redoitem.settext(on) self.redo_label = on else: self.redoitem.settext("Nothing to redo") self.redoitem.enable(0) changed = 1 if changed: DrawMenuBar() # # Apple menu # def do_about(self, id, item, window, event): EasyDialogs.Message("A simple single-font text editor based on MacTextEditor") # # File menu # def open(self, *args): self._open(0) def openfile(self, *args): self._open(1) 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: fp = open(path, 'rb') # NOTE binary, we need cr as end-of-line data = fp.read() fp.close() except IOError, arg: EasyDialogs.Message("IOERROR: "+`arg`) return else: path = None name = "Untitled %d"%self.num data = '' w = WasteWindow(self) w.open(path, name, data) self.num = self.num + 1 def closewin(self, *args): if self.active: self.active.close() else: EasyDialogs.Message("No active window?") def save(self, *args): if self.active: self.active.menu_save() else: EasyDialogs.Message("No active window?") def saveas(self, *args): if self.active: self.active.menu_save_as() else: EasyDialogs.Message("No active window?") def quit(self, *args): for w in self._windows.values(): w.close() if self._windows: return self._quit() # # Edit menu # def undo(self, *args): if self.active: self.active.menu_undo() else: EasyDialogs.Message("No active window?") def redo(self, *args): if self.active: self.active.menu_redo() else: EasyDialogs.Message("No active window?") def cut(self, *args): if self.active: self.active.menu_cut() else: EasyDialogs.Message("No active window?") def copy(self, *args): if self.active: self.active.menu_copy() else: EasyDialogs.Message("No active window?") def paste(self, *args): if self.active: self.active.menu_paste() else: EasyDialogs.Message("No active window?") def clear(self, *args): if self.active: self.active.menu_clear() else: EasyDialogs.Message("No active window?") # # Other stuff # def idle(self, event): if self.active: self.active.do_idle(event) def main(): Mlte.TXNInitTextension(0) try: App = Mlted() App.mainloop() finally: Mlte.TXNTerminateTextension() if __name__ == '__main__': main() From lemburg@users.sourceforge.net Sat Jul 14 17:21:46 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Sat, 14 Jul 2001 09:21:46 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0248.txt,1.2,1.3 pep-0249.txt,1.3,1.4 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv9043 Modified Files: pep-0248.txt pep-0249.txt Log Message: Added Release-Date tags. Index: pep-0248.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0248.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** pep-0248.txt 2001/03/30 16:56:15 1.2 --- pep-0248.txt 2001/07/14 16:21:44 1.3 *************** *** 7,10 **** --- 7,11 ---- Replaced-By: 249 Type: Informational + Release-Date: 09 Apr 1996 Introduction Index: pep-0249.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0249.txt,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** pep-0249.txt 2001/04/27 11:20:14 1.3 --- pep-0249.txt 2001/07/14 16:21:44 1.4 *************** *** 7,10 **** --- 7,11 ---- Type: Informational Replaces: 248 + Release-Date: 07 Apr 1999 Introduction From gvanrossum@users.sourceforge.net Sat Jul 14 18:58:02 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 14 Jul 2001 10:58:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects object.c,2.132,2.133 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv23798 Modified Files: object.c Log Message: _Py_GetObjects(): GCC suggests to add () around && within || for some code only compiled in debug mode, and I dutifully comply. Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.132 retrieving revision 2.133 diff -C2 -r2.132 -r2.133 *** object.c 2001/06/09 07:34:05 2.132 --- object.c 2001/07/14 17:58:00 2.133 *************** *** 1411,1415 **** for (i = 0; (n == 0 || i < n) && op != &refchain; i++) { while (op == self || op == args || op == res || op == t || ! t != NULL && op->ob_type != (PyTypeObject *) t) { op = op->_ob_next; if (op == &refchain) --- 1411,1415 ---- for (i = 0; (n == 0 || i < n) && op != &refchain; i++) { while (op == self || op == args || op == res || op == t || ! (t != NULL && op->ob_type != (PyTypeObject *) t)) { op = op->_ob_next; if (op == &refchain) From akuchling@users.sourceforge.net Sat Jul 14 21:28:12 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Sat, 14 Jul 2001 13:28:12 -0700 Subject: [Python-checkins] CVS: python/dist/src setup.py,1.41,1.42 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv12399 Modified Files: setup.py Log Message: Fix bug #437487: "2.1 build on Solaris fails if CC is set" by adding the contents of CCSHARED to the compiler specified by CC Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -r1.41 -r1.42 *** setup.py 2001/05/21 20:48:09 1.41 --- setup.py 2001/07/14 20:28:10 1.42 *************** *** 117,121 **** # compilers if compiler is not None: ! args['compiler_so'] = compiler if linker_so is not None: args['linker_so'] = linker_so + ' -shared' --- 117,122 ---- # compilers if compiler is not None: ! (ccshared,) = sysconfig.get_config_vars('CCSHARED') ! args['compiler_so'] = compiler + ' ' + ccshared if linker_so is not None: args['linker_so'] = linker_so + ' -shared' From akuchling@users.sourceforge.net Sat Jul 14 21:38:32 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Sat, 14 Jul 2001 13:38:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _cursesmodule.c,2.52,2.53 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv13810 Modified Files: _cursesmodule.c Log Message: Fix bug #417212: "curses.newwin can return pads" by changing the Python newwin() wrapper to always return a window, and never a pad. This makes the code match the documentation. Index: _cursesmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_cursesmodule.c,v retrieving revision 2.52 retrieving revision 2.53 diff -C2 -r2.52 -r2.53 *** _cursesmodule.c 2001/06/23 19:58:46 2.52 --- _cursesmodule.c 2001/07/14 20:38:30 2.53 *************** *** 2052,2056 **** { WINDOW *win; ! int nlines, ncols, begin_y, begin_x; PyCursesInitialised --- 2052,2056 ---- { WINDOW *win; ! int nlines, ncols, begin_y=0, begin_x=0; PyCursesInitialised *************** *** 2060,2064 **** if (!PyArg_Parse(args,"(ii);nlines,ncols",&nlines,&ncols)) return NULL; - win = newpad(nlines, ncols); break; case 4: --- 2060,2063 ---- *************** *** 2066,2070 **** &nlines,&ncols,&begin_y,&begin_x)) return NULL; - win = newwin(nlines,ncols,begin_y,begin_x); break; default: --- 2065,2068 ---- *************** *** 2073,2076 **** --- 2071,2075 ---- } + win = newwin(nlines,ncols,begin_y,begin_x); if (win == NULL) { PyErr_SetString(PyCursesError, catchall_NULL); From akuchling@users.sourceforge.net Sat Jul 14 21:54:39 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Sat, 14 Jul 2001 13:54:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules selectmodule.c,2.51,2.52 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv17054 Modified Files: selectmodule.c Log Message: [Bug #438050] Include sys/poll.h if it was found by the configure script. The OpenGroup spec says poll.h is the correct header file to use, so that file is preferred. Index: selectmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/selectmodule.c,v retrieving revision 2.51 retrieving revision 2.52 diff -C2 -r2.51 -r2.52 *** selectmodule.c 2001/05/21 03:29:05 2.51 --- selectmodule.c 2001/07/14 20:54:37 2.52 *************** *** 22,27 **** #include #endif ! #ifdef HAVE_POLL_H #include #endif --- 22,29 ---- #include #endif ! #if defined(HAVE_POLL_H) #include + #elif defined(HAVE_SYS_POLL_H) + #include #endif From akuchling@users.sourceforge.net Sat Jul 14 21:55:55 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Sat, 14 Jul 2001 13:55:55 -0700 Subject: [Python-checkins] CVS: python/dist/src configure.in,1.227,1.228 config.h.in,2.100,2.101 configure,1.219,1.220 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv17434 Modified Files: configure.in config.h.in configure Log Message: [Bug #438050] Check for sys/poll.h in configure script Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.227 retrieving revision 1.228 diff -C2 -r1.227 -r1.228 *** configure.in 2001/07/11 22:35:31 1.227 --- configure.in 2001/07/14 20:55:52 1.228 *************** *** 544,548 **** 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/modem.h db_185.h db.h \ ! sys/param.h sys/select.h sys/socket.h sys/time.h sys/times.h \ sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ ndbm.h db1/ndbm.h gdbm/ndbm.h sys/resource.h) --- 544,548 ---- 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/modem.h db_185.h db.h \ ! sys/param.h sys/poll.h sys/select.h sys/socket.h sys/time.h sys/times.h \ sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ ndbm.h db1/ndbm.h gdbm/ndbm.h sys/resource.h) Index: config.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/config.h.in,v retrieving revision 2.100 retrieving revision 2.101 diff -C2 -r2.100 -r2.101 *** config.h.in 2001/07/11 22:35:31 2.100 --- config.h.in 2001/07/14 20:55:52 2.101 *************** *** 1,3 **** ! /* config.h.in. Generated automatically from configure.in by autoheader 2.13. */ /* Define if on AIX 3. --- 1,3 ---- ! /* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define if on AIX 3. *************** *** 644,647 **** --- 644,650 ---- /* Define if you have the header file. */ #undef HAVE_SYS_PARAM_H + + /* Define if you have the header file. */ + #undef HAVE_SYS_POLL_H /* Define if you have the header file. */ Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.219 retrieving revision 1.220 diff -C2 -r1.219 -r1.220 *** configure 2001/07/11 22:35:31 1.219 --- configure 2001/07/14 20:55:52 1.220 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.226 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.227 [...3466 lines suppressed...] if eval "test \"`echo '$''{'ac_cv_type_socklen_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < *************** *** 6984,6988 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6987: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then --- 6973,6977 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6976: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then From tim_one@users.sourceforge.net Sun Jul 15 07:10:36 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 23:10:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/plat-aix3 FCNTL.py,1.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-aix3 In directory usw-pr-cvs1:/tmp/cvs-serv19323/descr/dist/src/Lib/plat-aix3 Removed Files: Tag: descr-branch FCNTL.py Log Message: Removing obsolete files. --- FCNTL.py DELETED --- From tim_one@users.sourceforge.net Sun Jul 15 07:10:36 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 23:10:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/plat-linux1 FCNTL.py,1.2,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-linux1 In directory usw-pr-cvs1:/tmp/cvs-serv19323/descr/dist/src/Lib/plat-linux1 Removed Files: Tag: descr-branch FCNTL.py Log Message: Removing obsolete files. --- FCNTL.py DELETED --- From tim_one@users.sourceforge.net Sun Jul 15 07:10:36 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 23:10:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/plat-beos5 FCNTL.py,1.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-beos5 In directory usw-pr-cvs1:/tmp/cvs-serv19323/descr/dist/src/Lib/plat-beos5 Removed Files: Tag: descr-branch FCNTL.py Log Message: Removing obsolete files. --- FCNTL.py DELETED --- From tim_one@users.sourceforge.net Sun Jul 15 07:10:36 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 23:10:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/plat-freebsd3 FCNTL.py,1.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-freebsd3 In directory usw-pr-cvs1:/tmp/cvs-serv19323/descr/dist/src/Lib/plat-freebsd3 Removed Files: Tag: descr-branch FCNTL.py Log Message: Removing obsolete files. --- FCNTL.py DELETED --- From tim_one@users.sourceforge.net Sun Jul 15 07:10:36 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 23:10:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/plat-aix4 FCNTL.py,1.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-aix4 In directory usw-pr-cvs1:/tmp/cvs-serv19323/descr/dist/src/Lib/plat-aix4 Removed Files: Tag: descr-branch FCNTL.py Log Message: Removing obsolete files. --- FCNTL.py DELETED --- From tim_one@users.sourceforge.net Sun Jul 15 07:10:36 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 23:10:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/plat-freebsd5 FCNTL.py,1.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-freebsd5 In directory usw-pr-cvs1:/tmp/cvs-serv19323/descr/dist/src/Lib/plat-freebsd5 Removed Files: Tag: descr-branch FCNTL.py Log Message: Removing obsolete files. --- FCNTL.py DELETED --- From tim_one@users.sourceforge.net Sun Jul 15 07:10:36 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 23:10:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/plat-freebsd2 FCNTL.py,1.2,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-freebsd2 In directory usw-pr-cvs1:/tmp/cvs-serv19323/descr/dist/src/Lib/plat-freebsd2 Removed Files: Tag: descr-branch FCNTL.py Log Message: Removing obsolete files. --- FCNTL.py DELETED --- From tim_one@users.sourceforge.net Sun Jul 15 07:10:36 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 23:10:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/plat-netbsd1 FCNTL.py,1.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-netbsd1 In directory usw-pr-cvs1:/tmp/cvs-serv19323/descr/dist/src/Lib/plat-netbsd1 Removed Files: Tag: descr-branch FCNTL.py Log Message: Removing obsolete files. --- FCNTL.py DELETED --- From tim_one@users.sourceforge.net Sun Jul 15 07:10:36 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 23:10:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/plat-irix6 FCNTL.py,1.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-irix6 In directory usw-pr-cvs1:/tmp/cvs-serv19323/descr/dist/src/Lib/plat-irix6 Removed Files: Tag: descr-branch FCNTL.py Log Message: Removing obsolete files. --- FCNTL.py DELETED --- From tim_one@users.sourceforge.net Sun Jul 15 07:10:36 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 23:10:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/plat-freebsd4 FCNTL.py,1.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-freebsd4 In directory usw-pr-cvs1:/tmp/cvs-serv19323/descr/dist/src/Lib/plat-freebsd4 Removed Files: Tag: descr-branch FCNTL.py Log Message: Removing obsolete files. --- FCNTL.py DELETED --- From tim_one@users.sourceforge.net Sun Jul 15 07:10:36 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 23:10:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/plat-irix5 FCNTL.py,1.3,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-irix5 In directory usw-pr-cvs1:/tmp/cvs-serv19323/descr/dist/src/Lib/plat-irix5 Removed Files: Tag: descr-branch FCNTL.py Log Message: Removing obsolete files. --- FCNTL.py DELETED --- From tim_one@users.sourceforge.net Sun Jul 15 07:10:36 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 23:10:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/plat-linux2 FCNTL.py,1.2,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-linux2 In directory usw-pr-cvs1:/tmp/cvs-serv19323/descr/dist/src/Lib/plat-linux2 Removed Files: Tag: descr-branch FCNTL.py Log Message: Removing obsolete files. --- FCNTL.py DELETED --- From tim_one@users.sourceforge.net Sun Jul 15 07:10:36 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 23:10:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/plat-sunos4 FCNTL.py,1.2,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-sunos4 In directory usw-pr-cvs1:/tmp/cvs-serv19323/descr/dist/src/Lib/plat-sunos4 Removed Files: Tag: descr-branch FCNTL.py Log Message: Removing obsolete files. --- FCNTL.py DELETED --- From tim_one@users.sourceforge.net Sun Jul 15 07:10:36 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 23:10:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/plat-sunos5 FCNTL.py,1.2,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-sunos5 In directory usw-pr-cvs1:/tmp/cvs-serv19323/descr/dist/src/Lib/plat-sunos5 Removed Files: Tag: descr-branch FCNTL.py Log Message: Removing obsolete files. --- FCNTL.py DELETED --- From tim_one@users.sourceforge.net Sun Jul 15 07:10:36 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 14 Jul 2001 23:10:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/plat-unixware7 FCNTL.py,1.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-unixware7 In directory usw-pr-cvs1:/tmp/cvs-serv19323/descr/dist/src/Lib/plat-unixware7 Removed Files: Tag: descr-branch FCNTL.py Log Message: Removing obsolete files. --- FCNTL.py DELETED --- From tim_one@users.sourceforge.net Sun Jul 15 10:11:16 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 15 Jul 2001 02:11:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.87,1.88 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv6358/python/dist/src/Objects Modified Files: longobject.c Log Message: long_format: Simplify the overly elaborate base-is-a-power-of-2 code. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.87 retrieving revision 1.88 diff -C2 -r1.87 -r1.88 *** longobject.c 2001/07/14 12:23:19 1.87 --- longobject.c 2001/07/15 09:11:14 1.88 *************** *** 793,828 **** else if ((base & (base - 1)) == 0) { /* JRH: special case for power-of-2 bases */ ! twodigits temp = a->ob_digit[0]; ! int bitsleft = SHIFT; ! int rem; ! int last = size_a; ! int basebits = 1; i = base; while ((i >>= 1) > 1) ++basebits; ! ! i = 0; ! for (;;) { ! while (bitsleft >= basebits) { ! if ((temp == 0) && (i >= last - 1)) break; ! rem = temp & (base - 1); ! if (rem < 10) ! rem += '0'; ! else ! rem += 'A' - 10; assert(p > PyString_AS_STRING(str)); ! *--p = (char) rem; ! bitsleft -= basebits; ! temp >>= basebits; ! } ! if (++i >= last) { ! if (temp == 0) break; ! bitsleft = 99; ! /* loop again to pick up final digits */ ! } ! else { ! temp = (a->ob_digit[i] << bitsleft) | temp; ! bitsleft += SHIFT; ! } } } --- 793,816 ---- else if ((base & (base - 1)) == 0) { /* JRH: special case for power-of-2 bases */ ! twodigits accum = 0; ! int accumbits = 0; /* # of bits in accum */ ! int basebits = 1; /* # of bits in base-1 */ i = base; while ((i >>= 1) > 1) ++basebits; ! ! for (i = 0; i < size_a; ++i) { ! accum |= a->ob_digit[i] << accumbits; ! accumbits += SHIFT; ! assert(accumbits >= basebits); ! do { ! char digit = (char)(accum & (base - 1)); ! digit += (digit < 10) ? '0' : 'A'-10; assert(p > PyString_AS_STRING(str)); ! *--p = digit; ! accumbits -= basebits; ! accum >>= basebits; ! } while (i < size_a-1 ? accumbits >= basebits : ! accum > 0); } } From gvanrossum@users.sourceforge.net Sun Jul 15 17:58:07 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 15 Jul 2001 09:58:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include Python.h,2.32,2.33 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv4740 Modified Files: Python.h Log Message: Define NDEBUG when Py_DEBUG undefined, to disable the assert macro. Index: Python.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/Python.h,v retrieving revision 2.32 retrieving revision 2.33 diff -C2 -r2.32 -r2.33 *** Python.h 2001/04/20 19:13:01 2.32 --- Python.h 2001/07/15 16:58:05 2.33 *************** *** 50,53 **** --- 50,57 ---- #include #endif + + #ifndef Py_DEBUG + #define NDEBUG 1 + #endif #include From tim_one@users.sourceforge.net Sun Jul 15 19:38:48 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 15 Jul 2001 11:38:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include Python.h,2.33,2.34 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv19539/Include Modified Files: Python.h Log Message: Python.h: Don't attempt to redefine NDEBUG if it's already defined. Others: Remove redundant includes of assert.h. Index: Python.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/Python.h,v retrieving revision 2.33 retrieving revision 2.34 diff -C2 -r2.33 -r2.34 *** Python.h 2001/07/15 16:58:05 2.33 --- Python.h 2001/07/15 18:38:46 2.34 *************** *** 52,56 **** --- 52,58 ---- #ifndef Py_DEBUG + #ifndef NDEBUG #define NDEBUG 1 + #endif #endif #include From tim_one@users.sourceforge.net Sun Jul 15 19:38:49 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 15 Jul 2001 11:38:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules mpzmodule.c,2.36,2.37 regexpr.c,1.34,1.35 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv19539/Modules Modified Files: mpzmodule.c regexpr.c Log Message: Python.h: Don't attempt to redefine NDEBUG if it's already defined. Others: Remove redundant includes of assert.h. Index: mpzmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/mpzmodule.c,v retrieving revision 2.36 retrieving revision 2.37 diff -C2 -r2.36 -r2.37 *** mpzmodule.c 2001/02/12 16:48:13 2.36 --- mpzmodule.c 2001/07/15 18:38:46 2.37 *************** *** 13,17 **** #include "Python.h" - #include #include /* For size_t */ --- 13,16 ---- Index: regexpr.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/regexpr.c,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -r1.34 -r1.35 *** regexpr.c 2001/07/03 19:27:05 1.34 --- regexpr.c 2001/07/15 18:38:46 1.35 *************** *** 31,35 **** #include "Python.h" #include "regexpr.h" - #include /* The original code blithely assumed that sizeof(short) == 2. Not --- 31,34 ---- From tim_one@users.sourceforge.net Sun Jul 15 19:38:49 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 15 Jul 2001 11:38:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/PC import_nt.c,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/PC In directory usw-pr-cvs1:/tmp/cvs-serv19539/PC Modified Files: import_nt.c Log Message: Python.h: Don't attempt to redefine NDEBUG if it's already defined. Others: Remove redundant includes of assert.h. Index: import_nt.c =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/import_nt.c,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -r1.14 -r1.15 *** import_nt.c 2000/08/22 11:20:21 1.14 --- import_nt.c 2001/07/15 18:38:47 1.15 *************** *** 9,13 **** #include "Python.h" #include "osdefs.h" - #include #include #include "importdl.h" --- 9,12 ---- From tim_one@users.sourceforge.net Sun Jul 15 19:38:49 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 15 Jul 2001 11:38:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.88,1.89 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv19539/Objects Modified Files: longobject.c Log Message: Python.h: Don't attempt to redefine NDEBUG if it's already defined. Others: Remove redundant includes of assert.h. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.88 retrieving revision 1.89 diff -C2 -r1.88 -r1.89 *** longobject.c 2001/07/15 09:11:14 1.88 --- longobject.c 2001/07/15 18:38:47 1.89 *************** *** 7,11 **** #include "longintrepr.h" - #include #include --- 7,10 ---- From tim_one@users.sourceforge.net Sun Jul 15 20:42:05 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 15 Jul 2001 12:42:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules pcremodule.c,2.26,2.27 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv29534 Modified Files: pcremodule.c Log Message: Remove redundant include of assert.h. Index: pcremodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/pcremodule.c,v retrieving revision 2.26 retrieving revision 2.27 diff -C2 -r2.26 -r2.27 *** pcremodule.c 2001/06/18 19:04:04 2.26 --- pcremodule.c 2001/07/15 19:42:03 2.27 *************** *** 3,7 **** #include "Python.h" - #include #ifndef Py_eval_input /* For Python 1.4, graminit.h has to be explicitly included */ --- 3,6 ---- From tim_one@users.sourceforge.net Sun Jul 15 21:26:57 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 15 Jul 2001 13:26:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include Python.h,2.32.2.1,2.32.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv4678/descr/dist/src/Include Modified Files: Tag: descr-branch Python.h Log Message: Merge trunk tag delta date2001-07-13 to date2001-07-15. Index: Python.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/Python.h,v retrieving revision 2.32.2.1 retrieving revision 2.32.2.2 diff -C2 -r2.32.2.1 -r2.32.2.2 *** Python.h 2001/04/24 00:49:08 2.32.2.1 --- Python.h 2001/07/15 20:26:55 2.32.2.2 *************** *** 50,53 **** --- 50,59 ---- #include #endif + + #ifndef Py_DEBUG + #ifndef NDEBUG + #define NDEBUG 1 + #endif + #endif #include From tim_one@users.sourceforge.net Sun Jul 15 21:26:57 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 15 Jul 2001 13:26:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib sgmllib.py,1.30.4.1,1.30.4.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv4678/descr/dist/src/Lib Modified Files: Tag: descr-branch sgmllib.py Log Message: Merge trunk tag delta date2001-07-13 to date2001-07-15. Index: sgmllib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sgmllib.py,v retrieving revision 1.30.4.1 retrieving revision 1.30.4.2 diff -C2 -r1.30.4.1 -r1.30.4.2 *** sgmllib.py 2001/07/07 22:55:28 1.30.4.1 --- sgmllib.py 2001/07/15 20:26:55 1.30.4.2 *************** *** 37,41 **** tagfind = re.compile('[a-zA-Z][-_.a-zA-Z0-9]*') attrfind = re.compile( ! r'\s*([a-zA-Z_][-.a-zA-Z_0-9]*)(\s*=\s*' r'(\'[^\']*\'|"[^"]*"|[-a-zA-Z0-9./:;+*%?!&$\(\)_#=~\'"]*))?') --- 37,41 ---- tagfind = re.compile('[a-zA-Z][-_.a-zA-Z0-9]*') attrfind = re.compile( ! r'\s*([a-zA-Z_][-:.a-zA-Z_0-9]*)(\s*=\s*' r'(\'[^\']*\'|"[^"]*"|[-a-zA-Z0-9./:;+*%?!&$\(\)_#=~\'"]*))?') From tim_one@users.sourceforge.net Sun Jul 15 21:26:58 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 15 Jul 2001 13:26:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild BUILDno.txt,1.12.2.1,1.12.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv4678/descr/dist/src/PCbuild Modified Files: Tag: descr-branch BUILDno.txt Log Message: Merge trunk tag delta date2001-07-13 to date2001-07-15. Index: BUILDno.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/BUILDno.txt,v retrieving revision 1.12.2.1 retrieving revision 1.12.2.2 diff -C2 -r1.12.2.1 -r1.12.2.2 *** BUILDno.txt 2001/07/07 22:55:30 1.12.2.1 --- BUILDno.txt 2001/07/15 20:26:56 1.12.2.2 *************** *** 36,40 **** 20 2.1.1 TENTATIVE 20-Jul-2001 ! 19 2.1.1c1 TENTATIVE 13-Jul-2001 18 2.0.1 --- 36,40 ---- 20 2.1.1 TENTATIVE 20-Jul-2001 ! 19 2.1.1c1 13-Jul-2001 18 2.0.1 From tim_one@users.sourceforge.net Sun Jul 15 21:26:58 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 15 Jul 2001 13:26:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/PC import_nt.c,1.14,1.14.8.1 Message-ID: Update of /cvsroot/python/python/dist/src/PC In directory usw-pr-cvs1:/tmp/cvs-serv4678/descr/dist/src/PC Modified Files: Tag: descr-branch import_nt.c Log Message: Merge trunk tag delta date2001-07-13 to date2001-07-15. Index: import_nt.c =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/import_nt.c,v retrieving revision 1.14 retrieving revision 1.14.8.1 diff -C2 -r1.14 -r1.14.8.1 *** import_nt.c 2000/08/22 11:20:21 1.14 --- import_nt.c 2001/07/15 20:26:55 1.14.8.1 *************** *** 9,13 **** #include "Python.h" #include "osdefs.h" - #include #include #include "importdl.h" --- 9,12 ---- From tim_one@users.sourceforge.net Sun Jul 15 21:26:57 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 15 Jul 2001 13:26:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _cursesmodule.c,2.51.4.1,2.51.4.2 mpzmodule.c,2.36,2.36.6.1 pcremodule.c,2.25.8.1,2.25.8.2 regexpr.c,1.33.8.1,1.33.8.2 selectmodule.c,2.50.6.1,2.50.6.2 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv4678/descr/dist/src/Modules Modified Files: Tag: descr-branch _cursesmodule.c mpzmodule.c pcremodule.c regexpr.c selectmodule.c Log Message: Merge trunk tag delta date2001-07-13 to date2001-07-15. Index: _cursesmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_cursesmodule.c,v retrieving revision 2.51.4.1 retrieving revision 2.51.4.2 diff -C2 -r2.51.4.1 -r2.51.4.2 *** _cursesmodule.c 2001/07/07 22:55:29 2.51.4.1 --- _cursesmodule.c 2001/07/15 20:26:55 2.51.4.2 *************** *** 2052,2056 **** { WINDOW *win; ! int nlines, ncols, begin_y, begin_x; PyCursesInitialised --- 2052,2056 ---- { WINDOW *win; ! int nlines, ncols, begin_y=0, begin_x=0; PyCursesInitialised *************** *** 2060,2064 **** if (!PyArg_Parse(args,"(ii);nlines,ncols",&nlines,&ncols)) return NULL; - win = newpad(nlines, ncols); break; case 4: --- 2060,2063 ---- *************** *** 2066,2070 **** &nlines,&ncols,&begin_y,&begin_x)) return NULL; - win = newwin(nlines,ncols,begin_y,begin_x); break; default: --- 2065,2068 ---- *************** *** 2073,2076 **** --- 2071,2075 ---- } + win = newwin(nlines,ncols,begin_y,begin_x); if (win == NULL) { PyErr_SetString(PyCursesError, catchall_NULL); Index: mpzmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/mpzmodule.c,v retrieving revision 2.36 retrieving revision 2.36.6.1 diff -C2 -r2.36 -r2.36.6.1 *** mpzmodule.c 2001/02/12 16:48:13 2.36 --- mpzmodule.c 2001/07/15 20:26:55 2.36.6.1 *************** *** 13,17 **** #include "Python.h" - #include #include /* For size_t */ --- 13,16 ---- Index: pcremodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/pcremodule.c,v retrieving revision 2.25.8.1 retrieving revision 2.25.8.2 diff -C2 -r2.25.8.1 -r2.25.8.2 *** pcremodule.c 2001/07/07 22:55:29 2.25.8.1 --- pcremodule.c 2001/07/15 20:26:55 2.25.8.2 *************** *** 3,7 **** #include "Python.h" - #include #ifndef Py_eval_input /* For Python 1.4, graminit.h has to be explicitly included */ --- 3,6 ---- Index: regexpr.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/regexpr.c,v retrieving revision 1.33.8.1 retrieving revision 1.33.8.2 diff -C2 -r1.33.8.1 -r1.33.8.2 *** regexpr.c 2001/07/07 22:55:29 1.33.8.1 --- regexpr.c 2001/07/15 20:26:55 1.33.8.2 *************** *** 31,35 **** #include "Python.h" #include "regexpr.h" - #include /* The original code blithely assumed that sizeof(short) == 2. Not --- 31,34 ---- Index: selectmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/selectmodule.c,v retrieving revision 2.50.6.1 retrieving revision 2.50.6.2 diff -C2 -r2.50.6.1 -r2.50.6.2 *** selectmodule.c 2001/07/07 22:55:29 2.50.6.1 --- selectmodule.c 2001/07/15 20:26:55 2.50.6.2 *************** *** 22,27 **** #include #endif ! #ifdef HAVE_POLL_H #include #endif --- 22,29 ---- #include #endif ! #if defined(HAVE_POLL_H) #include + #elif defined(HAVE_SYS_POLL_H) + #include #endif From tim_one@users.sourceforge.net Sun Jul 15 21:26:58 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 15 Jul 2001 13:26:58 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.1.2.27,1.1.2.28 config.h.in,2.92.2.2,2.92.2.3 configure,1.209.2.2,1.209.2.3 configure.in,1.217.2.2,1.217.2.3 setup.py,1.38.4.1,1.38.4.2 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv4678/descr/dist/src Modified Files: Tag: descr-branch PLAN.txt config.h.in configure configure.in setup.py Log Message: Merge trunk tag delta date2001-07-13 to date2001-07-15. Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Attic/PLAN.txt,v retrieving revision 1.1.2.27 retrieving revision 1.1.2.28 diff -C2 -r1.1.2.27 -r1.1.2.28 *** PLAN.txt 2001/07/14 07:47:33 1.1.2.27 --- PLAN.txt 2001/07/15 20:26:55 1.1.2.28 *************** *** 269,272 **** --- 269,283 ---- ---------------------------------------------------------------------------- + 2001-07-15 + + Tagged trunk about 15:44 EDT, like so: + cvs tag date2001-07-15 python + + Merged trunk delta into branch via: + cvs -q -z3 up -j date2001-07-13 -j date2001-07-15 descr + + Four files with conflicts, all artificial RCS Id & Revision thingies. + Resolved and committed. + ---------------------------------------------------------------------------- 2001-07-13 Index: config.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/config.h.in,v retrieving revision 2.92.2.2 retrieving revision 2.92.2.3 diff -C2 -r2.92.2.2 -r2.92.2.3 *** config.h.in 2001/07/14 07:47:33 2.92.2.2 --- config.h.in 2001/07/15 20:26:55 2.92.2.3 *************** *** 1,3 **** ! /* config.h.in. Generated automatically from configure.in by autoheader 2.13. */ /* Define if on AIX 3. --- 1,3 ---- ! /* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define if on AIX 3. *************** *** 644,647 **** --- 644,650 ---- /* Define if you have the header file. */ #undef HAVE_SYS_PARAM_H + + /* Define if you have the header file. */ + #undef HAVE_SYS_POLL_H /* Define if you have the header file. */ Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.209.2.2 retrieving revision 1.209.2.3 diff -C2 -r1.209.2.2 -r1.209.2.3 *** configure 2001/07/14 07:47:33 1.209.2.2 --- configure 2001/07/15 20:26:55 1.209.2.3 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.226 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.227 [...3466 lines suppressed...] if eval "test \"`echo '$''{'ac_cv_type_socklen_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < *************** *** 6984,6988 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6987: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then --- 6973,6977 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6976: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.217.2.2 retrieving revision 1.217.2.3 diff -C2 -r1.217.2.2 -r1.217.2.3 *** configure.in 2001/07/14 07:47:34 1.217.2.2 --- configure.in 2001/07/15 20:26:55 1.217.2.3 *************** *** 544,548 **** 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/modem.h db_185.h db.h \ ! sys/param.h sys/select.h sys/socket.h sys/time.h sys/times.h \ sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ ndbm.h db1/ndbm.h gdbm/ndbm.h sys/resource.h) --- 544,548 ---- 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/modem.h db_185.h db.h \ ! sys/param.h sys/poll.h sys/select.h sys/socket.h sys/time.h sys/times.h \ sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ ndbm.h db1/ndbm.h gdbm/ndbm.h sys/resource.h) Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.38.4.1 retrieving revision 1.38.4.2 diff -C2 -r1.38.4.1 -r1.38.4.2 *** setup.py 2001/07/07 22:55:27 1.38.4.1 --- setup.py 2001/07/15 20:26:55 1.38.4.2 *************** *** 117,121 **** # compilers if compiler is not None: ! args['compiler_so'] = compiler if linker_so is not None: args['linker_so'] = linker_so + ' -shared' --- 117,122 ---- # compilers if compiler is not None: ! (ccshared,) = sysconfig.get_config_vars('CCSHARED') ! args['compiler_so'] = compiler + ' ' + ccshared if linker_so is not None: args['linker_so'] = linker_so + ' -shared' From tim_one@users.sourceforge.net Sun Jul 15 21:26:58 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 15 Jul 2001 13:26:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.71.6.5,1.71.6.6 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv4678/descr/dist/src/Objects Modified Files: Tag: descr-branch longobject.c Log Message: Merge trunk tag delta date2001-07-13 to date2001-07-15. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.71.6.5 retrieving revision 1.71.6.6 diff -C2 -r1.71.6.5 -r1.71.6.6 *** longobject.c 2001/07/14 07:47:35 1.71.6.5 --- longobject.c 2001/07/15 20:26:55 1.71.6.6 *************** *** 7,11 **** #include "longintrepr.h" - #include #include --- 7,10 ---- *************** *** 16,20 **** static PyLongObject *mul1(PyLongObject *, wdigit); static PyLongObject *muladd1(PyLongObject *, wdigit, wdigit); ! static PyLongObject *divrem1(PyLongObject *, wdigit, digit *); static PyObject *long_format(PyObject *aa, int base, int addL); --- 15,19 ---- static PyLongObject *mul1(PyLongObject *, wdigit); static PyLongObject *muladd1(PyLongObject *, wdigit, wdigit); ! static PyLongObject *divrem1(PyLongObject *, digit, digit *); static PyObject *long_format(PyObject *aa, int base, int addL); *************** *** 708,711 **** --- 707,733 ---- } + /* Divide long pin, w/ size digits, by non-zero digit n, storing quotient + in pout, and returning the remainder. pin and pout point at the LSD. + It's OK for pin == pout on entry, which saves oodles of mallocs/frees in + long_format, but that should be done with great care since longs are + immutable. */ + + static digit + inplace_divrem1(digit *pout, digit *pin, int size, digit n) + { + twodigits rem = 0; + + assert(n > 0 && n <= MASK); + pin += size; + pout += size; + while (--size >= 0) { + digit hi; + rem = (rem << SHIFT) + *--pin; + *--pout = hi = (digit)(rem / n); + rem -= hi * n; + } + return (digit)rem; + } + /* Divide a long integer by a digit, returning both the quotient (as function result) and the remainder (through *prem). *************** *** 713,722 **** static PyLongObject * ! divrem1(PyLongObject *a, wdigit n, digit *prem) { ! int size = ABS(a->ob_size); PyLongObject *z; - int i; - twodigits rem = 0; assert(n > 0 && n <= MASK); --- 735,742 ---- static PyLongObject * ! divrem1(PyLongObject *a, digit n, digit *prem) { ! const int size = ABS(a->ob_size); PyLongObject *z; assert(n > 0 && n <= MASK); *************** *** 724,733 **** if (z == NULL) return NULL; ! for (i = size; --i >= 0; ) { ! rem = (rem << SHIFT) + a->ob_digit[i]; ! z->ob_digit[i] = (digit) (rem/n); ! rem %= n; ! } ! *prem = (digit) rem; return long_normalize(z); } --- 744,748 ---- if (z == NULL) return NULL; ! *prem = inplace_divrem1(z->ob_digit, a->ob_digit, size, n); return long_normalize(z); } *************** *** 743,747 **** PyStringObject *str; int i; ! int size_a = ABS(a->ob_size); char *p; int bits; --- 758,762 ---- PyStringObject *str; int i; ! const int size_a = ABS(a->ob_size); char *p; int bits; *************** *** 777,812 **** else if ((base & (base - 1)) == 0) { /* JRH: special case for power-of-2 bases */ ! twodigits temp = a->ob_digit[0]; ! int bitsleft = SHIFT; ! int rem; ! int last = abs(a->ob_size); ! int basebits = 1; i = base; while ((i >>= 1) > 1) ++basebits; ! ! i = 0; ! for (;;) { ! while (bitsleft >= basebits) { ! if ((temp == 0) && (i >= last - 1)) break; ! rem = temp & (base - 1); ! if (rem < 10) ! rem += '0'; ! else ! rem += 'A' - 10; assert(p > PyString_AS_STRING(str)); ! *--p = (char) rem; ! bitsleft -= basebits; ! temp >>= basebits; ! } ! if (++i >= last) { ! if (temp == 0) break; ! bitsleft = 99; ! /* loop again to pick up final digits */ ! } ! else { ! temp = (a->ob_digit[i] << bitsleft) | temp; ! bitsleft += SHIFT; ! } } } --- 792,815 ---- else if ((base & (base - 1)) == 0) { /* JRH: special case for power-of-2 bases */ ! twodigits accum = 0; ! int accumbits = 0; /* # of bits in accum */ ! int basebits = 1; /* # of bits in base-1 */ i = base; while ((i >>= 1) > 1) ++basebits; ! ! for (i = 0; i < size_a; ++i) { ! accum |= a->ob_digit[i] << accumbits; ! accumbits += SHIFT; ! assert(accumbits >= basebits); ! do { ! char digit = (char)(accum & (base - 1)); ! digit += (digit < 10) ? '0' : 'A'-10; assert(p > PyString_AS_STRING(str)); ! *--p = digit; ! accumbits -= basebits; ! accum >>= basebits; ! } while (i < size_a-1 ? accumbits >= basebits : ! accum > 0); } } *************** *** 815,818 **** --- 818,825 ---- base, but for speed use the highest power of base that fits in a digit. */ + int size = size_a; + digit *pin = a->ob_digit; + PyLongObject *scratch; + /* powbasw <- largest power of base that fits in a digit. */ digit powbase = base; /* powbase == base ** power */ int power = 1; *************** *** 823,845 **** powbase = (digit)newpow; ++power; } ! ! Py_INCREF(a); do { int ntostore = power; ! digit rem; ! PyLongObject *temp = divrem1(a, powbase, &rem); ! Py_DECREF(a); ! if (temp == NULL) { ! Py_DECREF(str); ! return NULL; ! } ! a = temp; SIGCHECK({ ! Py_DECREF(a); Py_DECREF(str); return NULL; }) ! while (--ntostore >= 0) { digit nextrem = (digit)(rem / base); char c = (char)(rem - nextrem * base); --- 830,859 ---- powbase = (digit)newpow; ++power; + } + + /* Get a scratch area for repeated division. */ + scratch = _PyLong_New(size); + if (scratch == NULL) { + Py_DECREF(str); + return NULL; } ! ! /* Repeatedly divide by powbase. */ do { int ntostore = power; ! digit rem = inplace_divrem1(scratch->ob_digit, ! pin, size, powbase); ! pin = scratch->ob_digit; /* no need to use a again */ ! if (pin[size - 1] == 0) ! --size; SIGCHECK({ ! Py_DECREF(scratch); Py_DECREF(str); return NULL; }) ! ! /* Break rem into digits. */ ! assert(ntostore > 0); ! do { digit nextrem = (digit)(rem / base); char c = (char)(rem - nextrem * base); *************** *** 848,856 **** *--p = c; rem = nextrem; ! if (a->ob_size == 0 && rem == 0) ! break; /* skip leading zeroes */ ! } ! } while (ABS(a->ob_size) != 0); ! Py_DECREF(a); } --- 862,872 ---- *--p = c; rem = nextrem; ! --ntostore; ! /* Termination is a bit delicate: must not ! store leading zeroes, so must get out if ! remaining quotient and rem are both 0. */ ! } while (ntostore && (size || rem)); ! } while (size != 0); ! Py_DECREF(scratch); } From gvanrossum@users.sourceforge.net Sun Jul 15 22:08:31 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 15 Jul 2001 14:08:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test pystone.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv12021/Lib/test Modified Files: pystone.py Log Message: Preliminary support for "from __future__ import generators" to enable the yield statement. I figure we have to have this in before I can release 2.2a1 on Wednesday. Note: test_generators is currently broken, I'm counting on Tim to fix this. Index: pystone.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pystone.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -r1.6 -r1.7 *** pystone.py 2000/10/23 17:22:07 1.6 --- pystone.py 2001/07/15 21:08:29 1.7 *************** *** 33,37 **** """ ! LOOPS = 10000 from time import clock --- 33,37 ---- """ ! LOOPS = 100000 from time import clock From gvanrossum@users.sourceforge.net Sun Jul 15 22:08:31 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 15 Jul 2001 14:08:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python future.c,2.5,2.6 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv12021/Python Modified Files: future.c Log Message: Preliminary support for "from __future__ import generators" to enable the yield statement. I figure we have to have this in before I can release 2.2a1 on Wednesday. Note: test_generators is currently broken, I'm counting on Tim to fix this. Index: future.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/future.c,v retrieving revision 2.5 retrieving revision 2.6 diff -C2 -r2.5 -r2.6 *** future.c 2001/03/10 02:15:37 2.5 --- future.c 2001/07/15 21:08:29 2.6 *************** *** 32,35 **** --- 32,37 ---- if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) { ff->ff_nested_scopes = 1; + } else if (strcmp(feature, FUTURE_GENERATORS) == 0) { + /* OK; this is processed by the parser */ } else if (strcmp(feature, "braces") == 0) { PyErr_SetString(PyExc_SyntaxError, From gvanrossum@users.sourceforge.net Sun Jul 15 22:08:31 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 15 Jul 2001 14:08:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib __future__.py,1.6,1.7 inspect.py,1.18,1.19 tokenize.py,1.24,1.25 types.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv12021/Lib Modified Files: __future__.py inspect.py tokenize.py types.py Log Message: Preliminary support for "from __future__ import generators" to enable the yield statement. I figure we have to have this in before I can release 2.2a1 on Wednesday. Note: test_generators is currently broken, I'm counting on Tim to fix this. Index: __future__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/__future__.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -r1.6 -r1.7 *** __future__.py 2001/07/12 22:36:02 1.6 --- __future__.py 2001/07/15 21:08:29 1.7 *************** *** 68,69 **** --- 68,70 ---- nested_scopes = _Feature((2, 1, 0, "beta", 1), (2, 2, 0, "alpha", 0)) + generators = _Feature((2, 2, 0, "alpha", 1), (2, 3, 0, "final", 0)) Index: inspect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/inspect.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -r1.18 -r1.19 *** inspect.py 2001/06/29 23:51:08 1.18 --- inspect.py 2001/07/15 21:08:29 1.19 *************** *** 25,28 **** --- 25,30 ---- # This module is in the public domain. No warranties. + from __future__ import generators + __author__ = 'Ka-Ping Yee ' __date__ = '1 Jan 2001' Index: tokenize.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/tokenize.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -r1.24 -r1.25 *** tokenize.py 2001/06/29 23:51:08 1.24 --- tokenize.py 2001/07/15 21:08:29 1.25 *************** *** 23,26 **** --- 23,28 ---- each time a new token is found.""" + from __future__ import generators + __author__ = 'Ka-Ping Yee ' __credits__ = \ Index: types.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/types.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -r1.15 -r1.16 *** types.py 2001/06/25 19:46:25 1.15 --- types.py 2001/07/15 21:08:29 1.16 *************** *** 3,6 **** --- 3,7 ---- Types that are part of optional modules (e.g. array) are not listed. """ + from __future__ import generators import sys From gvanrossum@users.sourceforge.net Sun Jul 15 22:08:31 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 15 Jul 2001 14:08:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Parser parser.c,2.18,2.19 parser.h,2.14,2.15 Message-ID: Update of /cvsroot/python/python/dist/src/Parser In directory usw-pr-cvs1:/tmp/cvs-serv12021/Parser Modified Files: parser.c parser.h Log Message: Preliminary support for "from __future__ import generators" to enable the yield statement. I figure we have to have this in before I can release 2.2a1 on Wednesday. Note: test_generators is currently broken, I'm counting on Tim to fix this. Index: parser.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Parser/parser.c,v retrieving revision 2.18 retrieving revision 2.19 diff -C2 -r2.18 -r2.19 *** parser.c 2000/10/02 10:21:59 2.18 --- parser.c 2001/07/15 21:08:29 2.19 *************** *** 80,83 **** --- 80,84 ---- return NULL; ps->p_grammar = g; + ps->p_generators = 0; ps->p_tree = PyNode_New(start); if (ps->p_tree == NULL) { *************** *** 132,137 **** static int ! classify(grammar *g, int type, char *str) { register int n = g->g_ll.ll_nlabels; --- 133,139 ---- static int ! classify(parser_state *ps, int type, char *str) { + grammar *g = ps->p_grammar; register int n = g->g_ll.ll_nlabels; *************** *** 144,147 **** --- 146,153 ---- l->lb_str[0] == s[0] && strcmp(l->lb_str, s) == 0) { + if (!ps->p_generators && + s[0] == 'y' && + strcmp(s, "yield") == 0) + break; /* not a keyword */ D(printf("It's a keyword\n")); return n - i; *************** *** 165,168 **** --- 171,190 ---- } + static void + future_hack(parser_state *ps) + { + node *n = ps->p_stack.s_top->s_parent; + node *ch; + + if (strcmp(STR(CHILD(n, 0)), "from") != 0) + return; + ch = CHILD(n, 1); + if (strcmp(STR(CHILD(ch, 0)), "__future__") != 0) + return; + ch = CHILD(n, 3); + if (NCH(ch) == 1 && strcmp(STR(CHILD(ch, 0)), "generators") == 0) + ps->p_generators = 1; + } + int PyParser_AddToken(register parser_state *ps, register int type, char *str, *************** *** 175,179 **** /* Find out which label this token is */ ! ilabel = classify(ps->p_grammar, type, str); if (ilabel < 0) return E_SYNTAX; --- 197,201 ---- /* Find out which label this token is */ ! ilabel = classify(ps, type, str); if (ilabel < 0) return E_SYNTAX; *************** *** 218,222 **** [ps->p_stack.s_top->s_state], s->s_accept && s->s_narcs == 1) { ! D(printf(" Direct pop.\n")); s_pop(&ps->p_stack); if (s_empty(&ps->p_stack)) { --- 240,251 ---- [ps->p_stack.s_top->s_state], s->s_accept && s->s_narcs == 1) { ! D(printf(" DFA '%s', state %d: " ! "Direct pop.\n", ! d->d_name, ! ps->p_stack.s_top->s_state)); ! if (d->d_name[0] == 'i' && ! strcmp(d->d_name, ! "import_stmt") == 0) ! future_hack(ps); s_pop(&ps->p_stack); if (s_empty(&ps->p_stack)) { *************** *** 231,234 **** --- 260,266 ---- if (s->s_accept) { + if (d->d_name[0] == 'i' && + strcmp(d->d_name, "import_stmt") == 0) + future_hack(ps); /* Pop this dfa and try again */ s_pop(&ps->p_stack); Index: parser.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Parser/parser.h,v retrieving revision 2.14 retrieving revision 2.15 diff -C2 -r2.14 -r2.15 *** parser.h 2000/09/01 23:29:28 2.14 --- parser.h 2001/07/15 21:08:29 2.15 *************** *** 26,29 **** --- 26,30 ---- grammar *p_grammar; /* Grammar to use */ node *p_tree; /* Top of parse tree */ + int p_generators; /* 1 if yield is a keyword */ } parser_state; From gvanrossum@users.sourceforge.net Sun Jul 15 22:08:31 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 15 Jul 2001 14:08:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include compile.h,2.31,2.32 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv12021/Include Modified Files: compile.h Log Message: Preliminary support for "from __future__ import generators" to enable the yield statement. I figure we have to have this in before I can release 2.2a1 on Wednesday. Note: test_generators is currently broken, I'm counting on Tim to fix this. Index: compile.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/compile.h,v retrieving revision 2.31 retrieving revision 2.32 diff -C2 -r2.31 -r2.32 *** compile.h 2001/07/12 12:50:23 2.31 --- compile.h 2001/07/15 21:08:29 2.32 *************** *** 66,69 **** --- 66,72 ---- #define FUTURE_NESTED_SCOPES "nested_scopes" + #define GENERATORS_DEFAULT 0 + #define FUTURE_GENERATORS "generators" + /* for internal use only */ #define _PyCode_GETCODEPTR(co, pp) \ From tim_one@users.sourceforge.net Mon Jul 16 03:29:47 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 15 Jul 2001 19:29:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv30317/python/dist/src/Lib/test Modified Files: test_generators.py Log Message: Part way to allowing "from __future__ import generators" to communicate that info to code dynamically compiled *by* code compiled with generators enabled. Doesn't yet work because there's still no way to tell the parser that "yield" is OK (unlike nested_scopes, the parser has its fingers in this too). Replaced PyEval_GetNestedScopes by a more-general PyEval_MergeCompilerFlags. Perhaps I should not have? I doubted it was *intended* to be part of the public API, so just did. Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -r1.22 -r1.23 *** test_generators.py 2001/07/13 09:12:12 1.22 --- test_generators.py 2001/07/16 02:29:45 1.23 *************** *** 1,2 **** --- 1,4 ---- + from __future__ import generators + tutorial_tests = """ Let's try a simple generator: From tim_one@users.sourceforge.net Mon Jul 16 03:29:47 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 15 Jul 2001 19:29:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules main.c,1.53,1.54 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv30317/python/dist/src/Modules Modified Files: main.c Log Message: Part way to allowing "from __future__ import generators" to communicate that info to code dynamically compiled *by* code compiled with generators enabled. Doesn't yet work because there's still no way to tell the parser that "yield" is OK (unlike nested_scopes, the parser has its fingers in this too). Replaced PyEval_GetNestedScopes by a more-general PyEval_MergeCompilerFlags. Perhaps I should not have? I doubted it was *intended* to be part of the public API, so just did. Index: main.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/main.c,v retrieving revision 1.53 retrieving revision 1.54 diff -C2 -r1.53 -r1.54 *** main.c 2001/06/12 16:13:51 1.53 --- main.c 2001/07/16 02:29:45 1.54 *************** *** 299,303 **** } ! cf.cf_nested_scopes = 0; if (command) { --- 299,303 ---- } ! cf.cf_flags = 0; if (command) { From tim_one@users.sourceforge.net Mon Jul 16 03:29:47 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 15 Jul 2001 19:29:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include Python.h,2.34,2.35 ceval.h,2.42,2.43 compile.h,2.32,2.33 pythonrun.h,2.41,2.42 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv30317/python/dist/src/Include Modified Files: Python.h ceval.h compile.h pythonrun.h Log Message: Part way to allowing "from __future__ import generators" to communicate that info to code dynamically compiled *by* code compiled with generators enabled. Doesn't yet work because there's still no way to tell the parser that "yield" is OK (unlike nested_scopes, the parser has its fingers in this too). Replaced PyEval_GetNestedScopes by a more-general PyEval_MergeCompilerFlags. Perhaps I should not have? I doubted it was *intended* to be part of the public API, so just did. Index: Python.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/Python.h,v retrieving revision 2.34 retrieving revision 2.35 diff -C2 -r2.34 -r2.35 *** Python.h 2001/07/15 18:38:46 2.34 --- Python.h 2001/07/16 02:29:45 2.35 *************** *** 97,102 **** #include "modsupport.h" - #include "ceval.h" #include "pythonrun.h" #include "sysmodule.h" #include "intrcheck.h" --- 97,102 ---- #include "modsupport.h" #include "pythonrun.h" + #include "ceval.h" #include "sysmodule.h" #include "intrcheck.h" Index: ceval.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/ceval.h,v retrieving revision 2.42 retrieving revision 2.43 diff -C2 -r2.42 -r2.43 *** ceval.h 2001/06/27 19:18:03 2.42 --- ceval.h 2001/07/16 02:29:45 2.43 *************** *** 32,36 **** DL_IMPORT(PyObject *) PyEval_GetFrame(void); DL_IMPORT(int) PyEval_GetRestricted(void); ! DL_IMPORT(int) PyEval_GetNestedScopes(void); DL_IMPORT(int) Py_FlushLine(void); --- 32,40 ---- DL_IMPORT(PyObject *) PyEval_GetFrame(void); DL_IMPORT(int) PyEval_GetRestricted(void); ! ! /* Look at the current frame's (if any) code's co_flags, and turn on ! the corresponding compiler flags in cf->cf_flags. Return 1 if any ! flag was set, else return 0. */ ! DL_IMPORT(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf); DL_IMPORT(int) Py_FlushLine(void); Index: compile.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/compile.h,v retrieving revision 2.32 retrieving revision 2.33 diff -C2 -r2.32 -r2.33 *** compile.h 2001/07/15 21:08:29 2.32 --- compile.h 2001/07/16 02:29:45 2.33 *************** *** 35,38 **** --- 35,45 ---- #define CO_NESTED 0x0010 #define CO_GENERATOR 0x0020 + /* XXX Temporary hack. Until generators are a permanent part of the + language, we need a way for a code object to record that generators + were *possible* when it was compiled. This is so code dynamically + compiled *by* a code object knows whether to allow yield stmts. In + effect, this passes on the "from __future__ import generators" state + in effect when the code block was compiled. */ + #define CO_GENERATOR_ALLOWED 0x1000 extern DL_IMPORT(PyTypeObject) PyCode_Type; *************** *** 57,60 **** --- 64,68 ---- int ff_last_lineno; int ff_nested_scopes; + int ff_generators; } PyFutureFeatures; Index: pythonrun.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pythonrun.h,v retrieving revision 2.41 retrieving revision 2.42 diff -C2 -r2.41 -r2.42 *** pythonrun.h 2001/03/23 02:46:52 2.41 --- pythonrun.h 2001/07/16 02:29:45 2.42 *************** *** 8,13 **** #endif typedef struct { ! int cf_nested_scopes; } PyCompilerFlags; --- 8,18 ---- #endif + /* These flags are named after the __future__ statements that introduced + them. May not remain true for later additions, so fiddle this comment + accordingly then. */ + #define PyCF_NESTED_SCOPES (0x00000001UL) + #define PyCF_GENERATORS (0x00000002UL) typedef struct { ! unsigned long cf_flags; /* bitmask of PyCF_xxx flags */ } PyCompilerFlags; From tim_one@users.sourceforge.net Mon Jul 16 03:29:47 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 15 Jul 2001 19:29:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.216,2.217 ceval.c,2.261,2.262 compile.c,2.206,2.207 future.c,2.6,2.7 pythonrun.c,2.134,2.135 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv30317/python/dist/src/Python Modified Files: bltinmodule.c ceval.c compile.c future.c pythonrun.c Log Message: Part way to allowing "from __future__ import generators" to communicate that info to code dynamically compiled *by* code compiled with generators enabled. Doesn't yet work because there's still no way to tell the parser that "yield" is OK (unlike nested_scopes, the parser has its fingers in this too). Replaced PyEval_GetNestedScopes by a more-general PyEval_MergeCompilerFlags. Perhaps I should not have? I doubted it was *intended* to be part of the public API, so just did. Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.216 retrieving revision 2.217 diff -C2 -r2.216 -r2.217 *** bltinmodule.c 2001/07/09 12:30:54 2.216 --- bltinmodule.c 2001/07/16 02:29:45 2.217 *************** *** 394,397 **** --- 394,398 ---- char *startstr; int start; + PyCompilerFlags cf; if (!PyArg_ParseTuple(args, "sss:compile", &str, &filename, &startstr)) *************** *** 408,416 **** return NULL; } ! if (PyEval_GetNestedScopes()) { ! PyCompilerFlags cf; ! cf.cf_nested_scopes = 1; return Py_CompileStringFlags(str, filename, start, &cf); ! } else return Py_CompileString(str, filename, start); } --- 409,416 ---- return NULL; } ! cf.cf_flags = 0; ! if (PyEval_MergeCompilerFlags(&cf)) return Py_CompileStringFlags(str, filename, start, &cf); ! else return Py_CompileString(str, filename, start); } *************** *** 823,826 **** --- 823,827 ---- PyObject *res; FILE* fp; + PyCompilerFlags cf; if (!PyArg_ParseTuple(args, "s|O!O!:execfile", *************** *** 848,857 **** return NULL; } ! if (PyEval_GetNestedScopes()) { ! PyCompilerFlags cf; ! cf.cf_nested_scopes = 1; res = PyRun_FileExFlags(fp, filename, Py_file_input, globals, locals, 1, &cf); ! } else res = PyRun_FileEx(fp, filename, Py_file_input, globals, locals, 1); --- 849,857 ---- return NULL; } ! cf.cf_flags = 0; ! if (PyEval_MergeCompilerFlags(&cf)) res = PyRun_FileExFlags(fp, filename, Py_file_input, globals, locals, 1, &cf); ! else res = PyRun_FileEx(fp, filename, Py_file_input, globals, locals, 1); Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.261 retrieving revision 2.262 diff -C2 -r2.261 -r2.262 *** ceval.c 2001/07/12 13:27:49 2.261 --- ceval.c 2001/07/16 02:29:45 2.262 *************** *** 2525,2529 **** /* Don't need to keep the reference to f_back, it will be set * when the generator is resumed. */ ! Py_DECREF(f->f_back); f->f_back = NULL; --- 2525,2529 ---- /* Don't need to keep the reference to f_back, it will be set * when the generator is resumed. */ ! Py_XDECREF(f->f_back); f->f_back = NULL; *************** *** 2907,2915 **** int ! PyEval_GetNestedScopes(void) { PyFrameObject *current_frame = PyThreadState_Get()->frame; ! return current_frame == NULL ? 0 : ! current_frame->f_code->co_flags & CO_NESTED; } --- 2907,2927 ---- int ! PyEval_MergeCompilerFlags(PyCompilerFlags *cf) { PyFrameObject *current_frame = PyThreadState_Get()->frame; ! int result = 0; ! ! if (current_frame != NULL) { ! const int codeflags = current_frame->f_code->co_flags; ! if (codeflags & CO_NESTED) { ! result = 1; ! cf->cf_flags |= PyCF_NESTED_SCOPES; ! } ! if (codeflags & CO_GENERATOR_ALLOWED) { ! result = 1; ! cf->cf_flags |= PyCF_GENERATORS; ! } ! } ! return result; } *************** *** 3731,3754 **** FILE *fp = PyFile_AsFile(prog); char *name = PyString_AsString(PyFile_Name(prog)); ! if (PyEval_GetNestedScopes()) { ! PyCompilerFlags cf; ! cf.cf_nested_scopes = 1; v = PyRun_FileFlags(fp, name, Py_file_input, globals, locals, &cf); ! } else { v = PyRun_File(fp, name, Py_file_input, globals, locals); - } } else { char *str; if (PyString_AsStringAndSize(prog, &str, NULL)) return -1; ! if (PyEval_GetNestedScopes()) { ! PyCompilerFlags cf; ! cf.cf_nested_scopes = 1; v = PyRun_StringFlags(str, Py_file_input, globals, locals, &cf); ! } else v = PyRun_String(str, Py_file_input, globals, locals); } --- 3743,3765 ---- FILE *fp = PyFile_AsFile(prog); char *name = PyString_AsString(PyFile_Name(prog)); ! PyCompilerFlags cf; ! cf.cf_flags = 0; ! if (PyEval_MergeCompilerFlags(&cf)) v = PyRun_FileFlags(fp, name, Py_file_input, globals, locals, &cf); ! else v = PyRun_File(fp, name, Py_file_input, globals, locals); } else { char *str; + PyCompilerFlags cf; if (PyString_AsStringAndSize(prog, &str, NULL)) return -1; ! cf.cf_flags = 0; ! if (PyEval_MergeCompilerFlags(&cf)) v = PyRun_StringFlags(str, Py_file_input, globals, locals, &cf); ! else v = PyRun_String(str, Py_file_input, globals, locals); } Index: compile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v retrieving revision 2.206 retrieving revision 2.207 diff -C2 -r2.206 -r2.207 *** compile.c 2001/06/28 01:52:22 2.206 --- compile.c 2001/07/16 02:29:45 2.207 *************** *** 3954,3961 **** } if (flags) { ! if (flags->cf_nested_scopes) sc.c_future->ff_nested_scopes = 1; else if (sc.c_future->ff_nested_scopes) ! flags->cf_nested_scopes = 1; } if (symtable_build(&sc, n) < 0) { --- 3954,3966 ---- } if (flags) { ! if (flags->cf_flags & PyCF_NESTED_SCOPES) sc.c_future->ff_nested_scopes = 1; else if (sc.c_future->ff_nested_scopes) ! flags->cf_flags |= PyCF_NESTED_SCOPES; ! ! if (flags->cf_flags & PyCF_GENERATORS) ! sc.c_future->ff_generators = 1; ! else if (sc.c_future->ff_generators) ! flags->cf_flags |= PyCF_GENERATORS; } if (symtable_build(&sc, n) < 0) { *************** *** 4427,4432 **** struct symbol_info *si) { ! if (c->c_future && c->c_future->ff_nested_scopes) ! c->c_flags |= CO_NESTED; if (ste->ste_generator) c->c_flags |= CO_GENERATOR; --- 4432,4441 ---- struct symbol_info *si) { ! if (c->c_future) { ! if (c->c_future->ff_nested_scopes) ! c->c_flags |= CO_NESTED; ! if (c->c_future->ff_generators) ! c->c_flags |= CO_GENERATOR_ALLOWED; ! } if (ste->ste_generator) c->c_flags |= CO_GENERATOR; Index: future.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/future.c,v retrieving revision 2.6 retrieving revision 2.7 diff -C2 -r2.6 -r2.7 *** future.c 2001/07/15 21:08:29 2.6 --- future.c 2001/07/16 02:29:45 2.7 *************** *** 33,37 **** ff->ff_nested_scopes = 1; } else if (strcmp(feature, FUTURE_GENERATORS) == 0) { ! /* OK; this is processed by the parser */ } else if (strcmp(feature, "braces") == 0) { PyErr_SetString(PyExc_SyntaxError, --- 33,37 ---- ff->ff_nested_scopes = 1; } else if (strcmp(feature, FUTURE_GENERATORS) == 0) { ! ff->ff_generators= 1; } else if (strcmp(feature, "braces") == 0) { PyErr_SetString(PyExc_SyntaxError, *************** *** 234,237 **** --- 234,238 ---- ff->ff_last_lineno = -1; ff->ff_nested_scopes = 0; + ff->ff_generators = 0; if (future_parse(ff, n, filename) < 0) { Index: pythonrun.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.134 retrieving revision 2.135 diff -C2 -r2.134 -r2.135 *** pythonrun.c 2001/06/13 17:18:06 2.134 --- pythonrun.c 2001/07/16 02:29:45 2.135 *************** *** 495,499 **** if (flags == NULL) { flags = &local_flags; ! local_flags.cf_nested_scopes = 0; } v = PySys_GetObject("ps1"); --- 495,499 ---- if (flags == NULL) { flags = &local_flags; ! local_flags.cf_flags = 0; } v = PySys_GetObject("ps1"); *************** *** 1076,1083 **** if (v && flags) { if (co->co_flags & CO_NESTED) ! flags->cf_nested_scopes = 1; #if 0 fprintf(stderr, "run_pyc_file: nested_scopes: %d\n", ! flags->cf_nested_scopes); #endif } --- 1076,1087 ---- if (v && flags) { if (co->co_flags & CO_NESTED) ! flags->cf_flags |= PyCF_NESTED_SCOPES; ! if (co->co_flags & CO_GENERATOR) ! flags->cf_flags |= PyCF_GENERATORS; #if 0 fprintf(stderr, "run_pyc_file: nested_scopes: %d\n", ! flags->cf_flags & PyCF_NESTED_SCOPES); ! fprintf(stderr, "run_pyc_file: generators: %d\n", ! flags->cf_flags & PyCF_GENERATORS); #endif } From tim_one@users.sourceforge.net Mon Jul 16 04:11:50 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 15 Jul 2001 20:11:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python future.c,2.7,2.8 pythonrun.c,2.135,2.136 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv3302/python/dist/src/Python Modified Files: future.c pythonrun.c Log Message: future.c: insert a cosmetic space. pythonrun.c, run_pyc_file(): repair semantic error wrt CO_GENERATOR vs CO_GENERATOR_ALLOWED. Index: future.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/future.c,v retrieving revision 2.7 retrieving revision 2.8 diff -C2 -r2.7 -r2.8 *** future.c 2001/07/16 02:29:45 2.7 --- future.c 2001/07/16 03:11:48 2.8 *************** *** 33,37 **** ff->ff_nested_scopes = 1; } else if (strcmp(feature, FUTURE_GENERATORS) == 0) { ! ff->ff_generators= 1; } else if (strcmp(feature, "braces") == 0) { PyErr_SetString(PyExc_SyntaxError, --- 33,37 ---- ff->ff_nested_scopes = 1; } else if (strcmp(feature, FUTURE_GENERATORS) == 0) { ! ff->ff_generators = 1; } else if (strcmp(feature, "braces") == 0) { PyErr_SetString(PyExc_SyntaxError, Index: pythonrun.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.135 retrieving revision 2.136 diff -C2 -r2.135 -r2.136 *** pythonrun.c 2001/07/16 02:29:45 2.135 --- pythonrun.c 2001/07/16 03:11:48 2.136 *************** *** 1077,1081 **** if (co->co_flags & CO_NESTED) flags->cf_flags |= PyCF_NESTED_SCOPES; ! if (co->co_flags & CO_GENERATOR) flags->cf_flags |= PyCF_GENERATORS; #if 0 --- 1077,1081 ---- if (co->co_flags & CO_NESTED) flags->cf_flags |= PyCF_NESTED_SCOPES; ! if (co->co_flags & CO_GENERATOR_ALLOWED) flags->cf_flags |= PyCF_GENERATORS; #if 0 From tim_one@users.sourceforge.net Mon Jul 16 06:37:26 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 15 Jul 2001 22:37:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib doctest.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv22251/python/dist/src/Lib Modified Files: doctest.py Log Message: Ugly. A pile of new xxxFlags() functions, to communicate to the parser that 'yield' is a keyword. This doesn't help test_generators at all! I don't know why not. These things do work now (and didn't before this patch): 1. "from __future__ import generators" now works in a native shell. 2. Similarly "python -i xxx.py" now has generators enabled in the shell if xxx.py had them enabled. 3. This program (which was my doctest proxy) works fine: from __future__ import generators source = """\ def f(): yield 1 """ exec compile(source, "", "single") in globals() print type(f()) Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -r1.14 -r1.15 *** doctest.py 2001/06/24 20:24:16 1.14 --- doctest.py 2001/07/16 05:37:24 1.15 *************** *** 349,352 **** --- 349,354 ---- # string method conversion + from __future__ import generators + __version__ = 0, 9, 7 From tim_one@users.sourceforge.net Mon Jul 16 06:37:26 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 15 Jul 2001 22:37:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Parser parsetok.c,2.25,2.26 Message-ID: Update of /cvsroot/python/python/dist/src/Parser In directory usw-pr-cvs1:/tmp/cvs-serv22251/python/dist/src/Parser Modified Files: parsetok.c Log Message: Ugly. A pile of new xxxFlags() functions, to communicate to the parser that 'yield' is a keyword. This doesn't help test_generators at all! I don't know why not. These things do work now (and didn't before this patch): 1. "from __future__ import generators" now works in a native shell. 2. Similarly "python -i xxx.py" now has generators enabled in the shell if xxx.py had them enabled. 3. This program (which was my doctest proxy) works fine: from __future__ import generators source = """\ def f(): yield 1 """ exec compile(source, "", "single") in globals() print type(f()) Index: parsetok.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Parser/parsetok.c,v retrieving revision 2.25 retrieving revision 2.26 diff -C2 -r2.25 -r2.26 *** parsetok.c 2000/09/01 23:29:28 2.25 --- parsetok.c 2001/07/16 05:37:24 2.26 *************** *** 14,24 **** /* Forward */ ! static node *parsetok(struct tok_state *, grammar *, int, perrdetail *); /* Parse input coming from a string. Return error code, print some errors. */ - node * PyParser_ParseString(char *s, grammar *g, int start, perrdetail *err_ret) { struct tok_state *tok; --- 14,30 ---- /* Forward */ ! static node *parsetok(struct tok_state *, grammar *, int, perrdetail *, int); /* Parse input coming from a string. Return error code, print some errors. */ node * PyParser_ParseString(char *s, grammar *g, int start, perrdetail *err_ret) { + return PyParser_ParseStringFlags(s, g, start, err_ret, 0); + } + + node * + PyParser_ParseStringFlags(char *s, grammar *g, int start, + perrdetail *err_ret, int flags) + { struct tok_state *tok; *************** *** 43,47 **** } ! return parsetok(tok, g, start, err_ret); } --- 49,53 ---- } ! return parsetok(tok, g, start, err_ret, flags); } *************** *** 53,56 **** --- 59,70 ---- char *ps1, char *ps2, perrdetail *err_ret) { + return PyParser_ParseFileFlags(fp, filename, g, start, ps1, ps2, + err_ret, 0); + } + + node * + PyParser_ParseFileFlags(FILE *fp, char *filename, grammar *g, int start, + char *ps1, char *ps2, perrdetail *err_ret, int flags) + { struct tok_state *tok; *************** *** 73,77 **** ! return parsetok(tok, g, start, err_ret); } --- 87,91 ---- ! return parsetok(tok, g, start, err_ret, flags); } *************** *** 80,84 **** static node * ! parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret) { parser_state *ps; --- 94,99 ---- static node * ! parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret, ! int flags) { parser_state *ps; *************** *** 91,94 **** --- 106,111 ---- return NULL; } + if (flags & PyPARSE_YIELD_IS_KEYWORD) + ps->p_generators = 1; for (;;) { From tim_one@users.sourceforge.net Mon Jul 16 06:37:26 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 15 Jul 2001 22:37:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python pythonrun.c,2.136,2.137 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv22251/python/dist/src/Python Modified Files: pythonrun.c Log Message: Ugly. A pile of new xxxFlags() functions, to communicate to the parser that 'yield' is a keyword. This doesn't help test_generators at all! I don't know why not. These things do work now (and didn't before this patch): 1. "from __future__ import generators" now works in a native shell. 2. Similarly "python -i xxx.py" now has generators enabled in the shell if xxx.py had them enabled. 3. This program (which was my doctest proxy) works fine: from __future__ import generators source = """\ def f(): yield 1 """ exec compile(source, "", "single") in globals() print type(f()) Index: pythonrun.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.136 retrieving revision 2.137 diff -C2 -r2.136 -r2.137 *** pythonrun.c 2001/07/16 03:11:48 2.136 --- pythonrun.c 2001/07/16 05:37:24 2.137 *************** *** 534,537 **** --- 534,538 ---- perrdetail err; char *ps1 = "", *ps2 = ""; + v = PySys_GetObject("ps1"); if (v != NULL) { *************** *** 550,555 **** ps2 = PyString_AsString(w); } ! n = PyParser_ParseFile(fp, filename, &_PyParser_Grammar, ! Py_single_input, ps1, ps2, &err); Py_XDECREF(v); Py_XDECREF(w); --- 551,559 ---- ps2 = PyString_AsString(w); } ! n = PyParser_ParseFileFlags(fp, filename, &_PyParser_Grammar, ! Py_single_input, ps1, ps2, &err, ! (flags && ! flags->cf_flags & PyCF_GENERATORS) ? ! PyPARSE_YIELD_IS_KEYWORD : 0); Py_XDECREF(v); Py_XDECREF(w); *************** *** 1018,1022 **** PyObject *locals, int closeit, PyCompilerFlags *flags) { ! node *n = PyParser_SimpleParseFile(fp, filename, start); if (closeit) fclose(fp); --- 1022,1028 ---- PyObject *locals, int closeit, PyCompilerFlags *flags) { ! node *n = PyParser_SimpleParseFileFlags(fp, filename, start, ! (flags && flags->cf_flags & PyCF_GENERATORS) ? ! PyPARSE_YIELD_IS_KEYWORD : 0); if (closeit) fclose(fp); *************** *** 1102,1106 **** node *n; PyCodeObject *co; ! n = PyParser_SimpleParseString(str, start); if (n == NULL) return NULL; --- 1108,1114 ---- node *n; PyCodeObject *co; ! n = PyParser_SimpleParseStringFlags(str, start, ! (flags && flags->cf_flags & PyCF_GENERATORS) ? ! PyPARSE_YIELD_IS_KEYWORD : 0); if (n == NULL) return NULL; *************** *** 1126,1135 **** node * ! PyParser_SimpleParseFile(FILE *fp, char *filename, int start) { node *n; perrdetail err; ! n = PyParser_ParseFile(fp, filename, &_PyParser_Grammar, start, ! (char *)0, (char *)0, &err); if (n == NULL) err_input(&err); --- 1134,1143 ---- node * ! PyParser_SimpleParseFileFlags(FILE *fp, char *filename, int start, int flags) { node *n; perrdetail err; ! n = PyParser_ParseFileFlags(fp, filename, &_PyParser_Grammar, start, ! (char *)0, (char *)0, &err, flags); if (n == NULL) err_input(&err); *************** *** 1137,1151 **** } /* Simplified interface to parsestring -- return node or set exception */ node * ! PyParser_SimpleParseString(char *str, int start) { node *n; perrdetail err; ! n = PyParser_ParseString(str, &_PyParser_Grammar, start, &err); if (n == NULL) err_input(&err); return n; } --- 1145,1172 ---- } + node * + PyParser_SimpleParseFile(FILE *fp, char *filename, int start) + { + return PyParser_SimpleParseFileFlags(fp, filename, start, 0); + } + /* Simplified interface to parsestring -- return node or set exception */ node * ! PyParser_SimpleParseStringFlags(char *str, int start, int flags) { node *n; perrdetail err; ! n = PyParser_ParseStringFlags(str, &_PyParser_Grammar, start, &err, ! flags); if (n == NULL) err_input(&err); return n; + } + + node * + PyParser_SimpleParseString(char *str, int start) + { + return PyParser_SimpleParseStringFlags(str, start, 0); } From tim_one@users.sourceforge.net Mon Jul 16 06:37:26 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 15 Jul 2001 22:37:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include parsetok.h,2.15,2.16 pythonrun.h,2.42,2.43 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv22251/python/dist/src/Include Modified Files: parsetok.h pythonrun.h Log Message: Ugly. A pile of new xxxFlags() functions, to communicate to the parser that 'yield' is a keyword. This doesn't help test_generators at all! I don't know why not. These things do work now (and didn't before this patch): 1. "from __future__ import generators" now works in a native shell. 2. Similarly "python -i xxx.py" now has generators enabled in the shell if xxx.py had them enabled. 3. This program (which was my doctest proxy) works fine: from __future__ import generators source = """\ def f(): yield 1 """ exec compile(source, "", "single") in globals() print type(f()) Index: parsetok.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/parsetok.h,v retrieving revision 2.15 retrieving revision 2.16 diff -C2 -r2.15 -r2.16 *** parsetok.h 2000/09/01 23:29:26 2.15 --- parsetok.h 2001/07/16 05:37:24 2.16 *************** *** 18,25 **** --- 18,33 ---- } perrdetail; + #define PyPARSE_YIELD_IS_KEYWORD 0x0001 + extern DL_IMPORT(node *) PyParser_ParseString(char *, grammar *, int, perrdetail *); extern DL_IMPORT(node *) PyParser_ParseFile (FILE *, char *, grammar *, int, char *, char *, perrdetail *); + + extern DL_IMPORT(node *) PyParser_ParseStringFlags(char *, grammar *, int, + perrdetail *, int); + extern DL_IMPORT(node *) PyParser_ParseFileFlags(FILE *, char *, grammar *, + int, char *, char *, + perrdetail *, int); #ifdef __cplusplus Index: pythonrun.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pythonrun.h,v retrieving revision 2.42 retrieving revision 2.43 diff -C2 -r2.42 -r2.43 *** pythonrun.h 2001/07/16 02:29:45 2.42 --- pythonrun.h 2001/07/16 05:37:24 2.43 *************** *** 46,49 **** --- 46,52 ---- DL_IMPORT(struct _node *) PyParser_SimpleParseString(char *, int); DL_IMPORT(struct _node *) PyParser_SimpleParseFile(FILE *, char *, int); + DL_IMPORT(struct _node *) PyParser_SimpleParseStringFlags(char *, int, int); + DL_IMPORT(struct _node *) PyParser_SimpleParseFileFlags(FILE *, char *, + int, int); DL_IMPORT(PyObject *) PyRun_String(char *, int, PyObject *, PyObject *); From gvanrossum@users.sourceforge.net Mon Jul 16 14:06:45 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 16 Jul 2001 06:06:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test pystone.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv18949 Modified Files: pystone.py Log Message: Oops, the change to pystone wasn't supposed to be committed. Index: pystone.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pystone.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** pystone.py 2001/07/15 21:08:29 1.7 --- pystone.py 2001/07/16 13:06:43 1.8 *************** *** 33,37 **** """ ! LOOPS = 100000 from time import clock --- 33,37 ---- """ ! LOOPS = 10000 from time import clock From akuchling@users.sourceforge.net Mon Jul 16 15:19:22 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Mon, 16 Jul 2001 07:19:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/distutils unixccompiler.py,1.33,1.34 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils In directory usw-pr-cvs1:/tmp/cvs-serv2891 Modified Files: unixccompiler.py Log Message: [Bug #441527] Fixes for preprocessor support, contributed by Tarn Weisner Burton Index: unixccompiler.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/unixccompiler.py,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -r1.33 -r1.34 *** unixccompiler.py 2001/04/05 15:46:48 1.33 --- unixccompiler.py 2001/07/16 14:19:20 1.34 *************** *** 100,109 **** pp_args[:0] = extra_preargs if extra_postargs: ! extra_postargs.extend(extra_postargs) ! # We need to preprocess: either we're being forced to, or the ! # source file is newer than the target (or the target doesn't # exist). ! if self.force or (output_file and newer(source, output_file)): if output_file: self.mkpath(os.path.dirname(output_file)) --- 100,110 ---- pp_args[:0] = extra_preargs if extra_postargs: ! pp_args.extend(extra_postargs) ! # We need to preprocess: either we're being forced to, or we're ! # generating output to stdout, or there's a target output file and ! # the source file is newer than the target (or the target doesn't # exist). ! if self.force or output_file is None or newer(source, output_file)): if output_file: self.mkpath(os.path.dirname(output_file)) From gvanrossum@users.sourceforge.net Mon Jul 16 15:46:15 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 16 Jul 2001 07:46:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/distutils unixccompiler.py,1.34,1.35 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils In directory usw-pr-cvs1:/tmp/cvs-serv8241 Modified Files: unixccompiler.py Log Message: Fix a mismatched parenthesis in the last patch. Index: unixccompiler.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/unixccompiler.py,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -r1.34 -r1.35 *** unixccompiler.py 2001/07/16 14:19:20 1.34 --- unixccompiler.py 2001/07/16 14:46:13 1.35 *************** *** 106,110 **** # the source file is newer than the target (or the target doesn't # exist). ! if self.force or output_file is None or newer(source, output_file)): if output_file: self.mkpath(os.path.dirname(output_file)) --- 106,110 ---- # the source file is newer than the target (or the target doesn't # exist). ! if self.force or output_file is None or newer(source, output_file): if output_file: self.mkpath(os.path.dirname(output_file)) From fdrake@users.sourceforge.net Mon Jul 16 16:40:59 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 16 Jul 2001 08:40:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libtime.tex,1.41,1.42 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv22657/lib Modified Files: libtime.tex Log Message: Revise the description of time.clock() so that it correctly describes the Windows version of the function as well as the Unix flavor. This fixes SF bug #441357. Index: libtime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libtime.tex,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -r1.41 -r1.42 *** libtime.tex 2001/07/14 02:50:55 1.41 --- libtime.tex 2001/07/16 15:40:57 1.42 *************** *** 127,136 **** \begin{funcdesc}{clock}{} ! Return the current processor time as a floating point number expressed in seconds. The precision, and in fact the very definition of the meaning ! of ``processor time''\index{CPU time}\index{processor time}, depends on ! that of the C function of the same name, but in any case, this is the ! function to use for benchmarking\index{benchmarking} Python or timing ! algorithms. \end{funcdesc} --- 127,142 ---- \begin{funcdesc}{clock}{} ! On \UNIX, return ! the current processor time as a floating point number expressed in seconds. The precision, and in fact the very definition of the meaning ! of ``processor time''\index{CPU time}\index{processor time}, depends ! on that of the C function of the same name, but in any case, this is ! the function to use for benchmarking\index{benchmarking} Python or ! timing algorithms. ! ! On Windows, this function returns the nearest approximation to ! wall-clock time since the first call to this function, based on the ! Win32 function \cfunction{QueryPerformanceCounter()}. The resolution ! is typically better than one microsecond. \end{funcdesc} From fdrake@users.sourceforge.net Mon Jul 16 16:41:40 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 16 Jul 2001 08:41:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libtime.tex,1.37.4.2,1.37.4.3 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv22899/lib Modified Files: Tag: release21-maint libtime.tex Log Message: Revise the description of time.clock() so that it correctly describes the Windows version of the function as well as the Unix flavor. This fixes SF bug #441357. Index: libtime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libtime.tex,v retrieving revision 1.37.4.2 retrieving revision 1.37.4.3 diff -C2 -r1.37.4.2 -r1.37.4.3 *** libtime.tex 2001/06/29 15:41:19 1.37.4.2 --- libtime.tex 2001/07/16 15:41:38 1.37.4.3 *************** *** 127,135 **** \begin{funcdesc}{clock}{} ! Return the current CPU time as a floating point number expressed in seconds. The precision, and in fact the very definition of the meaning ! of ``CPU time''\index{CPU time}, depends on that of the C function ! of the same name, but in any case, this is the function to use for ! benchmarking\index{benchmarking} Python or timing algorithms. \end{funcdesc} --- 127,142 ---- \begin{funcdesc}{clock}{} ! On \UNIX, return ! the current processor time as a floating point number expressed in seconds. The precision, and in fact the very definition of the meaning ! of ``processor time''\index{CPU time}\index{processor time}, depends ! on that of the C function of the same name, but in any case, this is ! the function to use for benchmarking\index{benchmarking} Python or ! timing algorithms. ! ! On Windows, this function returns the nearest approximation to ! wall-clock time since the first call to this function, based on the ! Win32 function \cfunction{QueryPerformanceCounter()}. The resolution ! is typically better than one microsecond. \end{funcdesc} From twouters@users.sourceforge.net Mon Jul 16 16:45:23 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Mon, 16 Jul 2001 08:45:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules mmapmodule.c,2.27.4.1,2.27.4.2 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv23104/Modules Modified Files: Tag: release21-maint mmapmodule.c Log Message: Fix SF #441664: Python crash on del of a slice of a mmap Check for slice/item deletion, which calls slice/item assignment with a NULL value, and raise a TypeError instead of coredumping. Bugreport and suggested fix by Alex Martelli. Index: mmapmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/mmapmodule.c,v retrieving revision 2.27.4.1 retrieving revision 2.27.4.2 diff -C2 -r2.27.4.1 -r2.27.4.2 *** mmapmodule.c 2001/07/12 12:43:11 2.27.4.1 --- mmapmodule.c 2001/07/16 15:45:20 2.27.4.2 *************** *** 664,667 **** --- 664,672 ---- ihigh = self->size; + if (v == NULL) { + PyErr_SetString(PyExc_TypeError, + "mmap object doesn't support slice deletion"); + return -1; + } if (! (PyString_Check(v)) ) { PyErr_SetString(PyExc_IndexError, *************** *** 687,690 **** --- 692,700 ---- if (i < 0 || (size_t)i >= self->size) { PyErr_SetString(PyExc_IndexError, "mmap index out of range"); + return -1; + } + if (v == NULL) { + PyErr_SetString(PyExc_TypeError, + "mmap object doesn't support item deletion"); return -1; } From twouters@users.sourceforge.net Mon Jul 16 16:47:38 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Mon, 16 Jul 2001 08:47:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules mmapmodule.c,2.31,2.32 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv24334 Modified Files: mmapmodule.c Log Message: Fix SF #441664: Python crash on del of a slice of a mmap Check for slice/item deletion, which calls slice/item assignment with a NULL value, and raise a TypeError instead of coredumping. Bugreport and suggested fix by Alex Martelli. Index: mmapmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/mmapmodule.c,v retrieving revision 2.31 retrieving revision 2.32 diff -C2 -r2.31 -r2.32 *** mmapmodule.c 2001/05/14 23:19:12 2.31 --- mmapmodule.c 2001/07/16 15:47:36 2.32 *************** *** 664,667 **** --- 664,672 ---- ihigh = self->size; + if (v == NULL) { + PyErr_SetString(PyExc_TypeError, + "mmap object doesn't support slice deletion"); + return -1; + } if (! (PyString_Check(v)) ) { PyErr_SetString(PyExc_IndexError, *************** *** 687,690 **** --- 692,700 ---- if (i < 0 || (size_t)i >= self->size) { PyErr_SetString(PyExc_IndexError, "mmap index out of range"); + return -1; + } + if (v == NULL) { + PyErr_SetString(PyExc_TypeError, + "mmap object doesn't support item deletion"); return -1; } From twouters@users.sourceforge.net Mon Jul 16 17:00:36 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Mon, 16 Jul 2001 09:00:36 -0700 Subject: [Python-checkins] CVS: python/dist/src setup.py,1.38,1.38.2.1 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv27861 Modified Files: Tag: release21-maint setup.py Log Message: Backport AMK's checkin 1.42: Fix bug #437487: "2.1 build on Solaris fails if CC is set" by adding the contents of CCSHARED to the compiler specified by CC Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.38 retrieving revision 1.38.2.1 diff -C2 -r1.38 -r1.38.2.1 *** setup.py 2001/04/15 15:16:12 1.38 --- setup.py 2001/07/16 16:00:32 1.38.2.1 *************** *** 119,123 **** # compilers if compiler is not None: ! args['compiler_so'] = compiler if linker_so is not None: args['linker_so'] = linker_so + ' -shared' --- 119,124 ---- # compilers if compiler is not None: ! (ccshared,) = sysconfig.get_config_vars('CCSHARED') ! args['compiler_so'] = compiler + ' ' + ccshared if linker_so is not None: args['linker_so'] = linker_so + ' -shared' From twouters@users.sourceforge.net Mon Jul 16 17:03:33 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Mon, 16 Jul 2001 09:03:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules selectmodule.c,2.50.4.1,2.50.4.2 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv28393/Modules Modified Files: Tag: release21-maint selectmodule.c Log Message: Backport of AMK's checkin 2.52: [Bug #438050] Include sys/poll.h if it was found by the configure script. The OpenGroup spec says poll.h is the correct header file to use, so that file is preferred. Index: selectmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/selectmodule.c,v retrieving revision 2.50.4.1 retrieving revision 2.50.4.2 diff -C2 -r2.50.4.1 -r2.50.4.2 *** selectmodule.c 2001/06/27 13:12:47 2.50.4.1 --- selectmodule.c 2001/07/16 16:03:31 2.50.4.2 *************** *** 22,27 **** #include #endif ! #ifdef HAVE_POLL_H #include #endif --- 22,29 ---- #include #endif ! #if defined(HAVE_POLL_H) #include + #elif defined(HAVE_SYS_POLL_H) + #include #endif From twouters@users.sourceforge.net Mon Jul 16 17:07:29 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Mon, 16 Jul 2001 09:07:29 -0700 Subject: [Python-checkins] CVS: python/dist/src config.h.in,2.91.2.4,2.91.2.5 configure.in,1.215.2.4,1.215.2.5 configure,1.207.2.4,1.207.2.5 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv29183 Modified Files: Tag: release21-maint config.h.in configure.in configure Log Message: Backport of AMK's checkins of configure.in (1.228), config.h.in (2.101) and configure (1.220): [Bug #438050] Check for sys/poll.h in configure script Index: config.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/config.h.in,v retrieving revision 2.91.2.4 retrieving revision 2.91.2.5 diff -C2 -r2.91.2.4 -r2.91.2.5 *** config.h.in 2001/07/11 22:27:39 2.91.2.4 --- config.h.in 2001/07/16 16:07:26 2.91.2.5 *************** *** 609,612 **** --- 609,615 ---- #undef HAVE_SYS_PARAM_H + /* Define if you have the header file. */ + #undef HAVE_SYS_POLL_H + /* Define if you have the header file. */ #undef HAVE_SYS_RESOURCE_H Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.215.2.4 retrieving revision 1.215.2.5 diff -C2 -r1.215.2.4 -r1.215.2.5 *** configure.in 2001/07/11 22:27:39 1.215.2.4 --- configure.in 2001/07/16 16:07:26 1.215.2.5 *************** *** 383,387 **** 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/modem.h db_185.h db.h \ ! sys/param.h sys/select.h sys/socket.h sys/time.h sys/times.h \ sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ ndbm.h db1/ndbm.h gdbm/ndbm.h sys/resource.h) --- 383,387 ---- 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/modem.h db_185.h db.h \ ! sys/param.h sys/poll.h sys/select.h sys/socket.h sys/time.h sys/times.h \ sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ ndbm.h db1/ndbm.h gdbm/ndbm.h sys/resource.h) Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.207.2.4 retrieving revision 1.207.2.5 diff -C2 -r1.207.2.4 -r1.207.2.5 *** configure 2001/07/11 22:27:38 1.207.2.4 --- configure 2001/07/16 16:07:26 1.207.2.5 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.215.2.3 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.215.2.4 # Guess values for system-dependent variables and create Makefiles. *************** *** 1816,1820 **** 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/modem.h db_185.h db.h \ ! sys/param.h sys/select.h sys/socket.h sys/time.h sys/times.h \ sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ ndbm.h db1/ndbm.h gdbm/ndbm.h sys/resource.h --- 1816,1820 ---- 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/modem.h db_185.h db.h \ ! sys/param.h sys/poll.h sys/select.h sys/socket.h sys/time.h sys/times.h \ sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ ndbm.h db1/ndbm.h gdbm/ndbm.h sys/resource.h From gvanrossum@users.sourceforge.net Mon Jul 16 17:51:35 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 16 Jul 2001 09:51:35 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python pythonrun.c,2.137,2.138 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv7726 Modified Files: pythonrun.c Log Message: PyRun_StringFlags(): forgot to pass the flags on to PyParser_SimpleParseString(). Now calls PyParser_SimpleParseStringFlags() with the correct flag. Index: pythonrun.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.137 retrieving revision 2.138 diff -C2 -r2.137 -r2.138 *** pythonrun.c 2001/07/16 05:37:24 2.137 --- pythonrun.c 2001/07/16 16:51:33 2.138 *************** *** 1006,1010 **** PyCompilerFlags *flags) { ! return run_err_node(PyParser_SimpleParseString(str, start), "", globals, locals, flags); } --- 1006,1013 ---- PyCompilerFlags *flags) { ! return run_err_node(PyParser_SimpleParseStringFlags( ! str, start, ! (flags && flags->cf_flags & PyCF_GENERATORS) ? ! PyPARSE_YIELD_IS_KEYWORD : 0), "", globals, locals, flags); } From gvanrossum@users.sourceforge.net Mon Jul 16 17:53:10 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 16 Jul 2001 09:53:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python compile.c,2.207,2.208 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv8149 Modified Files: compile.c Log Message: jcompile(): inherit the CO_GENERATOR_ALLOWED flag from the 'base' compiling struct. Index: compile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v retrieving revision 2.207 retrieving revision 2.208 diff -C2 -r2.207 -r2.208 *** compile.c 2001/07/16 02:29:45 2.207 --- compile.c 2001/07/16 16:53:08 2.208 *************** *** 3946,3949 **** --- 3946,3950 ---- || (sc.c_symtable->st_cur->ste_type == TYPE_FUNCTION)) sc.c_nested = 1; + sc.c_flags |= base->c_flags & CO_GENERATOR_ALLOWED; } else { sc.c_private = NULL; From fdrake@users.sourceforge.net Mon Jul 16 19:30:37 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 16 Jul 2001 11:30:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib sgmllib.py,1.33,1.34 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv30799 Modified Files: sgmllib.py Log Message: In CDATA mode, make sure entity-reference syntax is not interpreted; entity references are not allowed in that mode. Do a better job of scanning declarations; based on the code in HTMLParser.py. Index: sgmllib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sgmllib.py,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -r1.33 -r1.34 *** sgmllib.py 2001/07/14 05:50:33 1.33 --- sgmllib.py 2001/07/16 18:30:35 1.34 *************** *** 6,10 **** # character data -- the normal case), RCDATA (replaceable character # data -- only char and entity references and end tags are special) ! # and CDATA (character data -- only end tags are special). --- 6,11 ---- # character data -- the normal case), RCDATA (replaceable character # data -- only char and entity references and end tags are special) ! # and CDATA (character data -- only end tags are special). RCDATA is ! # not supported at all. *************** *** 35,38 **** --- 36,42 ---- commentopen = re.compile(' ¬-an-entity-ref; " " ") self.collector = CDATAEventCollector self.check_events(s, [ ("starttag", "cdata", []), ("data", " ¬-an-entity-ref; "), ("endtag", "cdata"), ("starttag", "notcdata", []), ("data", " "), ("comment", " comment "), ("data", " "), ("endtag", "notcdata"), ]) s = """ """ self.check_events(s, [ ("starttag", "cdata", []), ("data", " "), ("endtag", "cdata"), ]) # XXX These tests have been disabled by prefixing their names with # an underscore. The first two exercise outstanding bugs in the # sgmllib module, and the third exhibits questionable behavior # that needs to be carefully considered before changing it. def _test_starttag_end_boundary(self): self.check_events("""""", [("starttag", "a", [("b", "<")])]) self.check_events("""""", [("starttag", "a", [("b", ">")])]) def _test_buffer_artefacts(self): output = [("starttag", "a", [("b", "<")])] self.check_events([""], output) self.check_events([""], output) self.check_events([""], output) self.check_events([""], output) self.check_events([""], output) self.check_events([""], output) output = [("starttag", "a", [("b", ">")])] self.check_events([""], output) self.check_events([""], output) self.check_events([""], output) self.check_events(["'>"], output) self.check_events([""], output) self.check_events([""], output) def _test_starttag_junk_chars(self): self.check_parse_error("<") self.check_parse_error("<>") self.check_parse_error("") self.check_parse_error("") self.check_parse_error("") self.check_parse_error("'") self.check_parse_error(" Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv12989/Python/Modules Modified Files: _tkinter.c Log Message: File handlers don't work on the mac, so don't pretend they do. I guess this is a 2.1.1 candidate, if it isn't too late for that. Index: _tkinter.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_tkinter.c,v retrieving revision 1.116 retrieving revision 1.117 diff -C2 -r1.116 -r1.117 *** _tkinter.c 2001/05/28 22:30:08 1.116 --- _tkinter.c 2001/07/16 19:32:52 1.117 *************** *** 58,62 **** #endif ! #if !(defined(MS_WINDOWS) || defined(__CYGWIN__)) #define HAVE_CREATEFILEHANDLER #endif --- 58,63 ---- #endif ! #if !(defined(MS_WINDOWS) || defined(__CYGWIN__) || defined(macintosh)) ! /* Mac has it, but it doesn't really work:-( */ #define HAVE_CREATEFILEHANDLER #endif From bwarsaw@users.sourceforge.net Mon Jul 16 21:40:37 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Mon, 16 Jul 2001 13:40:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib rfc822.py,1.57,1.58 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv29304 Modified Files: rfc822.py Log Message: Fix address parsing to be RFC 2822 conformant. Specifically, dots are now allowed in unquoted RealName areas (technically, they are defined as "obsolete syntax" we MUST accept in phrases, as part of the obs-phrase production). Thus, parsing To: User J. Person correctly returns "User J. Person" as the RealName. AddrlistClass.__init__(): Add definition of self.phraseends which is just self.atomends with `.' removed. getatom(): Add an optional argument `atomends' which, if None (the default) means use self.atomends. getphraselist(): Pass self.phraseends to getatom() and break out of the loop only when the current character is in phraseends instead of atomends. This allows dots to continue to serve as atom delimiters in all contexts except phrases. Also, loads of docstring updates to document RFC 2822 conformance (sorry, this should have been two separate patches). Index: rfc822.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/rfc822.py,v retrieving revision 1.57 retrieving revision 1.58 diff -C2 -r1.57 -r1.58 *** rfc822.py 2001/07/04 07:07:33 1.57 --- rfc822.py 2001/07/16 20:40:35 1.58 *************** *** 1,51 **** ! """RFC-822 message manipulation class. ! XXX This is only a very rough sketch of a full RFC-822 parser; ! in particular the tokenizing of addresses does not adhere to all the ! quoting rules. Directions for use: To create a Message object: first open a file, e.g.: fp = open(file, 'r') You can use any other legal way of getting an open file object, e.g. use ! sys.stdin or call os.popen(). ! Then pass the open file object to the Message() constructor: m = Message(fp) ! This class can work with any input object that supports a readline ! method. If the input object has seek and tell capability, the ! rewindbody method will work; also illegal lines will be pushed back ! onto the input stream. If the input object lacks seek but has an ! `unread' method that can push back a line of input, Message will use ! that to push back illegal lines. Thus this class can be used to parse ! messages coming from a buffered stream. ! ! The optional `seekable' argument is provided as a workaround for ! certain stdio libraries in which tell() discards buffered data before ! discovering that the lseek() system call doesn't work. For maximum ! portability, you should set the seekable argument to zero to prevent ! that initial \code{tell} when passing in an unseekable object such as ! a a file object created from a socket object. If it is 1 on entry -- ! which it is by default -- the tell() method of the open file object is ! called once; if this raises an exception, seekable is reset to 0. For ! other nonzero values of seekable, this test is not made. To get the text of a particular header there are several methods: str = m.getheader(name) str = m.getrawheader(name) - where name is the name of the header, e.g. 'Subject'. - The difference is that getheader() strips the leading and trailing - whitespace, while getrawheader() doesn't. Both functions retain - embedded whitespace (including newlines) exactly as they are - specified in the header, and leave the case of the text unchanged. For addresses and address lists there are functions ! realname, mailaddress = m.getaddr(name) and list = m.getaddrlist(name) where the latter returns a list of (realname, mailaddr) tuples. There is also a method time = m.getdate(name) which parses a Date-like field and returns a time-compatible tuple, i.e. a tuple such as returned by time.localtime() or accepted by --- 1,65 ---- ! """RFC 2822 message manipulation. ! Note: This is only a very rough sketch of a full RFC-822 parser; in particular ! the tokenizing of addresses does not adhere to all the quoting rules. + Note: RFC 2822 is a long awaited update to RFC 822. This module should + conform to RFC 2822, and is thus mis-named (it's not worth renaming it). Some + effort at RFC 2822 updates have been made, but a thorough audit has not been + performed. Consider any RFC 2822 non-conformance to be a bug. + + RFC 2822: http://www.faqs.org/rfcs/rfc2822.html + RFC 822: http://www.faqs.org/rfcs/rfc822.html (obsolete) + Directions for use: To create a Message object: first open a file, e.g.: + fp = open(file, 'r') + You can use any other legal way of getting an open file object, e.g. use ! sys.stdin or call os.popen(). Then pass the open file object to the Message() ! constructor: ! m = Message(fp) ! This class can work with any input object that supports a readline method. If ! the input object has seek and tell capability, the rewindbody method will ! work; also illegal lines will be pushed back onto the input stream. If the ! input object lacks seek but has an `unread' method that can push back a line ! of input, Message will use that to push back illegal lines. Thus this class ! can be used to parse messages coming from a buffered stream. ! ! The optional `seekable' argument is provided as a workaround for certain stdio ! libraries in which tell() discards buffered data before discovering that the ! lseek() system call doesn't work. For maximum portability, you should set the ! seekable argument to zero to prevent that initial \code{tell} when passing in ! an unseekable object such as a a file object created from a socket object. If ! it is 1 on entry -- which it is by default -- the tell() method of the open ! file object is called once; if this raises an exception, seekable is reset to ! 0. For other nonzero values of seekable, this test is not made. To get the text of a particular header there are several methods: + str = m.getheader(name) str = m.getrawheader(name) + where name is the name of the header, e.g. 'Subject'. The difference is that + getheader() strips the leading and trailing whitespace, while getrawheader() + doesn't. Both functions retain embedded whitespace (including newlines) + exactly as they are specified in the header, and leave the case of the text + unchanged. + For addresses and address lists there are functions ! ! realname, mailaddress = m.getaddr(name) list = m.getaddrlist(name) + where the latter returns a list of (realname, mailaddr) tuples. There is also a method + time = m.getdate(name) + which parses a Date-like field and returns a time-compatible tuple, i.e. a tuple such as returned by time.localtime() or accepted by *************** *** 66,70 **** class Message: ! """Represents a single RFC-822-compliant message.""" def __init__(self, fp, seekable = 1): --- 80,84 ---- class Message: ! """Represents a single RFC 2822-compliant message.""" def __init__(self, fp, seekable = 1): *************** *** 107,122 **** """Read header lines. ! Read header lines up to the entirely blank line that ! terminates them. The (normally blank) line that ends the ! headers is skipped, but not included in the returned list. ! If a non-header line ends the headers, (which is an error), ! an attempt is made to backspace over it; it is never ! included in the returned list. ! ! The variable self.status is set to the empty string if all ! went well, otherwise it is an error message. ! The variable self.headers is a completely uninterpreted list ! of lines contained in the header (so printing them will ! reproduce the header exactly as it appears in the file). """ self.dict = {} --- 121,135 ---- """Read header lines. ! Read header lines up to the entirely blank line that terminates them. ! The (normally blank) line that ends the headers is skipped, but not ! included in the returned list. If a non-header line ends the headers, ! (which is an error), an attempt is made to backspace over it; it is ! never included in the returned list. ! ! The variable self.status is set to the empty string if all went well, ! otherwise it is an error message. The variable self.headers is a ! completely uninterpreted list of lines contained in the header (so ! printing them will reproduce the header exactly as it appears in the ! file). """ self.dict = {} *************** *** 184,189 **** This method should return the header name, suitably canonicalized. ! You may override this method in order to use Message parsing ! on tagged data in RFC822-like formats with special header formats. """ i = line.find(':') --- 197,202 ---- This method should return the header name, suitably canonicalized. ! You may override this method in order to use Message parsing on tagged ! data in RFC 2822-like formats with special header formats. """ i = line.find(':') *************** *** 194,204 **** def islast(self, line): ! """Determine whether a line is a legal end of RFC-822 headers. ! You may override this method if your application wants ! to bend the rules, e.g. to strip trailing whitespace, ! or to recognize MH template separators ('--------'). ! For convenience (e.g. for code reading from sockets) a ! line consisting of \r\n also matches. """ return line in _blanklines --- 207,216 ---- def islast(self, line): ! """Determine whether a line is a legal end of RFC 2822 headers. ! You may override this method if your application wants to bend the ! rules, e.g. to strip trailing whitespace, or to recognize MH template ! separators ('--------'). For convenience (e.g. for code reading from ! sockets) a line consisting of \r\n also matches. """ return line in _blanklines *************** *** 207,213 **** """Determine whether a line should be skipped entirely. ! You may override this method in order to use Message parsing ! on tagged data in RFC822-like formats that support embedded ! comments or free-text data. """ return None --- 219,225 ---- """Determine whether a line should be skipped entirely. ! You may override this method in order to use Message parsing on tagged ! data in RFC 2822-like formats that support embedded comments or ! free-text data. """ return None *************** *** 216,226 **** """Find all header lines matching a given header name. ! Look through the list of headers and find all lines ! matching a given header name (and their continuation ! lines). A list of the lines is returned, without ! interpretation. If the header does not occur, an ! empty list is returned. If the header occurs multiple ! times, all occurrences are returned. Case is not ! important in the header name. """ name = name.lower() + ':' --- 228,236 ---- """Find all header lines matching a given header name. ! Look through the list of headers and find all lines matching a given ! header name (and their continuation lines). A list of the lines is ! returned, without interpretation. If the header does not occur, an ! empty list is returned. If the header occurs multiple times, all ! occurrences are returned. Case is not important in the header name. """ name = name.lower() + ':' *************** *** 240,246 **** """Get the first header line matching name. ! This is similar to getallmatchingheaders, but it returns ! only the first matching header (and its continuation ! lines). """ name = name.lower() + ':' --- 250,255 ---- """Get the first header line matching name. ! This is similar to getallmatchingheaders, but it returns only the ! first matching header (and its continuation lines). """ name = name.lower() + ':' *************** *** 261,269 **** """A higher-level interface to getfirstmatchingheader(). ! Return a string containing the literal text of the ! header but with the keyword stripped. All leading, ! trailing and embedded whitespace is kept in the ! string, however. ! Return None if the header does not occur. """ --- 270,277 ---- """A higher-level interface to getfirstmatchingheader(). ! Return a string containing the literal text of the header but with the ! keyword stripped. All leading, trailing and embedded whitespace is ! kept in the string, however. Return None if the header does not ! occur. """ *************** *** 277,284 **** """Get the header value for a name. ! This is the normal interface: it returns a stripped ! version of the header value for a given header name, ! or None if it doesn't exist. This uses the dictionary ! version which finds the *last* such header. """ try: --- 285,291 ---- """Get the header value for a name. ! This is the normal interface: it returns a stripped version of the ! header value for a given header name, or None if it doesn't exist. ! This uses the dictionary version which finds the *last* such header. """ try: *************** *** 291,298 **** """Get all values for a header. ! This returns a list of values for headers given more than once; ! each value in the result list is stripped in the same way as the ! result of getheader(). If the header is not given, return an ! empty list. """ result = [] --- 298,304 ---- """Get all values for a header. ! This returns a list of values for headers given more than once; each ! value in the result list is stripped in the same way as the result of ! getheader(). If the header is not given, return an empty list. """ result = [] *************** *** 333,337 **** tuple as returned by getaddr(). Scans all named headers, so it works properly with multiple To: or Cc: headers for example. - """ raw = [] --- 339,342 ---- *************** *** 353,358 **** """Retrieve a date field from a header. ! Retrieves a date field from the named header, returning ! a tuple compatible with time.mktime(). """ try: --- 358,363 ---- """Retrieve a date field from a header. ! Retrieves a date field from the named header, returning a tuple ! compatible with time.mktime(). """ try: *************** *** 365,371 **** """Retrieve a date field from a header as a 10-tuple. ! The first 9 elements make up a tuple compatible with ! time.mktime(), and the 10th is the offset of the poster's ! time zone from GMT/UTC. """ try: --- 370,375 ---- """Retrieve a date field from a header as a 10-tuple. ! The first 9 elements make up a tuple compatible with time.mktime(), ! and the 10th is the offset of the poster's time zone from GMT/UTC. """ try: *************** *** 389,395 **** """Set the value of a header. ! Note: This is not a perfect inversion of __getitem__, because ! any changed headers get stuck at the end of the raw-headers list ! rather than where the altered header was. """ del self[name] # Won't fail if it doesn't exist --- 393,399 ---- """Set the value of a header. ! Note: This is not a perfect inversion of __getitem__, because any ! changed headers get stuck at the end of the raw-headers list rather ! than where the altered header was. """ del self[name] # Won't fail if it doesn't exist *************** *** 503,508 **** To understand what this class does, it helps to have a copy of ! RFC-822 in front of you. Note: this class interface is deprecated and may be removed in the future. Use rfc822.AddressList instead. --- 507,514 ---- To understand what this class does, it helps to have a copy of ! RFC 2822 in front of you. + http://www.faqs.org/rfcs/rfc2822.html + Note: this class interface is deprecated and may be removed in the future. Use rfc822.AddressList instead. *************** *** 512,517 **** """Initialize a new instance. ! `field' is an unparsed address header field, containing ! one or more addresses. """ self.specials = '()<>@,:;.\"[]' --- 518,523 ---- """Initialize a new instance. ! `field' is an unparsed address header field, containing one or more ! addresses. """ self.specials = '()<>@,:;.\"[]' *************** *** 520,523 **** --- 526,533 ---- self.CR = '\r\n' self.atomends = self.specials + self.LWS + self.CR + # Note that RFC 2822 now specifies `.' as obs-phrase, meaning that it + # is obsolete syntax. RFC 2822 requires that we recognize obsolete + # syntax, so allow dots in phrases. + self.phraseends = self.atomends.replace('.', '') self.field = field self.commentlist = [] *************** *** 634,638 **** def getaddrspec(self): ! """Parse an RFC-822 addr-spec.""" aslist = [] --- 644,648 ---- def getaddrspec(self): ! """Parse an RFC 2822 addr-spec.""" aslist = [] *************** *** 678,690 **** """Parse a header fragment delimited by special characters. ! `beginchar' is the start character for the fragment. ! If self is not looking at an instance of `beginchar' then ! getdelimited returns the empty string. `endchars' is a sequence of allowable end-delimiting characters. Parsing stops when one of these is encountered. ! If `allowcomments' is non-zero, embedded RFC-822 comments ! are allowed within the parsed fragment. """ if self.field[self.pos] != beginchar: --- 688,700 ---- """Parse a header fragment delimited by special characters. ! `beginchar' is the start character for the fragment. If self is not ! looking at an instance of `beginchar' then getdelimited returns the ! empty string. `endchars' is a sequence of allowable end-delimiting characters. Parsing stops when one of these is encountered. ! If `allowcomments' is non-zero, embedded RFC 2822 comments are allowed ! within the parsed fragment. """ if self.field[self.pos] != beginchar: *************** *** 720,732 **** def getdomainliteral(self): ! """Parse an RFC-822 domain-literal.""" return '[%s]' % self.getdelimited('[', ']\r', 0) ! def getatom(self): ! """Parse an RFC-822 atom.""" atomlist = [''] while self.pos < len(self.field): ! if self.field[self.pos] in self.atomends: break else: atomlist.append(self.field[self.pos]) --- 730,749 ---- def getdomainliteral(self): ! """Parse an RFC 2822 domain-literal.""" return '[%s]' % self.getdelimited('[', ']\r', 0) + + def getatom(self, atomends=None): + """Parse an RFC 2822 atom. ! Optional atomends specifies a different set of end token delimiters ! (the default is to use self.atomends). This is used e.g. in ! getphraselist() since phrase endings must not include the `.' (which ! is legal in phrases).""" atomlist = [''] + if atomends is None: + atomends = self.atomends while self.pos < len(self.field): ! if self.field[self.pos] in atomends: break else: atomlist.append(self.field[self.pos]) *************** *** 736,744 **** def getphraselist(self): ! """Parse a sequence of RFC-822 phrases. ! A phrase is a sequence of words, which are in turn either ! RFC-822 atoms or quoted-strings. Phrases are canonicalized ! by squeezing all runs of continuous whitespace into one space. """ plist = [] --- 753,761 ---- def getphraselist(self): ! """Parse a sequence of RFC 2822 phrases. ! A phrase is a sequence of words, which are in turn either RFC 2822 ! atoms or quoted-strings. Phrases are canonicalized by squeezing all ! runs of continuous whitespace into one space. """ plist = [] *************** *** 751,762 **** elif self.field[self.pos] == '(': self.commentlist.append(self.getcomment()) ! elif self.field[self.pos] in self.atomends: break ! else: plist.append(self.getatom()) return plist class AddressList(AddrlistClass): ! """An AddressList encapsulates a list of parsed RFC822 addresses.""" def __init__(self, field): AddrlistClass.__init__(self, field) --- 768,780 ---- elif self.field[self.pos] == '(': self.commentlist.append(self.getcomment()) ! elif self.field[self.pos] in self.phraseends: break ! else: ! plist.append(self.getatom(self.phraseends)) return plist class AddressList(AddrlistClass): ! """An AddressList encapsulates a list of parsed RFC 2822 addresses.""" def __init__(self, field): AddrlistClass.__init__(self, field) From bwarsaw@users.sourceforge.net Mon Jul 16 21:41:42 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Mon, 16 Jul 2001 13:41:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib rfc822.py,1.58,1.59 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv29666 Modified Files: rfc822.py Log Message: Stoopid change, just to mention that the last checkin resolves SF bug #437395 Index: rfc822.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/rfc822.py,v retrieving revision 1.58 retrieving revision 1.59 diff -C2 -r1.58 -r1.59 *** rfc822.py 2001/07/16 20:40:35 1.58 --- rfc822.py 2001/07/16 20:41:40 1.59 *************** *** 10,14 **** RFC 2822: http://www.faqs.org/rfcs/rfc2822.html ! RFC 822: http://www.faqs.org/rfcs/rfc822.html (obsolete) Directions for use: --- 10,14 ---- RFC 2822: http://www.faqs.org/rfcs/rfc2822.html ! RFC 822 : http://www.faqs.org/rfcs/rfc822.html (obsolete) Directions for use: From bwarsaw@users.sourceforge.net Mon Jul 16 21:44:18 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Mon, 16 Jul 2001 13:44:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_rfc822.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv30376 Modified Files: test_rfc822.py Log Message: test_basic(): Add a test for "person@dom.ain (User J. Person)" which was already correctly parsed (contrary to a comment in Mailman). test_rfc2822_phrases(): RFC 2822 now requires that we allow `.' in phrases, which means we must accept dots in unquoted realname parts. Add a test to check the change in rfc822.py 1.58. Index: test_rfc822.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_rfc822.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -r1.11 -r1.12 *** test_rfc822.py 2001/05/22 19:38:31 1.11 --- test_rfc822.py 2001/07/16 20:44:16 1.12 *************** *** 118,121 **** --- 118,125 ---- ]) + self.check( + 'To: person@dom.ain (User J. Person)\n\n', + [('User J. Person', 'person@dom.ain')]) + def test_twisted(self): # This one is just twisted. I don't know what the proper *************** *** 165,168 **** --- 169,180 ---- [('', 'guido@[132.151.1.21]')]) + def test_rfc2822_phrases(self): + # RFC 2822 (the update to RFC 822) specifies that dots in phrases are + # obsolete syntax, which conforming programs MUST recognize but NEVER + # generate (see $4.1 Miscellaneous obsolete tokens). This is a + # departure from RFC 822 which did not allow dots in non-quoted + # phrases. + self.check('To: User J. Person \n\n', + [('User J. Person', 'person@dom.ain')]) test_support.run_unittest(MessageTestCase) From bwarsaw@users.sourceforge.net Mon Jul 16 21:48:00 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Mon, 16 Jul 2001 13:48:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib librfc822.tex,1.34,1.35 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv31284 Modified Files: librfc822.tex Log Message: Updated the documentation in several respects: - This module, despite its name, now should conform to RFC 2822, the update to RFC 822. - This module doesn't just represent "email headers", but entire email messages. - Added documentation for other useful public functions such as quote(), unquote(), praseaddr(), and dump_address_pair(). Index: librfc822.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/librfc822.tex,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -r1.34 -r1.35 *** librfc822.tex 2001/05/22 22:00:40 1.34 --- librfc822.tex 2001/07/16 20:47:58 1.35 *************** *** 1,14 **** \section{\module{rfc822} --- ! Parse RFC 822 mail headers} \declaremodule{standard}{rfc822} ! \modulesynopsis{Parse \rfc{822} style mail headers.} ! This module defines a class, \class{Message}, which represents a ! collection of ``email headers'' as defined by the Internet standard ! \rfc{822}. It is used in various contexts, usually to read such ! headers from a file. This module also defines a helper class ! \class{AddressList} for parsing \rfc{822} addresses. Please refer to ! the RFC for information on the specific syntax of \rfc{822} headers. The \refmodule{mailbox}\refstmodindex{mailbox} module provides classes --- 1,19 ---- \section{\module{rfc822} --- ! Parse RFC 2822 mail headers} \declaremodule{standard}{rfc822} ! \modulesynopsis{Parse \rfc{2822} style mail messages.} ! This module defines a class, \class{Message}, which represents an ! ``email message'' as defined by the Internet standard ! \rfc{2822}\footnote{This module originally conformed to \rfc{822}, ! hence the name. Since then, \rfc{2822} has been released as an ! update to \rfc{822}. This module should be considered ! \rfc{2822}-conformant, especially in cases where the ! syntax or semantics have changed since \rfc{822}.}. Such messages ! consist of a collection of message headers, and a message body. This ! module also defines a helper class ! \class{AddressList} for parsing \rfc{2822} addresses. Please refer to ! the RFC for information on the specific syntax of \rfc{2822} messages. The \refmodule{mailbox}\refstmodindex{mailbox} module provides classes *************** *** 51,63 **** \begin{classdesc}{AddressList}{field} You may instantiate the \class{AddressList} helper class using a single ! string parameter, a comma-separated list of \rfc{822} addresses to be parsed. (The parameter \code{None} yields an empty list.) \end{classdesc} \begin{funcdesc}{parsedate}{date} ! Attempts to parse a date according to the rules in \rfc{822}. however, some mailers don't follow that format as specified, so \function{parsedate()} tries to guess correctly in such cases. ! \var{date} is a string containing an \rfc{822} date, such as \code{'Mon, 20 Nov 1995 19:12:08 -0500'}. If it succeeds in parsing the date, \function{parsedate()} returns a 9-tuple that can be passed --- 56,95 ---- \begin{classdesc}{AddressList}{field} You may instantiate the \class{AddressList} helper class using a single ! string parameter, a comma-separated list of \rfc{2822} addresses to be parsed. (The parameter \code{None} yields an empty list.) \end{classdesc} + \begin{funcdesc}{quote}{str} + Return a new string with backslashes in \var{str} replaced by two + backslashes and double quotes replaced by backslash-double quote. + \end{funcdesc} + + \begin{funcdesc}{unquote}{str} + Return a new string which is an \emph{unquoted} version of \var{str}. + If \var{str} ends and begins with double quotes, they are stripped + off. Likewise if \var{str} ends and begins with angle brackets, they + are stripped off. + \end{funcdesc} + + \begin{funcdesc}{parseaddr}{address} + Parse address -- which should be the value of some address-containing + field such as \code{To:} or \code{Cc:} -- into its constituent + ``realname'' and ``email address'' parts. Returns a tuple of that + information, unless the parse fails, in which case a 2-tuple of + \code{(None, None)} is returned. + \end{funcdesc} + + \begin{funcdesc}{dump_address_pair}{pair} + The inverse of \method{parseaddr()}, this takes a 2-tuple of the form + \code{(realname, email_address)} and returns the string value suitable + for a \code{To:} or \code{Cc:} header. If the first element of + \var{pair} is false, then the second element is returned unmodified. + \end{funcdesc} + \begin{funcdesc}{parsedate}{date} ! Attempts to parse a date according to the rules in \rfc{2822}. however, some mailers don't follow that format as specified, so \function{parsedate()} tries to guess correctly in such cases. ! \var{date} is a string containing an \rfc{2822} date, such as \code{'Mon, 20 Nov 1995 19:12:08 -0500'}. If it succeeds in parsing the date, \function{parsedate()} returns a 9-tuple that can be passed *************** *** 75,79 **** offset is the opposite of the sign of the \code{time.timezone} variable for the same timezone; the latter variable follows the ! \POSIX{} standard while this module follows \rfc{822}.) If the input string has no timezone, the last element of the tuple returned is \code{None}. Note that fields 6, 7, and 8 of the result tuple are not --- 107,111 ---- offset is the opposite of the sign of the \code{time.timezone} variable for the same timezone; the latter variable follows the ! \POSIX{} standard while this module follows \rfc{2822}.) If the input string has no timezone, the last element of the tuple returned is \code{None}. Note that fields 6, 7, and 8 of the result tuple are not *************** *** 110,114 **** \begin{methoddesc}{isheader}{line} Returns a line's canonicalized fieldname (the dictionary key that will ! be used to index it) if the line is a legal \rfc{822} header; otherwise returns None (implying that parsing should stop here and the line be pushed back on the input stream). It is sometimes useful to override --- 142,146 ---- \begin{methoddesc}{isheader}{line} Returns a line's canonicalized fieldname (the dictionary key that will ! be used to index it) if the line is a legal \rfc{2822} header; otherwise returns None (implying that parsing should stop here and the line be pushed back on the input stream). It is sometimes useful to override From tim_one@users.sourceforge.net Mon Jul 16 21:49:51 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 13:49:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_urllib2.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv31486/python/dist/src/Lib/test Modified Files: test_urllib2.py Log Message: This has never worked on Windows. Now it does. If it breaks on Unix now, great, it's your turn to watch it fail for months <0.9 wink>. Index: test_urllib2.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_urllib2.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** test_urllib2.py 2001/05/29 06:06:54 1.2 --- test_urllib2.py 2001/07/16 20:49:49 1.3 *************** *** 1,4 **** --- 1,5 ---- from test_support import verify import urllib2 + import os # A couple trivial tests *************** *** 11,16 **** verify(0) ! file_url = "file://%s" % urllib2.__file__ f = urllib2.urlopen(file_url) buf = f.read() f.close() --- 12,22 ---- verify(0) ! # XXX Name hacking to get this to work on Windows. ! fname = os.path.abspath(urllib2.__file__).replace('\\', '/') ! if fname[1:2] == ":": ! fname = fname[2:] ! file_url = "file://%s" % fname f = urllib2.urlopen(file_url) + buf = f.read() f.close() From tim_one@users.sourceforge.net Mon Jul 16 22:21:08 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 14:21:08 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.1.2.29,1.1.2.30 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv6458/descr/dist/src Modified Files: Tag: descr-branch PLAN.txt Log Message: Merge of trunk delta from tag date2001-07-15 to tag date2001-07-16. From tim_one@users.sourceforge.net Mon Jul 16 22:21:09 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 14:21:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Demo/sgi/video IN.py,NONE,1.1.2.1 Makefile,NONE,1.1.2.1 Vrecc.py,NONE,1.1.2.1 cam.py,NONE,1.2.2.1 camcorder.py,NONE,1.4.2.1 colorsys.py,NONE,1.4.2.1 i2v.c,NONE,1.1.2.1 makemovie.py,NONE,1.4.2.1 squash.c,NONE,1.2.2.1 squash2.c,NONE,1.1.2.1 statit.py,NONE,1.2.2.1 syncaudio.py,NONE,1.2.2.1 tomono.c,NONE,1.1.2.1 tv.py,NONE,1.2.2.1 v2i.c,NONE,1.2.2.1 video.py,NONE,1.10.2.1 vpregs.py,NONE,1.1.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Demo/sgi/video In directory usw-pr-cvs1:/tmp/cvs-serv6458/descr/dist/src/Demo/sgi/video Added Files: Tag: descr-branch IN.py Makefile Vrecc.py cam.py camcorder.py colorsys.py i2v.c makemovie.py squash.c squash2.c statit.py syncaudio.py tomono.c tv.py v2i.c video.py vpregs.py Log Message: Merge of trunk delta from tag date2001-07-15 to tag date2001-07-16. --- NEW FILE: IN.py --- --- NEW FILE: Makefile --- --- NEW FILE: Vrecc.py --- --- NEW FILE: cam.py --- --- NEW FILE: camcorder.py --- --- NEW FILE: colorsys.py --- --- NEW FILE: i2v.c --- --- NEW FILE: makemovie.py --- --- NEW FILE: squash.c --- --- NEW FILE: squash2.c --- --- NEW FILE: statit.py --- --- NEW FILE: syncaudio.py --- --- NEW FILE: tomono.c --- --- NEW FILE: tv.py --- --- NEW FILE: v2i.c --- --- NEW FILE: video.py --- --- NEW FILE: vpregs.py --- From tim_one@users.sourceforge.net Mon Jul 16 22:21:09 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 14:21:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Demo/scripts freeze.py,NONE,1.5.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Demo/scripts In directory usw-pr-cvs1:/tmp/cvs-serv6458/descr/dist/src/Demo/scripts Added Files: Tag: descr-branch freeze.py Log Message: Merge of trunk delta from tag date2001-07-15 to tag date2001-07-16. --- NEW FILE: freeze.py --- From tim_one@users.sourceforge.net Mon Jul 16 22:21:08 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 14:21:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Demo/pdist new,NONE,1.1.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Demo/pdist In directory usw-pr-cvs1:/tmp/cvs-serv6458/descr/dist/src/Demo/pdist Added Files: Tag: descr-branch new Log Message: Merge of trunk delta from tag date2001-07-15 to tag date2001-07-16. --- NEW FILE: new --- From tim_one@users.sourceforge.net Mon Jul 16 22:38:11 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 14:38:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include Python.h,2.32.2.2,2.32.2.3 ceval.h,2.41.4.2,2.41.4.3 compile.h,2.29.4.2,2.29.4.3 parsetok.h,2.15,2.15.8.1 pythonrun.h,2.41.4.1,2.41.4.2 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv11200/descr/dist/src/Include Modified Files: Tag: descr-branch Python.h ceval.h compile.h parsetok.h pythonrun.h Log Message: Resuming interrupted merge checkin. Index: Python.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/Python.h,v retrieving revision 2.32.2.2 retrieving revision 2.32.2.3 diff -C2 -r2.32.2.2 -r2.32.2.3 *** Python.h 2001/07/15 20:26:55 2.32.2.2 --- Python.h 2001/07/16 21:38:09 2.32.2.3 *************** *** 98,103 **** #include "modsupport.h" - #include "ceval.h" #include "pythonrun.h" #include "sysmodule.h" #include "intrcheck.h" --- 98,103 ---- #include "modsupport.h" #include "pythonrun.h" + #include "ceval.h" #include "sysmodule.h" #include "intrcheck.h" Index: ceval.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/ceval.h,v retrieving revision 2.41.4.2 retrieving revision 2.41.4.3 diff -C2 -r2.41.4.2 -r2.41.4.3 *** ceval.h 2001/07/07 22:55:27 2.41.4.2 --- ceval.h 2001/07/16 21:38:09 2.41.4.3 *************** *** 32,36 **** DL_IMPORT(PyObject *) PyEval_GetFrame(void); DL_IMPORT(int) PyEval_GetRestricted(void); ! DL_IMPORT(int) PyEval_GetNestedScopes(void); DL_IMPORT(int) Py_FlushLine(void); --- 32,40 ---- DL_IMPORT(PyObject *) PyEval_GetFrame(void); DL_IMPORT(int) PyEval_GetRestricted(void); ! ! /* Look at the current frame's (if any) code's co_flags, and turn on ! the corresponding compiler flags in cf->cf_flags. Return 1 if any ! flag was set, else return 0. */ ! DL_IMPORT(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf); DL_IMPORT(int) Py_FlushLine(void); Index: compile.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/compile.h,v retrieving revision 2.29.4.2 retrieving revision 2.29.4.3 diff -C2 -r2.29.4.2 -r2.29.4.3 *** compile.h 2001/07/14 07:47:34 2.29.4.2 --- compile.h 2001/07/16 21:38:09 2.29.4.3 *************** *** 35,38 **** --- 35,45 ---- #define CO_NESTED 0x0010 #define CO_GENERATOR 0x0020 + /* XXX Temporary hack. Until generators are a permanent part of the + language, we need a way for a code object to record that generators + were *possible* when it was compiled. This is so code dynamically + compiled *by* a code object knows whether to allow yield stmts. In + effect, this passes on the "from __future__ import generators" state + in effect when the code block was compiled. */ + #define CO_GENERATOR_ALLOWED 0x1000 extern DL_IMPORT(PyTypeObject) PyCode_Type; *************** *** 57,60 **** --- 64,68 ---- int ff_last_lineno; int ff_nested_scopes; + int ff_generators; } PyFutureFeatures; *************** *** 65,68 **** --- 73,79 ---- #define NESTED_SCOPES_DEFAULT 1 #define FUTURE_NESTED_SCOPES "nested_scopes" + + #define GENERATORS_DEFAULT 0 + #define FUTURE_GENERATORS "generators" /* for internal use only */ Index: parsetok.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/parsetok.h,v retrieving revision 2.15 retrieving revision 2.15.8.1 diff -C2 -r2.15 -r2.15.8.1 *** parsetok.h 2000/09/01 23:29:26 2.15 --- parsetok.h 2001/07/16 21:38:09 2.15.8.1 *************** *** 18,25 **** --- 18,33 ---- } perrdetail; + #define PyPARSE_YIELD_IS_KEYWORD 0x0001 + extern DL_IMPORT(node *) PyParser_ParseString(char *, grammar *, int, perrdetail *); extern DL_IMPORT(node *) PyParser_ParseFile (FILE *, char *, grammar *, int, char *, char *, perrdetail *); + + extern DL_IMPORT(node *) PyParser_ParseStringFlags(char *, grammar *, int, + perrdetail *, int); + extern DL_IMPORT(node *) PyParser_ParseFileFlags(FILE *, char *, grammar *, + int, char *, char *, + perrdetail *, int); #ifdef __cplusplus Index: pythonrun.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pythonrun.h,v retrieving revision 2.41.4.1 retrieving revision 2.41.4.2 diff -C2 -r2.41.4.1 -r2.41.4.2 *** pythonrun.h 2001/06/28 16:15:37 2.41.4.1 --- pythonrun.h 2001/07/16 21:38:09 2.41.4.2 *************** *** 8,13 **** #endif typedef struct { ! int cf_nested_scopes; } PyCompilerFlags; --- 8,18 ---- #endif + /* These flags are named after the __future__ statements that introduced + them. May not remain true for later additions, so fiddle this comment + accordingly then. */ + #define PyCF_NESTED_SCOPES (0x00000001UL) + #define PyCF_GENERATORS (0x00000002UL) typedef struct { ! unsigned long cf_flags; /* bitmask of PyCF_xxx flags */ } PyCompilerFlags; *************** *** 41,44 **** --- 46,52 ---- DL_IMPORT(struct _node *) PyParser_SimpleParseString(char *, int); DL_IMPORT(struct _node *) PyParser_SimpleParseFile(FILE *, char *, int); + DL_IMPORT(struct _node *) PyParser_SimpleParseStringFlags(char *, int, int); + DL_IMPORT(struct _node *) PyParser_SimpleParseFileFlags(FILE *, char *, + int, int); DL_IMPORT(PyObject *) PyRun_String(char *, int, PyObject *, PyObject *); From tim_one@users.sourceforge.net Mon Jul 16 22:39:43 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 14:39:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/distutils unixccompiler.py,1.33,1.33.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils In directory usw-pr-cvs1:/tmp/cvs-serv11584/descr/dist/src/Lib/distutils Modified Files: Tag: descr-branch unixccompiler.py Log Message: Resuming interrupted merge checkin. Index: unixccompiler.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/unixccompiler.py,v retrieving revision 1.33 retrieving revision 1.33.4.1 diff -C2 -r1.33 -r1.33.4.1 *** unixccompiler.py 2001/04/05 15:46:48 1.33 --- unixccompiler.py 2001/07/16 21:39:41 1.33.4.1 *************** *** 100,109 **** pp_args[:0] = extra_preargs if extra_postargs: ! extra_postargs.extend(extra_postargs) ! # We need to preprocess: either we're being forced to, or the ! # source file is newer than the target (or the target doesn't # exist). ! if self.force or (output_file and newer(source, output_file)): if output_file: self.mkpath(os.path.dirname(output_file)) --- 100,110 ---- pp_args[:0] = extra_preargs if extra_postargs: ! pp_args.extend(extra_postargs) ! # We need to preprocess: either we're being forced to, or we're ! # generating output to stdout, or there's a target output file and ! # the source file is newer than the target (or the target doesn't # exist). ! if self.force or output_file is None or newer(source, output_file): if output_file: self.mkpath(os.path.dirname(output_file)) From tim_one@users.sourceforge.net Mon Jul 16 22:39:43 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 14:39:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib builtin.py,NONE,1.1.2.1 macstat.py,NONE,1.1.2.1 persist.py,NONE,1.6.4.1 __future__.py,1.5.4.1,1.5.4.2 doctest.py,1.10.4.1,1.10.4.2 inspect.py,1.16,1.16.4.1 sgmllib.py,1.30.4.2,1.30.4.3 tokenize.py,1.22.4.1,1.22.4.2 types.py,1.14.10.6,1.14.10.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv11584/descr/dist/src/Lib Modified Files: Tag: descr-branch __future__.py doctest.py inspect.py sgmllib.py tokenize.py types.py Added Files: Tag: descr-branch builtin.py macstat.py persist.py Log Message: Resuming interrupted merge checkin. --- NEW FILE: builtin.py --- # B/W compat hack so code that says "import builtin" won't break after # name change from builtin to __builtin__. from __builtin__ import * --- NEW FILE: macstat.py --- # Module 'stat' # # Defines constants and functions for interpreting stat/lstat struct # as returned by os.stat() and os.lstat() (if it exists). # # Suggested usage: from stat import * # # XXX Strictly spoken, this module may have to be adapted for each POSIX # implementation; in practice, however, the numeric constants used by # stat() are almost universal (even for stat() emulations on non-UNIX # systems like MS-DOS). # Indices for stat struct members in tuple returned by os.stat() ST_MODE = 0 ST_INO = 1 ST_DEV = 2 ST_NLINK = 3 ST_UID = 4 ST_GID = 5 ST_SIZE = 6 ST_ATIME = 7 ST_MTIME = 8 ST_CTIME = 9 # Extract bits from the mode def S_IMODE(mode): return 0 def S_IFMT(mode): return mode & 0xFFFF # Constants used as S_IFMT() for various file types # (not all are implemented on all systems) S_IFDIR = 0x0000 S_IFREG = 0x0003 # Functions to test for each file type def S_ISDIR(mode): return S_IFMT(mode) == S_IFDIR def S_ISCHR(mode): return 0 def S_ISBLK(mode): return 0 def S_ISREG(mode): return S_IFMT(mode) == S_IFREG def S_ISFIFO(mode): return 0 def S_ISLNK(mode): return 0 def S_ISSOCK(mode): return 0 # Names for permission bits S_ISUID = 04000 S_ISGID = 02000 S_ENFMT = S_ISGID S_ISVTX = 01000 S_IREAD = 00400 S_IWRITE = 00200 S_IEXEC = 00100 S_IRWXU = 00700 S_IRUSR = 00400 S_IWUSR = 00200 S_IXUSR = 00100 S_IRWXG = 00070 S_IRGRP = 00040 S_IWGRP = 00020 S_IXGRP = 00010 S_IRWXO = 00007 S_IROTH = 00004 S_IWOTH = 00002 S_IXOTH = 00001 --- NEW FILE: persist.py --- # persist.py # # Implement limited persistence. # # Simple interface: # persist.save() save __main__ module on file (overwrite) # persist.load() load __main__ module from file (merge) # # These use the filename persist.defaultfile, initialized to 'wsrestore.py'. # # A raw interface also exists: # persist.writedict(dict, fp) save dictionary to open file # persist.readdict(dict, fp) read (merge) dictionary from open file # # Internally, the function dump() and a whole bunch of support of functions # traverse a graph of objects and print them in a restorable form # (which happens to be a Python module). # # XXX Limitations: # - Volatile objects are dumped as strings: # - open files, windows etc. # - Other 'obscure' objects are dumped as strings: # - classes, instances and methods # - compiled regular expressions # - anything else reasonably obscure (e.g., capabilities) # - type objects for obscure objects # - It's slow when there are many of lists or dictionaries # (This could be fixed if there were a quick way to compute a hash # function of any object, even if recursive) defaultfile = 'wsrestore.py' def save(): import __main__ import os # XXX On SYSV, if len(defaultfile) >= 14, this is wrong! backup = defaultfile + '~' try: os.unlink(backup) except os.error: pass try: os.rename(defaultfile, backup) except os.error: pass fp = open(defaultfile, 'w') writedict(__main__.__dict__, fp) fp.close() def load(): import __main__ fp = open(defaultfile, 'r') readdict(__main__.__dict__, fp) def writedict(dict, fp): import sys savestdout = sys.stdout try: sys.stdout = fp dump(dict) # Writes to sys.stdout finally: sys.stdout = savestdout def readdict(dict, fp): contents = fp.read() globals = {} exec(contents, globals) top = globals['top'] for key in top.keys(): if dict.has_key(key): print 'warning:', key, 'not overwritten' else: dict[key] = top[key] # Function dump(x) prints (on sys.stdout!) a sequence of Python statements # that, when executed in an empty environment, will reconstruct the # contents of an arbitrary dictionary. import sys # Name used for objects dict on output. # FUNNYNAME = FN = 'A' # Top-level function. Call with the object you want to dump. # def dump(x): types = {} stack = [] # Used by test for recursive objects print FN, '= {}' topuid = dumpobject(x, types, stack) print 'top =', FN, '[', `topuid`, ']' # Generic function to dump any object. # dumpswitch = {} # def dumpobject(x, types, stack): typerepr = `type(x)` if not types.has_key(typerepr): types[typerepr] = {} typedict = types[typerepr] if dumpswitch.has_key(typerepr): return dumpswitch[typerepr](x, typedict, types, stack) else: return dumpbadvalue(x, typedict, types, stack) # Generic function to dump unknown values. # This assumes that the Python interpreter prints such values as # . # The object will be read back as a string: ''. # In some cases it may be possible to fix the dump manually; # to ease the editing, these cases are labeled with an XXX comment. # def dumpbadvalue(x, typedict, types, stack): xrepr = `x` if typedict.has_key(xrepr): return typedict[xrepr] uid = genuid() typedict[xrepr] = uid print FN, '[', `uid`, '] =', `xrepr`, '# XXX' return uid # Generic function to dump pure, simple values, except strings # def dumpvalue(x, typedict, types, stack): xrepr = `x` if typedict.has_key(xrepr): return typedict[xrepr] uid = genuid() typedict[xrepr] = uid print FN, '[', `uid`, '] =', `x` return uid # Functions to dump string objects # def dumpstring(x, typedict, types, stack): # XXX This can break if strings have embedded '\0' bytes # XXX because of a bug in the dictionary module if typedict.has_key(x): return typedict[x] uid = genuid() typedict[x] = uid print FN, '[', `uid`, '] =', `x` return uid # Function to dump type objects # typeswitch = {} class some_class: def method(self): pass some_instance = some_class() # def dumptype(x, typedict, types, stack): xrepr = `x` if typedict.has_key(xrepr): return typedict[xrepr] uid = genuid() typedict[xrepr] = uid if typeswitch.has_key(xrepr): print FN, '[', `uid`, '] =', typeswitch[xrepr] elif x == type(sys): print 'import sys' print FN, '[', `uid`, '] = type(sys)' elif x == type(sys.stderr): print 'import sys' print FN, '[', `uid`, '] = type(sys.stderr)' elif x == type(dumptype): print 'def some_function(): pass' print FN, '[', `uid`, '] = type(some_function)' elif x == type(some_class): print 'class some_class: pass' print FN, '[', `uid`, '] = type(some_class)' elif x == type(some_instance): print 'class another_class: pass' print 'some_instance = another_class()' print FN, '[', `uid`, '] = type(some_instance)' elif x == type(some_instance.method): print 'class yet_another_class:' print ' def method(): pass' print 'another_instance = yet_another_class()' print FN, '[', `uid`, '] = type(another_instance.method)' else: # Unknown type print FN, '[', `uid`, '] =', `xrepr`, '# XXX' return uid # Initialize the typeswitch # for x in None, 0, 0.0, '', (), [], {}: typeswitch[`type(x)`] = 'type(' + `x` + ')' for s in 'type(0)', 'abs', '[].append': typeswitch[`type(eval(s))`] = 'type(' + s + ')' # Dump a tuple object # def dumptuple(x, typedict, types, stack): item_uids = [] xrepr = '' for item in x: item_uid = dumpobject(item, types, stack) item_uids.append(item_uid) xrepr = xrepr + ' ' + item_uid del stack[-1:] if typedict.has_key(xrepr): return typedict[xrepr] uid = genuid() typedict[xrepr] = uid print FN, '[', `uid`, '] = (', for item_uid in item_uids: print FN, '[', `item_uid`, '],', print ')' return uid # Dump a list object # def dumplist(x, typedict, types, stack): # Check for recursion for x1, uid1 in stack: if x is x1: return uid1 # Check for occurrence elsewhere in the typedict for uid1 in typedict.keys(): if x is typedict[uid1]: return uid1 # This uses typedict differently! uid = genuid() typedict[uid] = x print FN, '[', `uid`, '] = []' stack.append(x, uid) item_uids = [] for item in x: item_uid = dumpobject(item, types, stack) item_uids.append(item_uid) del stack[-1:] for item_uid in item_uids: print FN, '[', `uid`, '].append(', FN, '[', `item_uid`, '])' return uid # Dump a dictionary object # def dumpdict(x, typedict, types, stack): # Check for recursion for x1, uid1 in stack: if x is x1: return uid1 # Check for occurrence elsewhere in the typedict for uid1 in typedict.keys(): if x is typedict[uid1]: return uid1 # This uses typedict differently! uid = genuid() typedict[uid] = x print FN, '[', `uid`, '] = {}' stack.append(x, uid) item_uids = [] for key in x.keys(): val_uid = dumpobject(x[key], types, stack) item_uids.append(key, val_uid) del stack[-1:] for key, val_uid in item_uids: print FN, '[', `uid`, '][', `key`, '] =', print FN, '[', `val_uid`, ']' return uid # Dump a module object # def dumpmodule(x, typedict, types, stack): xrepr = `x` if typedict.has_key(xrepr): return typedict[xrepr] from string import split # `x` has the form name = xrepr[9:-2] uid = genuid() typedict[xrepr] = uid print 'import', name print FN, '[', `uid`, '] =', name return uid # Initialize dumpswitch, a table of functions to dump various objects, # indexed by `type(x)`. # for x in None, 0, 0.0: dumpswitch[`type(x)`] = dumpvalue for x, f in ('', dumpstring), (type(0), dumptype), ((), dumptuple), \ ([], dumplist), ({}, dumpdict), (sys, dumpmodule): dumpswitch[`type(x)`] = f # Generate the next unique id; a string consisting of digits. # The seed is stored as seed[0]. # seed = [0] # def genuid(): x = seed[0] seed[0] = seed[0] + 1 return `x` Index: __future__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/__future__.py,v retrieving revision 1.5.4.1 retrieving revision 1.5.4.2 diff -C2 -r1.5.4.1 -r1.5.4.2 *** __future__.py 2001/07/14 07:47:34 1.5.4.1 --- __future__.py 2001/07/16 21:39:41 1.5.4.2 *************** *** 68,69 **** --- 68,70 ---- nested_scopes = _Feature((2, 1, 0, "beta", 1), (2, 2, 0, "alpha", 0)) + generators = _Feature((2, 2, 0, "alpha", 1), (2, 3, 0, "final", 0)) Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.10.4.1 retrieving revision 1.10.4.2 diff -C2 -r1.10.4.1 -r1.10.4.2 *** doctest.py 2001/07/07 22:55:27 1.10.4.1 --- doctest.py 2001/07/16 21:39:41 1.10.4.2 *************** *** 349,352 **** --- 349,361 ---- # string method conversion + # XXX Until generators are part of the language, examples in doctest'ed + # modules will inherit doctest's __future__ settings (see PEP 236 for + # more on that). In the absence of a better working idea, the std + # test suite needs generators, while the set of doctest'ed modules that + # don't use "yield" in a generator context may well be empty. So + # enable generators here. This can go away when generators are no + # longer optional. + from __future__ import generators + __version__ = 0, 9, 7 Index: inspect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/inspect.py,v retrieving revision 1.16 retrieving revision 1.16.4.1 diff -C2 -r1.16 -r1.16.4.1 *** inspect.py 2001/04/13 14:04:02 1.16 --- inspect.py 2001/07/16 21:39:41 1.16.4.1 *************** *** 25,28 **** --- 25,30 ---- # This module is in the public domain. No warranties. + from __future__ import generators + __author__ = 'Ka-Ping Yee ' __date__ = '1 Jan 2001' Index: sgmllib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sgmllib.py,v retrieving revision 1.30.4.2 retrieving revision 1.30.4.3 diff -C2 -r1.30.4.2 -r1.30.4.3 *** sgmllib.py 2001/07/15 20:26:55 1.30.4.2 --- sgmllib.py 2001/07/16 21:39:41 1.30.4.3 *************** *** 6,10 **** # character data -- the normal case), RCDATA (replaceable character # data -- only char and entity references and end tags are special) ! # and CDATA (character data -- only end tags are special). --- 6,11 ---- # character data -- the normal case), RCDATA (replaceable character # data -- only char and entity references and end tags are special) ! # and CDATA (character data -- only end tags are special). RCDATA is ! # not supported at all. *************** *** 35,38 **** --- 36,42 ---- commentopen = re.compile(' ¬-an-entity-ref; " " ") self.collector = CDATAEventCollector self.check_events(s, [ ("starttag", "cdata", []), ("data", " ¬-an-entity-ref; "), ("endtag", "cdata"), ("starttag", "notcdata", []), ("data", " "), ("comment", " comment "), ("data", " "), ("endtag", "notcdata"), ]) s = """ """ self.check_events(s, [ ("starttag", "cdata", []), ("data", " "), ("endtag", "cdata"), ]) # XXX These tests have been disabled by prefixing their names with # an underscore. The first two exercise outstanding bugs in the # sgmllib module, and the third exhibits questionable behavior # that needs to be carefully considered before changing it. def _test_starttag_end_boundary(self): self.check_events("""""", [("starttag", "a", [("b", "<")])]) self.check_events("""""", [("starttag", "a", [("b", ">")])]) def _test_buffer_artefacts(self): output = [("starttag", "a", [("b", "<")])] self.check_events([""], output) self.check_events([""], output) self.check_events([""], output) self.check_events([""], output) self.check_events([""], output) self.check_events([""], output) output = [("starttag", "a", [("b", ">")])] self.check_events([""], output) self.check_events([""], output) self.check_events([""], output) self.check_events(["'>"], output) self.check_events([""], output) self.check_events([""], output) def _test_starttag_junk_chars(self): self.check_parse_error("<") self.check_parse_error("<>") self.check_parse_error("") self.check_parse_error("") self.check_parse_error("") self.check_parse_error("'") self.check_parse_error("") self._parse_error("") --- 200,203 ---- Index: test_support.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_support.py,v retrieving revision 1.21.4.1 retrieving revision 1.21.4.2 diff -C2 -r1.21.4.1 -r1.21.4.2 *** test_support.py 2001/07/06 21:20:46 1.21.4.1 --- test_support.py 2001/07/16 21:39:41 1.21.4.2 *************** *** 136,139 **** result = runner.run(suite) if not result.wasSuccessful(): ! raise TestFailed("errors occurred in %s.%s" ! % (testclass.__module__, testclass.__name__)) --- 136,148 ---- result = runner.run(suite) if not result.wasSuccessful(): ! if len(result.errors) == 1 and not result.failures: ! err = result.errors[0][1] ! elif len(result.failures) == 1 and not result.errors: ! err = result.failures[0][1] ! else: ! raise TestFailed("errors occurred in %s.%s" ! % (testclass.__module__, testclass.__name__)) ! if err[0] is AssertionError: ! raise TestFailed(str(err[1])) ! else: ! raise TestFailed("%s: %s" % err[:2]) From tim_one@users.sourceforge.net Mon Jul 16 22:41:09 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 14:41:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Parser parser.c,2.18,2.18.8.1 parser.h,2.14,2.14.8.1 parsetok.c,2.25,2.25.8.1 Message-ID: Update of /cvsroot/python/python/dist/src/Parser In directory usw-pr-cvs1:/tmp/cvs-serv12044/descr/dist/src/Parser Modified Files: Tag: descr-branch parser.c parser.h parsetok.c Log Message: Resuming interrupted merge checkin. Index: parser.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Parser/parser.c,v retrieving revision 2.18 retrieving revision 2.18.8.1 diff -C2 -r2.18 -r2.18.8.1 *** parser.c 2000/10/02 10:21:59 2.18 --- parser.c 2001/07/16 21:41:07 2.18.8.1 *************** *** 80,83 **** --- 80,84 ---- return NULL; ps->p_grammar = g; + ps->p_generators = 0; ps->p_tree = PyNode_New(start); if (ps->p_tree == NULL) { *************** *** 132,137 **** static int ! classify(grammar *g, int type, char *str) { register int n = g->g_ll.ll_nlabels; --- 133,139 ---- static int ! classify(parser_state *ps, int type, char *str) { + grammar *g = ps->p_grammar; register int n = g->g_ll.ll_nlabels; *************** *** 144,147 **** --- 146,153 ---- l->lb_str[0] == s[0] && strcmp(l->lb_str, s) == 0) { + if (!ps->p_generators && + s[0] == 'y' && + strcmp(s, "yield") == 0) + break; /* not a keyword */ D(printf("It's a keyword\n")); return n - i; *************** *** 165,168 **** --- 171,190 ---- } + static void + future_hack(parser_state *ps) + { + node *n = ps->p_stack.s_top->s_parent; + node *ch; + + if (strcmp(STR(CHILD(n, 0)), "from") != 0) + return; + ch = CHILD(n, 1); + if (strcmp(STR(CHILD(ch, 0)), "__future__") != 0) + return; + ch = CHILD(n, 3); + if (NCH(ch) == 1 && strcmp(STR(CHILD(ch, 0)), "generators") == 0) + ps->p_generators = 1; + } + int PyParser_AddToken(register parser_state *ps, register int type, char *str, *************** *** 175,179 **** /* Find out which label this token is */ ! ilabel = classify(ps->p_grammar, type, str); if (ilabel < 0) return E_SYNTAX; --- 197,201 ---- /* Find out which label this token is */ ! ilabel = classify(ps, type, str); if (ilabel < 0) return E_SYNTAX; *************** *** 218,222 **** [ps->p_stack.s_top->s_state], s->s_accept && s->s_narcs == 1) { ! D(printf(" Direct pop.\n")); s_pop(&ps->p_stack); if (s_empty(&ps->p_stack)) { --- 240,251 ---- [ps->p_stack.s_top->s_state], s->s_accept && s->s_narcs == 1) { ! D(printf(" DFA '%s', state %d: " ! "Direct pop.\n", ! d->d_name, ! ps->p_stack.s_top->s_state)); ! if (d->d_name[0] == 'i' && ! strcmp(d->d_name, ! "import_stmt") == 0) ! future_hack(ps); s_pop(&ps->p_stack); if (s_empty(&ps->p_stack)) { *************** *** 231,234 **** --- 260,266 ---- if (s->s_accept) { + if (d->d_name[0] == 'i' && + strcmp(d->d_name, "import_stmt") == 0) + future_hack(ps); /* Pop this dfa and try again */ s_pop(&ps->p_stack); Index: parser.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Parser/parser.h,v retrieving revision 2.14 retrieving revision 2.14.8.1 diff -C2 -r2.14 -r2.14.8.1 *** parser.h 2000/09/01 23:29:28 2.14 --- parser.h 2001/07/16 21:41:07 2.14.8.1 *************** *** 26,29 **** --- 26,30 ---- grammar *p_grammar; /* Grammar to use */ node *p_tree; /* Top of parse tree */ + int p_generators; /* 1 if yield is a keyword */ } parser_state; Index: parsetok.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Parser/parsetok.c,v retrieving revision 2.25 retrieving revision 2.25.8.1 diff -C2 -r2.25 -r2.25.8.1 *** parsetok.c 2000/09/01 23:29:28 2.25 --- parsetok.c 2001/07/16 21:41:07 2.25.8.1 *************** *** 14,24 **** /* Forward */ ! static node *parsetok(struct tok_state *, grammar *, int, perrdetail *); /* Parse input coming from a string. Return error code, print some errors. */ - node * PyParser_ParseString(char *s, grammar *g, int start, perrdetail *err_ret) { struct tok_state *tok; --- 14,30 ---- /* Forward */ ! static node *parsetok(struct tok_state *, grammar *, int, perrdetail *, int); /* Parse input coming from a string. Return error code, print some errors. */ node * PyParser_ParseString(char *s, grammar *g, int start, perrdetail *err_ret) { + return PyParser_ParseStringFlags(s, g, start, err_ret, 0); + } + + node * + PyParser_ParseStringFlags(char *s, grammar *g, int start, + perrdetail *err_ret, int flags) + { struct tok_state *tok; *************** *** 43,47 **** } ! return parsetok(tok, g, start, err_ret); } --- 49,53 ---- } ! return parsetok(tok, g, start, err_ret, flags); } *************** *** 53,56 **** --- 59,70 ---- char *ps1, char *ps2, perrdetail *err_ret) { + return PyParser_ParseFileFlags(fp, filename, g, start, ps1, ps2, + err_ret, 0); + } + + node * + PyParser_ParseFileFlags(FILE *fp, char *filename, grammar *g, int start, + char *ps1, char *ps2, perrdetail *err_ret, int flags) + { struct tok_state *tok; *************** *** 73,77 **** ! return parsetok(tok, g, start, err_ret); } --- 87,91 ---- ! return parsetok(tok, g, start, err_ret, flags); } *************** *** 80,84 **** static node * ! parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret) { parser_state *ps; --- 94,99 ---- static node * ! parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret, ! int flags) { parser_state *ps; *************** *** 91,94 **** --- 106,111 ---- return NULL; } + if (flags & PyPARSE_YIELD_IS_KEYWORD) + ps->p_generators = 1; for (;;) { From tim_one@users.sourceforge.net Mon Jul 16 22:42:49 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 14:42:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python pythonmain.c,NONE,2.30.2.1 bltinmodule.c,2.198.2.8,2.198.2.9 ceval.c,2.241.2.8,2.241.2.9 compile.c,2.197.2.1,2.197.2.2 future.c,2.5,2.5.6.1 pythonrun.c,2.133.4.4,2.133.4.5 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv12359/descr/dist/src/Python Modified Files: Tag: descr-branch bltinmodule.c ceval.c compile.c future.c pythonrun.c Added Files: Tag: descr-branch pythonmain.c Log Message: Resuming interrupted merge checkin. --- NEW FILE: pythonmain.c --- /*********************************************************** Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam, The Netherlands. 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 names of Stichting Mathematisch Centrum or CWI not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM 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. ******************************************************************/ /* Python interpreter main program */ #include "allobjects.h" extern int debugging; /* Needed in parser.c, declared in pythonrun.c */ extern int verbose; /* Needed in import.c, declared in pythonrun.c */ extern int suppress_print; /* Needed in ceval.c, declared in pythonrun.c */ /* Interface to getopt(): */ extern int optind; extern char *optarg; extern int getopt(); /* PROTO((int, char **, char *)); -- not standardized */ extern char *getenv(); extern char *getversion(); extern char *getcopyright(); int realmain(argc, argv) int argc; char **argv; { int c; int sts; char *command = NULL; char *filename = NULL; FILE *fp = stdin; char *p; int inspect = 0; int unbuffered = 0; if ((p = getenv("PYTHONDEBUG")) && *p != '\0') debugging = 1; if ((p = getenv("PYTHONSUPPRESS")) && *p != '\0') suppress_print = 1; if ((p = getenv("PYTHONVERBOSE")) && *p != '\0') verbose = 1; if ((p = getenv("PYTHONINSPECT")) && *p != '\0') inspect = 1; if ((p = getenv("PYTHONUNBUFFERED")) && *p != '\0') unbuffered = 1; #ifdef macintosh PyMac_InteractiveOptions(&inspect, &verbose, &suppress_print, &unbuffered, &debugging); #endif while ((c = getopt(argc, argv, "c:disuv")) != EOF) { if (c == 'c') { /* -c is the last option; following arguments that look like options are left for the the command to interpret. */ command = malloc(strlen(optarg) + 2); if (command == NULL) fatal("not enough memory to copy -c argument"); strcpy(command, optarg); strcat(command, "\n"); break; } switch (c) { case 'd': debugging++; break; case 'i': inspect++; break; case 's': suppress_print++; break; case 'u': unbuffered++; break; case 'v': verbose++; break; /* This space reserved for other options */ default: fprintf(stderr, "usage: %s [-d] [-i] [-s] [-u ] [-v] [-c cmd | file | -] [arg] ...\n", argv[0]); #if !(defined(__CFM68K__) && defined(__MWERKS__)) /* Mwerks cfm68k linker doesn't like these... */ fprintf(stderr, "\ \n\ Options and arguments (and corresponding environment variables):\n\ -d : debug output from parser (also PYTHONDEBUG=x)\n\ -i : inspect interactively after running script (also PYTHONINSPECT=x)\n\ -s : suppress the printing of top level expressions (also PYTHONSUPPRESS=x)\n\ -u : unbuffered stdout and stderr (also PYTHONUNBUFFERED=x)\n\ -v : verbose (trace import statements) (also PYTHONVERBOSE=x)\n\ -c cmd : program passed in as string (terminates option list)\n\ "); /* ANSI does not allow strings > 512 chars and MPW doesn't like it either -- so split it! */ fprintf(stderr, "\ file : program read from script file\n\ - : program read from stdin (default; interactive mode if a tty)\n\ arg ...: arguments passed to program in sys.argv[1:]\n\ \n\ Other environment variables:\n\ PYTHONSTARTUP: file executed on interactive startup (no default)\n\ PYTHONPATH : colon-separated list of directories prefixed to the\n\ default module search path. The result is sys.path.\n\ "); #endif /* !cfm68k || !mwerks */ exit(2); /*NOTREACHED*/ } } if (unbuffered) { #ifndef MPW setbuf(stdout, (char *)NULL); setbuf(stderr, (char *)NULL); #else /* On MPW (3.2) unbuffered seems to hang */ setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ); setvbuf(stderr, (char *)NULL, _IOLBF, BUFSIZ); #endif } if (command == NULL && optind < argc && strcmp(argv[optind], "-") != 0) filename = argv[optind]; if (verbose || command == NULL && filename == NULL && isatty((int)fileno(fp))) fprintf(stderr, "Python %s\n%s\n", getversion(), getcopyright()); if (filename != NULL) { if ((fp = fopen(filename, "r")) == NULL) { fprintf(stderr, "%s: can't open file '%s'\n", argv[0], filename); exit(2); } } initall(); if (command != NULL) { /* Backup optind and force sys.argv[0] = '-c' */ optind--; argv[optind] = "-c"; } setpythonargv(argc-optind, argv+optind); if (command) { sts = run_command(command) != 0; } else { if (filename == NULL && isatty((int)fileno(fp))) { char *startup = getenv("PYTHONSTARTUP"); #ifdef macintosh if (startup == NULL) startup = "PythonStartup"; #endif if (startup != NULL && startup[0] != '\0') { FILE *fp = fopen(startup, "r"); if (fp != NULL) { (void) run_script(fp, startup); err_clear(); fclose(fp); } } } sts = run(fp, filename == NULL ? "" : filename) != 0; if (filename != NULL) fclose(fp); } if (inspect && isatty((int)fileno(stdin)) && (filename != NULL || command != NULL)) sts = run(stdin, "") != 0; goaway(sts); /*NOTREACHED*/ } Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.198.2.8 retrieving revision 2.198.2.9 diff -C2 -r2.198.2.8 -r2.198.2.9 *** bltinmodule.c 2001/07/14 07:47:35 2.198.2.8 --- bltinmodule.c 2001/07/16 21:42:46 2.198.2.9 *************** *** 374,377 **** --- 374,378 ---- char *startstr; int start; + PyCompilerFlags cf; if (!PyArg_ParseTuple(args, "sss:compile", &str, &filename, &startstr)) *************** *** 388,396 **** return NULL; } ! if (PyEval_GetNestedScopes()) { ! PyCompilerFlags cf; ! cf.cf_nested_scopes = 1; return Py_CompileStringFlags(str, filename, start, &cf); ! } else return Py_CompileString(str, filename, start); } --- 389,396 ---- return NULL; } ! cf.cf_flags = 0; ! if (PyEval_MergeCompilerFlags(&cf)) return Py_CompileStringFlags(str, filename, start, &cf); ! else return Py_CompileString(str, filename, start); } *************** *** 552,555 **** --- 552,556 ---- PyObject *res; FILE* fp; + PyCompilerFlags cf; if (!PyArg_ParseTuple(args, "s|O!O!:execfile", *************** *** 577,586 **** return NULL; } ! if (PyEval_GetNestedScopes()) { ! PyCompilerFlags cf; ! cf.cf_nested_scopes = 1; res = PyRun_FileExFlags(fp, filename, Py_file_input, globals, locals, 1, &cf); ! } else res = PyRun_FileEx(fp, filename, Py_file_input, globals, locals, 1); --- 578,586 ---- return NULL; } ! cf.cf_flags = 0; ! if (PyEval_MergeCompilerFlags(&cf)) res = PyRun_FileExFlags(fp, filename, Py_file_input, globals, locals, 1, &cf); ! else res = PyRun_FileEx(fp, filename, Py_file_input, globals, locals, 1); Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.241.2.8 retrieving revision 2.241.2.9 diff -C2 -r2.241.2.8 -r2.241.2.9 *** ceval.c 2001/07/14 07:47:35 2.241.2.8 --- ceval.c 2001/07/16 21:42:46 2.241.2.9 *************** *** 2508,2512 **** /* Don't need to keep the reference to f_back, it will be set * when the generator is resumed. */ ! Py_DECREF(f->f_back); f->f_back = NULL; --- 2508,2512 ---- /* Don't need to keep the reference to f_back, it will be set * when the generator is resumed. */ ! Py_XDECREF(f->f_back); f->f_back = NULL; *************** *** 2890,2898 **** int ! PyEval_GetNestedScopes(void) { PyFrameObject *current_frame = PyThreadState_Get()->frame; ! return current_frame == NULL ? 0 : ! current_frame->f_code->co_flags & CO_NESTED; } --- 2890,2910 ---- int ! PyEval_MergeCompilerFlags(PyCompilerFlags *cf) { PyFrameObject *current_frame = PyThreadState_Get()->frame; ! int result = 0; ! ! if (current_frame != NULL) { ! const int codeflags = current_frame->f_code->co_flags; ! if (codeflags & CO_NESTED) { ! result = 1; ! cf->cf_flags |= PyCF_NESTED_SCOPES; ! } ! if (codeflags & CO_GENERATOR_ALLOWED) { ! result = 1; ! cf->cf_flags |= PyCF_GENERATORS; ! } ! } ! return result; } *************** *** 3677,3700 **** FILE *fp = PyFile_AsFile(prog); char *name = PyString_AsString(PyFile_Name(prog)); ! if (PyEval_GetNestedScopes()) { ! PyCompilerFlags cf; ! cf.cf_nested_scopes = 1; v = PyRun_FileFlags(fp, name, Py_file_input, globals, locals, &cf); ! } else { v = PyRun_File(fp, name, Py_file_input, globals, locals); - } } else { char *str; if (PyString_AsStringAndSize(prog, &str, NULL)) return -1; ! if (PyEval_GetNestedScopes()) { ! PyCompilerFlags cf; ! cf.cf_nested_scopes = 1; v = PyRun_StringFlags(str, Py_file_input, globals, locals, &cf); ! } else v = PyRun_String(str, Py_file_input, globals, locals); } --- 3689,3711 ---- FILE *fp = PyFile_AsFile(prog); char *name = PyString_AsString(PyFile_Name(prog)); ! PyCompilerFlags cf; ! cf.cf_flags = 0; ! if (PyEval_MergeCompilerFlags(&cf)) v = PyRun_FileFlags(fp, name, Py_file_input, globals, locals, &cf); ! else v = PyRun_File(fp, name, Py_file_input, globals, locals); } else { char *str; + PyCompilerFlags cf; if (PyString_AsStringAndSize(prog, &str, NULL)) return -1; ! cf.cf_flags = 0; ! if (PyEval_MergeCompilerFlags(&cf)) v = PyRun_StringFlags(str, Py_file_input, globals, locals, &cf); ! else v = PyRun_String(str, Py_file_input, globals, locals); } Index: compile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v retrieving revision 2.197.2.1 retrieving revision 2.197.2.2 diff -C2 -r2.197.2.1 -r2.197.2.2 *** compile.c 2001/07/07 22:55:30 2.197.2.1 --- compile.c 2001/07/16 21:42:46 2.197.2.2 *************** *** 3946,3949 **** --- 3946,3950 ---- || (sc.c_symtable->st_cur->ste_type == TYPE_FUNCTION)) sc.c_nested = 1; + sc.c_flags |= base->c_flags & CO_GENERATOR_ALLOWED; } else { sc.c_private = NULL; *************** *** 3954,3961 **** } if (flags) { ! if (flags->cf_nested_scopes) sc.c_future->ff_nested_scopes = 1; else if (sc.c_future->ff_nested_scopes) ! flags->cf_nested_scopes = 1; } if (symtable_build(&sc, n) < 0) { --- 3955,3967 ---- } if (flags) { ! if (flags->cf_flags & PyCF_NESTED_SCOPES) sc.c_future->ff_nested_scopes = 1; else if (sc.c_future->ff_nested_scopes) ! flags->cf_flags |= PyCF_NESTED_SCOPES; ! ! if (flags->cf_flags & PyCF_GENERATORS) ! sc.c_future->ff_generators = 1; ! else if (sc.c_future->ff_generators) ! flags->cf_flags |= PyCF_GENERATORS; } if (symtable_build(&sc, n) < 0) { *************** *** 4427,4432 **** struct symbol_info *si) { ! if (c->c_future && c->c_future->ff_nested_scopes) ! c->c_flags |= CO_NESTED; if (ste->ste_generator) c->c_flags |= CO_GENERATOR; --- 4433,4442 ---- struct symbol_info *si) { ! if (c->c_future) { ! if (c->c_future->ff_nested_scopes) ! c->c_flags |= CO_NESTED; ! if (c->c_future->ff_generators) ! c->c_flags |= CO_GENERATOR_ALLOWED; ! } if (ste->ste_generator) c->c_flags |= CO_GENERATOR; Index: future.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/future.c,v retrieving revision 2.5 retrieving revision 2.5.6.1 diff -C2 -r2.5 -r2.5.6.1 *** future.c 2001/03/10 02:15:37 2.5 --- future.c 2001/07/16 21:42:46 2.5.6.1 *************** *** 32,35 **** --- 32,37 ---- if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) { ff->ff_nested_scopes = 1; + } else if (strcmp(feature, FUTURE_GENERATORS) == 0) { + ff->ff_generators = 1; } else if (strcmp(feature, "braces") == 0) { PyErr_SetString(PyExc_SyntaxError, *************** *** 232,235 **** --- 234,238 ---- ff->ff_last_lineno = -1; ff->ff_nested_scopes = 0; + ff->ff_generators = 0; if (future_parse(ff, n, filename) < 0) { Index: pythonrun.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.133.4.4 retrieving revision 2.133.4.5 diff -C2 -r2.133.4.4 -r2.133.4.5 *** pythonrun.c 2001/07/07 22:55:31 2.133.4.4 --- pythonrun.c 2001/07/16 21:42:47 2.133.4.5 *************** *** 498,502 **** if (flags == NULL) { flags = &local_flags; ! local_flags.cf_nested_scopes = 0; } v = PySys_GetObject("ps1"); --- 498,502 ---- if (flags == NULL) { flags = &local_flags; ! local_flags.cf_flags = 0; } v = PySys_GetObject("ps1"); *************** *** 537,540 **** --- 537,541 ---- perrdetail err; char *ps1 = "", *ps2 = ""; + v = PySys_GetObject("ps1"); if (v != NULL) { *************** *** 553,558 **** ps2 = PyString_AsString(w); } ! n = PyParser_ParseFile(fp, filename, &_PyParser_Grammar, ! Py_single_input, ps1, ps2, &err); Py_XDECREF(v); Py_XDECREF(w); --- 554,562 ---- ps2 = PyString_AsString(w); } ! n = PyParser_ParseFileFlags(fp, filename, &_PyParser_Grammar, ! Py_single_input, ps1, ps2, &err, ! (flags && ! flags->cf_flags & PyCF_GENERATORS) ? ! PyPARSE_YIELD_IS_KEYWORD : 0); Py_XDECREF(v); Py_XDECREF(w); *************** *** 1005,1009 **** PyCompilerFlags *flags) { ! return run_err_node(PyParser_SimpleParseString(str, start), "", globals, locals, flags); } --- 1009,1016 ---- PyCompilerFlags *flags) { ! return run_err_node(PyParser_SimpleParseStringFlags( ! str, start, ! (flags && flags->cf_flags & PyCF_GENERATORS) ? ! PyPARSE_YIELD_IS_KEYWORD : 0), "", globals, locals, flags); } *************** *** 1021,1025 **** PyObject *locals, int closeit, PyCompilerFlags *flags) { ! node *n = PyParser_SimpleParseFile(fp, filename, start); if (closeit) fclose(fp); --- 1028,1034 ---- PyObject *locals, int closeit, PyCompilerFlags *flags) { ! node *n = PyParser_SimpleParseFileFlags(fp, filename, start, ! (flags && flags->cf_flags & PyCF_GENERATORS) ? ! PyPARSE_YIELD_IS_KEYWORD : 0); if (closeit) fclose(fp); *************** *** 1079,1086 **** if (v && flags) { if (co->co_flags & CO_NESTED) ! flags->cf_nested_scopes = 1; #if 0 fprintf(stderr, "run_pyc_file: nested_scopes: %d\n", ! flags->cf_nested_scopes); #endif } --- 1088,1099 ---- if (v && flags) { if (co->co_flags & CO_NESTED) ! flags->cf_flags |= PyCF_NESTED_SCOPES; ! if (co->co_flags & CO_GENERATOR_ALLOWED) ! flags->cf_flags |= PyCF_GENERATORS; #if 0 fprintf(stderr, "run_pyc_file: nested_scopes: %d\n", ! flags->cf_flags & PyCF_NESTED_SCOPES); ! fprintf(stderr, "run_pyc_file: generators: %d\n", ! flags->cf_flags & PyCF_GENERATORS); #endif } *************** *** 1101,1105 **** node *n; PyCodeObject *co; ! n = PyParser_SimpleParseString(str, start); if (n == NULL) return NULL; --- 1114,1120 ---- node *n; PyCodeObject *co; ! n = PyParser_SimpleParseStringFlags(str, start, ! (flags && flags->cf_flags & PyCF_GENERATORS) ? ! PyPARSE_YIELD_IS_KEYWORD : 0); if (n == NULL) return NULL; *************** *** 1125,1134 **** node * ! PyParser_SimpleParseFile(FILE *fp, char *filename, int start) { node *n; perrdetail err; ! n = PyParser_ParseFile(fp, filename, &_PyParser_Grammar, start, ! (char *)0, (char *)0, &err); if (n == NULL) err_input(&err); --- 1140,1149 ---- node * ! PyParser_SimpleParseFileFlags(FILE *fp, char *filename, int start, int flags) { node *n; perrdetail err; ! n = PyParser_ParseFileFlags(fp, filename, &_PyParser_Grammar, start, ! (char *)0, (char *)0, &err, flags); if (n == NULL) err_input(&err); *************** *** 1136,1150 **** } /* Simplified interface to parsestring -- return node or set exception */ node * ! PyParser_SimpleParseString(char *str, int start) { node *n; perrdetail err; ! n = PyParser_ParseString(str, &_PyParser_Grammar, start, &err); if (n == NULL) err_input(&err); return n; } --- 1151,1178 ---- } + node * + PyParser_SimpleParseFile(FILE *fp, char *filename, int start) + { + return PyParser_SimpleParseFileFlags(fp, filename, start, 0); + } + /* Simplified interface to parsestring -- return node or set exception */ node * ! PyParser_SimpleParseStringFlags(char *str, int start, int flags) { node *n; perrdetail err; ! n = PyParser_ParseStringFlags(str, &_PyParser_Grammar, start, &err, ! flags); if (n == NULL) err_input(&err); return n; + } + + node * + PyParser_SimpleParseString(char *str, int start) + { + return PyParser_SimpleParseStringFlags(str, start, 0); } From tim_one@users.sourceforge.net Mon Jul 16 22:46:02 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 14:46:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules Setup.guido,NONE,2.7.2.1 Setup.irix4,NONE,1.1.4.1 Setup.irix5,NONE,2.6.2.1 Setup.minix,NONE,2.3.2.1 Setup.solaris2,NONE,1.1.4.1 Setup.sunos4,NONE,1.1.4.1 imgformat.c,NONE,2.1.2.1 version.c,NONE,2.2.2.1 main.c,1.52.4.1,1.52.4.2 mmapmodule.c,2.28.2.1,2.28.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv13232/descr/dist/src/Modules Modified Files: Tag: descr-branch main.c mmapmodule.c Added Files: Tag: descr-branch Setup.guido Setup.irix4 Setup.irix5 Setup.minix Setup.solaris2 Setup.sunos4 imgformat.c version.c Log Message: Resuming interrupted merge checkin. --- NEW FILE: Setup.guido --- # Each line in this file describes one or more optional modules. # Comment out lines to suppress modules. # Lines have the following structure: # # ... [ ...] [ ...] [ ...] # # is anything ending in .o # is anything starting with -I, -D, -U or -C # is anything ending in .a or beginning with -l or -L # is anything else but should be a valid Python # identifier (letters, digits, underscores, beginning with non-digit) # # Lines can also have the form # # = # # which defines a Make variable definition inserted into Makefile.in # # NOTE: As a standard policy, as many modules as can be supported by a # platform should be present. The distribution comes with all modules # enabled that are supported by most platforms and don't require you # to ftp sources from elsewhere. To make this easier for SGI # platforms, you can copy Setup.sgi to Setup (or edit Makefile.in.in # to use Setup.sgi instead of Setup). # Some special rules to define PYTHONPATH # Edit the definitions below to indicate which options you are using # Don't edit this (usually) DESTLIB=$(prefix)/lib/python # Standard enabled (tests are always available) TESTPATH=:$(DESTLIB)/test # Enable this for SGI systems ARCHPATH=:$(DESTLIB)/sgi # Enable this for Sun systems #ARCHPATH=:$(DESTLIB)/sun4 # Enable this if stdwin installed STDWINPATH=:$(DESTLIB)/stdwin PYTHONPATH=.:$(DESTLIB)$(TESTPATH)$(ARCHPATH)$(STDWINPATH) # Modules that should always be present (non UNIX dependent) array arraymodule.o # array objects math mathmodule.o # math library functions, e.g. sin() parser parsermodule.o # raw interface to the Python parser posix posixmodule.o # posix (UNIX) system calls regex regexmodule.o regexpr.o # Regular expressions, GNU Emacs style strop stropmodule.o # fast string operations implemented in C struct structmodule.o # binary structure packing/unpacking time timemodule.o # time operations and variables # Modules with some UNIX dependencies -- on by default. # Note that some UNIX versions still don't support all of these # so you may have to comment them out before the build completes. dbm dbmmodule.o # dbm(3) may require -ldbm or similar fcntl fcntlmodule.o # fcntl(2) and ioctl(2) nis nismodule.o # Sun yellow pages -- not everywhere pwd grp pwdmodule.o # pwd(3) and grp(3) crypt cryptmodule.o # crypt(3) select selectmodule.o # select(2); not on ancient System V socket socketmodule.o # socket(2); not on ancient System V # Multimedia modules -- on by default # These represent audio samples or images as strings audioop audioopmodule.o # Operations on audio samples imageop imageopmodule.o # Operations on images rgbimg rgbimgmodule.o # Read SGI RGB image files (but coded portably) # The stdwin module provides a simple, portable (between X11 and Mac) # windowing interface. You need to ftp the STDWIN library, e.g. from # ftp://ftp.cwi.nl/pub/stdwin. The STDWIN variable must point to the # STDWIN toplevel directory. The ARCH variable must be set to the # architecture identifier used to build STDWIN. NB if you combine this # with the gl module on an SGI machine, you should replace "-lX11" with # "-lX11_s". STDWIN=/ufs/guido/src/stdwin ARCH=sgi stdwin stdwinmodule.o -I$(STDWIN)/H $(STDWIN)/Build/$(ARCH)/x11/lib/lib.a -lX11_s # The md5 module implements the RSA Data Security, Inc. MD5 # Message-Digest Algorithm, described in RFC 1321. The necessary files # md5c.c and md5.h are included here. md5 md5module.o md5c.o # The mpz module interfaces to the GNU Multiple Precision library. # You need to ftp the GNU MP library. This was last tested with a # somewhat modified (to get around bugs) version of GMP 1.2; it will # likely need some work for more recent versions. The GMP variable # must point to the GMP source directory. GMP=/ufs/guido/src/gmp mpz mpzmodule.o -I$(GMP) $(GMP)/libgmp.a # The rotor module (contributed by Lance Ellinghouse) implements a # rotor-based encryption algorithm. It is self-contained. rotor rotormodule.o # SGI IRIX specific modules -- off by default. # Switch this on if you have an SGI machine. # Note that some required libraries and header files aren't always # installed; you may be better off switching on only 'fm' and 'gl' # (Font Manager and Graphics Library). al almodule.o -laudio # audio cd cdmodule.o -lcdaudio -lds # cl clmodule.o -lcl fm fmmodule.o -lfm_s -lgl_s gl glmodule.o -lgl_s -lX11_s imgfile imgfilemodule.o -limage -lgutil -lm sgi sgimodule.o sv svmodule.o yuvconvert.o -lsvideo -lXext -lX11_s # The FORMS library, by Mark Overmars, implements user interface # components such as dialogs and buttons using SGI's GL and FM # libraries. You must ftp the FORMS library separately from # ftp://ftp.cs.ruu.nl/pub/SGI/FORMS. It was tested with FORMS 2.2a. # The FORMS variable must point to the FORMS subdirectory of the forms # toplevel directory. FORMS=/ufs/guido/src/forms/FORMS fl flmodule.o -I$(FORMS) $(FORMS)/libforms.a # SunOS specific modules -- off by default # sunaudiodev sunaudiodevmodule.o # Thread module -- works on SGI IRIX and on SunOS 5.x (SOLARIS) only. # Note that you must have configured (and built!) Python with the # --with-thread option passed to the configure script for this to work. thread threadmodule.o # GNN's timing module timing timingmodule.o # Example -- included for reference only # xx xxmodule.o --- NEW FILE: Setup.irix4 --- # This file is used by the makesetup script to construct Makefile.in # and config.c, from Makefile.in.in (sic!) and config.c.in, # respectively. # # Each line in this file describes one or more optional modules. # Comment out lines to suppress modules. # Lines have the following structure: # # ... [ ...] [ ...] [ ...] # # is anything ending in .o # is anything starting with -I, -D, -U or -C # is anything ending in .a or beginning with -l or -L # is anything else but should be a valid Python # identifier (letters, digits, underscores, beginning with non-digit) # # Lines can also have the form # # = # # which defines a Make variable definition inserted into Makefile.in # # NOTE: As a standard policy, as many modules as can be supported by a # platform should be present. The distribution comes with all modules # enabled that are supported by most platforms and don't require you # to ftp sources from elsewhere. To make this easier for SGI # platforms, you can copy Setup.sgi to Setup (or edit Makefile.in.in # to use Setup.sgi instead of Setup). # Modules that should always be present (non UNIX dependent) array arraymodule.o # array objects math mathmodule.o # math library functions, e.g. sin() parser parsermodule.o # raw interface to the Python parser posix posixmodule.o # posix (UNIX) system calls regex regexmodule.o regexpr.o # Regular expressions, GNU Emacs style strop stropmodule.o # fast string operations implemented in C struct structmodule.o # binary structure packing/unpacking time timemodule.o # time operations and variables # Modules with some UNIX dependencies -- on by default. # Note that some UNIX versions still don't support all of these # so you may have to comment them out before the build completes. dbm dbmmodule.o # dbm(3) may require -ldbm or similar fcntl fcntlmodule.o # fcntl(2) and ioctl(2) nis nismodule.o # Sun yellow pages -- not everywhere pwd grp pwdmodule.o # pwd(3) and grp(3) select selectmodule.o # select(2); not on ancient System V socket socketmodule.o # socket(2); not on ancient System V # Multimedia modules -- off by default # These represent audio samples or images as strings audioop audioopmodule.o # Operations on audio samples imageop imageopmodule.o # Operations on images rgbimg rgbimgmodule.o # Read SGI RGB image files (but coded portably) # The stdwin module provides a simple, portable (between X11 and Mac) # windowing interface. You need to ftp the STDWIN library, e.g. from # ftp://ftp.cwi.nl/pub/stdwin. The STDWIN variable must point to the # STDWIN toplevel directory. The ARCH variable must be set to the # architecture identifier used to build STDWIN. NB if you combine this # with the gl module on an SGI machine, you should replace "-lX11" with # "-lX11_s". STDWIN=/ufs/guido/src/stdwin ARCH=sgi stdwin stdwinmodule.o -I$(STDWIN)/H $(STDWIN)/Build/$(ARCH)/x11/lib/lib.a -lX11_s # The md5 module implements the RSA Data Security, Inc. MD5 # Message-Digest Algorithm, described in RFC 1321. The necessary files # md5c.c and md5.h are included here. md5 md5module.o md5c.o # The mpz module interfaces to the GNU Multiple Precision library. # You need to ftp the GNU MP library. This was last tested with a # somewhat modified (to get around bugs) version of GMP 1.2; it will # likely need some work for more recent versions. The GMP variable # must point to the GMP source directory. GMP=/ufs/guido/src/gmp mpz mpzmodule.o -I$(GMP) $(GMP)/libgmp.a # The rotor module (contributed by Lance Ellinghouse) implements a # rotor-based encryption algorithm. It is self-contained. rotor rotormodule.o # SGI IRIX specific modules -- off by default. # Switch this on if you have an SGI machine. # Note that some required libraries and header files aren't always # installed; you may be better off switching on only 'fm' and 'gl' # (Font Manager and Graphics Library). al almodule.o -laudio # audio cd cdmodule.o -lcdaudio -lds # cl clmodule.o -lcl fm fmmodule.o -lfm_s -lgl_s gl glmodule.o -lgl_s imgfile imgfilemodule.o -limage -lgutil -lm sgi sgimodule.o sv svmodule.o yuvconvert.o -lsvideo -lXext -lX11_s # The FORMS library, by Mark Overmars, implements user interface # components such as dialogs and buttons using SGI's GL and FM # libraries. You must ftp the FORMS library separately from # ftp://ftp.cs.ruu.nl/pub/SGI/FORMS. It was tested with FORMS 2.2a. # The FORMS variable must point to the FORMS subdirectory of the forms # toplevel directory. FORMS=/ufs/guido/src/forms/FORMS fl flmodule.o -I$(FORMS) $(FORMS)/libforms.a # SunOS specific modules -- off by default # sunaudiodev sunaudiodevmodule.o # Thread module -- works on SGI IRIX and on SunOS 5.x (SOLARIS) only. # Note that you must have configured (and built!) Python with the # --with-thread option passed to the configure script for this to work. thread threadmodule.o # Example -- included for reference only # xx xxmodule.o --- NEW FILE: Setup.irix5 --- # Each line in this file describes one or more optional modules. # Comment out lines to suppress modules. # Lines have the following structure: # # ... [ ...] [ ...] [ ...] # # is anything ending in .o # is anything starting with -I, -D, -U or -C # is anything ending in .a or beginning with -l or -L # is anything else but should be a valid Python # identifier (letters, digits, underscores, beginning with non-digit) # # Lines can also have the form # # = # # which defines a Make variable definition inserted into Makefile.in # # NOTE: As a standard policy, as many modules as can be supported by a # platform should be present. The distribution comes with all modules # enabled that are supported by most platforms and don't require you # to ftp sources from elsewhere. To make this easier for SGI # platforms, you can copy Setup.sgi to Setup (or edit Makefile.in.in # to use Setup.sgi instead of Setup). # Some special rules to define PYTHONPATH # Edit the definitions below to indicate which options you are using # Don't edit this (usually) DESTLIB=$(prefix)/lib/python # Standard enabled (tests are always available) TESTPATH=:$(DESTLIB)/test # Enable this for SGI systems ARCHPATH=:$(DESTLIB)/sgi # Enable this for Sun systems #ARCHPATH=:$(DESTLIB)/sun4 # Enable this if stdwin installed STDWINPATH=:$(DESTLIB)/stdwin PYTHONPATH=.:$(DESTLIB)$(TESTPATH)$(ARCHPATH)$(STDWINPATH) # Modules that should always be present (non UNIX dependent) array arraymodule.o # array objects math mathmodule.o # math library functions, e.g. sin() parser parsermodule.o # raw interface to the Python parser posix posixmodule.o # posix (UNIX) system calls regex regexmodule.o regexpr.o # Regular expressions, GNU Emacs style strop stropmodule.o # fast string operations implemented in C struct structmodule.o # binary structure packing/unpacking time timemodule.o # time operations and variables # Modules with some UNIX dependencies -- on by default. # Note that some UNIX versions still don't support all of these # so you may have to comment them out before the build completes. dbm dbmmodule.o # dbm(3) may require -ldbm or similar fcntl fcntlmodule.o # fcntl(2) and ioctl(2) nis nismodule.o # Sun yellow pages -- not everywhere pwd grp pwdmodule.o # pwd(3) and grp(3) crypt cryptmodule.o # crypt(3) select selectmodule.o # select(2); not on ancient System V socket socketmodule.o # socket(2); not on ancient System V # Multimedia modules -- on by default # These represent audio samples or images as strings audioop audioopmodule.o # Operations on audio samples imageop imageopmodule.o # Operations on images rgbimg rgbimgmodule.o # Read SGI RGB image files (but coded portably) # The stdwin module provides a simple, portable (between X11 and Mac) # windowing interface. You need to ftp the STDWIN library, e.g. from # ftp://ftp.cwi.nl/pub/stdwin. The STDWIN variable must point to the # STDWIN toplevel directory. The ARCH variable must be set to the # architecture identifier used to build STDWIN. NB if you combine this # with the gl module on an SGI machine, you should replace "-lX11" with # "-lX11_s". #STDWIN=/ufs/guido/src/stdwin #ARCH=sgi #stdwin stdwinmodule.o -I$(STDWIN)/H $(STDWIN)/Build/$(ARCH)/x11/lib/lib.a -lX11_s # The md5 module implements the RSA Data Security, Inc. MD5 # Message-Digest Algorithm, described in RFC 1321. The necessary files # md5c.c and md5.h are included here. md5 md5module.o md5c.o # The mpz module interfaces to the GNU Multiple Precision library. # You need to ftp the GNU MP library. This was last tested with a # somewhat modified (to get around bugs) version of GMP 1.2; it will # likely need some work for more recent versions. The GMP variable # must point to the GMP source directory. #GMP=/ufs/guido/src/gmp #mpz mpzmodule.o -I$(GMP) $(GMP)/libgmp.a # The rotor module (contributed by Lance Ellinghouse) implements a # rotor-based encryption algorithm. It is self-contained. rotor rotormodule.o # SGI IRIX specific modules -- off by default. # Switch this on if you have an SGI machine. # Note that some required libraries and header files aren't always # installed; you may be better off switching on only 'fm' and 'gl' # (Font Manager and Graphics Library). #al almodule.o -laudio #cd cdmodule.o -lcdaudio -lds -lmediad #cl clmodule.o -lcl -lawareaudio fm fmmodule.o -lfm_s -lgl_s gl glmodule.o -lgl_s -lX11_s #imgfile imgfilemodule.o -limage -lgutil -lm sgi sgimodule.o #sv svmodule.o yuvconvert.o -lsvideo -lXext -lX11_s # The FORMS library, by Mark Overmars, implements user interface # components such as dialogs and buttons using SGI's GL and FM # libraries. You must ftp the FORMS library separately from # ftp://ftp.cs.ruu.nl/pub/SGI/FORMS. It was tested with FORMS 2.2a. # The FORMS variable must point to the FORMS subdirectory of the forms # toplevel directory. #FORMS=/ufs/guido/src/forms/FORMS #fl flmodule.o -I$(FORMS) $(FORMS)/libforms.a # SunOS specific modules -- off by default # sunaudiodev sunaudiodevmodule.o # Thread module -- works on SGI IRIX and on SunOS 5.x (SOLARIS) only. # Note that you must have configured (and built!) Python with the # --with-thread option passed to the configure script for this to work. thread threadmodule.o # GNN's timing module timing timingmodule.o # Example -- included for reference only # xx xxmodule.o --- NEW FILE: Setup.minix --- # Each line in this file describes one or more optional modules. # Comment out lines to suppress modules. # Lines have the following structure: # # ... [ ...] [ ...] [ ...] # # is anything ending in .o # is anything starting with -I, -D, -U or -C # is anything ending in .a or beginning with -l or -L # is anything else but should be a valid Python # identifier (letters, digits, underscores, beginning with non-digit) # # Lines can also have the form # # = # # which defines a Make variable definition inserted into Makefile.in # # NOTE: As a standard policy, as many modules as can be supported by a # platform should be present. The distribution comes with all modules # enabled that are supported by most platforms and don't require you # to ftp sources from elsewhere. To make this easier for SGI # platforms, you can copy Setup.sgi to Setup (or edit Makefile.in.in # to use Setup.sgi instead of Setup). # Some special rules to define PYTHONPATH # Edit the definitions below to indicate which options you are using # Don't edit this (usually) DESTLIB=$(prefix)/lib/python # Standard enabled (tests are always available) TESTPATH=:$(DESTLIB)/test # Enable this for SGI systems #ARCHPATH=:$(DESTLIB)/sgi # Enable this for Sun systems #ARCHPATH=:$(DESTLIB)/sun4 # Enable this if stdwin installed #STDWINPATH=:$(DESTLIB)/stdwin PYTHONPATH=.:$(DESTLIB)$(TESTPATH)$(ARCHPATH)$(STDWINPATH) # Modules that should always be present (non UNIX dependent) array arraymodule.o # array objects math mathmodule.o # math library functions, e.g. sin() parser parsermodule.o # raw interface to the Python parser posix posixmodule.o # posix (UNIX) system calls regex regexmodule.o regexpr.o # Regular expressions, GNU Emacs style strop stropmodule.o # fast string operations implemented in C struct structmodule.o # binary structure packing/unpacking time timemodule.o # time operations and variables # Modules with some UNIX dependencies -- on by default. # Note that some UNIX versions still don't support all of these # so you may have to comment them out before the build completes. #dbm dbmmodule.o # dbm(3) may require -ldbm or similar fcntl fcntlmodule.o # fcntl(2) and ioctl(2) #nis nismodule.o # Sun yellow pages -- not everywhere pwd grp pwdmodule.o # pwd(3) and grp(3) crypt cryptmodule.o # crypt(3) #select selectmodule.o # select(2); not on ancient System V #socket socketmodule.o # socket(2); not on ancient System V # Multimedia modules -- on by default # These represent audio samples or images as strings #audioop audioopmodule.o # Operations on audio samples #imageop imageopmodule.o # Operations on images #rgbimg rgbimgmodule.o # Read SGI RGB image files (but coded portably) # The stdwin module provides a simple, portable (between X11 and Mac) # windowing interface. You need to ftp the STDWIN library, e.g. from # ftp://ftp.cwi.nl/pub/stdwin. The STDWIN variable must point to the # STDWIN toplevel directory. The ARCH variable must be set to the # architecture identifier used to build STDWIN. NB if you combine this # with the gl module on an SGI machine, you should replace "-lX11" with # "-lX11_s". #STDWIN=/ufs/guido/src/stdwin #ARCH=??? #stdwin stdwinmodule.o -I$(STDWIN)/H $(STDWIN)/Build/$(ARCH)/x11/lib/lib.a -lX11 # The md5 module implements the RSA Data Security, Inc. MD5 # Message-Digest Algorithm, described in RFC 1321. The necessary files # md5c.c and md5.h are included here. md5 md5module.o md5c.o # The mpz module interfaces to the GNU Multiple Precision library. # You need to ftp the GNU MP library. This was last tested with a # somewhat modified (to get around bugs) version of GMP 1.2; it will # likely need some work for more recent versions. The GMP variable # must point to the GMP source directory. #GMP=/ufs/guido/src/gmp #mpz mpzmodule.o -I$(GMP) $(GMP)/libgmp.a # The rotor module (contributed by Lance Ellinghouse) implements a # rotor-based encryption algorithm. It is self-contained. rotor rotormodule.o # SGI IRIX specific modules -- off by default. # Switch this on if you have an SGI machine. # Note that some required libraries and header files aren't always # installed; you may be better off switching on only 'fm' and 'gl' # (Font Manager and Graphics Library). #al almodule.o -laudio # audio #cd cdmodule.o -lcdaudio -lds # #cl clmodule.o -lcl #fm fmmodule.o -lfm_s -lgl_s #gl glmodule.o -lgl_s -lX11_s #imgfile imgfilemodule.o -limage -lgutil -lm #sgi sgimodule.o #sv svmodule.o yuvconvert.o -lsvideo -lXext -lX11_s # The FORMS library, by Mark Overmars, implements user interface # components such as dialogs and buttons using SGI's GL and FM # libraries. You must ftp the FORMS library separately from # ftp://ftp.cs.ruu.nl/pub/SGI/FORMS. It was tested with FORMS 2.2a. # The FORMS variable must point to the FORMS subdirectory of the forms # toplevel directory. #FORMS=/ufs/guido/src/forms/FORMS #fl flmodule.o -I$(FORMS) $(FORMS)/libforms.a # SunOS specific modules -- off by default #sunaudiodev sunaudiodevmodule.o # Thread module -- works on SGI IRIX and on SunOS 5.x (SOLARIS) only. # Note that you must have configured (and built!) Python with the # --with-thread option passed to the configure script for this to work. # thread threadmodule.o # GNN's timing module timing timingmodule.o # Example -- included for reference only # xx xxmodule.o --- NEW FILE: Setup.solaris2 --- # This file is used by the makesetup script to construct Makefile.in # and config.c, from Makefile.in.in (sic!) and config.c.in, # respectively. # # Each line in this file describes one or more optional modules. # Comment out lines to suppress modules. # Lines have the following structure: # # ... [ ...] [ ...] [ ...] # # is anything ending in .o # is anything starting with -I, -D, -U or -C # is anything ending in .a or beginning with -l or -L # is anything else but should be a valid Python # identifier (letters, digits, underscores, beginning with non-digit) # # Lines can also have the form # # = # # which defines a Make variable definition inserted into Makefile.in # # NOTE: As a standard policy, as many modules as can be supported by a # platform should be present. The distribution comes with all modules # enabled that are supported by most platforms and don't require you # to ftp sources from elsewhere. To make this easier for SGI # platforms, you can copy Setup.sgi to Setup (or edit Makefile.in.in # to use Setup.sgi instead of Setup). # Modules that should always be present (non UNIX dependent) array arraymodule.o # array objects math mathmodule.o # math library functions, e.g. sin() parser parsermodule.o # raw interface to the Python parser posix posixmodule.o # posix (UNIX) system calls regex regexmodule.o regexpr.o # Regular expressions, GNU Emacs style strop stropmodule.o # fast string operations implemented in C struct structmodule.o # binary structure packing/unpacking time timemodule.o # time operations and variables # Modules with some UNIX dependencies -- on by default. # Note that some UNIX versions still don't support all of these # so you may have to comment them out before the build completes. dbm dbmmodule.o # dbm(3) may require -ldbm or similar fcntl fcntlmodule.o # fcntl(2) and ioctl(2) nis nismodule.o # Sun yellow pages -- not everywhere pwd grp pwdmodule.o # pwd(3) and grp(3) select selectmodule.o # select(2); not on ancient System V socket socketmodule.o # socket(2); not on ancient System V # Multimedia modules -- off by default # These represent audio samples or images as strings audioop audioopmodule.o # Operations on audio samples imageop imageopmodule.o # Operations on images rgbimg rgbimgmodule.o # Read SGI RGB image files (but coded portably) # The stdwin module provides a simple, portable (between X11 and Mac) # windowing interface. You need to ftp the STDWIN library, e.g. from # ftp://ftp.cwi.nl/pub/stdwin. The STDWIN variable must point to the # STDWIN toplevel directory. The ARCH variable must be set to the # architecture identifier used to build STDWIN. NB if you combine this # with the gl module on an SGI machine, you should replace "-lX11" with # "-lX11_s". #STDWIN=/ufs/guido/src/stdwin #ARCH=sgi #stdwin stdwinmodule.o -I$(STDWIN)/H $(STDWIN)/Build/$(ARCH)/x11/lib/lib.a -lX11 # The md5 module implements the RSA Data Security, Inc. MD5 # Message-Digest Algorithm, described in RFC 1321. The necessary files # md5c.c and md5.h are included here. md5 md5module.o md5c.o # The mpz module interfaces to the GNU Multiple Precision library. # You need to ftp the GNU MP library. This was last tested with a # somewhat modified (to get around bugs) version of GMP 1.2; it will # likely need some work for more recent versions. The GMP variable # must point to the GMP source directory. #GMP=/ufs/guido/src/gmp #mpz mpzmodule.o -I$(GMP) $(GMP)/libgmp.a # The rotor module (contributed by Lance Ellinghouse) implements a # rotor-based encryption algorithm. It is self-contained. rotor rotormodule.o # SGI IRIX specific modules -- off by default. # Switch this on if you have an SGI machine. # Note that some required libraries and header files aren't always # installed; you may be better off switching on only 'fm' and 'gl' # (Font Manager and Graphics Library). #al almodule.o -laudio # audio #cd cdmodule.o -lcdaudio -lds # #cl clmodule.o -lcl #fm fmmodule.o -lfm_s -lgl_s #gl glmodule.o -lgl_s #imgfile imgfilemodule.o -limage -lgutil -lm #sgi sgimodule.o #sv svmodule.o yuvconvert.o -lsvideo -lXext -lX11_s # The FORMS library, by Mark Overmars, implements user interface # components such as dialogs and buttons using SGI's GL and FM # libraries. You must ftp the FORMS library separately from # ftp://ftp.cs.ruu.nl/pub/SGI/FORMS. It was tested with FORMS 2.2a. # The FORMS variable must point to the FORMS subdirectory of the forms # toplevel directory. #FORMS=/ufs/guido/src/forms/FORMS #fl flmodule.o -I$(FORMS) $(FORMS)/libforms.a # SunOS specific modules -- off by default sunaudiodev sunaudiodevmodule.o # Thread module -- works on SGI IRIX and on SunOS 5.x (SOLARIS) only. # Note that you must have configured (and built!) Python with the # --with-thread option passed to the configure script for this to work. thread threadmodule.o # Example -- included for reference only # xx xxmodule.o --- NEW FILE: Setup.sunos4 --- # This file is used by the makesetup script to construct Makefile.in # and config.c, from Makefile.in.in (sic!) and config.c.in, # respectively. # # Each line in this file describes one or more optional modules. # Comment out lines to suppress modules. # Lines have the following structure: # # ... [ ...] [ ...] [ ...] # # is anything ending in .o # is anything starting with -I, -D, -U or -C # is anything ending in .a or beginning with -l or -L # is anything else but should be a valid Python # identifier (letters, digits, underscores, beginning with non-digit) # # Lines can also have the form # # = # # which defines a Make variable definition inserted into Makefile.in # # NOTE: As a standard policy, as many modules as can be supported by a # platform should be present. The distribution comes with all modules # enabled that are supported by most platforms and don't require you # to ftp sources from elsewhere. To make this easier for SGI # platforms, you can copy Setup.sgi to Setup (or edit Makefile.in.in # to use Setup.sgi instead of Setup). # Modules that should always be present (non UNIX dependent) array arraymodule.o # array objects math mathmodule.o # math library functions, e.g. sin() parser parsermodule.o # raw interface to the Python parser posix posixmodule.o # posix (UNIX) system calls regex regexmodule.o regexpr.o # Regular expressions, GNU Emacs style strop stropmodule.o # fast string operations implemented in C struct structmodule.o # binary structure packing/unpacking time timemodule.o # time operations and variables # Modules with some UNIX dependencies -- on by default. # Note that some UNIX versions still don't support all of these # so you may have to comment them out before the build completes. dbm dbmmodule.o # dbm(3) may require -ldbm or similar fcntl fcntlmodule.o # fcntl(2) and ioctl(2) nis nismodule.o # Sun yellow pages -- not everywhere pwd grp pwdmodule.o # pwd(3) and grp(3) select selectmodule.o # select(2); not on ancient System V socket socketmodule.o # socket(2); not on ancient System V # Multimedia modules -- off by default # These represent audio samples or images as strings audioop audioopmodule.o # Operations on audio samples imageop imageopmodule.o # Operations on images rgbimg rgbimgmodule.o # Read SGI RGB image files (but coded portably) # The stdwin module provides a simple, portable (between X11 and Mac) # windowing interface. You need to ftp the STDWIN library, e.g. from # ftp://ftp.cwi.nl/pub/stdwin. The STDWIN variable must point to the # STDWIN toplevel directory. The ARCH variable must be set to the # architecture identifier used to build STDWIN. NB if you combine this # with the gl module on an SGI machine, you should replace "-lX11" with # "-lX11_s". #STDWIN=/ufs/guido/src/stdwin #ARCH=sgi #stdwin stdwinmodule.o -I$(STDWIN)/H $(STDWIN)/Build/$(ARCH)/x11/lib/lib.a -lX11 # The md5 module implements the RSA Data Security, Inc. MD5 # Message-Digest Algorithm, described in RFC 1321. The necessary files # md5c.c and md5.h are included here. md5 md5module.o md5c.o # The mpz module interfaces to the GNU Multiple Precision library. # You need to ftp the GNU MP library. This was last tested with a # somewhat modified (to get around bugs) version of GMP 1.2; it will # likely need some work for more recent versions. The GMP variable # must point to the GMP source directory. #GMP=/ufs/guido/src/gmp #mpz mpzmodule.o -I$(GMP) $(GMP)/libgmp.a # The rotor module (contributed by Lance Ellinghouse) implements a # rotor-based encryption algorithm. It is self-contained. rotor rotormodule.o # SGI IRIX specific modules -- off by default. # Switch this on if you have an SGI machine. # Note that some required libraries and header files aren't always # installed; you may be better off switching on only 'fm' and 'gl' # (Font Manager and Graphics Library). #al almodule.o -laudio # audio #cd cdmodule.o -lcdaudio -lds # #cl clmodule.o -lcl #fm fmmodule.o -lfm_s -lgl_s #gl glmodule.o -lgl_s #imgfile imgfilemodule.o -limage -lgutil -lm #sgi sgimodule.o #sv svmodule.o yuvconvert.o -lsvideo -lXext -lX11_s # The FORMS library, by Mark Overmars, implements user interface # components such as dialogs and buttons using SGI's GL and FM # libraries. You must ftp the FORMS library separately from # ftp://ftp.cs.ruu.nl/pub/SGI/FORMS. It was tested with FORMS 2.2a. # The FORMS variable must point to the FORMS subdirectory of the forms # toplevel directory. #FORMS=/ufs/guido/src/forms/FORMS #fl flmodule.o -I$(FORMS) $(FORMS)/libforms.a # SunOS specific modules -- off by default sunaudiodev sunaudiodevmodule.o # Thread module -- works on SGI IRIX and on SunOS 5.x (SOLARIS) only. # Note that you must have configured (and built!) Python with the # --with-thread option passed to the configure script for this to work. # thread threadmodule.o # Example -- included for reference only # xx xxmodule.o --- NEW FILE: imgformat.c --- /*********************************************************** Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum, Amsterdam, The Netherlands. 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 names of Stichting Mathematisch Centrum or CWI not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM 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. ******************************************************************/ /* Imgformat objects */ #include "allobjects.h" #include "modsupport.h" /* For getargs() etc. */ typedef struct { OB_HEAD char *name; } imgformatobject; staticforward typeobject Imgformattype; #define is_imgformatobject(v) ((v)->ob_type == &Imgformattype) static object *dict; /* Dictionary of known types */ static imgformatobject * newimgformatobject(name) char *name; { imgformatobject *xp; xp = NEWOBJ(imgformatobject, &Imgformattype); if (xp == NULL) return NULL; if( (xp->name = malloc(strlen(name)+1)) == NULL ) { DEL(xp); return (imgformatobject *)err_nomem(); } strcpy(xp->name, name); return xp; } /* Imgformat methods */ static void imgformat_dealloc(xp) imgformatobject *xp; { free(xp->name); DEL(xp); } static object * imgformat_repr(self) imgformatobject *self; { char buf[100]; sprintf(buf, "", self->name, self); return newstringobject(buf); } static struct methodlist imgformat_methods[] = { {NULL, NULL} /* sentinel */ }; static typeobject Imgformattype = { OB_HEAD_INIT(&Typetype) 0, /*ob_size*/ "imgformat", /*tp_name*/ sizeof(imgformatobject), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ (destructor)imgformat_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ (reprfunc)imgformat_repr, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ }; static object * imgformat_new(self, args) object *self; /* Not used */ object *args; { char *name, *descr; object *obj; if (!getargs(args, "(ss)", &name, &descr)) return NULL; obj = (object *)newimgformatobject(descr); if (obj == NULL) return NULL; if (dictinsert(dict, name, obj) != 0) { DECREF(obj); return NULL; } return obj; } /* Helper function for other modules, to obtain imgformat-by-name */ object * getimgformat(name) char *name; { return dictlookup(dict, name); } /* List of functions defined in the module */ static struct methodlist imgformat_module_methods[] = { {"new", imgformat_new}, {NULL, NULL} /* sentinel */ }; /* Initialization function for the module (*must* be called initimgformat) */ void initimgformat() { object *m, *d, *x; /* Create the module and add the functions */ m = initmodule("imgformat", imgformat_module_methods); dict = getmoduledict(m); x = (object *)newimgformatobject("SGI 32bit RGB(A) top-to-bottom"); dictinsert(dict, "rgb", x); x = (object *)newimgformatobject("SGI 32bit RGB(A) bottom-to-top"); dictinsert(dict, "rgb_b2t", x); x = (object *)newimgformatobject("SGI 3:3:2 RGB top-to-bottom"); dictinsert(dict, "rgb8", x); x = (object *)newimgformatobject("SGI 3:3:2 RGB bottom-to-top"); dictinsert(dict, "rgb8_b2t", x); x = (object *)newimgformatobject("SGI 8bit grey top-to-bottom"); dictinsert(dict, "grey", x); x = (object *)newimgformatobject("SGI 8bit grey bottom-to-top"); dictinsert(dict, "grey_b2t", x); x = (object *)newimgformatobject("SGI 8bit colormap top-to-bottom"); dictinsert(dict, "colormap", x); x = (object *)newimgformatobject("SGI 8bit colormap bottom-to-top"); dictinsert(dict, "colormap_b2t", x); /* Check for errors */ if (err_occurred()) fatal("can't initialize module imgformat"); } --- NEW FILE: version.c --- /*********************************************************** Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum, Amsterdam, The Netherlands. 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 names of Stichting Mathematisch Centrum or CWI not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM 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. ******************************************************************/ /* Python version information */ #include "patchlevel.h" /* Return the version string. This is constructed from the official version number, the patch level, and the current date (if known to the compiler, else a manually inserted date). */ #define VERSION "1.0.%d++ (%s)" #ifdef __DATE__ #define DATE __DATE__ #else #define DATE "18 May 1994" #endif char * getversion() { static char version[80]; sprintf(version, VERSION, PATCHLEVEL, DATE); return version; } /* Return the copyright string. This is updated manually. */ char * getcopyright() { return "Copyright 1991-1994 Stichting Mathematisch Centrum, Amsterdam"; } Index: main.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/main.c,v retrieving revision 1.52.4.1 retrieving revision 1.52.4.2 diff -C2 -r1.52.4.1 -r1.52.4.2 *** main.c 2001/07/07 22:55:29 1.52.4.1 --- main.c 2001/07/16 21:46:00 1.52.4.2 *************** *** 299,303 **** } ! cf.cf_nested_scopes = 0; if (command) { --- 299,303 ---- } ! cf.cf_flags = 0; if (command) { Index: mmapmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/mmapmodule.c,v retrieving revision 2.28.2.1 retrieving revision 2.28.2.2 diff -C2 -r2.28.2.1 -r2.28.2.2 *** mmapmodule.c 2001/07/07 22:55:29 2.28.2.1 --- mmapmodule.c 2001/07/16 21:46:00 2.28.2.2 *************** *** 664,667 **** --- 664,672 ---- ihigh = self->size; + if (v == NULL) { + PyErr_SetString(PyExc_TypeError, + "mmap object doesn't support slice deletion"); + return -1; + } if (! (PyString_Check(v)) ) { PyErr_SetString(PyExc_IndexError, *************** *** 687,690 **** --- 692,700 ---- if (i < 0 || (size_t)i >= self->size) { PyErr_SetString(PyExc_IndexError, "mmap index out of range"); + return -1; + } + if (v == NULL) { + PyErr_SetString(PyExc_TypeError, + "mmap object doesn't support item deletion"); return -1; } From jackjansen@users.sourceforge.net Mon Jul 16 22:57:52 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Mon, 16 Jul 2001 14:57:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Demo/mlte mlted.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Demo/mlte In directory usw-pr-cvs1:/tmp/cvs-serv16062/Python/Mac/Demo/mlte Modified Files: mlted.py Log Message: It now works under Carbon. Under Classic the scrollbars don't show up, for reasons unknown. Index: mlted.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Demo/mlte/mlted.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** mlted.py 2001/07/14 14:02:21 1.1 --- mlted.py 2001/07/16 21:57:50 1.2 *************** *** 7,10 **** --- 7,11 ---- from FrameWork import * import Win + import Ctl import Qd import Res *************** *** 19,23 **** "Style Change", "Align Left", "Align Center", "Align Right", "Drop", "Move"] ! class WasteWindow(Window): def open(self, path, name, data): self.path = path --- 20,24 ---- "Style Change", "Align Left", "Align Center", "Align Right", "Drop", "Move"] ! class MlteWindow(Window): def open(self, path, name, data): self.path = path *************** *** 26,45 **** w = Win.NewWindow(r, name, 1, 0, -1, 1, 0x55555555) self.wid = w ! ## vr = 0, 0, r[2]-r[0]-15, r[3]-r[1]-15 ! ## dr = (0, 0, 10240, 0) ! ## Qd.SetPort(w) ! ## Qd.TextFont(4) ! ## Qd.TextSize(9) ! ## self.ted = waste.WENew(dr, vr, flags) ! flags = MacTextEditor.kTXNDrawGrowIconMask|MacTextEditor.kTXNShowWindowMask|MacTextEditor.kTXNWantHScrollBarMask| \ MacTextEditor.kTXNWantVScrollBarMask self.ted, self.frameid = Mlte.TXNNewObject(None, w, None, flags, MacTextEditor.kTXNTextEditStyleFrameType, MacTextEditor.kTXNTextFile, MacTextEditor.kTXNMacOSEncoding) - ## self.tedtexthandle = Res.Resource(data) - ## self.ted.WEUseText(self.tedtexthandle) self.ted.TXNSetData(MacTextEditor.kTXNTextData, data, 0, 0x7fffffff) - ## self.ted.WECalText() - ## w.DrawGrowIcon() - ## self.scrollbars() self.changed = 0 self.do_postopen() --- 27,35 ---- w = Win.NewWindow(r, name, 1, 0, -1, 1, 0x55555555) self.wid = w ! flags = MacTextEditor.kTXNDrawGrowIconMask|MacTextEditor.kTXNWantHScrollBarMask| \ MacTextEditor.kTXNWantVScrollBarMask self.ted, self.frameid = Mlte.TXNNewObject(None, w, None, flags, MacTextEditor.kTXNTextEditStyleFrameType, MacTextEditor.kTXNTextFile, MacTextEditor.kTXNMacOSEncoding) self.ted.TXNSetData(MacTextEditor.kTXNTextData, data, 0, 0x7fffffff) self.changed = 0 self.do_postopen() *************** *** 47,157 **** def do_idle(self, event): - ## (what, message, when, where, modifiers) = event - ## Qd.SetPort(self.wid) self.ted.TXNIdle() self.ted.TXNAdjustCursor(None) - ## def getscrollbarvalues(self): - ## dr = self.ted.WEGetDestRect() - ## vr = self.ted.WEGetViewRect() - ## vx = self.scalebarvalue(dr[0], dr[2], vr[0], vr[2]) - ## vy = self.scalebarvalue(dr[1], dr[3], vr[1], vr[3]) - #### print dr, vr, vx, vy - ## return vx, vy - ## - ## def scrollbar_callback(self, which, what, value): - ## if which == 'y': - ## if what == 'set': - ## height = self.ted.WEGetHeight(0, 0x3fffffff) - ## cur = self.getscrollbarvalues()[1] - ## delta = (cur-value)*height/32767 - ## if what == '-': - ## topline_off,dummy = self.ted.WEGetOffset((1,1)) - ## topline_num = self.ted.WEOffsetToLine(topline_off) - ## delta = self.ted.WEGetHeight(topline_num, topline_num+1) - ## elif what == '--': - ## delta = (self.ted.WEGetViewRect()[3]-10) - ## if delta <= 0: - ## delta = 10 # Random value - ## elif what == '+': - ## # XXXX Wrong: should be bottom line size - ## topline_off,dummy = self.ted.WEGetOffset((1,1)) - ## topline_num = self.ted.WEOffsetToLine(topline_off) - ## delta = -self.ted.WEGetHeight(topline_num, topline_num+1) - ## elif what == '++': - ## delta = -(self.ted.WEGetViewRect()[3]-10) - ## if delta >= 0: - ## delta = -10 - ## self.ted.WEScroll(0, delta) - #### print 'SCROLL Y', delta - ## else: - ## if what == 'set': - ## return # XXXX - ## vr = self.ted.WEGetViewRect() - ## winwidth = vr[2]-vr[0] - ## if what == '-': - ## delta = winwidth/10 - ## elif what == '--': - ## delta = winwidth/2 - ## elif what == '+': - ## delta = -winwidth/10 - ## elif what == '++': - ## delta = -winwidth/2 - ## self.ted.WEScroll(delta, 0) - ## # Pin the scroll - ## l, t, r, b = self.ted.WEGetDestRect() - ## vl, vt, vr, vb = self.ted.WEGetViewRect() - ## if t > 0 or l > 0: - ## dx = dy = 0 - ## if t > 0: dy = -t - ## if l > 0: dx = -l - #### print 'Extra scroll', dx, dy - ## self.ted.WEScroll(dx, dy) - ## elif b < vb: - #### print 'Extra downscroll', b-vb - ## self.ted.WEScroll(0, b-vb) def do_activate(self, onoff, evt): - ## print "ACTIVATE", onoff - Qd.SetPort(self.wid) - Window.do_activate(self, onoff, evt) if onoff: self.ted.TXNFocus(1) self.parent.active = self - self.parent.updatemenubar() else: self.ted.TXNFocus(0) def do_update(self, wid, event): ! Qd.SetPort(self.wid) ! ## region = wid.GetWindowPort().visRgn ! ## if Qd.EmptyRgn(region): ! ## return ! ## Qd.EraseRgn(region) ! self.ted.TXNUpdate() ! ## self.updatescrollbars() ! ## def do_postresize(self, width, height, window): ! ## l, t, r, b = self.ted.WEGetViewRect() ! ## vr = (l, t, l+width-15, t+height-15) ! ## self.ted.WESetViewRect(vr) ! ## self.wid.InvalWindowRect(vr) ! ## ScrolledWindow.do_postresize(self, width, height, window) def do_contentclick(self, local, modifiers, evt): - ## (what, message, when, where, modifiers) = evt self.ted.TXNClick(evt) - ## self.updatescrollbars() self.parent.updatemenubar() ! def do_char(self, ch, event): self.ted.TXNKeyDown(event) ! ## self.ted.WESelView() ! ## (what, message, when, where, modifiers) = event ! ## self.ted.WEKey(ord(ch), modifiers) ! ## self.changed = 1 ! ## self.updatescrollbars() ! ## self.parent.updatemenubar() def close(self): --- 37,68 ---- def do_idle(self, event): self.ted.TXNIdle() self.ted.TXNAdjustCursor(None) def do_activate(self, onoff, evt): if onoff: + ## self.ted.TXNActivate(self.frameid, 0) self.ted.TXNFocus(1) self.parent.active = self else: self.ted.TXNFocus(0) + self.parent.active = None + self.parent.updatemenubar() def do_update(self, wid, event): ! self.ted.TXNDraw(None) ! def do_postresize(self, width, height, window): ! self.ted.TXNResizeFrame(width, height, self.frameid) def do_contentclick(self, local, modifiers, evt): self.ted.TXNClick(evt) self.parent.updatemenubar() ! def do_char(self, ch, event): self.ted.TXNKeyDown(event) ! self.parent.updatemenubar() def close(self): *************** *** 164,168 **** if self.parent.active == self: self.parent.active = None ! ## self.parent.updatemenubar() del self.ted ## del self.tedtexthandle --- 75,79 ---- if self.parent.active == self: self.parent.active = None ! self.ted.TXNDeleteObject() del self.ted ## del self.tedtexthandle *************** *** 173,177 **** self.menu_save_as() return # Will call us recursively - print 'Saving to ', self.path dhandle = self.ted.TXNGetData(0, 0x7fffffff) data = dhandle.data --- 84,87 ---- *************** *** 280,284 **** self.editmenu = m = Menu(self.menubar, "Edit") self.undoitem = MenuItem(m, "Undo", "Z", self.undo) ! self.redoitem = MenuItem(m, "Undo", None, self.redo) self.cutitem = MenuItem(m, "Cut", "X", self.cut) self.copyitem = MenuItem(m, "Copy", "C", self.copy) --- 190,195 ---- self.editmenu = m = Menu(self.menubar, "Edit") self.undoitem = MenuItem(m, "Undo", "Z", self.undo) ! self.redoitem = MenuItem(m, "Redo", None, self.redo) ! m.addseparator() self.cutitem = MenuItem(m, "Cut", "X", self.cut) self.copyitem = MenuItem(m, "Copy", "C", self.copy) *************** *** 374,378 **** name = "Untitled %d"%self.num data = '' ! w = WasteWindow(self) w.open(path, name, data) self.num = self.num + 1 --- 285,289 ---- name = "Untitled %d"%self.num data = '' ! w = MlteWindow(self) w.open(path, name, data) self.num = self.num + 1 From jackjansen@users.sourceforge.net Mon Jul 16 22:58:38 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Mon, 16 Jul 2001 14:58:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/mlte Mltemodule.c,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/mlte In directory usw-pr-cvs1:/tmp/cvs-serv16283/Python/Mac/Modules/mlte Modified Files: Mltemodule.c Log Message: The TNXDraw gworld argument is optional. Index: Mltemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/mlte/Mltemodule.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** Mltemodule.c 2001/07/14 14:00:41 1.3 --- Mltemodule.c 2001/07/16 21:58:35 1.4 *************** *** 71,74 **** --- 71,88 ---- } + /* + ** Parse an optional GWorld + */ + static int + OptGWorldObj_Convert(PyObject *v, GWorldPtr *p_itself) + { + if (v == Py_None) + { + *p_itself = NULL; + return 1; + } + return GWorldObj_Convert(v, p_itself); + } + static PyObject *Mlte_Error; *************** *** 277,281 **** PyMac_PRECHECK(TXNDraw); if (!PyArg_ParseTuple(_args, "O&", ! GWorldObj_Convert, &iDrawPort)) return NULL; TXNDraw(_self->ob_itself, --- 291,295 ---- PyMac_PRECHECK(TXNDraw); if (!PyArg_ParseTuple(_args, "O&", ! OptGWorldObj_Convert, &iDrawPort)) return NULL; TXNDraw(_self->ob_itself, From jackjansen@users.sourceforge.net Mon Jul 16 22:58:42 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Mon, 16 Jul 2001 14:58:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/mlte mltescan.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/mlte In directory usw-pr-cvs1:/tmp/cvs-serv16313/Python/Mac/Modules/mlte Modified Files: mltescan.py Log Message: The TNXDraw gworld argument is optional. Index: mltescan.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/mlte/mltescan.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** mltescan.py 2001/07/14 14:00:45 1.3 --- mltescan.py 2001/07/16 21:58:40 1.4 *************** *** 117,121 **** # The AdjustCursor region handle is optional ([("RgnHandle", "ioCursorRgn", "InMode")], ! [("OptRgnHandle", "*", "*")]) ] --- 117,125 ---- # The AdjustCursor region handle is optional ([("RgnHandle", "ioCursorRgn", "InMode")], ! [("OptRgnHandle", "*", "*")]), ! ! # The GWorld for TXNDraw is optional ! ([('GWorldPtr', 'iDrawPort', 'InMode')], ! [('OptGWorldPtr', '*', '*')]), ] From jackjansen@users.sourceforge.net Mon Jul 16 22:58:47 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Mon, 16 Jul 2001 14:58:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/mlte mltesupport.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/mlte In directory usw-pr-cvs1:/tmp/cvs-serv16337/Python/Mac/Modules/mlte Modified Files: mltesupport.py Log Message: The TNXDraw gworld argument is optional. Index: mltesupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/mlte/mltesupport.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** mltesupport.py 2001/07/14 14:00:50 1.3 --- mltesupport.py 2001/07/16 21:58:44 1.4 *************** *** 75,78 **** --- 75,92 ---- } + /* + ** Parse an optional GWorld + */ + static int + OptGWorldObj_Convert(PyObject *v, GWorldPtr *p_itself) + { + if (v == Py_None) + { + *p_itself = NULL; + return 1; + } + return GWorldObj_Convert(v, p_itself); + } + """ *************** *** 110,113 **** --- 124,128 ---- OptRgnHandle = OpaqueByValueType("RgnHandle", "OptResObj") GWorldPtr = OpaqueByValueType("GWorldPtr", "GWorldObj") + OptGWorldPtr = OpaqueByValueType("GWorldPtr", "OptGWorldObj") MlteInBuffer = VarInputBufferType('void *', 'ByteCount', 'l') From jackjansen@users.sourceforge.net Mon Jul 16 23:04:10 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Mon, 16 Jul 2001 15:04:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/scripts fullbuild.py,1.67,1.68 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory usw-pr-cvs1:/tmp/cvs-serv17491/Python/Mac/scripts Modified Files: fullbuild.py Log Message: Typo in the classic mlte build line. Index: fullbuild.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/fullbuild.py,v retrieving revision 1.67 retrieving revision 1.68 diff -C2 -r1.67 -r1.68 *** fullbuild.py 2001/07/13 20:57:43 1.67 --- fullbuild.py 2001/07/16 22:04:08 1.68 *************** *** 262,266 **** (":Mac:Build:Sndihooks.mcp", "Sndihooks.ppc"), (":Mac:Build:TE.mcp", "TE.ppc"), ! (":Mac:Build:Mlte.ppc.mcp", "Mlte.ppc"), ]), --- 262,266 ---- (":Mac:Build:Sndihooks.mcp", "Sndihooks.ppc"), (":Mac:Build:TE.mcp", "TE.ppc"), ! (":Mac:Build:Mlte.mcp", "Mlte.ppc"), ]), From tim_one@users.sourceforge.net Tue Jul 17 00:43:19 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 16:43:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Demo/sgi/video IN.py,1.1.2.1,NONE Makefile,1.1.2.1,NONE Vrecc.py,1.1.2.1,NONE cam.py,1.2.2.1,NONE camcorder.py,1.4.2.1,NONE colorsys.py,1.4.2.1,NONE i2v.c,1.1.2.1,NONE makemovie.py,1.4.2.1,NONE squash.c,1.2.2.1,NONE squash2.c,1.1.2.1,NONE statit.py,1.2.2.1,NONE syncaudio.py,1.2.2.1,NONE tomono.c,1.1.2.1,NONE tv.py,1.2.2.1,NONE v2i.c,1.2.2.1,NONE video.py,1.10.2.1,NONE vpregs.py,1.1.2.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Demo/sgi/video In directory usw-pr-cvs1:/tmp/cvs-serv2674/branch/dist/src/Demo/sgi/video Removed Files: Tag: descr-branch IN.py Makefile Vrecc.py cam.py camcorder.py colorsys.py i2v.c makemovie.py squash.c squash2.c statit.py syncaudio.py tomono.c tv.py v2i.c video.py vpregs.py Log Message: Bury unholy merge zombies again. --- IN.py DELETED --- --- Makefile DELETED --- --- Vrecc.py DELETED --- --- cam.py DELETED --- --- camcorder.py DELETED --- --- colorsys.py DELETED --- --- i2v.c DELETED --- --- makemovie.py DELETED --- --- squash.c DELETED --- --- squash2.c DELETED --- --- statit.py DELETED --- --- syncaudio.py DELETED --- --- tomono.c DELETED --- --- tv.py DELETED --- --- v2i.c DELETED --- --- video.py DELETED --- --- vpregs.py DELETED --- From tim_one@users.sourceforge.net Tue Jul 17 00:43:19 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 16:43:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules Setup.guido,2.7.2.1,NONE Setup.irix4,1.1.4.1,NONE Setup.irix5,2.6.2.1,NONE Setup.minix,2.3.2.1,NONE Setup.solaris2,1.1.4.1,NONE Setup.sunos4,1.1.4.1,NONE imgformat.c,2.1.2.1,NONE version.c,2.2.2.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv2674/branch/dist/src/Modules Removed Files: Tag: descr-branch Setup.guido Setup.irix4 Setup.irix5 Setup.minix Setup.solaris2 Setup.sunos4 imgformat.c version.c Log Message: Bury unholy merge zombies again. --- Setup.guido DELETED --- --- Setup.irix4 DELETED --- --- Setup.irix5 DELETED --- --- Setup.minix DELETED --- --- Setup.solaris2 DELETED --- --- Setup.sunos4 DELETED --- --- imgformat.c DELETED --- --- version.c DELETED --- From tim_one@users.sourceforge.net Tue Jul 17 00:43:19 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 16:43:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib builtin.py,1.1.2.1,NONE macstat.py,1.1.2.1,NONE persist.py,1.6.4.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv2674/branch/dist/src/Lib Removed Files: Tag: descr-branch builtin.py macstat.py persist.py Log Message: Bury unholy merge zombies again. --- builtin.py DELETED --- --- macstat.py DELETED --- --- persist.py DELETED --- From tim_one@users.sourceforge.net Tue Jul 17 00:43:19 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 16:43:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Demo/pdist new,1.1.2.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Demo/pdist In directory usw-pr-cvs1:/tmp/cvs-serv2674/branch/dist/src/Demo/pdist Removed Files: Tag: descr-branch new Log Message: Bury unholy merge zombies again. --- new DELETED --- From tim_one@users.sourceforge.net Tue Jul 17 00:43:19 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 16:43:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Demo/scripts freeze.py,1.5.2.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Demo/scripts In directory usw-pr-cvs1:/tmp/cvs-serv2674/branch/dist/src/Demo/scripts Removed Files: Tag: descr-branch freeze.py Log Message: Bury unholy merge zombies again. --- freeze.py DELETED --- From tim_one@users.sourceforge.net Tue Jul 17 00:43:19 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 16:43:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python pythonmain.c,2.30.2.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv2674/branch/dist/src/Python Removed Files: Tag: descr-branch pythonmain.c Log Message: Bury unholy merge zombies again. --- pythonmain.c DELETED --- From fdrake@users.sourceforge.net Tue Jul 17 03:59:17 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 16 Jul 2001 19:59:17 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules parsermodule.c,2.61,2.62 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv1365/Modules Modified Files: parsermodule.c Log Message: Add support for yield statements. (Should be merged with descr branch.) Index: parsermodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/parsermodule.c,v retrieving revision 2.61 retrieving revision 2.62 diff -C2 -r2.61 -r2.62 *** parsermodule.c 2001/06/23 19:55:38 2.61 --- parsermodule.c 2001/07/17 02:59:15 2.62 *************** *** 831,835 **** VALIDATER(exprlist); VALIDATER(dictmaker); VALIDATER(arglist); VALIDATER(argument); ! VALIDATER(listmaker); #undef VALIDATER --- 831,835 ---- VALIDATER(exprlist); VALIDATER(dictmaker); VALIDATER(arglist); VALIDATER(argument); ! VALIDATER(listmaker); VALIDATER(yield_stmt); #undef VALIDATER *************** *** 1539,1543 **** --- 1539,1555 ---- + /* yield_stmt: 'yield' testlist + */ static int + validate_yield_stmt(node *tree) + { + return (validate_ntype(tree, yield_stmt) + && validate_numnodes(tree, 2, "yield_stmt") + && validate_name(CHILD(tree, 0), "yield") + && validate_testlist(CHILD(tree, 1))); + } + + + static int validate_import_as_name(node *tree) { *************** *** 2556,2559 **** --- 2568,2572 ---- && ((TYPE(CHILD(tree, 0)) == break_stmt) || (TYPE(CHILD(tree, 0)) == continue_stmt) + || (TYPE(CHILD(tree, 0)) == yield_stmt) || (TYPE(CHILD(tree, 0)) == return_stmt) || (TYPE(CHILD(tree, 0)) == raise_stmt))); *************** *** 2562,2565 **** --- 2575,2581 ---- else if (nch == 1) err_string("illegal flow_stmt type"); + break; + case yield_stmt: + res = validate_yield_stmt(tree); break; /* From fdrake@users.sourceforge.net Tue Jul 17 04:01:31 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 16 Jul 2001 20:01:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_parser.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv1770/Lib/test Modified Files: test_parser.py Log Message: Added tests for the new yield support in the parser module. (Should be merged with descr branch.) Index: test_parser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_parser.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** test_parser.py 2001/06/04 03:56:24 1.7 --- test_parser.py 2001/07/17 03:01:29 1.8 *************** *** 27,30 **** --- 27,42 ---- self.roundtrip(parser.suite, s) + def test_yield_statement(self): + self.check_suite("from __future__ import generators\n" + "def f(): yield 1") + self.check_suite("from __future__ import generators\n" + "def f(): return; yield 1") + self.check_suite("from __future__ import generators\n" + "def f(): yield 1; return") + self.check_suite("from __future__ import generators\n" + "def f():\n" + " for x in range(30):\n" + " yield x\n") + def test_expressions(self): self.check_expr("foo(1)") *************** *** 139,144 **** self.check_bad_tree((1, 2, 3), "") def test_print_chevron_comma(self): ! "Illegal input: print >>fp,""" tree = \ (257, --- 151,275 ---- self.check_bad_tree((1, 2, 3), "") + def test_illegal_yield_1(self): + """Illegal yield statement: def f(): return 1; yield 1""" + tree = \ + (257, + (264, + (285, + (259, + (1, 'def'), + (1, 'f'), + (260, (7, '('), (8, ')')), + (11, ':'), + (291, + (4, ''), + (5, ''), + (264, + (265, + (266, + (272, + (275, + (1, 'return'), + (313, + (292, + (293, + (294, + (295, + (297, + (298, + (299, + (300, + (301, + (302, (303, (304, (305, (2, '1')))))))))))))))))), + (264, + (265, + (266, + (272, + (276, + (1, 'yield'), + (313, + (292, + (293, + (294, + (295, + (297, + (298, + (299, + (300, + (301, + (302, + (303, (304, (305, (2, '1')))))))))))))))))), + (4, ''))), + (6, ''))))), + (4, ''), + (0, '')))) + self.check_bad_tree(tree, "def f():\n return 1\n yield 1") + + def test_illegal_yield_2(self): + """Illegal return in generator: def f(): return 1; yield 1""" + tree = \ + (257, + (264, + (265, + (266, + (278, + (1, 'from'), + (281, (1, '__future__')), + (1, 'import'), + (279, (1, 'generators')))), + (4, ''))), + (264, + (285, + (259, + (1, 'def'), + (1, 'f'), + (260, (7, '('), (8, ')')), + (11, ':'), + (291, + (4, ''), + (5, ''), + (264, + (265, + (266, + (272, + (275, + (1, 'return'), + (313, + (292, + (293, + (294, + (295, + (297, + (298, + (299, + (300, + (301, + (302, (303, (304, (305, (2, '1')))))))))))))))))), + (264, + (265, + (266, + (272, + (276, + (1, 'yield'), + (313, + (292, + (293, + (294, + (295, + (297, + (298, + (299, + (300, + (301, + (302, + (303, (304, (305, (2, '1')))))))))))))))))), + (4, ''))), + (6, ''))))), + (4, ''), + (0, '')))) + self.check_bad_tree(tree, "def f():\n return 1\n yield 1") + def test_print_chevron_comma(self): ! """Illegal input: print >>fp,""" tree = \ (257, From tim_one@users.sourceforge.net Tue Jul 17 05:05:45 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 21:05:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild BUILDno.txt,1.16,1.17 python20.wse,1.41,1.42 pythoncore.dsp,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv6122/python/dist/src/PCbuild Modified Files: BUILDno.txt python20.wse pythoncore.dsp Log Message: Prepare Windows installer for 2.2a1. Index: BUILDno.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/BUILDno.txt,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -r1.16 -r1.17 *** BUILDno.txt 2001/07/14 03:31:35 1.16 --- BUILDno.txt 2001/07/17 04:05:43 1.17 *************** *** 34,37 **** --- 34,39 ---- Windows Python BUILD numbers ---------------------------- + 21 2.2a1 TENTATIVE + 18-Jul-2001 20 2.1.1 TENTATIVE 20-Jul-2001 Index: python20.wse =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/python20.wse,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -r1.41 -r1.42 *** python20.wse 2001/07/12 20:15:25 1.41 --- python20.wse 2001/07/17 04:05:43 1.42 *************** *** 2,6 **** item: Global Version=5.0 ! Title=Python 2.2 pre-alpha Flags=00010100 Languages=65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 --- 2,6 ---- item: Global Version=5.0 ! Title=Python 2.2 alpha 1 Flags=00010100 Languages=65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 *************** *** 17,20 **** --- 17,21 ---- Patch Threshold=85 Patch Memory=4000 + EXE Filename=Python-2.2a1.exe Variable Name1=_SYS_ Variable Description1=System directory (where to find MSVCRT.DLL) *************** *** 67,71 **** item: Set Variable Variable=APPTITLE ! Value=Python 2.2 pre-alpha end item: Set Variable --- 68,72 ---- item: Set Variable Variable=APPTITLE ! Value=Python 2.2a1 end item: Set Variable Index: pythoncore.dsp =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/pythoncore.dsp,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -r1.16 -r1.17 *** pythoncore.dsp 2001/07/05 21:19:02 1.16 --- pythoncore.dsp 2001/07/17 04:05:43 1.17 *************** *** 710,718 **** !IF "$(CFG)" == "pythoncore - Win32 Release" ! # ADD CPP /D BUILD=16 !ELSEIF "$(CFG)" == "pythoncore - Win32 Debug" ! # ADD CPP /D BUILD=16 !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Debug" --- 710,718 ---- !IF "$(CFG)" == "pythoncore - Win32 Release" ! # ADD CPP /D BUILD=21 !ELSEIF "$(CFG)" == "pythoncore - Win32 Debug" ! # ADD CPP /D BUILD=21 !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Debug" From tim_one@users.sourceforge.net Tue Jul 17 05:19:07 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 21:19:07 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.1.2.30,1.1.2.31 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv7540/descr/dist/src Modified Files: Tag: descr-branch PLAN.txt Log Message: Last trunk->branch merge for today . Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Attic/PLAN.txt,v retrieving revision 1.1.2.30 retrieving revision 1.1.2.31 diff -C2 -r1.1.2.30 -r1.1.2.31 *** PLAN.txt 2001/07/16 21:21:06 1.1.2.30 --- PLAN.txt 2001/07/17 04:19:05 1.1.2.31 *************** *** 269,272 **** --- 269,280 ---- ---------------------------------------------------------------------------- + 2001-07-17 + + Tagged trunk about 00:05 EDT, like so: + cvs tag date2001-07-17a python + + Merged trunk delta into branch via: + cvs -q -z3 up -j date2001-07-16 -j date2001-07-17a descr + ---------------------------------------------------------------------------- 2001-07-16 From tim_one@users.sourceforge.net Tue Jul 17 05:19:07 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 21:19:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib librfc822.tex,1.34,1.34.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv7540/descr/dist/src/Doc/lib Modified Files: Tag: descr-branch librfc822.tex Log Message: Last trunk->branch merge for today . Index: librfc822.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/librfc822.tex,v retrieving revision 1.34 retrieving revision 1.34.2.1 diff -C2 -r1.34 -r1.34.2.1 *** librfc822.tex 2001/05/22 22:00:40 1.34 --- librfc822.tex 2001/07/17 04:19:05 1.34.2.1 *************** *** 1,14 **** \section{\module{rfc822} --- ! Parse RFC 822 mail headers} \declaremodule{standard}{rfc822} ! \modulesynopsis{Parse \rfc{822} style mail headers.} ! This module defines a class, \class{Message}, which represents a ! collection of ``email headers'' as defined by the Internet standard ! \rfc{822}. It is used in various contexts, usually to read such ! headers from a file. This module also defines a helper class ! \class{AddressList} for parsing \rfc{822} addresses. Please refer to ! the RFC for information on the specific syntax of \rfc{822} headers. The \refmodule{mailbox}\refstmodindex{mailbox} module provides classes --- 1,19 ---- \section{\module{rfc822} --- ! Parse RFC 2822 mail headers} \declaremodule{standard}{rfc822} ! \modulesynopsis{Parse \rfc{2822} style mail messages.} ! This module defines a class, \class{Message}, which represents an ! ``email message'' as defined by the Internet standard ! \rfc{2822}\footnote{This module originally conformed to \rfc{822}, ! hence the name. Since then, \rfc{2822} has been released as an ! update to \rfc{822}. This module should be considered ! \rfc{2822}-conformant, especially in cases where the ! syntax or semantics have changed since \rfc{822}.}. Such messages ! consist of a collection of message headers, and a message body. This ! module also defines a helper class ! \class{AddressList} for parsing \rfc{2822} addresses. Please refer to ! the RFC for information on the specific syntax of \rfc{2822} messages. The \refmodule{mailbox}\refstmodindex{mailbox} module provides classes *************** *** 51,63 **** \begin{classdesc}{AddressList}{field} You may instantiate the \class{AddressList} helper class using a single ! string parameter, a comma-separated list of \rfc{822} addresses to be parsed. (The parameter \code{None} yields an empty list.) \end{classdesc} \begin{funcdesc}{parsedate}{date} ! Attempts to parse a date according to the rules in \rfc{822}. however, some mailers don't follow that format as specified, so \function{parsedate()} tries to guess correctly in such cases. ! \var{date} is a string containing an \rfc{822} date, such as \code{'Mon, 20 Nov 1995 19:12:08 -0500'}. If it succeeds in parsing the date, \function{parsedate()} returns a 9-tuple that can be passed --- 56,95 ---- \begin{classdesc}{AddressList}{field} You may instantiate the \class{AddressList} helper class using a single ! string parameter, a comma-separated list of \rfc{2822} addresses to be parsed. (The parameter \code{None} yields an empty list.) \end{classdesc} + \begin{funcdesc}{quote}{str} + Return a new string with backslashes in \var{str} replaced by two + backslashes and double quotes replaced by backslash-double quote. + \end{funcdesc} + + \begin{funcdesc}{unquote}{str} + Return a new string which is an \emph{unquoted} version of \var{str}. + If \var{str} ends and begins with double quotes, they are stripped + off. Likewise if \var{str} ends and begins with angle brackets, they + are stripped off. + \end{funcdesc} + + \begin{funcdesc}{parseaddr}{address} + Parse address -- which should be the value of some address-containing + field such as \code{To:} or \code{Cc:} -- into its constituent + ``realname'' and ``email address'' parts. Returns a tuple of that + information, unless the parse fails, in which case a 2-tuple of + \code{(None, None)} is returned. + \end{funcdesc} + + \begin{funcdesc}{dump_address_pair}{pair} + The inverse of \method{parseaddr()}, this takes a 2-tuple of the form + \code{(realname, email_address)} and returns the string value suitable + for a \code{To:} or \code{Cc:} header. If the first element of + \var{pair} is false, then the second element is returned unmodified. + \end{funcdesc} + \begin{funcdesc}{parsedate}{date} ! Attempts to parse a date according to the rules in \rfc{2822}. however, some mailers don't follow that format as specified, so \function{parsedate()} tries to guess correctly in such cases. ! \var{date} is a string containing an \rfc{2822} date, such as \code{'Mon, 20 Nov 1995 19:12:08 -0500'}. If it succeeds in parsing the date, \function{parsedate()} returns a 9-tuple that can be passed *************** *** 75,79 **** offset is the opposite of the sign of the \code{time.timezone} variable for the same timezone; the latter variable follows the ! \POSIX{} standard while this module follows \rfc{822}.) If the input string has no timezone, the last element of the tuple returned is \code{None}. Note that fields 6, 7, and 8 of the result tuple are not --- 107,111 ---- offset is the opposite of the sign of the \code{time.timezone} variable for the same timezone; the latter variable follows the ! \POSIX{} standard while this module follows \rfc{2822}.) If the input string has no timezone, the last element of the tuple returned is \code{None}. Note that fields 6, 7, and 8 of the result tuple are not *************** *** 110,114 **** \begin{methoddesc}{isheader}{line} Returns a line's canonicalized fieldname (the dictionary key that will ! be used to index it) if the line is a legal \rfc{822} header; otherwise returns None (implying that parsing should stop here and the line be pushed back on the input stream). It is sometimes useful to override --- 142,146 ---- \begin{methoddesc}{isheader}{line} Returns a line's canonicalized fieldname (the dictionary key that will ! be used to index it) if the line is a legal \rfc{2822} header; otherwise returns None (implying that parsing should stop here and the line be pushed back on the input stream). It is sometimes useful to override From tim_one@users.sourceforge.net Tue Jul 17 05:19:07 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 21:19:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/scripts fullbuild.py,1.67,1.67.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory usw-pr-cvs1:/tmp/cvs-serv7540/descr/dist/src/Mac/scripts Modified Files: Tag: descr-branch fullbuild.py Log Message: Last trunk->branch merge for today . Index: fullbuild.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/fullbuild.py,v retrieving revision 1.67 retrieving revision 1.67.2.1 diff -C2 -r1.67 -r1.67.2.1 *** fullbuild.py 2001/07/13 20:57:43 1.67 --- fullbuild.py 2001/07/17 04:19:05 1.67.2.1 *************** *** 262,266 **** (":Mac:Build:Sndihooks.mcp", "Sndihooks.ppc"), (":Mac:Build:TE.mcp", "TE.ppc"), ! (":Mac:Build:Mlte.ppc.mcp", "Mlte.ppc"), ]), --- 262,266 ---- (":Mac:Build:Sndihooks.mcp", "Sndihooks.ppc"), (":Mac:Build:TE.mcp", "TE.ppc"), ! (":Mac:Build:Mlte.mcp", "Mlte.ppc"), ]), From tim_one@users.sourceforge.net Tue Jul 17 05:19:07 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 21:19:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild BUILDno.txt,1.12.2.2,1.12.2.3 python20.wse,1.40.2.1,1.40.2.2 pythoncore.dsp,1.15.2.4,1.15.2.5 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv7540/descr/dist/src/PCbuild Modified Files: Tag: descr-branch BUILDno.txt python20.wse pythoncore.dsp Log Message: Last trunk->branch merge for today . Index: BUILDno.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/BUILDno.txt,v retrieving revision 1.12.2.2 retrieving revision 1.12.2.3 diff -C2 -r1.12.2.2 -r1.12.2.3 *** BUILDno.txt 2001/07/15 20:26:56 1.12.2.2 --- BUILDno.txt 2001/07/17 04:19:05 1.12.2.3 *************** *** 34,37 **** --- 34,39 ---- Windows Python BUILD numbers ---------------------------- + 21 2.2a1 TENTATIVE + 18-Jul-2001 20 2.1.1 TENTATIVE 20-Jul-2001 Index: python20.wse =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/python20.wse,v retrieving revision 1.40.2.1 retrieving revision 1.40.2.2 diff -C2 -r1.40.2.1 -r1.40.2.2 *** python20.wse 2001/07/14 07:47:35 1.40.2.1 --- python20.wse 2001/07/17 04:19:05 1.40.2.2 *************** *** 2,6 **** item: Global Version=5.0 ! Title=Python 2.2 pre-alpha Flags=00010100 Languages=65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 --- 2,6 ---- item: Global Version=5.0 ! Title=Python 2.2 alpha 1 Flags=00010100 Languages=65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 *************** *** 17,20 **** --- 17,21 ---- Patch Threshold=85 Patch Memory=4000 + EXE Filename=Python-2.2a1.exe Variable Name1=_SYS_ Variable Description1=System directory (where to find MSVCRT.DLL) *************** *** 67,71 **** item: Set Variable Variable=APPTITLE ! Value=Python 2.2 pre-alpha end item: Set Variable --- 68,72 ---- item: Set Variable Variable=APPTITLE ! Value=Python 2.2a1 end item: Set Variable Index: pythoncore.dsp =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/pythoncore.dsp,v retrieving revision 1.15.2.4 retrieving revision 1.15.2.5 diff -C2 -r1.15.2.4 -r1.15.2.5 *** pythoncore.dsp 2001/07/06 18:53:48 1.15.2.4 --- pythoncore.dsp 2001/07/17 04:19:05 1.15.2.5 *************** *** 496,514 **** # Begin Source File - SOURCE=..\Objects\descrobject.c - - !IF "$(CFG)" == "pythoncore - Win32 Release" - - !ELSEIF "$(CFG)" == "pythoncore - Win32 Debug" - - !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Debug" - - !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Release" - - !ENDIF - - # End Source File - # Begin Source File - SOURCE=..\Objects\dictobject.c --- 496,499 ---- *************** *** 725,733 **** !IF "$(CFG)" == "pythoncore - Win32 Release" ! # ADD CPP /D BUILD=16 !ELSEIF "$(CFG)" == "pythoncore - Win32 Debug" ! # ADD CPP /D BUILD=16 !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Debug" --- 710,718 ---- !IF "$(CFG)" == "pythoncore - Win32 Release" ! # ADD CPP /D BUILD=21 !ELSEIF "$(CFG)" == "pythoncore - Win32 Debug" ! # ADD CPP /D BUILD=21 !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Debug" *************** *** 1724,1742 **** SOURCE=..\Modules\xreadlinesmodule.c - - !IF "$(CFG)" == "pythoncore - Win32 Release" - - !ELSEIF "$(CFG)" == "pythoncore - Win32 Debug" - - !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Debug" - - !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Release" - - !ENDIF - - # End Source File - # Begin Source File - - SOURCE=..\Modules\xxsubtype.c !IF "$(CFG)" == "pythoncore - Win32 Release" --- 1709,1712 ---- From tim_one@users.sourceforge.net Tue Jul 17 05:19:07 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 21:19:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/mlte Mltemodule.c,1.3,1.3.2.1 mltescan.py,1.3,1.3.2.1 mltesupport.py,1.3,1.3.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/mlte In directory usw-pr-cvs1:/tmp/cvs-serv7540/descr/dist/src/Mac/Modules/mlte Modified Files: Tag: descr-branch Mltemodule.c mltescan.py mltesupport.py Log Message: Last trunk->branch merge for today . Index: Mltemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/mlte/Mltemodule.c,v retrieving revision 1.3 retrieving revision 1.3.2.1 diff -C2 -r1.3 -r1.3.2.1 *** Mltemodule.c 2001/07/14 14:00:41 1.3 --- Mltemodule.c 2001/07/17 04:19:05 1.3.2.1 *************** *** 71,74 **** --- 71,88 ---- } + /* + ** Parse an optional GWorld + */ + static int + OptGWorldObj_Convert(PyObject *v, GWorldPtr *p_itself) + { + if (v == Py_None) + { + *p_itself = NULL; + return 1; + } + return GWorldObj_Convert(v, p_itself); + } + static PyObject *Mlte_Error; *************** *** 277,281 **** PyMac_PRECHECK(TXNDraw); if (!PyArg_ParseTuple(_args, "O&", ! GWorldObj_Convert, &iDrawPort)) return NULL; TXNDraw(_self->ob_itself, --- 291,295 ---- PyMac_PRECHECK(TXNDraw); if (!PyArg_ParseTuple(_args, "O&", ! OptGWorldObj_Convert, &iDrawPort)) return NULL; TXNDraw(_self->ob_itself, Index: mltescan.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/mlte/mltescan.py,v retrieving revision 1.3 retrieving revision 1.3.2.1 diff -C2 -r1.3 -r1.3.2.1 *** mltescan.py 2001/07/14 14:00:45 1.3 --- mltescan.py 2001/07/17 04:19:05 1.3.2.1 *************** *** 117,121 **** # The AdjustCursor region handle is optional ([("RgnHandle", "ioCursorRgn", "InMode")], ! [("OptRgnHandle", "*", "*")]) ] --- 117,125 ---- # The AdjustCursor region handle is optional ([("RgnHandle", "ioCursorRgn", "InMode")], ! [("OptRgnHandle", "*", "*")]), ! ! # The GWorld for TXNDraw is optional ! ([('GWorldPtr', 'iDrawPort', 'InMode')], ! [('OptGWorldPtr', '*', '*')]), ] Index: mltesupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/mlte/mltesupport.py,v retrieving revision 1.3 retrieving revision 1.3.2.1 diff -C2 -r1.3 -r1.3.2.1 *** mltesupport.py 2001/07/14 14:00:50 1.3 --- mltesupport.py 2001/07/17 04:19:05 1.3.2.1 *************** *** 75,78 **** --- 75,92 ---- } + /* + ** Parse an optional GWorld + */ + static int + OptGWorldObj_Convert(PyObject *v, GWorldPtr *p_itself) + { + if (v == Py_None) + { + *p_itself = NULL; + return 1; + } + return GWorldObj_Convert(v, p_itself); + } + """ *************** *** 110,113 **** --- 124,128 ---- OptRgnHandle = OpaqueByValueType("RgnHandle", "OptResObj") GWorldPtr = OpaqueByValueType("GWorldPtr", "GWorldObj") + OptGWorldPtr = OpaqueByValueType("GWorldPtr", "OptGWorldObj") MlteInBuffer = VarInputBufferType('void *', 'ByteCount', 'l') From tim_one@users.sourceforge.net Tue Jul 17 05:19:07 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 21:19:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Demo/mlte mlted.py,1.1,1.1.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Demo/mlte In directory usw-pr-cvs1:/tmp/cvs-serv7540/descr/dist/src/Mac/Demo/mlte Modified Files: Tag: descr-branch mlted.py Log Message: Last trunk->branch merge for today . Index: mlted.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Demo/mlte/mlted.py,v retrieving revision 1.1 retrieving revision 1.1.2.1 diff -C2 -r1.1 -r1.1.2.1 *** mlted.py 2001/07/14 14:02:21 1.1 --- mlted.py 2001/07/17 04:19:05 1.1.2.1 *************** *** 7,10 **** --- 7,11 ---- from FrameWork import * import Win + import Ctl import Qd import Res *************** *** 19,23 **** "Style Change", "Align Left", "Align Center", "Align Right", "Drop", "Move"] ! class WasteWindow(Window): def open(self, path, name, data): self.path = path --- 20,24 ---- "Style Change", "Align Left", "Align Center", "Align Right", "Drop", "Move"] ! class MlteWindow(Window): def open(self, path, name, data): self.path = path *************** *** 26,45 **** w = Win.NewWindow(r, name, 1, 0, -1, 1, 0x55555555) self.wid = w ! ## vr = 0, 0, r[2]-r[0]-15, r[3]-r[1]-15 ! ## dr = (0, 0, 10240, 0) ! ## Qd.SetPort(w) ! ## Qd.TextFont(4) ! ## Qd.TextSize(9) ! ## self.ted = waste.WENew(dr, vr, flags) ! flags = MacTextEditor.kTXNDrawGrowIconMask|MacTextEditor.kTXNShowWindowMask|MacTextEditor.kTXNWantHScrollBarMask| \ MacTextEditor.kTXNWantVScrollBarMask self.ted, self.frameid = Mlte.TXNNewObject(None, w, None, flags, MacTextEditor.kTXNTextEditStyleFrameType, MacTextEditor.kTXNTextFile, MacTextEditor.kTXNMacOSEncoding) - ## self.tedtexthandle = Res.Resource(data) - ## self.ted.WEUseText(self.tedtexthandle) self.ted.TXNSetData(MacTextEditor.kTXNTextData, data, 0, 0x7fffffff) - ## self.ted.WECalText() - ## w.DrawGrowIcon() - ## self.scrollbars() self.changed = 0 self.do_postopen() --- 27,35 ---- w = Win.NewWindow(r, name, 1, 0, -1, 1, 0x55555555) self.wid = w ! flags = MacTextEditor.kTXNDrawGrowIconMask|MacTextEditor.kTXNWantHScrollBarMask| \ MacTextEditor.kTXNWantVScrollBarMask self.ted, self.frameid = Mlte.TXNNewObject(None, w, None, flags, MacTextEditor.kTXNTextEditStyleFrameType, MacTextEditor.kTXNTextFile, MacTextEditor.kTXNMacOSEncoding) self.ted.TXNSetData(MacTextEditor.kTXNTextData, data, 0, 0x7fffffff) self.changed = 0 self.do_postopen() *************** *** 47,157 **** def do_idle(self, event): - ## (what, message, when, where, modifiers) = event - ## Qd.SetPort(self.wid) self.ted.TXNIdle() self.ted.TXNAdjustCursor(None) - ## def getscrollbarvalues(self): - ## dr = self.ted.WEGetDestRect() - ## vr = self.ted.WEGetViewRect() - ## vx = self.scalebarvalue(dr[0], dr[2], vr[0], vr[2]) - ## vy = self.scalebarvalue(dr[1], dr[3], vr[1], vr[3]) - #### print dr, vr, vx, vy - ## return vx, vy - ## - ## def scrollbar_callback(self, which, what, value): - ## if which == 'y': - ## if what == 'set': - ## height = self.ted.WEGetHeight(0, 0x3fffffff) - ## cur = self.getscrollbarvalues()[1] - ## delta = (cur-value)*height/32767 - ## if what == '-': - ## topline_off,dummy = self.ted.WEGetOffset((1,1)) - ## topline_num = self.ted.WEOffsetToLine(topline_off) - ## delta = self.ted.WEGetHeight(topline_num, topline_num+1) - ## elif what == '--': - ## delta = (self.ted.WEGetViewRect()[3]-10) - ## if delta <= 0: - ## delta = 10 # Random value - ## elif what == '+': - ## # XXXX Wrong: should be bottom line size - ## topline_off,dummy = self.ted.WEGetOffset((1,1)) - ## topline_num = self.ted.WEOffsetToLine(topline_off) - ## delta = -self.ted.WEGetHeight(topline_num, topline_num+1) - ## elif what == '++': - ## delta = -(self.ted.WEGetViewRect()[3]-10) - ## if delta >= 0: - ## delta = -10 - ## self.ted.WEScroll(0, delta) - #### print 'SCROLL Y', delta - ## else: - ## if what == 'set': - ## return # XXXX - ## vr = self.ted.WEGetViewRect() - ## winwidth = vr[2]-vr[0] - ## if what == '-': - ## delta = winwidth/10 - ## elif what == '--': - ## delta = winwidth/2 - ## elif what == '+': - ## delta = -winwidth/10 - ## elif what == '++': - ## delta = -winwidth/2 - ## self.ted.WEScroll(delta, 0) - ## # Pin the scroll - ## l, t, r, b = self.ted.WEGetDestRect() - ## vl, vt, vr, vb = self.ted.WEGetViewRect() - ## if t > 0 or l > 0: - ## dx = dy = 0 - ## if t > 0: dy = -t - ## if l > 0: dx = -l - #### print 'Extra scroll', dx, dy - ## self.ted.WEScroll(dx, dy) - ## elif b < vb: - #### print 'Extra downscroll', b-vb - ## self.ted.WEScroll(0, b-vb) def do_activate(self, onoff, evt): - ## print "ACTIVATE", onoff - Qd.SetPort(self.wid) - Window.do_activate(self, onoff, evt) if onoff: self.ted.TXNFocus(1) self.parent.active = self - self.parent.updatemenubar() else: self.ted.TXNFocus(0) def do_update(self, wid, event): ! Qd.SetPort(self.wid) ! ## region = wid.GetWindowPort().visRgn ! ## if Qd.EmptyRgn(region): ! ## return ! ## Qd.EraseRgn(region) ! self.ted.TXNUpdate() ! ## self.updatescrollbars() ! ## def do_postresize(self, width, height, window): ! ## l, t, r, b = self.ted.WEGetViewRect() ! ## vr = (l, t, l+width-15, t+height-15) ! ## self.ted.WESetViewRect(vr) ! ## self.wid.InvalWindowRect(vr) ! ## ScrolledWindow.do_postresize(self, width, height, window) def do_contentclick(self, local, modifiers, evt): - ## (what, message, when, where, modifiers) = evt self.ted.TXNClick(evt) - ## self.updatescrollbars() self.parent.updatemenubar() ! def do_char(self, ch, event): self.ted.TXNKeyDown(event) ! ## self.ted.WESelView() ! ## (what, message, when, where, modifiers) = event ! ## self.ted.WEKey(ord(ch), modifiers) ! ## self.changed = 1 ! ## self.updatescrollbars() ! ## self.parent.updatemenubar() def close(self): --- 37,68 ---- def do_idle(self, event): self.ted.TXNIdle() self.ted.TXNAdjustCursor(None) def do_activate(self, onoff, evt): if onoff: + ## self.ted.TXNActivate(self.frameid, 0) self.ted.TXNFocus(1) self.parent.active = self else: self.ted.TXNFocus(0) + self.parent.active = None + self.parent.updatemenubar() def do_update(self, wid, event): ! self.ted.TXNDraw(None) ! def do_postresize(self, width, height, window): ! self.ted.TXNResizeFrame(width, height, self.frameid) def do_contentclick(self, local, modifiers, evt): self.ted.TXNClick(evt) self.parent.updatemenubar() ! def do_char(self, ch, event): self.ted.TXNKeyDown(event) ! self.parent.updatemenubar() def close(self): *************** *** 164,168 **** if self.parent.active == self: self.parent.active = None ! ## self.parent.updatemenubar() del self.ted ## del self.tedtexthandle --- 75,79 ---- if self.parent.active == self: self.parent.active = None ! self.ted.TXNDeleteObject() del self.ted ## del self.tedtexthandle *************** *** 173,177 **** self.menu_save_as() return # Will call us recursively - print 'Saving to ', self.path dhandle = self.ted.TXNGetData(0, 0x7fffffff) data = dhandle.data --- 84,87 ---- *************** *** 280,284 **** self.editmenu = m = Menu(self.menubar, "Edit") self.undoitem = MenuItem(m, "Undo", "Z", self.undo) ! self.redoitem = MenuItem(m, "Undo", None, self.redo) self.cutitem = MenuItem(m, "Cut", "X", self.cut) self.copyitem = MenuItem(m, "Copy", "C", self.copy) --- 190,195 ---- self.editmenu = m = Menu(self.menubar, "Edit") self.undoitem = MenuItem(m, "Undo", "Z", self.undo) ! self.redoitem = MenuItem(m, "Redo", None, self.redo) ! m.addseparator() self.cutitem = MenuItem(m, "Cut", "X", self.cut) self.copyitem = MenuItem(m, "Copy", "C", self.copy) *************** *** 374,378 **** name = "Untitled %d"%self.num data = '' ! w = WasteWindow(self) w.open(path, name, data) self.num = self.num + 1 --- 285,289 ---- name = "Untitled %d"%self.num data = '' ! w = MlteWindow(self) w.open(path, name, data) self.num = self.num + 1 From tim_one@users.sourceforge.net Tue Jul 17 05:19:07 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 21:19:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib rfc822.py,1.54.6.1,1.54.6.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv7540/descr/dist/src/Lib Modified Files: Tag: descr-branch rfc822.py Log Message: Last trunk->branch merge for today . Index: rfc822.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/rfc822.py,v retrieving revision 1.54.6.1 retrieving revision 1.54.6.2 diff -C2 -r1.54.6.1 -r1.54.6.2 *** rfc822.py 2001/07/07 22:55:28 1.54.6.1 --- rfc822.py 2001/07/17 04:19:05 1.54.6.2 *************** *** 1,51 **** ! """RFC-822 message manipulation class. ! XXX This is only a very rough sketch of a full RFC-822 parser; ! in particular the tokenizing of addresses does not adhere to all the ! quoting rules. Directions for use: To create a Message object: first open a file, e.g.: fp = open(file, 'r') You can use any other legal way of getting an open file object, e.g. use ! sys.stdin or call os.popen(). ! Then pass the open file object to the Message() constructor: m = Message(fp) ! This class can work with any input object that supports a readline ! method. If the input object has seek and tell capability, the ! rewindbody method will work; also illegal lines will be pushed back ! onto the input stream. If the input object lacks seek but has an ! `unread' method that can push back a line of input, Message will use ! that to push back illegal lines. Thus this class can be used to parse ! messages coming from a buffered stream. ! ! The optional `seekable' argument is provided as a workaround for ! certain stdio libraries in which tell() discards buffered data before ! discovering that the lseek() system call doesn't work. For maximum ! portability, you should set the seekable argument to zero to prevent ! that initial \code{tell} when passing in an unseekable object such as ! a a file object created from a socket object. If it is 1 on entry -- ! which it is by default -- the tell() method of the open file object is ! called once; if this raises an exception, seekable is reset to 0. For ! other nonzero values of seekable, this test is not made. To get the text of a particular header there are several methods: str = m.getheader(name) str = m.getrawheader(name) - where name is the name of the header, e.g. 'Subject'. - The difference is that getheader() strips the leading and trailing - whitespace, while getrawheader() doesn't. Both functions retain - embedded whitespace (including newlines) exactly as they are - specified in the header, and leave the case of the text unchanged. For addresses and address lists there are functions ! realname, mailaddress = m.getaddr(name) and list = m.getaddrlist(name) where the latter returns a list of (realname, mailaddr) tuples. There is also a method time = m.getdate(name) which parses a Date-like field and returns a time-compatible tuple, i.e. a tuple such as returned by time.localtime() or accepted by --- 1,65 ---- ! """RFC 2822 message manipulation. ! Note: This is only a very rough sketch of a full RFC-822 parser; in particular ! the tokenizing of addresses does not adhere to all the quoting rules. + Note: RFC 2822 is a long awaited update to RFC 822. This module should + conform to RFC 2822, and is thus mis-named (it's not worth renaming it). Some + effort at RFC 2822 updates have been made, but a thorough audit has not been + performed. Consider any RFC 2822 non-conformance to be a bug. + + RFC 2822: http://www.faqs.org/rfcs/rfc2822.html + RFC 822 : http://www.faqs.org/rfcs/rfc822.html (obsolete) + Directions for use: To create a Message object: first open a file, e.g.: + fp = open(file, 'r') + You can use any other legal way of getting an open file object, e.g. use ! sys.stdin or call os.popen(). Then pass the open file object to the Message() ! constructor: ! m = Message(fp) ! This class can work with any input object that supports a readline method. If ! the input object has seek and tell capability, the rewindbody method will ! work; also illegal lines will be pushed back onto the input stream. If the ! input object lacks seek but has an `unread' method that can push back a line ! of input, Message will use that to push back illegal lines. Thus this class ! can be used to parse messages coming from a buffered stream. ! ! The optional `seekable' argument is provided as a workaround for certain stdio ! libraries in which tell() discards buffered data before discovering that the ! lseek() system call doesn't work. For maximum portability, you should set the ! seekable argument to zero to prevent that initial \code{tell} when passing in ! an unseekable object such as a a file object created from a socket object. If ! it is 1 on entry -- which it is by default -- the tell() method of the open ! file object is called once; if this raises an exception, seekable is reset to ! 0. For other nonzero values of seekable, this test is not made. To get the text of a particular header there are several methods: + str = m.getheader(name) str = m.getrawheader(name) + where name is the name of the header, e.g. 'Subject'. The difference is that + getheader() strips the leading and trailing whitespace, while getrawheader() + doesn't. Both functions retain embedded whitespace (including newlines) + exactly as they are specified in the header, and leave the case of the text + unchanged. + For addresses and address lists there are functions ! ! realname, mailaddress = m.getaddr(name) list = m.getaddrlist(name) + where the latter returns a list of (realname, mailaddr) tuples. There is also a method + time = m.getdate(name) + which parses a Date-like field and returns a time-compatible tuple, i.e. a tuple such as returned by time.localtime() or accepted by *************** *** 66,70 **** class Message: ! """Represents a single RFC-822-compliant message.""" def __init__(self, fp, seekable = 1): --- 80,84 ---- class Message: ! """Represents a single RFC 2822-compliant message.""" def __init__(self, fp, seekable = 1): *************** *** 107,122 **** """Read header lines. ! Read header lines up to the entirely blank line that ! terminates them. The (normally blank) line that ends the ! headers is skipped, but not included in the returned list. ! If a non-header line ends the headers, (which is an error), ! an attempt is made to backspace over it; it is never ! included in the returned list. ! ! The variable self.status is set to the empty string if all ! went well, otherwise it is an error message. ! The variable self.headers is a completely uninterpreted list ! of lines contained in the header (so printing them will ! reproduce the header exactly as it appears in the file). """ self.dict = {} --- 121,135 ---- """Read header lines. ! Read header lines up to the entirely blank line that terminates them. ! The (normally blank) line that ends the headers is skipped, but not ! included in the returned list. If a non-header line ends the headers, ! (which is an error), an attempt is made to backspace over it; it is ! never included in the returned list. ! ! The variable self.status is set to the empty string if all went well, ! otherwise it is an error message. The variable self.headers is a ! completely uninterpreted list of lines contained in the header (so ! printing them will reproduce the header exactly as it appears in the ! file). """ self.dict = {} *************** *** 184,189 **** This method should return the header name, suitably canonicalized. ! You may override this method in order to use Message parsing ! on tagged data in RFC822-like formats with special header formats. """ i = line.find(':') --- 197,202 ---- This method should return the header name, suitably canonicalized. ! You may override this method in order to use Message parsing on tagged ! data in RFC 2822-like formats with special header formats. """ i = line.find(':') *************** *** 194,204 **** def islast(self, line): ! """Determine whether a line is a legal end of RFC-822 headers. ! You may override this method if your application wants ! to bend the rules, e.g. to strip trailing whitespace, ! or to recognize MH template separators ('--------'). ! For convenience (e.g. for code reading from sockets) a ! line consisting of \r\n also matches. """ return line in _blanklines --- 207,216 ---- def islast(self, line): ! """Determine whether a line is a legal end of RFC 2822 headers. ! You may override this method if your application wants to bend the ! rules, e.g. to strip trailing whitespace, or to recognize MH template ! separators ('--------'). For convenience (e.g. for code reading from ! sockets) a line consisting of \r\n also matches. """ return line in _blanklines *************** *** 207,213 **** """Determine whether a line should be skipped entirely. ! You may override this method in order to use Message parsing ! on tagged data in RFC822-like formats that support embedded ! comments or free-text data. """ return None --- 219,225 ---- """Determine whether a line should be skipped entirely. ! You may override this method in order to use Message parsing on tagged ! data in RFC 2822-like formats that support embedded comments or ! free-text data. """ return None *************** *** 216,226 **** """Find all header lines matching a given header name. ! Look through the list of headers and find all lines ! matching a given header name (and their continuation ! lines). A list of the lines is returned, without ! interpretation. If the header does not occur, an ! empty list is returned. If the header occurs multiple ! times, all occurrences are returned. Case is not ! important in the header name. """ name = name.lower() + ':' --- 228,236 ---- """Find all header lines matching a given header name. ! Look through the list of headers and find all lines matching a given ! header name (and their continuation lines). A list of the lines is ! returned, without interpretation. If the header does not occur, an ! empty list is returned. If the header occurs multiple times, all ! occurrences are returned. Case is not important in the header name. """ name = name.lower() + ':' *************** *** 240,246 **** """Get the first header line matching name. ! This is similar to getallmatchingheaders, but it returns ! only the first matching header (and its continuation ! lines). """ name = name.lower() + ':' --- 250,255 ---- """Get the first header line matching name. ! This is similar to getallmatchingheaders, but it returns only the ! first matching header (and its continuation lines). """ name = name.lower() + ':' *************** *** 261,269 **** """A higher-level interface to getfirstmatchingheader(). ! Return a string containing the literal text of the ! header but with the keyword stripped. All leading, ! trailing and embedded whitespace is kept in the ! string, however. ! Return None if the header does not occur. """ --- 270,277 ---- """A higher-level interface to getfirstmatchingheader(). ! Return a string containing the literal text of the header but with the ! keyword stripped. All leading, trailing and embedded whitespace is ! kept in the string, however. Return None if the header does not ! occur. """ *************** *** 277,284 **** """Get the header value for a name. ! This is the normal interface: it returns a stripped ! version of the header value for a given header name, ! or None if it doesn't exist. This uses the dictionary ! version which finds the *last* such header. """ try: --- 285,291 ---- """Get the header value for a name. ! This is the normal interface: it returns a stripped version of the ! header value for a given header name, or None if it doesn't exist. ! This uses the dictionary version which finds the *last* such header. """ try: *************** *** 291,298 **** """Get all values for a header. ! This returns a list of values for headers given more than once; ! each value in the result list is stripped in the same way as the ! result of getheader(). If the header is not given, return an ! empty list. """ result = [] --- 298,304 ---- """Get all values for a header. ! This returns a list of values for headers given more than once; each ! value in the result list is stripped in the same way as the result of ! getheader(). If the header is not given, return an empty list. """ result = [] *************** *** 333,337 **** tuple as returned by getaddr(). Scans all named headers, so it works properly with multiple To: or Cc: headers for example. - """ raw = [] --- 339,342 ---- *************** *** 353,358 **** """Retrieve a date field from a header. ! Retrieves a date field from the named header, returning ! a tuple compatible with time.mktime(). """ try: --- 358,363 ---- """Retrieve a date field from a header. ! Retrieves a date field from the named header, returning a tuple ! compatible with time.mktime(). """ try: *************** *** 365,371 **** """Retrieve a date field from a header as a 10-tuple. ! The first 9 elements make up a tuple compatible with ! time.mktime(), and the 10th is the offset of the poster's ! time zone from GMT/UTC. """ try: --- 370,375 ---- """Retrieve a date field from a header as a 10-tuple. ! The first 9 elements make up a tuple compatible with time.mktime(), ! and the 10th is the offset of the poster's time zone from GMT/UTC. """ try: *************** *** 389,395 **** """Set the value of a header. ! Note: This is not a perfect inversion of __getitem__, because ! any changed headers get stuck at the end of the raw-headers list ! rather than where the altered header was. """ del self[name] # Won't fail if it doesn't exist --- 393,399 ---- """Set the value of a header. ! Note: This is not a perfect inversion of __getitem__, because any ! changed headers get stuck at the end of the raw-headers list rather ! than where the altered header was. """ del self[name] # Won't fail if it doesn't exist *************** *** 503,508 **** To understand what this class does, it helps to have a copy of ! RFC-822 in front of you. Note: this class interface is deprecated and may be removed in the future. Use rfc822.AddressList instead. --- 507,514 ---- To understand what this class does, it helps to have a copy of ! RFC 2822 in front of you. + http://www.faqs.org/rfcs/rfc2822.html + Note: this class interface is deprecated and may be removed in the future. Use rfc822.AddressList instead. *************** *** 512,517 **** """Initialize a new instance. ! `field' is an unparsed address header field, containing ! one or more addresses. """ self.specials = '()<>@,:;.\"[]' --- 518,523 ---- """Initialize a new instance. ! `field' is an unparsed address header field, containing one or more ! addresses. """ self.specials = '()<>@,:;.\"[]' *************** *** 520,523 **** --- 526,533 ---- self.CR = '\r\n' self.atomends = self.specials + self.LWS + self.CR + # Note that RFC 2822 now specifies `.' as obs-phrase, meaning that it + # is obsolete syntax. RFC 2822 requires that we recognize obsolete + # syntax, so allow dots in phrases. + self.phraseends = self.atomends.replace('.', '') self.field = field self.commentlist = [] *************** *** 634,638 **** def getaddrspec(self): ! """Parse an RFC-822 addr-spec.""" aslist = [] --- 644,648 ---- def getaddrspec(self): ! """Parse an RFC 2822 addr-spec.""" aslist = [] *************** *** 678,690 **** """Parse a header fragment delimited by special characters. ! `beginchar' is the start character for the fragment. ! If self is not looking at an instance of `beginchar' then ! getdelimited returns the empty string. `endchars' is a sequence of allowable end-delimiting characters. Parsing stops when one of these is encountered. ! If `allowcomments' is non-zero, embedded RFC-822 comments ! are allowed within the parsed fragment. """ if self.field[self.pos] != beginchar: --- 688,700 ---- """Parse a header fragment delimited by special characters. ! `beginchar' is the start character for the fragment. If self is not ! looking at an instance of `beginchar' then getdelimited returns the ! empty string. `endchars' is a sequence of allowable end-delimiting characters. Parsing stops when one of these is encountered. ! If `allowcomments' is non-zero, embedded RFC 2822 comments are allowed ! within the parsed fragment. """ if self.field[self.pos] != beginchar: *************** *** 720,732 **** def getdomainliteral(self): ! """Parse an RFC-822 domain-literal.""" return '[%s]' % self.getdelimited('[', ']\r', 0) ! def getatom(self): ! """Parse an RFC-822 atom.""" atomlist = [''] while self.pos < len(self.field): ! if self.field[self.pos] in self.atomends: break else: atomlist.append(self.field[self.pos]) --- 730,749 ---- def getdomainliteral(self): ! """Parse an RFC 2822 domain-literal.""" return '[%s]' % self.getdelimited('[', ']\r', 0) + + def getatom(self, atomends=None): + """Parse an RFC 2822 atom. ! Optional atomends specifies a different set of end token delimiters ! (the default is to use self.atomends). This is used e.g. in ! getphraselist() since phrase endings must not include the `.' (which ! is legal in phrases).""" atomlist = [''] + if atomends is None: + atomends = self.atomends while self.pos < len(self.field): ! if self.field[self.pos] in atomends: break else: atomlist.append(self.field[self.pos]) *************** *** 736,744 **** def getphraselist(self): ! """Parse a sequence of RFC-822 phrases. ! A phrase is a sequence of words, which are in turn either ! RFC-822 atoms or quoted-strings. Phrases are canonicalized ! by squeezing all runs of continuous whitespace into one space. """ plist = [] --- 753,761 ---- def getphraselist(self): ! """Parse a sequence of RFC 2822 phrases. ! A phrase is a sequence of words, which are in turn either RFC 2822 ! atoms or quoted-strings. Phrases are canonicalized by squeezing all ! runs of continuous whitespace into one space. """ plist = [] *************** *** 751,762 **** elif self.field[self.pos] == '(': self.commentlist.append(self.getcomment()) ! elif self.field[self.pos] in self.atomends: break ! else: plist.append(self.getatom()) return plist class AddressList(AddrlistClass): ! """An AddressList encapsulates a list of parsed RFC822 addresses.""" def __init__(self, field): AddrlistClass.__init__(self, field) --- 768,780 ---- elif self.field[self.pos] == '(': self.commentlist.append(self.getcomment()) ! elif self.field[self.pos] in self.phraseends: break ! else: ! plist.append(self.getatom(self.phraseends)) return plist class AddressList(AddrlistClass): ! """An AddressList encapsulates a list of parsed RFC 2822 addresses.""" def __init__(self, field): AddrlistClass.__init__(self, field) From tim_one@users.sourceforge.net Tue Jul 17 05:19:07 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 21:19:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _tkinter.c,1.115.6.1,1.115.6.2 parsermodule.c,2.60.6.1,2.60.6.2 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv7540/descr/dist/src/Modules Modified Files: Tag: descr-branch _tkinter.c parsermodule.c Log Message: Last trunk->branch merge for today . Index: _tkinter.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_tkinter.c,v retrieving revision 1.115.6.1 retrieving revision 1.115.6.2 diff -C2 -r1.115.6.1 -r1.115.6.2 *** _tkinter.c 2001/07/07 22:55:29 1.115.6.1 --- _tkinter.c 2001/07/17 04:19:05 1.115.6.2 *************** *** 58,62 **** #endif ! #if !(defined(MS_WINDOWS) || defined(__CYGWIN__)) #define HAVE_CREATEFILEHANDLER #endif --- 58,63 ---- #endif ! #if !(defined(MS_WINDOWS) || defined(__CYGWIN__) || defined(macintosh)) ! /* Mac has it, but it doesn't really work:-( */ #define HAVE_CREATEFILEHANDLER #endif Index: parsermodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/parsermodule.c,v retrieving revision 2.60.6.1 retrieving revision 2.60.6.2 diff -C2 -r2.60.6.1 -r2.60.6.2 *** parsermodule.c 2001/07/07 22:55:29 2.60.6.1 --- parsermodule.c 2001/07/17 04:19:05 2.60.6.2 *************** *** 831,835 **** VALIDATER(exprlist); VALIDATER(dictmaker); VALIDATER(arglist); VALIDATER(argument); ! VALIDATER(listmaker); #undef VALIDATER --- 831,835 ---- VALIDATER(exprlist); VALIDATER(dictmaker); VALIDATER(arglist); VALIDATER(argument); ! VALIDATER(listmaker); VALIDATER(yield_stmt); #undef VALIDATER *************** *** 1539,1543 **** --- 1539,1555 ---- + /* yield_stmt: 'yield' testlist + */ static int + validate_yield_stmt(node *tree) + { + return (validate_ntype(tree, yield_stmt) + && validate_numnodes(tree, 2, "yield_stmt") + && validate_name(CHILD(tree, 0), "yield") + && validate_testlist(CHILD(tree, 1))); + } + + + static int validate_import_as_name(node *tree) { *************** *** 2556,2559 **** --- 2568,2572 ---- && ((TYPE(CHILD(tree, 0)) == break_stmt) || (TYPE(CHILD(tree, 0)) == continue_stmt) + || (TYPE(CHILD(tree, 0)) == yield_stmt) || (TYPE(CHILD(tree, 0)) == return_stmt) || (TYPE(CHILD(tree, 0)) == raise_stmt))); *************** *** 2562,2565 **** --- 2575,2581 ---- else if (nch == 1) err_string("illegal flow_stmt type"); + break; + case yield_stmt: + res = validate_yield_stmt(tree); break; /* From tim_one@users.sourceforge.net Tue Jul 17 05:19:07 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 21:19:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_parser.py,1.6.6.1,1.6.6.2 test_rfc822.py,1.9.6.1,1.9.6.2 test_urllib2.py,1.2.4.1,1.2.4.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv7540/descr/dist/src/Lib/test Modified Files: Tag: descr-branch test_parser.py test_rfc822.py test_urllib2.py Log Message: Last trunk->branch merge for today . Index: test_parser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_parser.py,v retrieving revision 1.6.6.1 retrieving revision 1.6.6.2 diff -C2 -r1.6.6.1 -r1.6.6.2 *** test_parser.py 2001/07/07 22:55:29 1.6.6.1 --- test_parser.py 2001/07/17 04:19:05 1.6.6.2 *************** *** 27,30 **** --- 27,42 ---- self.roundtrip(parser.suite, s) + def test_yield_statement(self): + self.check_suite("from __future__ import generators\n" + "def f(): yield 1") + self.check_suite("from __future__ import generators\n" + "def f(): return; yield 1") + self.check_suite("from __future__ import generators\n" + "def f(): yield 1; return") + self.check_suite("from __future__ import generators\n" + "def f():\n" + " for x in range(30):\n" + " yield x\n") + def test_expressions(self): self.check_expr("foo(1)") *************** *** 139,144 **** self.check_bad_tree((1, 2, 3), "") def test_print_chevron_comma(self): ! "Illegal input: print >>fp,""" tree = \ (257, --- 151,275 ---- self.check_bad_tree((1, 2, 3), "") + def test_illegal_yield_1(self): + """Illegal yield statement: def f(): return 1; yield 1""" + tree = \ + (257, + (264, + (285, + (259, + (1, 'def'), + (1, 'f'), + (260, (7, '('), (8, ')')), + (11, ':'), + (291, + (4, ''), + (5, ''), + (264, + (265, + (266, + (272, + (275, + (1, 'return'), + (313, + (292, + (293, + (294, + (295, + (297, + (298, + (299, + (300, + (301, + (302, (303, (304, (305, (2, '1')))))))))))))))))), + (264, + (265, + (266, + (272, + (276, + (1, 'yield'), + (313, + (292, + (293, + (294, + (295, + (297, + (298, + (299, + (300, + (301, + (302, + (303, (304, (305, (2, '1')))))))))))))))))), + (4, ''))), + (6, ''))))), + (4, ''), + (0, '')))) + self.check_bad_tree(tree, "def f():\n return 1\n yield 1") + + def test_illegal_yield_2(self): + """Illegal return in generator: def f(): return 1; yield 1""" + tree = \ + (257, + (264, + (265, + (266, + (278, + (1, 'from'), + (281, (1, '__future__')), + (1, 'import'), + (279, (1, 'generators')))), + (4, ''))), + (264, + (285, + (259, + (1, 'def'), + (1, 'f'), + (260, (7, '('), (8, ')')), + (11, ':'), + (291, + (4, ''), + (5, ''), + (264, + (265, + (266, + (272, + (275, + (1, 'return'), + (313, + (292, + (293, + (294, + (295, + (297, + (298, + (299, + (300, + (301, + (302, (303, (304, (305, (2, '1')))))))))))))))))), + (264, + (265, + (266, + (272, + (276, + (1, 'yield'), + (313, + (292, + (293, + (294, + (295, + (297, + (298, + (299, + (300, + (301, + (302, + (303, (304, (305, (2, '1')))))))))))))))))), + (4, ''))), + (6, ''))))), + (4, ''), + (0, '')))) + self.check_bad_tree(tree, "def f():\n return 1\n yield 1") + def test_print_chevron_comma(self): ! """Illegal input: print >>fp,""" tree = \ (257, Index: test_rfc822.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_rfc822.py,v retrieving revision 1.9.6.1 retrieving revision 1.9.6.2 diff -C2 -r1.9.6.1 -r1.9.6.2 *** test_rfc822.py 2001/07/07 22:55:29 1.9.6.1 --- test_rfc822.py 2001/07/17 04:19:05 1.9.6.2 *************** *** 118,121 **** --- 118,125 ---- ]) + self.check( + 'To: person@dom.ain (User J. Person)\n\n', + [('User J. Person', 'person@dom.ain')]) + def test_twisted(self): # This one is just twisted. I don't know what the proper *************** *** 165,168 **** --- 169,180 ---- [('', 'guido@[132.151.1.21]')]) + def test_rfc2822_phrases(self): + # RFC 2822 (the update to RFC 822) specifies that dots in phrases are + # obsolete syntax, which conforming programs MUST recognize but NEVER + # generate (see $4.1 Miscellaneous obsolete tokens). This is a + # departure from RFC 822 which did not allow dots in non-quoted + # phrases. + self.check('To: User J. Person \n\n', + [('User J. Person', 'person@dom.ain')]) test_support.run_unittest(MessageTestCase) Index: test_urllib2.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_urllib2.py,v retrieving revision 1.2.4.1 retrieving revision 1.2.4.2 diff -C2 -r1.2.4.1 -r1.2.4.2 *** test_urllib2.py 2001/07/07 22:55:29 1.2.4.1 --- test_urllib2.py 2001/07/17 04:19:05 1.2.4.2 *************** *** 1,4 **** --- 1,5 ---- from test_support import verify import urllib2 + import os # A couple trivial tests *************** *** 11,16 **** verify(0) ! file_url = "file://%s" % urllib2.__file__ f = urllib2.urlopen(file_url) buf = f.read() f.close() --- 12,22 ---- verify(0) ! # XXX Name hacking to get this to work on Windows. ! fname = os.path.abspath(urllib2.__file__).replace('\\', '/') ! if fname[1:2] == ":": ! fname = fname[2:] ! file_url = "file://%s" % fname f = urllib2.urlopen(file_url) + buf = f.read() f.close() From tim_one@users.sourceforge.net Tue Jul 17 05:28:30 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 21:28:30 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0255.txt,1.14,1.15 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv9050/peps Modified Files: pep-0255.txt Log Message: New text about "from __future__ import generators". Index: pep-0255.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0255.txt,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -r1.14 -r1.15 *** pep-0255.txt 2001/07/05 19:20:16 1.14 --- pep-0255.txt 2001/07/17 04:28:28 1.15 *************** *** 126,133 **** "yield" is a new keyword, so a future statement[8] is needed to phase ! this in. [XXX spell this out -- but new keywords have ripple effects ! across tools too, and it's not clear this can be forced into the future ! framework at all -- it's not even clear that Python's parser alone can ! be taught to swing both ways based on a future stmt] The yield statement may only be used inside functions. A function that --- 126,138 ---- "yield" is a new keyword, so a future statement[8] is needed to phase ! this in: in the initial release, a module desiring to use generators ! must include the line ! ! from __future__ import generators ! ! near the top (see PEP 236[8]) for details). Modules using the ! identifier "yield" without a future statement will trigger warnings. ! In the following release, yield will be a language keyword and the ! future statement will no longer be needed. The yield statement may only be used inside functions. A function that From tim_one@users.sourceforge.net Tue Jul 17 05:51:56 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 16 Jul 2001 21:51:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild pythoncore.dsp,1.15.2.5,1.15.2.6 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv11968/descr/dist/src/PCbuild Modified Files: Tag: descr-branch pythoncore.dsp Log Message: Ack, the last merge dropped descrobject.c and xxsubtype.c from the descr-branch Windows build. pythoncore.dsp is a binary file as far as CVS is concerned, and its idea of "merging" consisted of replacing the file entirely. Index: pythoncore.dsp =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/pythoncore.dsp,v retrieving revision 1.15.2.5 retrieving revision 1.15.2.6 diff -C2 -r1.15.2.5 -r1.15.2.6 *** pythoncore.dsp 2001/07/17 04:19:05 1.15.2.5 --- pythoncore.dsp 2001/07/17 04:51:54 1.15.2.6 *************** *** 496,499 **** --- 496,514 ---- # Begin Source File + SOURCE=..\Objects\descrobject.c + + !IF "$(CFG)" == "pythoncore - Win32 Release" + + !ELSEIF "$(CFG)" == "pythoncore - Win32 Debug" + + !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Debug" + + !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Release" + + !ENDIF + + # End Source File + # Begin Source File + SOURCE=..\Objects\dictobject.c *************** *** 1709,1712 **** --- 1724,1742 ---- SOURCE=..\Modules\xreadlinesmodule.c + + !IF "$(CFG)" == "pythoncore - Win32 Release" + + !ELSEIF "$(CFG)" == "pythoncore - Win32 Debug" + + !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Debug" + + !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Release" + + !ENDIF + + # End Source File + # Begin Source File + + SOURCE=..\Modules\xxsubtype.c !IF "$(CFG)" == "pythoncore - Win32 Release" From fdrake@users.sourceforge.net Tue Jul 17 06:18:00 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 16 Jul 2001 22:18:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib librfc822.tex,1.35,1.36 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv15850/lib Modified Files: librfc822.tex Log Message: Fix a couple of minor markup nits. Footnotes should be added *after* punctuation, not before. (Yes, this should be merged with the descr branch. Sorry, Tim!) Index: librfc822.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/librfc822.tex,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -r1.35 -r1.36 *** librfc822.tex 2001/07/16 20:47:58 1.35 --- librfc822.tex 2001/07/17 05:17:58 1.36 *************** *** 7,15 **** This module defines a class, \class{Message}, which represents an ``email message'' as defined by the Internet standard ! \rfc{2822}\footnote{This module originally conformed to \rfc{822}, hence the name. Since then, \rfc{2822} has been released as an update to \rfc{822}. This module should be considered \rfc{2822}-conformant, especially in cases where the ! syntax or semantics have changed since \rfc{822}.}. Such messages consist of a collection of message headers, and a message body. This module also defines a helper class --- 7,15 ---- This module defines a class, \class{Message}, which represents an ``email message'' as defined by the Internet standard ! \rfc{2822}.\footnote{This module originally conformed to \rfc{822}, hence the name. Since then, \rfc{2822} has been released as an update to \rfc{822}. This module should be considered \rfc{2822}-conformant, especially in cases where the ! syntax or semantics have changed since \rfc{822}.} Such messages consist of a collection of message headers, and a message body. This module also defines a helper class *************** *** 73,78 **** \begin{funcdesc}{parseaddr}{address} ! Parse address -- which should be the value of some address-containing ! field such as \code{To:} or \code{Cc:} -- into its constituent ``realname'' and ``email address'' parts. Returns a tuple of that information, unless the parse fails, in which case a 2-tuple of --- 73,78 ---- \begin{funcdesc}{parseaddr}{address} ! Parse \var{address}, which should be the value of some address-containing ! field such as \code{To:} or \code{Cc:}, into its constituent ``realname'' and ``email address'' parts. Returns a tuple of that information, unless the parse fails, in which case a 2-tuple of *************** *** 258,262 **** support the \method{clear()}, \method{copy()}, \method{popitem()}, or \method{update()} methods of the mapping interface. (Support for ! \method{.get()} and \method{.setdefault()} was only added in Python 2.2.) --- 258,262 ---- support the \method{clear()}, \method{copy()}, \method{popitem()}, or \method{update()} methods of the mapping interface. (Support for ! \method{get()} and \method{setdefault()} was only added in Python 2.2.) From gvanrossum@users.sourceforge.net Tue Jul 17 14:57:19 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 17 Jul 2001 06:57:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Demo/scripts freeze.py,1.5,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Demo/scripts In directory usw-pr-cvs1:/tmp/cvs-serv4846 Removed Files: freeze.py Log Message: Deleting merge zombie. --- freeze.py DELETED --- From fdrake@users.sourceforge.net Tue Jul 17 15:45:47 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 17 Jul 2001 07:45:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools mkhowto,1.27,1.27.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools In directory usw-pr-cvs1:/tmp/cvs-serv20991/tools Modified Files: Tag: descr-branch mkhowto Log Message: Job.__init__(): Only create the builddir directory if it will be used (by building the HTML or text documentation). There is no need to create it for other formats. Job.build_html(): The builddir parameter is always passed in, so it need not be optional. Index: mkhowto =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/mkhowto,v retrieving revision 1.27 retrieving revision 1.27.2.1 diff -C2 -r1.27 -r1.27.2.1 *** mkhowto 2001/06/23 03:06:01 1.27 --- mkhowto 2001/07/17 14:45:43 1.27.2.1 *************** *** 228,234 **** self.filedir, self.doc = split_pathname(path) self.builddir = os.path.abspath(options.builddir or self.doc) ! if not os.path.exists(self.builddir): ! os.mkdir(self.builddir) ! self.log_filename = os.path.join(self.builddir, self.doc + ".how") if os.path.exists(self.log_filename): os.unlink(self.log_filename) --- 228,237 ---- self.filedir, self.doc = split_pathname(path) self.builddir = os.path.abspath(options.builddir or self.doc) ! if ("html" in options.formats or "text" in options.formats): ! if not os.path.exists(self.builddir): ! os.mkdir(self.builddir) ! self.log_filename = os.path.join(self.builddir, self.doc + ".how") ! else: ! self.log_filename = os.path.abspath(self.doc + ".how") if os.path.exists(self.log_filename): os.unlink(self.log_filename) *************** *** 351,357 **** self.run("%s -N0 -o %s.ps %s" % (DVIPS_BINARY, self.doc, self.doc)) ! def build_html(self, builddir=None, max_split_depth=None): ! if builddir is None: ! builddir = self.builddir if max_split_depth is None: max_split_depth = self.options.max_split_depth --- 354,358 ---- self.run("%s -N0 -o %s.ps %s" % (DVIPS_BINARY, self.doc, self.doc)) ! def build_html(self, builddir, max_split_depth=None): if max_split_depth is None: max_split_depth = self.options.max_split_depth From fdrake@users.sourceforge.net Tue Jul 17 15:46:11 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 17 Jul 2001 07:46:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools mkhowto,1.27,1.28 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools In directory usw-pr-cvs1:/tmp/cvs-serv21180/tools Modified Files: mkhowto Log Message: Job.__init__(): Only create the builddir directory if it will be used (by building the HTML or text documentation). There is no need to create it for other formats. Job.build_html(): The builddir parameter is always passed in, so it need not be optional. Index: mkhowto =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/mkhowto,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -r1.27 -r1.28 *** mkhowto 2001/06/23 03:06:01 1.27 --- mkhowto 2001/07/17 14:46:09 1.28 *************** *** 228,234 **** self.filedir, self.doc = split_pathname(path) self.builddir = os.path.abspath(options.builddir or self.doc) ! if not os.path.exists(self.builddir): ! os.mkdir(self.builddir) ! self.log_filename = os.path.join(self.builddir, self.doc + ".how") if os.path.exists(self.log_filename): os.unlink(self.log_filename) --- 228,237 ---- self.filedir, self.doc = split_pathname(path) self.builddir = os.path.abspath(options.builddir or self.doc) ! if ("html" in options.formats or "text" in options.formats): ! if not os.path.exists(self.builddir): ! os.mkdir(self.builddir) ! self.log_filename = os.path.join(self.builddir, self.doc + ".how") ! else: ! self.log_filename = os.path.abspath(self.doc + ".how") if os.path.exists(self.log_filename): os.unlink(self.log_filename) *************** *** 351,357 **** self.run("%s -N0 -o %s.ps %s" % (DVIPS_BINARY, self.doc, self.doc)) ! def build_html(self, builddir=None, max_split_depth=None): ! if builddir is None: ! builddir = self.builddir if max_split_depth is None: max_split_depth = self.options.max_split_depth --- 354,358 ---- self.run("%s -N0 -o %s.ps %s" % (DVIPS_BINARY, self.doc, self.doc)) ! def build_html(self, builddir, max_split_depth=None): if max_split_depth is None: max_split_depth = self.options.max_split_depth From gvanrossum@users.sourceforge.net Tue Jul 17 16:41:11 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 17 Jul 2001 08:41:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib builtin.py,1.1,NONE macstat.py,1.1,NONE persist.py,1.6,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv5654 Removed Files: builtin.py macstat.py persist.py Log Message: Deleting zombies --- builtin.py DELETED --- --- macstat.py DELETED --- --- persist.py DELETED --- From gvanrossum@users.sourceforge.net Tue Jul 17 16:43:40 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 17 Jul 2001 08:43:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python pythonmain.c,2.30,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv6257 Removed Files: pythonmain.c Log Message: Deleting zombies --- pythonmain.c DELETED --- From gvanrossum@users.sourceforge.net Tue Jul 17 16:44:24 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 17 Jul 2001 08:44:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Demo/pdist new,1.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Demo/pdist In directory usw-pr-cvs1:/tmp/cvs-serv6513 Removed Files: new Log Message: Deleting zombies --- new DELETED --- From gvanrossum@users.sourceforge.net Tue Jul 17 16:45:11 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 17 Jul 2001 08:45:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Demo/sgi/video IN.py,1.1,NONE Makefile,1.1,NONE Vrecc.py,1.1,NONE cam.py,1.2,NONE camcorder.py,1.4,NONE colorsys.py,1.4,NONE i2v.c,1.1,NONE makemovie.py,1.4,NONE squash.c,1.2,NONE squash2.c,1.1,NONE statit.py,1.2,NONE syncaudio.py,1.2,NONE tomono.c,1.1,NONE tv.py,1.2,NONE v2i.c,1.2,NONE video.py,1.10,NONE vpregs.py,1.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Demo/sgi/video In directory usw-pr-cvs1:/tmp/cvs-serv6803 Removed Files: IN.py Makefile Vrecc.py cam.py camcorder.py colorsys.py i2v.c makemovie.py squash.c squash2.c statit.py syncaudio.py tomono.c tv.py v2i.c video.py vpregs.py Log Message: Deleting zombies --- IN.py DELETED --- --- Makefile DELETED --- --- Vrecc.py DELETED --- --- cam.py DELETED --- --- camcorder.py DELETED --- --- colorsys.py DELETED --- --- i2v.c DELETED --- --- makemovie.py DELETED --- --- squash.c DELETED --- --- squash2.c DELETED --- --- statit.py DELETED --- --- syncaudio.py DELETED --- --- tomono.c DELETED --- --- tv.py DELETED --- --- v2i.c DELETED --- --- video.py DELETED --- --- vpregs.py DELETED --- From gvanrossum@users.sourceforge.net Tue Jul 17 16:49:24 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 17 Jul 2001 08:49:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include patchlevel.h,2.50,2.50.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv8503 Modified Files: Tag: descr-branch patchlevel.h Log Message: Increment patchlevel to 2.2a1. Index: patchlevel.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/patchlevel.h,v retrieving revision 2.50 retrieving revision 2.50.2.1 diff -C2 -r2.50 -r2.50.2.1 *** patchlevel.h 2001/04/18 04:31:01 2.50 --- patchlevel.h 2001/07/17 15:49:22 2.50.2.1 *************** *** 24,34 **** #define PY_MICRO_VERSION 0 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA ! #define PY_RELEASE_SERIAL 0 /* Version as a string */ ! #define PY_VERSION "2.2a0" /* Historic */ ! #define PATCHLEVEL "2.2a0" /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. --- 24,34 ---- #define PY_MICRO_VERSION 0 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA ! #define PY_RELEASE_SERIAL 1 /* Version as a string */ ! #define PY_VERSION "2.2a1" /* Historic */ ! #define PATCHLEVEL "2.2a1" /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. From gvanrossum@users.sourceforge.net Tue Jul 17 17:09:00 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 17 Jul 2001 09:09:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python import.c,2.176.2.2,2.176.2.3 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv14263 Modified Files: Tag: descr-branch import.c Log Message: New .pyc magic number, in celebration of the imminent 2.2a1 release. Index: import.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/import.c,v retrieving revision 2.176.2.2 retrieving revision 2.176.2.3 diff -C2 -r2.176.2.2 -r2.176.2.3 *** import.c 2001/07/07 22:55:31 2.176.2.2 --- import.c 2001/07/17 16:08:57 2.176.2.3 *************** *** 44,48 **** added to the .pyc file header? */ /* New way to come up with the magic number: (YEAR-1995), MONTH, DAY */ ! #define MAGIC (60420 | ((long)'\r'<<16) | ((long)'\n'<<24)) /* Magic word as global; note that _PyImport_Init() can change the --- 44,48 ---- added to the .pyc file header? */ /* New way to come up with the magic number: (YEAR-1995), MONTH, DAY */ ! #define MAGIC (60717 | ((long)'\r'<<16) | ((long)'\n'<<24)) /* Magic word as global; note that _PyImport_Init() can change the From gvanrossum@users.sourceforge.net Tue Jul 17 17:12:04 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 17 Jul 2001 09:12:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include modsupport.h,2.36,2.36.6.1 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv14532/Include Modified Files: Tag: descr-branch modsupport.h Log Message: New API version, celebrating the imminent 2.2a1 release. Index: modsupport.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/modsupport.h,v retrieving revision 2.36 retrieving revision 2.36.6.1 diff -C2 -r2.36 -r2.36.6.1 *** modsupport.h 2001/01/25 22:13:34 2.36 --- modsupport.h 2001/07/17 16:12:02 2.36.6.1 *************** *** 23,28 **** extern DL_IMPORT(int) PyModule_AddStringConstant(PyObject *, char *, char *); ! #define PYTHON_API_VERSION 1010 ! #define PYTHON_API_STRING "1010" /* The API version is maintained (independently from the Python version) so we can detect mismatches between the interpreter and dynamically --- 23,28 ---- extern DL_IMPORT(int) PyModule_AddStringConstant(PyObject *, char *, char *); ! #define PYTHON_API_VERSION 1011 ! #define PYTHON_API_STRING "1011" /* The API version is maintained (independently from the Python version) so we can detect mismatches between the interpreter and dynamically *************** *** 37,40 **** --- 37,42 ---- Please add a line or two to the top of this log for each API version change: + + 17-Jul-2001 GvR 1011 Descr-branch, just to be on the safe side 25-Jan-2001 FLD 1010 Parameters added to PyCode_New() and From fdrake@users.sourceforge.net Tue Jul 17 17:28:52 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 17 Jul 2001 09:28:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/texinputs boilerplate.tex,1.62,1.63 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory usw-pr-cvs1:/tmp/cvs-serv20350/texinputs Modified Files: boilerplate.tex Log Message: Update the release information. Index: boilerplate.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/boilerplate.tex,v retrieving revision 1.62 retrieving revision 1.63 diff -C2 -r1.62 -r1.63 *** boilerplate.tex 2001/07/14 02:11:17 1.62 --- boilerplate.tex 2001/07/17 16:28:50 1.63 *************** *** 8,11 **** \date{\today} % XXX update before release! \release{2.2} % software release, not documentation ! \setreleaseinfo{a0} % empty for final release \setshortversion{2.2} % major.minor only for software --- 8,11 ---- \date{\today} % XXX update before release! \release{2.2} % software release, not documentation ! \setreleaseinfo{a1} % empty for final release \setshortversion{2.2} % major.minor only for software From fdrake@users.sourceforge.net Tue Jul 17 17:46:16 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 17 Jul 2001 09:46:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools rewrite.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools In directory usw-pr-cvs1:/tmp/cvs-serv25158/tools Added Files: rewrite.py Log Message: Script to re-write @FOO@-style marks with values, initializing the replacement for @DATE@ from a TeX file containing a \date{...} mark (such as texinputs/boilerplate.tex). This will be used to re-write the html/index.html.in file instead of a combination of grep, date, and sed -- this is more portable to non-Unix platforms. This solves part of the problem reported in SF patch #429611, but does not use the suggested patch. --- NEW FILE: rewrite.py --- """Simple script to replace @DATE@ and friends with real information. Usage: rewrite.py boilerplate.tex [VAR=value] ...