From montanaro@users.sourceforge.net Fri Jun 1 17:25:40 2001 From: montanaro@users.sourceforge.net (Skip Montanaro) Date: Fri, 01 Jun 2001 09:25:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib httplib.py,1.34,1.35 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv4026 Modified Files: httplib.py Log Message: more public symbols for __all__ Index: httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/httplib.py,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -r1.34 -r1.35 *** httplib.py 2001/04/13 14:57:08 1.34 --- httplib.py 2001/06/01 16:25:38 1.35 *************** *** 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 From tim_one@users.sourceforge.net Sat Jun 2 06:27:21 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 01 Jun 2001 22:27:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.178,1.179 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv8127/python/dist/src/Misc Modified Files: NEWS Log Message: New collision resolution scheme: no polynomials, simpler, faster, less code, less memory. Tests have uncovered no drawbacks. Christian and Vladimir are the other two people who have burned many brain cells on the dict code in recent years, and they like the approach too, so I'm checking it in without further ado. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.178 retrieving revision 1.179 diff -C2 -r1.178 -r1.179 *** NEWS 2001/05/28 22:30:07 1.178 --- NEWS 2001/06/02 05:27:19 1.179 *************** *** 16,20 **** casing of Unicode object return values was dropped (Unicode objects were auto-magically converted to string using the default encoding). ! Both methods will now return whatever the codec in charge of the requested encoding returns as object, e.g. Unicode codecs will --- 16,20 ---- casing of Unicode object return values was dropped (Unicode objects were auto-magically converted to string using the default encoding). ! Both methods will now return whatever the codec in charge of the requested encoding returns as object, e.g. Unicode codecs will *************** *** 117,127 **** values mutated the dicts. Making the code bulletproof slowed it down. ! - Collisions in dicts now use polynomial division instead of multiplication ! to generate the probe sequence, following an idea of Christian Tismer's. ! This allows all bits of the hash code to come into play. It should have ! little or no effect on speed in ordinary cases, but can help dramatically ! in bad cases. For example, looking up every key in a dict d with ! d.keys() = [i << 16 for i in range(20000)] is approximately 500x faster ! now. Library --- 117,125 ---- values mutated the dicts. Making the code bulletproof slowed it down. ! - Collisions in dicts are resolved via a new approach, which can help ! dramatically in bad cases. For example, looking up every key in a dict ! d with d.keys() = [i << 16 for i in range(20000)] is approximately 500x ! faster now. Thanks to Christian Tismer for pointing out the cause and ! the nature of an effective cure (last December! better late than never). Library From tim_one@users.sourceforge.net Sat Jun 2 06:27:21 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 01 Jun 2001 22:27:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.96,2.97 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv8127/python/dist/src/Objects Modified Files: dictobject.c Log Message: New collision resolution scheme: no polynomials, simpler, faster, less code, less memory. Tests have uncovered no drawbacks. Christian and Vladimir are the other two people who have burned many brain cells on the dict code in recent years, and they like the approach too, so I'm checking it in without further ado. Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.96 retrieving revision 2.97 diff -C2 -r2.96 -r2.97 *** dictobject.c 2001/05/27 07:39:22 2.96 --- dictobject.c 2001/06/02 05:27:19 2.97 *************** *** 4,122 **** #include "Python.h" ! ! /* ! * MINSIZE is the minimum size of a dictionary. This many slots are * allocated directly in the dict object (in the ma_smalltable member). ! * This must be a power of 2, and the first entry in the polys[] vector must ! * match. */ #define MINSIZE 8 ! /* define this out if you don't want conversion statistics on exit */ #undef SHOW_CONVERSION_COUNTS /* ! Table of irreducible polynomials to efficiently cycle through ! GF(2^n)-{0}, 2<=n<=30. A table size is always a power of 2. ! For a table size of 2**i, the polys entry is 2**i + j for some j in 1 thru ! 2**i-1 inclusive. The polys[] entries here happen to add in the smallest j ! values "that work". Work means this: given any integer k in 1 thru 2**i-1 ! inclusive, a poly works if & only if repeating this code: ! print k ! k <<= 1 ! if k >= 2**i: ! k ^= poly ! prints every integer in 1 thru 2**i-1 inclusive exactly once before printing ! k a second time. Theory can be used to find such polys efficiently, but the ! operational defn. of "works" is sufficient to find them in reasonable time ! via brute force program (hint: any poly that has an even number of 1 bits ! cannot work; ditto any poly with low bit 0; exploit those). ! ! Some major subtleties: Most hash schemes depend on having a "good" hash ! function, in the sense of simulating randomness. Python doesn't: some of ! its hash functions are trivial, such as hash(i) == i for ints i (excepting ! i == -1, because -1 is the "error occurred" return value from tp_hash). ! ! This isn't necessarily bad! To the contrary, that our hash tables are powers ! of 2 in size, and that we take the low-order bits as the initial table index, ! means that there are no collisions at all for dicts indexed by a contiguous ! range of ints. This is "better than random" behavior, and that's very ! desirable. ! ! On the other hand, when collisions occur, the tendency to fill contiguous ! slices of the hash table makes a good collision resolution strategy crucial; ! e.g., linear probing is right out. ! ! Reimer Behrends contributed the idea of using a polynomial-based approach, ! using repeated multiplication by x in GF(2**n) where a polynomial is chosen ! such that x is a primitive root. This visits every table location exactly ! once, and the sequence of locations probed is highly non-linear. ! ! The same is also largely true of quadratic probing for power-of-2 tables, of ! the specific ! ! (i + comb(1, 2)) mod size ! (i + comb(2, 2)) mod size ! (i + comb(3, 2)) mod size ! (i + comb(4, 2)) mod size ! ... ! (i + comb(j, 2)) mod size ! ! flavor. The polynomial approach "scrambles" the probe indices better, but ! more importantly allows to get *some* additional bits of the hash code into ! play via computing the initial increment, thus giving a weak form of double ! hashing. Quadratic probing cannot be extended that way (the first probe ! offset must be 1, the second 3, the third 6, etc). ! ! Christian Tismer later contributed the idea of using polynomial division ! instead of multiplication. The problem is that the multiplicative method ! can't get *all* the bits of the hash code into play without expensive ! computations that slow down the initial index and/or initial increment ! computation. For a set of keys like [i << 16 for i in range(20000)], under ! the multiplicative method the initial index and increment were the same for ! all keys, so every key followed exactly the same probe sequence, and so ! this degenerated into a (very slow) linear search. The division method uses ! all the bits of the hash code naturally in the increment, although it *may* ! visit locations more than once until such time as all the high bits of the ! increment have been shifted away. It's also impossible to tell in advance ! whether incr is congruent to 0 modulo poly, so each iteration of the loop has ! to guard against incr becoming 0. These are minor costs, as we usually don't ! get into the probe loop, and when we do we usually get out on its first ! iteration. */ - static long polys[] = { - /* 4 + 3, */ /* first active entry if MINSIZE == 4 */ - 8 + 3, /* first active entry if MINSIZE == 8 */ - 16 + 3, - 32 + 5, - 64 + 3, - 128 + 3, - 256 + 29, - 512 + 17, - 1024 + 9, - 2048 + 5, - 4096 + 83, - 8192 + 27, - 16384 + 43, - 32768 + 3, - 65536 + 45, - 131072 + 9, - 262144 + 39, - 524288 + 39, - 1048576 + 9, - 2097152 + 5, - 4194304 + 3, - 8388608 + 33, - 16777216 + 27, - 33554432 + 9, - 67108864 + 71, - 134217728 + 39, - 268435456 + 9, - 536870912 + 5, - 1073741824 + 83 - /* 2147483648 + 9 -- if we ever boost this to unsigned long */ - }; - /* Object used as dummy key to fill deleted entries */ static PyObject *dummy; /* Initialized by first call to newdictobject() */ --- 4,117 ---- #include "Python.h" ! /* 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 MINSIZE 8 ! /* Define this out if you don't want conversion statistics on exit. */ #undef SHOW_CONVERSION_COUNTS + /* See large comment block below. This must be >= 1. */ + #define PERTURB_SHIFT 5 + /* ! Major subtleties ahead: Most hash schemes depend on having a "good" hash ! function, in the sense of simulating randomness. Python doesn't: its most ! important hash functions (for strings and ints) are very regular in common ! cases: ! ! >>> map(hash, (0, 1, 2, 3)) ! [0, 1, 2, 3] ! >>> map(hash, ("namea", "nameb", "namec", "named")) ! [-1658398457, -1658398460, -1658398459, -1658398462] ! >>> ! ! This isn't necessarily bad! To the contrary, in a table of size 2**i, taking ! the low-order i bits as the initial table index is extremely fast, and there ! are no collisions at all for dicts indexed by a contiguous range of ints. ! The same is approximately true when keys are "consecutive" strings. So this ! gives better-than-random behavior in common cases, and that's very desirable. ! ! OTOH, when collisions occur, the tendency to fill contiguous slices of the ! hash table makes a good collision resolution strategy crucial. Taking only ! the last i bits of the hash code is also vulnerable: for example, consider ! [i << 16 for i in range(20000)] as a set of keys. Since ints are their own ! hash codes, and this fits in a dict of size 2**15, the last 15 bits of every ! hash code are all 0: they *all* map to the same table index. ! ! But catering to unusual cases should not slow the usual ones, so we just take ! the last i bits anyway. It's up to collision resolution to do the rest. If ! we *usually* find the key we're looking for on the first try (and, it turns ! out, we usually do -- the table load factor is kept under 2/3, so the odds ! are solidly in our favor), then it makes best sense to keep the initial index ! computation dirt cheap. ! ! The first half of collision resolution is to visit table indices via this ! recurrence: ! ! j = ((5*j) + 1) mod 2**i ! ! For any initial j in range(2**i), repeating that 2**i times generates each ! int in range(2**i) exactly once (see any text on random-number generation for ! proof). By itself, this doesn't help much: like linear probing (setting ! j += 1, or j -= 1, on each loop trip), it scans the table entries in a fixed ! order. This would be bad, except that's not the only thing we do, and it's ! actually *good* in the common cases where hash keys are consecutive. In an ! example that's really too small to make this entirely clear, for a table of ! size 2**3 the order of indices is: ! ! 0 -> 1 -> 6 -> 7 -> 4 -> 5 -> 2 -> 3 -> 0 [and here it's repeating] ! ! If two things come in at index 5, the first place we look after is index 2, ! not 6, so if another comes in at index 6 the collision at 5 didn't hurt it. ! Linear probing is deadly in this case because there the fixed probe order ! is the *same* as the order consecutive keys are likely to arrive. But it's ! extremely unlikely hash codes will follow a 5*j+1 recurrence by accident, ! and certain that consecutive hash codes do not. ! ! The other half of the strategy is to get the other bits of the hash code ! into play. This is done by initializing a (unsigned) vrbl "perturb" to the ! full hash code, and changing the recurrence to: ! ! j = (5*j) + 1 + perturb; ! perturb >>= PERTURB_SHIFT; ! use j % 2**i as the next table index; ! ! Now the probe sequence depends (eventually) on every bit in the hash code, ! and the pseudo-scrambling property of recurring on 5*j+1 is more valuable, ! because it quickly magnifies small differences in the bits that didn't affect ! the initial index. Note that because perturb is unsigned, if the recurrence ! is executed often enough perturb eventually becomes and remains 0. At that ! point (very rarely reached) the recurrence is on (just) 5*j+1 again, and ! that's certain to find an empty slot eventually (since it generates every int ! in range(2**i), and we make sure there's always at least one empty slot). ! ! Selecting a good value for PERTURB_SHIFT is a balancing act. You want it ! small so that the high bits of the hash code continue to affect the probe ! sequence across iterations; but you want it large so that in really bad cases ! the high-order hash bits have an effect on early iterations. 5 was "the ! best" in minimizing total collisions across experiments Tim Peters ran (on ! both normal and pathological cases), but 4 and 6 weren't significantly worse. ! ! Historical: Reimer Behrends contributed the idea of using a polynomial-based ! approach, using repeated multiplication by x in GF(2**n) where an irreducible ! polynomial for each table size was chosen such that x was a primitive root. ! Christian Tismer later extended that to use division by x instead, as an ! efficient way to get the high bits of the hash code into play. This scheme ! also gave excellent collision statistics, but was more expensive: two ! if-tests were required inside the loop; computing "the next" index took about ! the same number of operations but without as much potential parallelism ! (e.g., computing 5*j can go on at the same time as computing 1+perturb in the ! above, and then shifting perturb can be done while the table index is being ! masked); and the dictobject struct required a member to hold the table's ! polynomial. In Tim's experiments the current scheme ran faster, produced ! equally good collision statistics, needed less code & used less memory. */ /* Object used as dummy key to fill deleted entries */ static PyObject *dummy; /* Initialized by first call to newdictobject() */ *************** *** 169,173 **** int ma_used; /* # Active */ int ma_size; /* total # slots in ma_table */ - int ma_poly; /* appopriate entry from polys vector */ /* ma_table points to ma_smalltable for small tables, else to * additional malloc'ed memory. ma_table is never NULL! This rule --- 164,167 ---- *************** *** 203,208 **** (mp)->ma_size = MINSIZE; \ (mp)->ma_used = (mp)->ma_fill = 0; \ - (mp)->ma_poly = polys[0]; \ - assert(MINSIZE < (mp)->ma_poly && (mp)->ma_poly < MINSIZE*2); \ } while(0) --- 197,200 ---- *************** *** 236,251 **** Open addressing is preferred over chaining since the link overhead for chaining would be substantial (100% with typical malloc overhead). - However, instead of going through the table at constant steps, we cycle - through the values of GF(2^n). This avoids modulo computations, being - much cheaper on RISC machines, without leading to clustering. - - The initial probe index is computed as hash mod the table size. - Subsequent probe indices use the values of x^i in GF(2^n)-{0} as an offset, - where x is a root. The initial offset is derived from hash, too. All arithmetic on hash should ignore overflow. ! (This version is due to Reimer Behrends, some ideas are also due to ! Jyrki Alakuijala and Vladimir Marangozov.) This function must never return NULL; failures are indicated by returning --- 228,240 ---- Open addressing is preferred over chaining since the link overhead for chaining would be substantial (100% with typical malloc overhead). + The initial probe index is computed as hash mod the table size. Subsequent + probe indices are computed as explained earlier. + All arithmetic on hash should ignore overflow. ! (The details in this version are due to Tim Peters, building on many past ! contributions by Reimer Behrends, Jyrki Alakuijala, Vladimir Marangozov and ! Christian Tismer). This function must never return NULL; failures are indicated by returning *************** *** 253,261 **** reported by this function, and outstanding exceptions are maintained. */ static dictentry * lookdict(dictobject *mp, PyObject *key, register long hash) { register int i; ! register unsigned int incr; register dictentry *freeslot; register unsigned int mask = mp->ma_size-1; --- 242,251 ---- reported by this function, and outstanding exceptions are maintained. */ + static dictentry * lookdict(dictobject *mp, PyObject *key, register long hash) { register int i; ! register unsigned int perturb; register dictentry *freeslot; register unsigned int mask = mp->ma_size-1; *************** *** 266,272 **** register int cmp; PyObject *err_type, *err_value, *err_tb; ! /* We must come up with (i, incr) such that 0 <= i < ma_size ! and 0 < incr < ma_size and both are a function of hash. ! i is the initial table index and incr the initial probe offset. */ i = hash & mask; ep = &ep0[i]; --- 256,260 ---- register int cmp; PyObject *err_type, *err_value, *err_tb; ! i = hash & mask; ep = &ep0[i]; *************** *** 295,308 **** freeslot = NULL; } - /* Derive incr from hash, just to make it more arbitrary. Note that - incr must not be 0, or we will get into an infinite loop.*/ - incr = hash ^ ((unsigned long)hash >> 3); /* In the loop, me_key == dummy is by far (factor of 100s) the least likely outcome, so test for that last. */ ! for (;;) { ! if (!incr) ! incr = 1; /* and incr will never be 0 again */ ! ep = &ep0[(i + incr) & mask]; if (ep->me_key == NULL) { if (restore_error) --- 283,292 ---- freeslot = NULL; } /* In the loop, me_key == dummy is by far (factor of 100s) the least likely outcome, so test for that last. */ ! for (perturb = hash; ; perturb >>= PERTURB_SHIFT) { ! i = (i << 2) + i + perturb + 1; ! ep = &ep0[i & mask]; if (ep->me_key == NULL) { if (restore_error) *************** *** 336,343 **** else if (ep->me_key == dummy && freeslot == NULL) freeslot = ep; - /* Cycle through GF(2**n). */ - if (incr & 1) - incr ^= mp->ma_poly; /* clears the lowest bit */ - incr >>= 1; } } --- 320,323 ---- *************** *** 357,361 **** { register int i; ! register unsigned int incr; register dictentry *freeslot; register unsigned int mask = mp->ma_size-1; --- 337,341 ---- { register int i; ! register unsigned int perturb; register dictentry *freeslot; register unsigned int mask = mp->ma_size-1; *************** *** 371,376 **** return lookdict(mp, key, hash); } - /* We must come up with (i, incr) such that 0 <= i < ma_size - and 0 < incr < ma_size and both are a function of hash */ i = hash & mask; ep = &ep0[i]; --- 351,354 ---- *************** *** 386,399 **** freeslot = NULL; } - /* Derive incr from hash, just to make it more arbitrary. Note that - incr must not be 0, or we will get into an infinite loop.*/ - incr = hash ^ ((unsigned long)hash >> 3); /* In the loop, me_key == dummy is by far (factor of 100s) the least likely outcome, so test for that last. */ ! for (;;) { ! if (!incr) ! incr = 1; /* and incr will never be 0 again */ ! ep = &ep0[(i + incr) & mask]; if (ep->me_key == NULL) return freeslot == NULL ? ep : freeslot; --- 364,373 ---- freeslot = NULL; } /* In the loop, me_key == dummy is by far (factor of 100s) the least likely outcome, so test for that last. */ ! for (perturb = hash; ; perturb >>= PERTURB_SHIFT) { ! i = (i << 2) + i + perturb + 1; ! ep = &ep0[i & mask]; if (ep->me_key == NULL) return freeslot == NULL ? ep : freeslot; *************** *** 405,412 **** if (ep->me_key == dummy && freeslot == NULL) freeslot = ep; - /* Cycle through GF(2**n). */ - if (incr & 1) - incr ^= mp->ma_poly; /* clears the lowest bit */ - incr >>= 1; } } --- 379,382 ---- *************** *** 449,453 **** dictresize(dictobject *mp, int minused) { ! int newsize, newpoly; dictentry *oldtable, *newtable, *ep; int i; --- 419,423 ---- dictresize(dictobject *mp, int minused) { ! int newsize; dictentry *oldtable, *newtable, *ep; int i; *************** *** 457,474 **** assert(minused >= 0); ! /* Find the smallest table size > minused, and its poly[] entry. */ ! newpoly = 0; ! newsize = MINSIZE; ! for (i = 0; i < sizeof(polys)/sizeof(polys[0]); ++i) { ! if (newsize > minused) { ! newpoly = polys[i]; ! break; ! } ! newsize <<= 1; ! if (newsize < 0) /* overflow */ ! break; ! } ! if (newpoly == 0) { ! /* Ran out of polynomials or newsize overflowed. */ PyErr_NoMemory(); return -1; --- 427,436 ---- assert(minused >= 0); ! /* Find the smallest table size > minused. */ ! for (newsize = MINSIZE; ! newsize <= minused && newsize > 0; ! newsize <<= 1) ! ; ! if (newsize <= 0) { PyErr_NoMemory(); return -1; *************** *** 512,516 **** mp->ma_size = newsize; memset(newtable, 0, sizeof(dictentry) * newsize); - mp->ma_poly = newpoly; mp->ma_used = 0; i = mp->ma_fill; --- 474,477 ---- *************** *** 1256,1260 **** /* can't be equal if # of entries differ */ return 0; ! /* Same # of entries -- check all of 'em. Exit early on any diff. */ for (i = 0; i < a->ma_size; i++) { --- 1217,1221 ---- /* can't be equal if # of entries differ */ return 0; ! /* Same # of entries -- check all of 'em. Exit early on any diff. */ for (i = 0; i < a->ma_size; i++) { From tim_one@users.sourceforge.net Sat Jun 2 06:42:31 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 01 Jun 2001 22:42:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.97,2.98 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv9951/python/dist/src/Objects Modified Files: dictobject.c Log Message: dict_popitem(): Repaired last-second 2.1 comment, which misidentified the true reason for allocating the tuple before checking the dict size. Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.97 retrieving revision 2.98 diff -C2 -r2.97 -r2.98 *** dictobject.c 2001/06/02 05:27:19 2.97 --- dictobject.c 2001/06/02 05:42:29 2.98 *************** *** 1363,1371 **** if (!PyArg_NoArgs(args)) return NULL; ! /* Allocate the result tuple first. Believe it or not, ! * this allocation could trigger a garbage collection which ! * could resize the dict, which would invalidate the pointer ! * (ep) into the dict calculated below. ! * So we have to do this first. */ res = PyTuple_New(2); --- 1363,1374 ---- if (!PyArg_NoArgs(args)) return NULL; ! /* Allocate the result tuple before checking the size. Believe it ! * or not, this allocation could trigger a garbage collection which ! * could empty the dict, so if we checked the size first and that ! * happened, the result would be an infinite loop (searching for an ! * entry that no longer exists). Note that the usual popitem() ! * idiom is "while d: k, v = d.popitem()". so needing to throw the ! * tuple away if the dict *is* empty isn't a significant ! * inefficiency -- possible, but unlikely in practice. */ res = PyTuple_New(2); From nascheme@users.sourceforge.net Sat Jun 2 07:16:04 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Fri, 01 Jun 2001 23:16:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Demo/embed Makefile,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Demo/embed In directory usw-pr-cvs1:/tmp/cvs-serv14048/Demo/embed Modified Files: Makefile Log Message: Separate CFLAGS and CPPFLAGS. CFLAGS should not contain preprocessor directives, which is the role of CPPFLAGS. Closes SF patch #414991. Index: Makefile =================================================================== RCS file: /cvsroot/python/python/dist/src/Demo/embed/Makefile,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -r1.9 -r1.10 *** Makefile 2001/02/20 20:53:37 1.9 --- Makefile 2001/06/02 06:16:02 1.10 *************** *** 16,20 **** OPT= -g INCLUDES= -I$(srcdir)/Include -I$(blddir) ! CFLAGS= $(OPT) $(INCLUDES) # The Python library --- 16,21 ---- OPT= -g INCLUDES= -I$(srcdir)/Include -I$(blddir) ! CFLAGS= $(OPT) ! CPPFLAGS= $(INCLUDES) # The Python library From nascheme@users.sourceforge.net Sat Jun 2 07:16:04 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Fri, 01 Jun 2001 23:16:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/freeze freeze.py,1.38,1.39 makemakefile.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/freeze In directory usw-pr-cvs1:/tmp/cvs-serv14048/Tools/freeze Modified Files: freeze.py makemakefile.py Log Message: Separate CFLAGS and CPPFLAGS. CFLAGS should not contain preprocessor directives, which is the role of CPPFLAGS. Closes SF patch #414991. Index: freeze.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/freeze/freeze.py,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -r1.38 -r1.39 *** freeze.py 2001/03/20 20:43:33 1.38 --- freeze.py 2001/06/02 06:16:02 1.39 *************** *** 425,429 **** infp.close() ! cflags = defines + includes + ['$(OPT)'] libs = [os.path.join(binlib, 'libpython$(VERSION).a')] --- 425,430 ---- infp.close() ! cflags = ['$(OPT)'] ! cppflags = defines + includes libs = [os.path.join(binlib, 'libpython$(VERSION).a')] *************** *** 435,438 **** --- 436,440 ---- somevars['CFLAGS'] = string.join(cflags) # override + somevars['CPPFLAGS'] = string.join(cppflags) # override files = ['$(OPT)', '$(LDFLAGS)', base_config_c, base_frozen_c] + \ files + supp_sources + addfiles + libs + \ Index: makemakefile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/freeze/makemakefile.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** makemakefile.py 1998/06/12 14:09:34 1.4 --- makemakefile.py 2001/06/02 06:16:02 1.5 *************** *** 20,24 **** dest = base[:-2] + '.o' outfp.write("%s: %s\n" % (dest, file)) ! outfp.write("\t$(CC) $(CFLAGS) -c %s\n" % file) files[i] = dest deps.append(dest) --- 20,24 ---- dest = base[:-2] + '.o' outfp.write("%s: %s\n" % (dest, file)) ! outfp.write("\t$(CC) $(CFLAGS) $(CPPFLAGS) -c %s\n" % file) files[i] = dest deps.append(dest) From nascheme@users.sourceforge.net Sat Jun 2 07:16:04 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Fri, 01 Jun 2001 23:16:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc Makefile.pre.in,1.20,1.21 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv14048/Misc Modified Files: Makefile.pre.in Log Message: Separate CFLAGS and CPPFLAGS. CFLAGS should not contain preprocessor directives, which is the role of CPPFLAGS. Closes SF patch #414991. Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/Makefile.pre.in,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -r1.20 -r1.21 *** Makefile.pre.in 2001/01/23 01:53:41 1.20 --- Makefile.pre.in 2001/06/02 06:16:02 1.21 *************** *** 96,100 **** # Add more -I and -D options here ! CFLAGS= $(OPT) -I$(INCLUDEPY) -I$(EXECINCLUDEPY) $(DEFS) # These two variables can be set in Setup to merge extensions. --- 96,101 ---- # Add more -I and -D options here ! CFLAGS= $(OPT) ! CPPFLAGS= -I$(INCLUDEPY) -I$(EXECINCLUDEPY) $(DEFS) # These two variables can be set in Setup to merge extensions. *************** *** 229,233 **** # Make config.o from the config.c created by makesetup config.o: config.c ! $(CC) $(CFLAGS) -c config.c # Setup is copied from Setup.in *only* if it doesn't yet exist --- 230,234 ---- # Make config.o from the config.c created by makesetup config.o: config.c ! $(CC) $(CFLAGS) $(CPPFLAGS) -c config.c # Setup is copied from Setup.in *only* if it doesn't yet exist From nascheme@users.sourceforge.net Sat Jun 2 07:16:04 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Fri, 01 Jun 2001 23:16:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Demo/pysvr Makefile,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Demo/pysvr In directory usw-pr-cvs1:/tmp/cvs-serv14048/Demo/pysvr Modified Files: Makefile Log Message: Separate CFLAGS and CPPFLAGS. CFLAGS should not contain preprocessor directives, which is the role of CPPFLAGS. Closes SF patch #414991. Index: Makefile =================================================================== RCS file: /cvsroot/python/python/dist/src/Demo/pysvr/Makefile,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** Makefile 2000/11/03 12:58:09 1.4 --- Makefile 2001/06/02 06:16:02 1.5 *************** *** 32,36 **** # Compilation and link flags -- no need to change normally ! CFLAGS=$(PYINCL) $(OPT) LIBS=$(PYLIBS) $(RLLIBS) $(OTHERLIBS) --- 32,37 ---- # Compilation and link flags -- no need to change normally ! CFLAGS=$(OPT) ! CPPFLAGS=$(PYINCL) LIBS=$(PYLIBS) $(RLLIBS) $(OTHERLIBS) From nascheme@users.sourceforge.net Sat Jun 2 07:16:04 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Fri, 01 Jun 2001 23:16:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules makesetup,1.35,1.36 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv14048/Modules Modified Files: makesetup Log Message: Separate CFLAGS and CPPFLAGS. CFLAGS should not contain preprocessor directives, which is the role of CPPFLAGS. Closes SF patch #414991. Index: makesetup =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/makesetup,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -r1.35 -r1.36 *** makesetup 2001/03/02 07:09:54 1.35 --- makesetup 2001/06/02 06:16:02 1.36 *************** *** 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)";; From nascheme@users.sourceforge.net Sat Jun 2 07:16:04 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Fri, 01 Jun 2001 23:16:04 -0700 Subject: [Python-checkins] CVS: python/dist/src Makefile.pre.in,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv14048 Modified Files: Makefile.pre.in Log Message: Separate CFLAGS and CPPFLAGS. CFLAGS should not contain preprocessor directives, which is the role of CPPFLAGS. Closes SF patch #414991. Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -r1.37 -r1.38 *** Makefile.pre.in 2001/04/20 19:13:01 1.37 --- Makefile.pre.in 2001/06/02 06:16:02 1.38 *************** *** 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) *************** *** 284,288 **** # Build the shared modules sharedmods: $(PYTHON) ! PYTHONPATH= ./$(PYTHON) $(srcdir)/setup.py build # buildno should really depend on something like LIBRARY_SRC --- 285,290 ---- # Build the shared modules sharedmods: $(PYTHON) ! unset PYTHONPATH PYTHONHOME PYTHONSTARTUP; \ ! ./$(PYTHON) $(srcdir)/setup.py build # buildno should really depend on something like LIBRARY_SRC *************** *** 400,407 **** 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 --- 402,409 ---- 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 From tim_one@users.sourceforge.net Sat Jun 2 09:02:58 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 02 Jun 2001 01:02:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_mutants.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv27849/python/dist/src/Lib/test Modified Files: test_mutants.py Log Message: Coredumpers from Michael Hudson, mutating dicts while printing or converting to string. Critical bugfix candidate -- if you take this seriously . Index: test_mutants.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_mutants.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** test_mutants.py 2001/05/10 20:18:30 1.3 --- test_mutants.py 2001/06/02 08:02:56 1.4 *************** *** 1,4 **** ! from test_support import verbose import random # From SF bug #422121: Insecurities in dict comparison. --- 1,5 ---- ! from test_support import verbose, TESTFN import random + import os # From SF bug #422121: Insecurities in dict comparison. *************** *** 152,153 **** --- 153,217 ---- # See last comment block for clues about good values for n. test(100) + + ########################################################################## + # Another segfault bug, distilled by Micheal Hundson 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 From tim_one@users.sourceforge.net Sat Jun 2 09:02:58 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 02 Jun 2001 01:02:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.98,2.99 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv27849/python/dist/src/Objects Modified Files: dictobject.c Log Message: Coredumpers from Michael Hudson, mutating dicts while printing or converting to string. Critical bugfix candidate -- if you take this seriously . Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.98 retrieving revision 2.99 diff -C2 -r2.98 -r2.99 *** dictobject.c 2001/06/02 05:42:29 2.98 --- dictobject.c 2001/06/02 08:02:56 2.99 *************** *** 741,745 **** register int i; register int any; - register dictentry *ep; i = Py_ReprEnter((PyObject*)mp); --- 741,744 ---- *************** *** 753,761 **** fprintf(fp, "{"); any = 0; ! for (i = 0, ep = mp->ma_table; i < mp->ma_size; i++, ep++) { ! if (ep->me_value != NULL) { if (any++ > 0) fprintf(fp, ", "); if (PyObject_Print((PyObject *)ep->me_key, fp, 0)!=0) { Py_ReprLeave((PyObject*)mp); return -1; --- 752,766 ---- fprintf(fp, "{"); any = 0; ! for (i = 0; i < mp->ma_size; i++) { ! dictentry *ep = mp->ma_table + i; ! PyObject *pvalue = ep->me_value; ! if (pvalue != NULL) { ! /* Prevent PyObject_Repr from deleting value during ! key format */ ! Py_INCREF(pvalue); if (any++ > 0) fprintf(fp, ", "); if (PyObject_Print((PyObject *)ep->me_key, fp, 0)!=0) { + Py_DECREF(pvalue); Py_ReprLeave((PyObject*)mp); return -1; *************** *** 763,769 **** --- 768,776 ---- fprintf(fp, ": "); if (PyObject_Print(ep->me_value, fp, 0) != 0) { + Py_DECREF(pvalue); Py_ReprLeave((PyObject*)mp); return -1; } + Py_DECREF(pvalue); } } *************** *** 780,784 **** register int i; register int any; - register dictentry *ep; i = Py_ReprEnter((PyObject*)mp); --- 787,790 ---- *************** *** 793,803 **** colon = PyString_FromString(": "); any = 0; ! for (i = 0, ep = mp->ma_table; i < mp->ma_size && v; i++, ep++) { ! if (ep->me_value != NULL) { if (any++) PyString_Concat(&v, sepa); PyString_ConcatAndDel(&v, PyObject_Repr(ep->me_key)); PyString_Concat(&v, colon); ! PyString_ConcatAndDel(&v, PyObject_Repr(ep->me_value)); } } --- 799,815 ---- colon = PyString_FromString(": "); any = 0; ! for (i = 0; i < mp->ma_size && v; i++) { ! dictentry *ep = mp->ma_table + i; ! PyObject *pvalue = ep->me_value; ! if (pvalue != NULL) { ! /* Prevent PyObject_Repr from deleting value during ! key format */ ! Py_INCREF(pvalue); if (any++) PyString_Concat(&v, sepa); PyString_ConcatAndDel(&v, PyObject_Repr(ep->me_key)); PyString_Concat(&v, colon); ! PyString_ConcatAndDel(&v, PyObject_Repr(pvalue)); ! Py_DECREF(pvalue); } } From tim_one@users.sourceforge.net Sat Jun 2 09:19:01 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 02 Jun 2001 01:19:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_mutants.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv30168/python/dist/src/Lib/test Modified Files: test_mutants.py Log Message: Fix comment. Index: test_mutants.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_mutants.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** test_mutants.py 2001/06/02 08:02:56 1.4 --- test_mutants.py 2001/06/02 08:18:58 1.5 *************** *** 155,159 **** ########################################################################## ! # Another segfault bug, distilled by Micheal Hundson from a c.l.py post. class Child: --- 155,159 ---- ########################################################################## ! # Another segfault bug, distilled by Michael Hudson from a c.l.py post. class Child: From tim_one@users.sourceforge.net Sat Jun 2 09:27:42 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 02 Jun 2001 01:27:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.99,2.100 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv31412/python/dist/src/Objects Modified Files: dictobject.c Log Message: Finish the dict->string coredump fix. Need sleep. Bugfix candidate. Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.99 retrieving revision 2.100 diff -C2 -r2.99 -r2.100 *** dictobject.c 2001/06/02 08:02:56 2.99 --- dictobject.c 2001/06/02 08:27:39 2.100 *************** *** 767,771 **** } fprintf(fp, ": "); ! if (PyObject_Print(ep->me_value, fp, 0) != 0) { Py_DECREF(pvalue); Py_ReprLeave((PyObject*)mp); --- 767,771 ---- } fprintf(fp, ": "); ! if (PyObject_Print(pvalue, fp, 0) != 0) { Py_DECREF(pvalue); Py_ReprLeave((PyObject*)mp); From fdrake@users.sourceforge.net Sun Jun 3 04:12:59 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Sat, 02 Jun 2001 20:12:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.125,1.126 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv21375/api Modified Files: api.tex Log Message: Explained more differences between PyList_SetItem() and PyList_SET_ITEM(). In particular, the affect on existing list content was not sufficiently explained. This closes SF bug #429554. Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.125 retrieving revision 1.126 diff -C2 -r1.125 -r1.126 *** api.tex 2001/05/29 18:51:41 1.125 --- api.tex 2001/06/03 03:12:57 1.126 *************** *** 3305,3309 **** PyObject *item} Sets the item at index \var{index} in list to \var{item}. ! \strong{Note:} This function ``steals'' a reference to \var{item}. \end{cfuncdesc} --- 3305,3311 ---- PyObject *item} Sets the item at index \var{index} in list to \var{item}. ! \strong{Note:} This function ``steals'' a reference to \var{item} and ! discards a reference to an item already in the list at the affected ! position. \end{cfuncdesc} *************** *** 3311,3315 **** PyObject *o} Macro form of \cfunction{PyList_SetItem()} without error checking. ! \strong{Note:} This function ``steals'' a reference to \var{item}. \end{cfuncdesc} --- 3313,3320 ---- 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} From fdrake@users.sourceforge.net Sun Jun 3 04:16:06 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Sat, 02 Jun 2001 20:16:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.117.2.3,1.117.2.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv22227/api Modified Files: Tag: release21-maint api.tex Log Message: Explained more differences between PyList_SetItem() and PyList_SET_ITEM(). In particular, the affect on existing list content was not sufficiently explained. This closes SF bug #429554. Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.117.2.3 retrieving revision 1.117.2.4 diff -C2 -r1.117.2.3 -r1.117.2.4 *** api.tex 2001/05/29 18:53:11 1.117.2.3 --- api.tex 2001/06/03 03:16:04 1.117.2.4 *************** *** 3246,3250 **** PyObject *item} Sets the item at index \var{index} in list to \var{item}. ! \strong{Note:} This function ``steals'' a reference to \var{item}. \end{cfuncdesc} --- 3246,3252 ---- PyObject *item} Sets the item at index \var{index} in list to \var{item}. ! \strong{Note:} This function ``steals'' a reference to \var{item} and ! discards a reference to an item already in the list at the affected ! position. \end{cfuncdesc} *************** *** 3252,3256 **** PyObject *o} Macro form of \cfunction{PyList_SetItem()} without error checking. ! \strong{Note:} This function ``steals'' a reference to \var{item}. \end{cfuncdesc} --- 3254,3261 ---- 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} From tim_one@users.sourceforge.net Sun Jun 3 05:14:45 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 02 Jun 2001 21:14:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.100,2.101 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv3399/python/dist/src/Objects Modified Files: dictobject.c Log Message: lookdict: Reduce obfuscating code duplication with a judicious goto. This code is likely to get even hairier to squash core dumps due to mutating comparisons, and it's hard enough to follow without that. Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.100 retrieving revision 2.101 diff -C2 -r2.100 -r2.101 *** dictobject.c 2001/06/02 08:27:39 2.100 --- dictobject.c 2001/06/03 04:14:43 2.101 *************** *** 252,257 **** dictentry *ep0 = mp->ma_table; register dictentry *ep; ! register int restore_error = 0; ! register int checked_error = 0; register int cmp; PyObject *err_type, *err_value, *err_tb; --- 252,257 ---- dictentry *ep0 = mp->ma_table; register dictentry *ep; ! register int restore_error; ! register int checked_error; register int cmp; PyObject *err_type, *err_value, *err_tb; *************** *** 261,264 **** --- 261,266 ---- if (ep->me_key == NULL || ep->me_key == key) return ep; + + restore_error = checked_error = 0; if (ep->me_key == dummy) freeslot = ep; *************** *** 272,282 **** } cmp = PyObject_RichCompareBool(ep->me_key, key, Py_EQ); ! if (cmp > 0) { ! if (restore_error) ! PyErr_Restore(err_type, err_value, ! err_tb); ! return ep; ! } ! else if (cmp < 0) PyErr_Clear(); } --- 274,280 ---- } cmp = PyObject_RichCompareBool(ep->me_key, key, Py_EQ); ! if (cmp > 0) ! goto Done; ! if (cmp < 0) PyErr_Clear(); } *************** *** 290,303 **** ep = &ep0[i & mask]; if (ep->me_key == NULL) { ! if (restore_error) ! PyErr_Restore(err_type, err_value, err_tb); ! return freeslot == NULL ? ep : freeslot; ! } ! if (ep->me_key == key) { ! if (restore_error) ! PyErr_Restore(err_type, err_value, err_tb); ! return ep; } ! else if (ep->me_hash == hash && ep->me_key != dummy) { if (!checked_error) { checked_error = 1; --- 288,298 ---- ep = &ep0[i & mask]; if (ep->me_key == NULL) { ! if (freeslot != NULL) ! ep = freeslot; ! break; } ! if (ep->me_key == key) ! break; ! if (ep->me_hash == hash && ep->me_key != dummy) { if (!checked_error) { checked_error = 1; *************** *** 309,319 **** } cmp = PyObject_RichCompareBool(ep->me_key, key, Py_EQ); ! if (cmp > 0) { ! if (restore_error) ! PyErr_Restore(err_type, err_value, ! err_tb); ! return ep; ! } ! else if (cmp < 0) PyErr_Clear(); } --- 304,310 ---- } cmp = PyObject_RichCompareBool(ep->me_key, key, Py_EQ); ! if (cmp > 0) ! break; ! if (cmp < 0) PyErr_Clear(); } *************** *** 321,324 **** --- 312,320 ---- freeslot = ep; } + + Done: + if (restore_error) + PyErr_Restore(err_type, err_value, err_tb); + return ep; } From tim_one@users.sourceforge.net Sun Jun 3 05:54:34 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 02 Jun 2001 21:54:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_mutants.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv9638/python/dist/src/Lib/test Modified Files: test_mutants.py Log Message: lookdict: stop more insane core-dump mutating comparison cases. Should be possible to provoke unbounded recursion now, but leaving that to someone else to provoke and repair. Bugfix candidate -- although this is getting harder to backstitch, and the cases it's protecting against are mondo contrived. Index: test_mutants.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_mutants.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** test_mutants.py 2001/06/02 08:18:58 1.5 --- test_mutants.py 2001/06/03 04:54:32 1.6 *************** *** 216,217 **** --- 216,285 ---- 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 From tim_one@users.sourceforge.net Sun Jun 3 05:54:34 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 02 Jun 2001 21:54:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.101,2.102 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv9638/python/dist/src/Objects Modified Files: dictobject.c Log Message: lookdict: stop more insane core-dump mutating comparison cases. Should be possible to provoke unbounded recursion now, but leaving that to someone else to provoke and repair. Bugfix candidate -- although this is getting harder to backstitch, and the cases it's protecting against are mondo contrived. Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.101 retrieving revision 2.102 diff -C2 -r2.101 -r2.102 *** dictobject.c 2001/06/03 04:14:43 2.101 --- dictobject.c 2001/06/03 04:54:32 2.102 *************** *** 256,259 **** --- 256,260 ---- register int cmp; PyObject *err_type, *err_value, *err_tb; + PyObject *startkey; i = hash & mask; *************** *** 273,281 **** PyErr_Fetch(&err_type, &err_value, &err_tb); } ! cmp = PyObject_RichCompareBool(ep->me_key, key, Py_EQ); ! if (cmp > 0) ! goto Done; if (cmp < 0) PyErr_Clear(); } freeslot = NULL; --- 274,294 ---- PyErr_Fetch(&err_type, &err_value, &err_tb); } ! startkey = ep->me_key; ! cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); if (cmp < 0) PyErr_Clear(); + if (ep0 == mp->ma_table && ep->me_key == startkey) { + if (cmp > 0) + goto Done; + } + else { + /* The compare did major nasty stuff to the + * dict: start over. + * XXX A clever adversary could prevent this + * XXX from terminating. + */ + ep = lookdict(mp, key, hash); + goto Done; + } } freeslot = NULL; *************** *** 303,311 **** } } ! cmp = PyObject_RichCompareBool(ep->me_key, key, Py_EQ); ! if (cmp > 0) ! break; if (cmp < 0) PyErr_Clear(); } else if (ep->me_key == dummy && freeslot == NULL) --- 316,336 ---- } } ! startkey = ep->me_key; ! cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); if (cmp < 0) PyErr_Clear(); + if (ep0 == mp->ma_table && ep->me_key == startkey) { + if (cmp > 0) + break; + } + else { + /* The compare did major nasty stuff to the + * dict: start over. + * XXX A clever adversary could prevent this + * XXX from terminating. + */ + ep = lookdict(mp, key, hash); + break; + } } else if (ep->me_key == dummy && freeslot == NULL) From loewis@users.sourceforge.net Sun Jun 3 15:06:44 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 03 Jun 2001 07:06:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/xml/dom minidom.py,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/xml/dom In directory usw-pr-cvs1:/tmp/cvs-serv23168 Modified Files: minidom.py Log Message: Fix getElementsByTagNameNS: - actually return a result - Compare with tag.localName in getElementsByTagNameNSHelper Index: minidom.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xml/dom/minidom.py,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -r1.32 -r1.33 *** minidom.py 2001/04/05 14:41:30 1.32 --- minidom.py 2001/06/03 14:06:42 1.33 *************** *** 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,558 ---- def getElementsByTagNameNS(self, namespaceURI, localName): ! rc = [] ! _getElementsByTagNameNSHelper(self, namespaceURI, localName, rc) ! return rc def __repr__(self): *************** *** 881,885 **** def getElementsByTagNameNS(self, namespaceURI, localName): ! _getElementsByTagNameNSHelper(self, namespaceURI, localName) def getElementsByTagName(self, name): --- 883,889 ---- def getElementsByTagNameNS(self, namespaceURI, localName): ! rc = [] ! _getElementsByTagNameNSHelper(self, namespaceURI, localName, rc) ! return rc def getElementsByTagName(self, name): From loewis@users.sourceforge.net Sun Jun 3 15:27:04 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 03 Jun 2001 07:27:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_minidom.py,1.26,1.27 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv27326 Modified Files: test_minidom.py Log Message: Implement testGetElementsByTagNameNS. Index: test_minidom.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_minidom.py,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -r1.26 -r1.27 *** test_minidom.py 2001/02/21 07:29:48 1.26 --- test_minidom.py 2001/06/03 14:27:02 1.27 *************** *** 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 From loewis@users.sourceforge.net Sun Jun 3 15:27:05 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 03 Jun 2001 07:27:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_minidom,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv27326/output Modified Files: test_minidom Log Message: Implement testGetElementsByTagNameNS. Index: test_minidom =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_minidom,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -r1.12 -r1.13 *** test_minidom 2000/12/31 04:03:27 1.12 --- test_minidom 2001/06/03 14:27:02 1.13 *************** *** 111,114 **** --- 111,115 ---- Test Succeeded testGetElementsByTagName Passed assertion: len(Node.allnodes) == 0 + Passed Test Test Succeeded testGetElementsByTagNameNS Passed assertion: len(Node.allnodes) == 0 From mhammond@users.sourceforge.net Mon Jun 4 03:31:25 2001 From: mhammond@users.sourceforge.net (Mark Hammond) Date: Sun, 03 Jun 2001 19:31:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/encodings aliases.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/encodings In directory usw-pr-cvs1:/tmp/cvs-serv11108 Modified Files: aliases.py Log Message: Add some useful Windows encodings - patch #423221. Index: aliases.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/aliases.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -r1.6 -r1.7 *** aliases.py 2001/05/15 15:34:07 1.6 --- aliases.py 2001/06/04 02:31:23 1.7 *************** *** 60,63 **** --- 60,68 ---- 'macturkish': 'mac_turkish', + # Windows + 'windows_1252': 'cp1252', + 'windows_1254': 'cp1254', + 'windows_1255': 'cp1255', + # MBCS 'dbcs': 'mbcs', From fdrake@users.sourceforge.net Mon Jun 4 04:56:27 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Sun, 03 Jun 2001 20:56:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_parser,1.4,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv25698/output Removed Files: test_parser Log Message: Convert the parser module test to use PyUnit. --- test_parser DELETED --- From fdrake@users.sourceforge.net Mon Jun 4 04:56:27 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Sun, 03 Jun 2001 20:56:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_parser.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv25698 Modified Files: test_parser.py Log Message: Convert the parser module test to use PyUnit. Index: test_parser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_parser.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -r1.6 -r1.7 *** test_parser.py 2001/01/17 21:51:36 1.6 --- test_parser.py 2001/06/04 03:56:24 1.7 *************** *** 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) From montanaro@users.sourceforge.net Mon Jun 4 16:30:43 2001 From: montanaro@users.sourceforge.net (Skip Montanaro) Date: Mon, 04 Jun 2001 08:30:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libos.tex,1.53.4.2,1.53.4.3 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv9402 Modified Files: Tag: release21-maint libos.tex Log Message: is -> if in rename description Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.53.4.2 retrieving revision 1.53.4.3 diff -C2 -r1.53.4.2 -r1.53.4.3 *** libos.tex 2001/05/31 20:27:18 1.53.4.2 --- libos.tex 2001/06/04 15:30:41 1.53.4.3 *************** *** 692,696 **** \var{dst} exists and is a file, it will be removed silently if the user has permission. The operation may fail on some \UNIX{} flavors ! is \var{src} and \var{dst} are on different filesystems. If successful, the renaming will be an atomic operation (this is a \POSIX{} requirement). On Windows, if \var{dst} already exists, --- 692,696 ---- \var{dst} exists and is a file, it will be removed silently if the user has permission. The operation may fail on some \UNIX{} flavors ! if \var{src} and \var{dst} are on different filesystems. If successful, the renaming will be an atomic operation (this is a \POSIX{} requirement). On Windows, if \var{dst} already exists, From montanaro@users.sourceforge.net Mon Jun 4 16:31:19 2001 From: montanaro@users.sourceforge.net (Skip Montanaro) Date: Mon, 04 Jun 2001 08:31:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libos.tex,1.55,1.56 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv9517 Modified Files: libos.tex Log Message: is -> if in rename description Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.55 retrieving revision 1.56 diff -C2 -r1.55 -r1.56 *** libos.tex 2001/05/31 20:27:46 1.55 --- libos.tex 2001/06/04 15:31:17 1.56 *************** *** 692,696 **** \var{dst} exists and is a file, it will be removed silently if the user has permission. The operation may fail on some \UNIX{} flavors ! is \var{src} and \var{dst} are on different filesystems. If successful, the renaming will be an atomic operation (this is a \POSIX{} requirement). On Windows, if \var{dst} already exists, --- 692,696 ---- \var{dst} exists and is a file, it will be removed silently if the user has permission. The operation may fail on some \UNIX{} flavors ! if \var{src} and \var{dst} are on different filesystems. If successful, the renaming will be an atomic operation (this is a \POSIX{} requirement). On Windows, if \var{dst} already exists, From tim_one@users.sourceforge.net Mon Jun 4 19:50:42 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 04 Jun 2001 11:50:42 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0042.txt,1.50,1.51 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv626/python/nondist/peps Modified Files: pep-0042.txt Log Message: Added two math module feature requests. Index: pep-0042.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0042.txt,v retrieving revision 1.50 retrieving revision 1.51 diff -C2 -r1.50 -r1.51 *** pep-0042.txt 2001/03/17 19:52:32 1.50 --- pep-0042.txt 2001/06/04 18:50:40 1.51 *************** *** 7,10 **** --- 7,11 ---- Created: 12-Sep-2000 + Introduction *************** *** 63,66 **** --- 64,68 ---- http://sourceforge.net/bugs/?func=detailbug&bug_id=116405&group_id=5470 + Standard Library *************** *** 218,221 **** --- 220,231 ---- http://sourceforge.net/bugs/?func=detailbug&bug_id=132493&group_id=5470 + + - Fatter math module docs and docstrings. + + http://sf.net/tracker/?func=detail&aid=426539&group_id=5470&atid=105470 + + - New math module radians() and degrees() functions. + + http://sf.net/tracker/?func=detail&aid=426539&group_id=5470&atid=105470 From bwarsaw@users.sourceforge.net Mon Jun 4 19:59:55 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Mon, 04 Jun 2001 11:59:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_urllib.py,1.2,1.2.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv2658 Modified Files: Tag: release20-maint test_urllib.py Log Message: The SF patch (#129288 - urllib.py - chanign %02x to %02X in quoting) was applied to urllib.py, but the corresponding change to test_urllib.py was not applied. Backport revision 1.6 of this file into the 2.0 maintenance branch. ---------------------------- revision 1.6 date: 2001/01/19 07:00:08; author: tim_one; state: Exp; lines: +8 -3 urllib.py very recently changed to produce uppercase escapes, but no corresponding changes were made to its std test. ---------------------------- Index: test_urllib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_urllib.py,v retrieving revision 1.2 retrieving revision 1.2.2.1 diff -C2 -r1.2 -r1.2.2.1 *** test_urllib.py 2000/09/14 16:59:07 1.2 --- test_urllib.py 2001/06/04 18:59:53 1.2.2.1 *************** *** 9,13 **** '\320\321\322\323\324\325\326\330\331\332\333\334\335\336' ! expected = 'abcdefghijklmnopqrstuvwxyz%df%e0%e1%e2%e3%e4%e5%e6%e7%e8%e9%ea%eb%ec%ed%ee%ef%f0%f1%f2%f3%f4%f5%f6%f8%f9%fa%fb%fc%fd%fe%ffABCDEFGHIJKLMNOPQRSTUVWXYZ%c0%c1%c2%c3%c4%c5%c6%c7%c8%c9%ca%cb%cc%cd%ce%cf%d0%d1%d2%d3%d4%d5%d6%d8%d9%da%db%dc%dd%de' test = urllib.quote(chars) --- 9,13 ---- '\320\321\322\323\324\325\326\330\331\332\333\334\335\336' ! expected = 'abcdefghijklmnopqrstuvwxyz%DF%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF%F0%F1%F2%F3%F4%F5%F6%F8%F9%FA%FB%FC%FD%FE%FFABCDEFGHIJKLMNOPQRSTUVWXYZ%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF%D0%D1%D2%D3%D4%D5%D6%D8%D9%DA%DB%DC%DD%DE' test = urllib.quote(chars) *************** *** 18,22 **** in1 = "abc/def" out1_1 = "abc/def" ! out1_2 = "abc%2fdef" assert urllib.quote(in1) == out1_1, "urllib.quote problem" --- 18,22 ---- in1 = "abc/def" out1_1 = "abc/def" ! out1_2 = "abc%2Fdef" assert urllib.quote(in1) == out1_1, "urllib.quote problem" *************** *** 24,28 **** in2 = "abc?def" ! out2_1 = "abc%3fdef" out2_2 = "abc?def" --- 24,28 ---- in2 = "abc?def" ! out2_1 = "abc%3Fdef" out2_2 = "abc?def" From bwarsaw@users.sourceforge.net Mon Jun 4 20:35:06 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Mon, 04 Jun 2001 12:35:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_mailbox.py,1.1,1.1.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv10256 Modified Files: Tag: release20-maint test_mailbox.py Log Message: Backported two fixes from the Py2.1 tree (pre-unittest rewrite): ---------------------------- revision 1.3 date: 2001/04/10 15:01:20; author: gvanrossum; state: Exp; lines: +6 -0 Some other tests, when failing, don't always remove their TESTFN file. Try to do it for them, so our mkdir() operation doesn't fail. ---------------------------- revision 1.2 date: 2001/03/02 05:46:17; author: gvanrossum; state: Exp; lines: +3 -3 When catching errors from os.rmdir(), test for os.error, not IOError! ---------------------------- except I used OSError instead of os.error. Index: test_mailbox.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_mailbox.py,v retrieving revision 1.1 retrieving revision 1.1.2.1 diff -C2 -r1.1 -r1.1.2.1 *** test_mailbox.py 2000/10/23 13:39:13 1.1 --- test_mailbox.py 2001/06/04 19:35:04 1.1.2.1 *************** *** 3,6 **** --- 3,12 ---- import test_support + # cleanup the turds of some of the other tests. :( + try: + os.unlink(test_support.TESTFN) + except OSError: + pass + # create a new maildir mailbox to work with: curdir = os.path.join(test_support.TESTFN, "cur") *************** *** 22,28 **** finally: try: os.rmdir(newdir) ! except IOError: pass try: os.rmdir(curdir) ! except IOError: pass try: os.rmdir(test_support.TESTFN) ! except IOError: pass --- 28,34 ---- finally: try: os.rmdir(newdir) ! except OSError: pass try: os.rmdir(curdir) ! except OSError: pass try: os.rmdir(test_support.TESTFN) ! except OSError: pass From tim_one@users.sourceforge.net Mon Jun 4 22:00:23 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 04 Jun 2001 14:00:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.102,2.103 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv29125/python/dist/src/Objects Modified Files: dictobject.c Log Message: Store the mask instead of the size in dictobjects. The mask is more frequently used, and in particular this allows to drop the last remaining obvious time-waster in the crucial lookdict() and lookdict_string() functions. Other changes consist mostly of changing "i < ma_size" to "i <= ma_mask" everywhere. Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.102 retrieving revision 2.103 diff -C2 -r2.102 -r2.103 *** dictobject.c 2001/06/03 04:54:32 2.102 --- dictobject.c 2001/06/04 21:00:21 2.103 *************** *** 163,167 **** int ma_fill; /* # Active + # Dummy */ int ma_used; /* # Active */ ! int ma_size; /* total # slots in ma_table */ /* ma_table points to ma_smalltable for small tables, else to * additional malloc'ed memory. ma_table is never NULL! This rule --- 163,173 ---- 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 *************** *** 195,199 **** memset((mp)->ma_smalltable, 0, sizeof((mp)->ma_smalltable)); \ (mp)->ma_table = (mp)->ma_smalltable; \ ! (mp)->ma_size = MINSIZE; \ (mp)->ma_used = (mp)->ma_fill = 0; \ } while(0) --- 201,205 ---- memset((mp)->ma_smalltable, 0, sizeof((mp)->ma_smalltable)); \ (mp)->ma_table = (mp)->ma_smalltable; \ ! (mp)->ma_mask = MINSIZE - 1; \ (mp)->ma_used = (mp)->ma_fill = 0; \ } while(0) *************** *** 249,253 **** register unsigned int perturb; register dictentry *freeslot; ! register unsigned int mask = mp->ma_size-1; dictentry *ep0 = mp->ma_table; register dictentry *ep; --- 255,259 ---- register unsigned int perturb; register dictentry *freeslot; ! register unsigned int mask = mp->ma_mask; dictentry *ep0 = mp->ma_table; register dictentry *ep; *************** *** 360,364 **** register unsigned int perturb; register dictentry *freeslot; ! register unsigned int mask = mp->ma_size-1; dictentry *ep0 = mp->ma_table; register dictentry *ep; --- 366,370 ---- register unsigned int perturb; register dictentry *freeslot; ! register unsigned int mask = mp->ma_mask; dictentry *ep0 = mp->ma_table; register dictentry *ep; *************** *** 493,497 **** assert(newtable != oldtable); mp->ma_table = newtable; ! mp->ma_size = newsize; memset(newtable, 0, sizeof(dictentry) * newsize); mp->ma_used = 0; --- 499,503 ---- assert(newtable != oldtable); mp->ma_table = newtable; ! mp->ma_mask = newsize - 1; memset(newtable, 0, sizeof(dictentry) * newsize); mp->ma_used = 0; *************** *** 581,585 **** return -1; } ! assert(mp->ma_fill < mp->ma_size); n_used = mp->ma_used; Py_INCREF(value); --- 587,591 ---- return -1; } ! assert(mp->ma_fill <= mp->ma_mask); /* at least one empty slot */ n_used = mp->ma_used; Py_INCREF(value); *************** *** 592,596 **** * deleted). */ ! if (mp->ma_used > n_used && mp->ma_fill*3 >= mp->ma_size*2) { if (dictresize(mp, mp->ma_used*2) != 0) return -1; --- 598,602 ---- * deleted). */ ! if (mp->ma_used > n_used && mp->ma_fill*3 >= (mp->ma_mask+1)*2) { if (dictresize(mp, mp->ma_used*2) != 0) return -1; *************** *** 653,657 **** mp = (dictobject *)op; #ifdef Py_DEBUG ! n = mp->ma_size; i = 0; #endif --- 659,663 ---- mp = (dictobject *)op; #ifdef Py_DEBUG ! n = mp->ma_mask + 1; i = 0; #endif *************** *** 722,729 **** if (i < 0) return 0; ! while (i < mp->ma_size && mp->ma_table[i].me_value == NULL) i++; *ppos = i+1; ! if (i >= mp->ma_size) return 0; if (pkey) --- 728,735 ---- if (i < 0) return 0; ! while (i <= mp->ma_mask && mp->ma_table[i].me_value == NULL) i++; *ppos = i+1; ! if (i > mp->ma_mask) return 0; if (pkey) *************** *** 773,777 **** fprintf(fp, "{"); any = 0; ! for (i = 0; i < mp->ma_size; i++) { dictentry *ep = mp->ma_table + i; PyObject *pvalue = ep->me_value; --- 779,783 ---- fprintf(fp, "{"); any = 0; ! for (i = 0; i <= mp->ma_mask; i++) { dictentry *ep = mp->ma_table + i; PyObject *pvalue = ep->me_value; *************** *** 820,824 **** colon = PyString_FromString(": "); any = 0; ! for (i = 0; i < mp->ma_size && v; i++) { dictentry *ep = mp->ma_table + i; PyObject *pvalue = ep->me_value; --- 826,830 ---- colon = PyString_FromString(": "); any = 0; ! for (i = 0; i <= mp->ma_mask && v; i++) { dictentry *ep = mp->ma_table + i; PyObject *pvalue = ep->me_value; *************** *** 906,910 **** goto again; } ! for (i = 0, j = 0; i < mp->ma_size; i++) { if (mp->ma_table[i].me_value != NULL) { PyObject *key = mp->ma_table[i].me_key; --- 912,916 ---- goto again; } ! for (i = 0, j = 0; i <= mp->ma_mask; i++) { if (mp->ma_table[i].me_value != NULL) { PyObject *key = mp->ma_table[i].me_key; *************** *** 937,941 **** goto again; } ! for (i = 0, j = 0; i < mp->ma_size; i++) { if (mp->ma_table[i].me_value != NULL) { PyObject *value = mp->ma_table[i].me_value; --- 943,947 ---- goto again; } ! for (i = 0, j = 0; i <= mp->ma_mask; i++) { if (mp->ma_table[i].me_value != NULL) { PyObject *value = mp->ma_table[i].me_value; *************** *** 982,986 **** } /* Nothing we do below makes any function calls. */ ! for (i = 0, j = 0; i < mp->ma_size; i++) { if (mp->ma_table[i].me_value != NULL) { key = mp->ma_table[i].me_key; --- 988,992 ---- } /* Nothing we do below makes any function calls. */ ! for (i = 0, j = 0; i <= mp->ma_mask; i++) { if (mp->ma_table[i].me_value != NULL) { key = mp->ma_table[i].me_key; *************** *** 1011,1019 **** resizing as we insert new items. Expect that there will be no (or few) overlapping keys. */ ! if ((mp->ma_fill + other->ma_used)*3 >= mp->ma_size*2) { if (dictresize(mp, (mp->ma_used + other->ma_used)*3/2) != 0) return NULL; } ! for (i = 0; i < other->ma_size; i++) { entry = &other->ma_table[i]; if (entry->me_value != NULL) { --- 1017,1025 ---- resizing as we insert new items. Expect that there will be no (or few) overlapping keys. */ ! if ((mp->ma_fill + other->ma_used)*3 >= (mp->ma_mask+1)*2) { if (dictresize(mp, (mp->ma_used + other->ma_used)*3/2) != 0) return NULL; } ! for (i = 0; i <= other->ma_mask; i++) { entry = &other->ma_table[i]; if (entry->me_value != NULL) { *************** *** 1056,1060 **** if (dictresize(copy, mp->ma_used*3/2) != 0) return NULL; ! for (i = 0; i < mp->ma_size; i++) { entry = &mp->ma_table[i]; if (entry->me_value != NULL) { --- 1062,1066 ---- if (dictresize(copy, mp->ma_used*3/2) != 0) return NULL; ! for (i = 0; i <= mp->ma_mask; i++) { entry = &mp->ma_table[i]; if (entry->me_value != NULL) { *************** *** 1124,1128 **** int i, cmp; ! for (i = 0; i < a->ma_size; i++) { PyObject *thiskey, *thisaval, *thisbval; if (a->ma_table[i].me_value == NULL) --- 1130,1134 ---- int i, cmp; ! for (i = 0; i <= a->ma_mask; i++) { PyObject *thiskey, *thisaval, *thisbval; if (a->ma_table[i].me_value == NULL) *************** *** 1137,1141 **** } if (cmp > 0 || ! i >= a->ma_size || a->ma_table[i].me_value == NULL) { --- 1143,1147 ---- } if (cmp > 0 || ! i > a->ma_mask || a->ma_table[i].me_value == NULL) { *************** *** 1252,1256 **** /* Same # of entries -- check all of 'em. Exit early on any diff. */ ! for (i = 0; i < a->ma_size; i++) { PyObject *aval = a->ma_table[i].me_value; if (aval != NULL) { --- 1258,1262 ---- /* Same # of entries -- check all of 'em. Exit early on any diff. */ ! for (i = 0; i <= a->ma_mask; i++) { PyObject *aval = a->ma_table[i].me_value; if (aval != NULL) { *************** *** 1428,1436 **** * or the table shrunk -- simply make sure it's in bounds now. */ ! if (i >= mp->ma_size || i < 1) i = 1; /* skip slot 0 */ while ((ep = &mp->ma_table[i])->me_value == NULL) { i++; ! if (i >= mp->ma_size) i = 1; } --- 1434,1442 ---- * or the table shrunk -- simply make sure it's in bounds now. */ ! if (i > mp->ma_mask || i < 1) i = 1; /* skip slot 0 */ while ((ep = &mp->ma_table[i])->me_value == NULL) { i++; ! if (i > mp->ma_mask) i = 1; } From gvanrossum@users.sourceforge.net Mon Jun 4 22:21:13 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 04 Jun 2001 14:21:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/idle extend.txt,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/idle In directory usw-pr-cvs1:/tmp/cvs-serv4092 Modified Files: extend.txt Log Message: Quick update to the extension mechanism (extend.py is gone, long live config.txt). *** This is a bugfix-release candidate (for 2.1.1 and 2.0.1)! *** Index: extend.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/idle/extend.txt,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** extend.txt 1999/04/20 17:32:52 1.3 --- extend.txt 2001/06/04 21:21:11 1.4 *************** *** 8,12 **** The list of extensions loaded at startup time is configured by editing ! the file extend.py; see below for details. An IDLE extension is defined by a class. Methods of the class define --- 8,12 ---- The list of extensions loaded at startup time is configured by editing ! the file config.txt; see below for details. An IDLE extension is defined by a class. Methods of the class define *************** *** 87,95 **** "...Do what you want here..." ! The final piece of the puzzle is the file "extend.py", which contains a ! simple table used to configure the loading of extensions. This file ! currently contains a single list variable named "standard", which is a ! list of extension names that are to be loaded. (In the future, other ! configuration variables may be added to this module.) Extensions can define key bindings and menu entries that reference --- 87,109 ---- "...Do what you want here..." ! The final piece of the puzzle is the file "config.txt", which is used ! to to configure the loading of extensions. For each extension, ! you must include a section in config.txt (or in any of the other ! configuration files that are consulted at startup: config-unix.txt, ! config-win.txt, or ~/.idle). A section is headed by the module name ! in square brackets, e.g. ! ! [ZoomHeight] ! ! The section may be empty, or it may define configuration options for ! the extension. (See ParenMatch.py for an example.) A special option ! is 'enable': including ! ! enable = 0 ! ! in a section disables that extension. More than one configuration ! file may specify options for the same extension, so a user may disable ! an extension that is loaded by default, or enable an extension that is ! disabled by default. Extensions can define key bindings and menu entries that reference From fdrake@users.sourceforge.net Tue Jun 5 03:17:04 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 04 Jun 2001 19:17:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ref ref5.tex,1.45,1.46 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory usw-pr-cvs1:/tmp/cvs-serv6705/ref Modified Files: ref5.tex Log Message: Update a "Programmer's note" about lambda forms and scoping to reflect the availability of nested scoping in Python 2.1 and 2.2. Index: ref5.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref5.tex,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -r1.45 -r1.46 *** ref5.tex 2001/05/09 16:51:49 1.45 --- ref5.tex 2001/06/05 02:17:02 1.46 *************** *** 870,878 **** \indexii{anonmymous}{function} ! \strong{Programmer's note:} a lambda form defined inside a function ! has no access to names defined in the function's namespace. This is ! because Python has only two scopes: local and global. A common ! work-around is to use default argument values to pass selected ! variables into the lambda's namespace, e.g.: \begin{verbatim} --- 870,878 ---- \indexii{anonmymous}{function} ! \strong{Programmer's note:} Prior to Python 2.1, a lambda form defined ! inside a function has no access to names defined in the function's ! namespace. This is because Python had only two scopes: local and ! global. A common work-around was to use default argument values to ! pass selected variables into the lambda's namespace, e.g.: \begin{verbatim} *************** *** 880,883 **** --- 880,897 ---- return lambda x, n=increment: x+n \end{verbatim} + + As of Python 2.1, nested scopes were introduced, and this work-around + has not been necessary. Python 2.1 supports nested scopes in modules + which include the statement \samp{from __future__ import + nested_scopes}, and more recent versions of Python enable nested + scopes by default. This version works starting with Python 2.1: + + \begin{verbatim} + from __future__ import nested_scopes + + def make_incrementor(increment): + return lambda x: x+increment + \end{verbatim} + \section{Expression lists\label{exprlists}} From fdrake@users.sourceforge.net Tue Jun 5 03:24:29 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 04 Jun 2001 19:24:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ref ref5.tex,1.43.2.1,1.43.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory usw-pr-cvs1:/tmp/cvs-serv7965/ref Modified Files: Tag: release21-maint ref5.tex Log Message: Update a "Programmer's note" about lambda forms and scoping to reflect the availability of nested scoping in Python 2.1. Note that this is a slightly different patch than was applied to the trunk of the development for Python 2.2. Index: ref5.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref5.tex,v retrieving revision 1.43.2.1 retrieving revision 1.43.2.2 diff -C2 -r1.43.2.1 -r1.43.2.2 *** ref5.tex 2001/05/09 16:53:19 1.43.2.1 --- ref5.tex 2001/06/05 02:24:26 1.43.2.2 *************** *** 868,876 **** \indexii{anonmymous}{function} ! \strong{Programmer's note:} a lambda form defined inside a function ! has no access to names defined in the function's namespace. This is ! because Python has only two scopes: local and global. A common ! work-around is to use default argument values to pass selected ! variables into the lambda's namespace, e.g.: \begin{verbatim} --- 868,876 ---- \indexii{anonmymous}{function} ! \strong{Programmer's note:} Prior to Python 2.1, a lambda form defined ! inside a function has no access to names defined in the function's ! namespace. This is because Python had only two scopes: local and ! global. A common work-around was to use default argument values to ! pass selected variables into the lambda's namespace, e.g.: \begin{verbatim} *************** *** 878,881 **** --- 878,895 ---- return lambda x, n=increment: x+n \end{verbatim} + + Python 2.1 introduced nested scopes as an optional feature, and this + work-around has not been necessary when the feature is enabled. The + use of nested scopes is enabled by the statement \samp{from __future__ + import nested_scopes}; future versions of Python will enable nested + scopes by default. This version works starting with Python 2.1: + + \begin{verbatim} + from __future__ import nested_scopes + + def make_incrementor(increment): + return lambda x: x+increment + \end{verbatim} + \section{Expression lists\label{exprlists}} From tim_one@users.sourceforge.net Tue Jun 5 05:43:28 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 04 Jun 2001 21:43:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules arraymodule.c,2.62,2.63 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv30144/python/dist/src/Modules Modified Files: arraymodule.c Log Message: Make it possible to find the use of tp_as_buffer here with a global search. (Just a change to a comment) Index: arraymodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/arraymodule.c,v retrieving revision 2.62 retrieving revision 2.63 diff -C2 -r2.62 -r2.63 *** arraymodule.c 2001/01/25 22:12:43 2.62 --- arraymodule.c 2001/06/05 04:43:26 2.63 *************** *** 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 */ From loewis@users.sourceforge.net Tue Jun 5 06:17:02 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Mon, 04 Jun 2001 22:17:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib mimetypes.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv1580 Modified Files: mimetypes.py Log Message: Add .pyo as an extension, fixes bug #416462. Also restore alphabetic order. Index: mimetypes.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/mimetypes.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -r1.13 -r1.14 *** mimetypes.py 2001/02/09 09:44:47 1.13 --- mimetypes.py 2001/06/05 05:17:00 1.14 *************** *** 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', From loewis@users.sourceforge.net Tue Jun 5 06:33:21 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Mon, 04 Jun 2001 22:33:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib dbhash.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv3378/Lib Modified Files: dbhash.py Log Message: Fix bug #422702: Make flag argument to open optional, and document it that way. Index: dbhash.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/dbhash.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** dbhash.py 2001/01/25 13:47:00 1.5 --- dbhash.py 2001/06/05 05:33:19 1.6 *************** *** 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) From loewis@users.sourceforge.net Tue Jun 5 06:33:21 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Mon, 04 Jun 2001 22:33:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libdbhash.tex,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv3378/Doc/lib Modified Files: libdbhash.tex Log Message: Fix bug #422702: Make flag argument to open optional, and document it that way. Index: libdbhash.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdbhash.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** libdbhash.tex 1999/04/19 21:19:21 1.3 --- libdbhash.tex 2001/06/05 05:33:19 1.4 *************** *** 22,26 **** \end{excdesc} ! \begin{funcdesc}{open}{path, flag\optional{, mode}} Open a \code{db} database and return the database object. The \var{path} argument is the name of the database file. --- 22,26 ---- \end{excdesc} ! \begin{funcdesc}{open}{path, \optional{, flag\optional{, mode}}} Open a \code{db} database and return the database object. The \var{path} argument is the name of the database file. From loewis@users.sourceforge.net Tue Jun 5 06:58:46 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Mon, 04 Jun 2001 22:58:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include rangeobject.h,2.15,2.16 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv6223 Modified Files: rangeobject.h Log Message: Wrap with extern "C". Fixes bug #428419. Also protect against multiple inclusion. Index: rangeobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/rangeobject.h,v retrieving revision 2.15 retrieving revision 2.16 diff -C2 -r2.15 -r2.16 *** rangeobject.h 2000/09/01 23:29:26 2.15 --- rangeobject.h 2001/06/05 05:58:44 2.16 *************** *** 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; *************** *** 15,16 **** --- 21,27 ---- extern DL_IMPORT(PyObject *) PyRange_New(long, long, long, int); + + #ifdef __cplusplus + } + #endif + #endif /* !Py_RANGEOBJECT_H */ From gvanrossum@users.sourceforge.net Tue Jun 5 11:33:50 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 05 Jun 2001 03:33:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.1.2.8,1.1.2.9 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv19068 Modified Files: Tag: descr-branch test_descr.py Log Message: Somehow a "global log" (or a "from __future__ import nested_scopes" :-) was missing from the pymods() test function. It couldn't have worked. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_descr.py,v retrieving revision 1.1.2.8 retrieving revision 1.1.2.9 diff -C2 -r1.1.2.8 -r1.1.2.9 *** test_descr.py 2001/05/22 20:04:03 1.1.2.8 --- test_descr.py 2001/06/05 10:33:48 1.1.2.9 *************** *** 314,317 **** --- 314,318 ---- def pymods(): if verbose: print "Testing Python subclass of module..." + global log log = [] class MM(MT): From gvanrossum@users.sourceforge.net Tue Jun 5 11:49:26 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 05 Jun 2001 03:49:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include object.h,2.79.2.8,2.79.2.9 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv20188/Include Modified Files: Tag: descr-branch object.h Log Message: Redo object creation; touching many files. - Get rid of tp_construct, it had a bogus interface (this moves tp_dictoffset one slot up). - New tp_ slots; the last two are "type methods" (their first argument is a type object, not an instance of that type): - tp_init is what tp_construct wanted to be, without the allocation; - tp_alloc does low-level allocation, initializing the object to its most basic form (up to and including registering it with the GC machinery); - tp_new does high-level object creation: it calls tp_alloc and then tp_init. - New generic functions PyType_GenericAlloc() and PyType_GenericNew() provide default implementations for tp_alloc and tp_new that are usually sufficient. - Used the above things to make standard list, dict and module objects subtypable as before. - Remove tp_construct initializer spacer from funcobject.c. - Add an __init__() override test to test_descr.py. Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.79.2.8 retrieving revision 2.79.2.9 diff -C2 -r2.79.2.8 -r2.79.2.9 *** object.h 2001/05/22 17:21:18 2.79.2.8 --- object.h 2001/06/05 10:49:24 2.79.2.9 *************** *** 205,208 **** --- 205,210 ---- typedef PyObject *(*descrgetfunc) (PyObject *, PyObject *); typedef int (*descrsetfunc) (PyObject *, PyObject *, PyObject *); + typedef int (*initproc)(PyObject *, PyObject *, PyObject *); + typedef PyObject *(*allocfunc)(struct _typeobject *, PyObject *, PyObject *); typedef struct _typeobject { *************** *** 266,273 **** descrgetfunc tp_descr_get; descrsetfunc tp_descr_set; - ternaryfunc tp_construct; long tp_dictoffset; - #ifdef COUNT_ALLOCS /* these must be last and never explicitly initialized */ --- 268,276 ---- descrgetfunc tp_descr_get; descrsetfunc tp_descr_set; long tp_dictoffset; + initproc tp_init; + allocfunc tp_alloc; + allocfunc tp_new; #ifdef COUNT_ALLOCS /* these must be last and never explicitly initialized */ *************** *** 290,293 **** --- 293,300 ---- extern DL_IMPORT(int) PyType_InitDict(PyTypeObject *); + extern DL_IMPORT(PyObject *) PyType_GenericAlloc(PyTypeObject *, + PyObject *, PyObject *); + extern DL_IMPORT(PyObject *) PyType_GenericNew(PyTypeObject *, + PyObject *, PyObject *); /* Generic operations on objects */ From gvanrossum@users.sourceforge.net Tue Jun 5 11:49:26 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 05 Jun 2001 03:49:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.1.2.9,1.1.2.10 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv20188/Lib/test Modified Files: Tag: descr-branch test_descr.py Log Message: Redo object creation; touching many files. - Get rid of tp_construct, it had a bogus interface (this moves tp_dictoffset one slot up). - New tp_ slots; the last two are "type methods" (their first argument is a type object, not an instance of that type): - tp_init is what tp_construct wanted to be, without the allocation; - tp_alloc does low-level allocation, initializing the object to its most basic form (up to and including registering it with the GC machinery); - tp_new does high-level object creation: it calls tp_alloc and then tp_init. - New generic functions PyType_GenericAlloc() and PyType_GenericNew() provide default implementations for tp_alloc and tp_new that are usually sufficient. - Used the above things to make standard list, dict and module objects subtypable as before. - Remove tp_construct initializer spacer from funcobject.c. - Add an __init__() override test to test_descr.py. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_descr.py,v retrieving revision 1.1.2.9 retrieving revision 1.1.2.10 diff -C2 -r1.1.2.9 -r1.1.2.10 *** test_descr.py 2001/06/05 10:33:48 1.1.2.9 --- test_descr.py 2001/06/05 10:49:24 1.1.2.10 *************** *** 317,320 **** --- 317,322 ---- log = [] class MM(MT): + def __init__(self): + MT.__init__(self) def __getattr__(self, name): log.append(("getattr", name)) *************** *** 330,338 **** x = a.foo del a.foo ! verify(log == [('getattr', '__setattr__'), ("setattr", "foo", 12), ("getattr", "foo"), ('getattr', '__delattr__'), ! ("delattr", "foo")]) def all(): --- 332,341 ---- x = a.foo del a.foo ! verify(log == [('getattr', '__init__'), ! ('getattr', '__setattr__'), ("setattr", "foo", 12), ("getattr", "foo"), ('getattr', '__delattr__'), ! ("delattr", "foo")], log) def all(): From gvanrossum@users.sourceforge.net Tue Jun 5 11:49:26 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 05 Jun 2001 03:49:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules spam.c,1.1.2.4,1.1.2.5 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv20188/Modules Modified Files: Tag: descr-branch spam.c Log Message: Redo object creation; touching many files. - Get rid of tp_construct, it had a bogus interface (this moves tp_dictoffset one slot up). - New tp_ slots; the last two are "type methods" (their first argument is a type object, not an instance of that type): - tp_init is what tp_construct wanted to be, without the allocation; - tp_alloc does low-level allocation, initializing the object to its most basic form (up to and including registering it with the GC machinery); - tp_new does high-level object creation: it calls tp_alloc and then tp_init. - New generic functions PyType_GenericAlloc() and PyType_GenericNew() provide default implementations for tp_alloc and tp_new that are usually sufficient. - Used the above things to make standard list, dict and module objects subtypable as before. - Remove tp_construct initializer spacer from funcobject.c. - Add an __init__() override test to test_descr.py. Index: spam.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/Attic/spam.c,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -C2 -r1.1.2.4 -r1.1.2.5 *** spam.c 2001/05/14 21:41:41 1.1.2.4 --- spam.c 2001/06/05 10:49:24 1.1.2.5 *************** *** 38,60 **** staticforward PyTypeObject spamlist_type; ! static PyObject * ! spamlist_construct(spamlistobject *arg, PyObject *args, PyObject *kwds) { ! spamlistobject *self; ! ! if (arg != NULL) ! self = arg; ! else { ! self = PyObject_New(spamlistobject, &spamlist_type); ! if (self == NULL) ! return NULL; ! } ! if (PyList_Type.tp_construct((PyObject *)self, args, kwds) == NULL) { ! if (self != arg) ! PyObject_Del(self); ! return NULL; ! } self->state = 0; ! return (PyObject *)self; } --- 38,48 ---- 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; } *************** *** 95,99 **** 0, /* tp_descr_get */ 0, /* tp_descr_set */ ! (ternaryfunc)spamlist_construct, /* tp_construct */ }; --- 83,90 ---- 0, /* tp_descr_get */ 0, /* tp_descr_set */ ! 0, /* tp_dictoffset */ ! (initproc)spamlist_init, /* tp_init */ ! PyType_GenericAlloc, /* tp_alloc */ ! PyType_GenericNew, /* tp_new */ }; *************** *** 141,163 **** staticforward PyTypeObject spamdict_type; ! static PyObject * ! spamdict_construct(spamdictobject *arg, PyObject *args, PyObject *kwds) { ! spamdictobject *self; ! ! if (arg != NULL) ! self = arg; ! else { ! self = PyObject_New(spamdictobject, &spamdict_type); ! if (self == NULL) ! return NULL; ! } ! if (PyDict_Type.tp_construct((PyObject *)self, args, kwds) == NULL) { ! if (self != arg) ! PyObject_Del(self); ! return NULL; ! } self->state = 0; ! return (PyObject *)self; } --- 132,142 ---- 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; } *************** *** 198,202 **** 0, /* tp_descr_get */ 0, /* tp_descr_set */ ! (ternaryfunc)spamdict_construct, /* tp_construct */ }; --- 177,184 ---- 0, /* tp_descr_get */ 0, /* tp_descr_set */ ! 0, /* tp_dictoffset */ ! (initproc)spamdict_init, /* tp_init */ ! PyType_GenericAlloc, /* tp_alloc */ ! PyType_GenericNew, /* tp_new */ }; From gvanrossum@users.sourceforge.net Tue Jun 5 11:49:26 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 05 Jun 2001 03:49:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.80.2.6,2.80.2.7 funcobject.c,2.37.4.3,2.37.4.4 listobject.c,2.92.6.4,2.92.6.5 moduleobject.c,2.31.6.2,2.31.6.3 typeobject.c,2.16.8.25,2.16.8.26 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv20188/Objects Modified Files: Tag: descr-branch dictobject.c funcobject.c listobject.c moduleobject.c typeobject.c Log Message: Redo object creation; touching many files. - Get rid of tp_construct, it had a bogus interface (this moves tp_dictoffset one slot up). - New tp_ slots; the last two are "type methods" (their first argument is a type object, not an instance of that type): - tp_init is what tp_construct wanted to be, without the allocation; - tp_alloc does low-level allocation, initializing the object to its most basic form (up to and including registering it with the GC machinery); - tp_new does high-level object creation: it calls tp_alloc and then tp_init. - New generic functions PyType_GenericAlloc() and PyType_GenericNew() provide default implementations for tp_alloc and tp_new that are usually sufficient. - Used the above things to make standard list, dict and module objects subtypable as before. - Remove tp_construct initializer spacer from funcobject.c. - Add an __init__() override test to test_descr.py. Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.80.2.6 retrieving revision 2.80.2.7 diff -C2 -r2.80.2.6 -r2.80.2.7 *** dictobject.c 2001/05/22 04:00:17 2.80.2.6 --- dictobject.c 2001/06/05 10:49:24 2.80.2.7 *************** *** 1277,1285 **** staticforward PyObject *dictiter_new(dictobject *); ! static PyObject * ! dict_construct(PyDictObject *self, PyObject *args, PyObject *kw) { - if (self == NULL) - return PyDict_New(); self->ma_size = 0; self->ma_poly = 0; --- 1277,1283 ---- staticforward PyObject *dictiter_new(dictobject *); ! static int ! dict_init(PyDictObject *self, PyObject *args, PyObject *kw) { self->ma_size = 0; self->ma_poly = 0; *************** *** 1291,1295 **** ++created; #endif ! return (PyObject *)self; } --- 1289,1293 ---- ++created; #endif ! return 0; } *************** *** 1330,1334 **** 0, /* tp_descr_get */ 0, /* tp_descr_set */ ! (ternaryfunc)dict_construct, /* tp_construct */ }; --- 1328,1335 ---- 0, /* tp_descr_get */ 0, /* tp_descr_set */ ! 0, /* tp_dictoffset */ ! (initproc)dict_init, /* tp_init */ ! PyType_GenericAlloc, /* tp_alloc */ ! PyType_GenericNew, /* tp_new */ }; Index: funcobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/funcobject.c,v retrieving revision 2.37.4.3 retrieving revision 2.37.4.4 diff -C2 -r2.37.4.3 -r2.37.4.4 *** funcobject.c 2001/05/11 20:45:22 2.37.4.3 --- funcobject.c 2001/06/05 10:49:24 2.37.4.4 *************** *** 377,381 **** func_descr_get, /* tp_descr_get */ 0, /* tp_descr_set */ - 0, /* tp_construct */ offsetof(PyFunctionObject, func_dict), /* tp_dictoffset */ }; --- 377,380 ---- Index: listobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v retrieving revision 2.92.6.4 retrieving revision 2.92.6.5 diff -C2 -r2.92.6.4 -r2.92.6.5 *** listobject.c 2001/05/14 21:35:52 2.92.6.4 --- listobject.c 2001/06/05 10:49:24 2.92.6.5 *************** *** 1243,1246 **** --- 1243,1247 ---- int err; PyObject *compare = NULL; + PyTypeObject *savetype; if (args != NULL) { *************** *** 1248,1256 **** return NULL; } self->ob_type = &immutable_list_type; err = samplesortslice(self->ob_item, self->ob_item + self->ob_size, compare); ! self->ob_type = &PyList_Type; if (err < 0) return NULL; --- 1249,1258 ---- return NULL; } + savetype = self->ob_type; self->ob_type = &immutable_list_type; err = samplesortslice(self->ob_item, self->ob_item + self->ob_size, compare); ! self->ob_type = savetype; if (err < 0) return NULL; *************** *** 1495,1506 **** } ! static PyObject * ! list_construct(PyListObject *self, PyObject *args, PyObject *kw) { - if (self == NULL) - return PyList_New(0); self->ob_size = 0; self->ob_item = NULL; ! return (PyObject *)self; } --- 1497,1506 ---- } ! static int ! list_init(PyListObject *self, PyObject *args, PyObject *kw) { self->ob_size = 0; self->ob_item = NULL; ! return 0; } *************** *** 1586,1590 **** 0, /* tp_descr_get */ 0, /* tp_descr_set */ ! (ternaryfunc)list_construct, /* tp_construct */ }; --- 1586,1593 ---- 0, /* tp_descr_get */ 0, /* tp_descr_set */ ! 0, /* tp_dictoffset */ ! (initproc)list_init, /* tp_init */ ! PyType_GenericAlloc, /* tp_alloc */ ! PyType_GenericNew, /* tp_new */ }; *************** *** 1669,1673 **** 0, /* tp_descr_get */ 0, /* tp_descr_set */ ! (ternaryfunc)list_construct, /* tp_construct */ /* NOTE: This is *not* the standard list_type struct! */ }; --- 1672,1676 ---- 0, /* tp_descr_get */ 0, /* tp_descr_set */ ! 0, /* tp_init */ /* NOTE: This is *not* the standard list_type struct! */ }; Index: moduleobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/moduleobject.c,v retrieving revision 2.31.6.2 retrieving revision 2.31.6.3 diff -C2 -r2.31.6.2 -r2.31.6.3 *** moduleobject.c 2001/05/12 20:40:47 2.31.6.2 --- moduleobject.c 2001/06/05 10:49:24 2.31.6.3 *************** *** 135,147 **** /* Methods */ ! static PyObject * ! module_construct(PyModuleObject *m, PyObject *args, PyObject *kw) { - if (m == NULL) - return PyModule_New("?"); m->md_dict = PyDict_New(); if (m->md_dict == NULL) ! return NULL; ! return (PyObject *)m; } --- 135,145 ---- /* Methods */ ! static int ! module_init(PyModuleObject *m, PyObject *args, PyObject *kw) { m->md_dict = PyDict_New(); if (m->md_dict == NULL) ! return -1; ! return 0; } *************** *** 226,230 **** 0, /* tp_descr_get */ 0, /* tp_descr_set */ - (ternaryfunc)module_construct, /* tp_construct */ offsetof(PyModuleObject, md_dict), /* tp_dictoffset */ }; --- 224,230 ---- 0, /* tp_descr_get */ 0, /* tp_descr_set */ offsetof(PyModuleObject, md_dict), /* tp_dictoffset */ + (initproc)module_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.25 retrieving revision 2.16.8.26 diff -C2 -r2.16.8.25 -r2.16.8.26 *** typeobject.c 2001/05/22 19:53:15 2.16.8.25 --- typeobject.c 2001/06/05 10:49:24 2.16.8.26 *************** *** 56,64 **** type_call(PyTypeObject *type, PyObject *args, PyObject *kwds) { ! int size; ! void *mem; ! PyObject *obj, *res; ! ! if (type->tp_construct == NULL) { PyErr_Format(PyExc_TypeError, "cannot construct '%.100s' instances", --- 56,60 ---- type_call(PyTypeObject *type, PyObject *args, PyObject *kwds) { ! if (type->tp_new == NULL) { PyErr_Format(PyExc_TypeError, "cannot construct '%.100s' instances", *************** *** 67,70 **** --- 63,76 ---- } + return type->tp_new(type, args, kwds); + } + + PyObject * + PyType_GenericAlloc(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + int size; + void *mem; + PyObject *obj; + /* Inline PyObject_New() so we can zero the memory */ size = _PyObject_SIZE(type); *************** *** 80,92 **** Py_INCREF(type); PyObject_INIT(obj, type); ! res = (type->tp_construct)(obj, args, kwds); ! if (res == NULL) { ! Py_DECREF(obj); return NULL; } ! if (PyType_IS_GC(type)) ! PyObject_GC_Init(res); ! return res; } --- 86,107 ---- Py_INCREF(type); PyObject_INIT(obj, type); + if (PyType_IS_GC(type)) + PyObject_GC_Init(obj); + return obj; + } ! PyObject * ! PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds) ! { ! PyObject *self; ! ! self = type->tp_alloc(type, args, kwds); ! if (self == NULL) ! return NULL; ! if (type->tp_init(self, args, kwds) < 0) { ! Py_DECREF(self); return NULL; } ! return self; } *************** *** 133,137 **** /* TypeType's constructor is called when a type is subclassed */ static PyObject * ! type_construct(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *name, *bases, *dict, *x, *slots; --- 148,152 ---- /* TypeType's constructor is called when a type is subclassed */ static PyObject * ! type_init(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *name, *bases, *dict, *x, *slots; *************** *** 167,171 **** return NULL; } ! if (base->tp_construct == NULL) { PyErr_SetString(PyExc_TypeError, "base type must have a constructor slot"); --- 182,186 ---- return NULL; } ! if (base->tp_init == NULL) { PyErr_SetString(PyExc_TypeError, "base type must have a constructor slot"); *************** *** 337,342 **** 0, /* tp_descr_get */ 0, /* tp_descr_set */ - (ternaryfunc)type_construct, /* tp_construct */ offsetof(PyTypeObject, tp_dict), /* tp_dictoffset */ }; --- 352,359 ---- 0, /* tp_descr_get */ 0, /* tp_descr_set */ offsetof(PyTypeObject, tp_dict), /* tp_dictoffset */ + (initproc)type_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ }; *************** *** 580,585 **** COPYSLOT(tp_descr_get); COPYSLOT(tp_descr_set); - COPYSLOT(tp_construct); COPYSLOT(tp_dictoffset); } --- 597,604 ---- COPYSLOT(tp_descr_get); COPYSLOT(tp_descr_set); COPYSLOT(tp_dictoffset); + COPYSLOT(tp_init); + COPYSLOT(tp_alloc); + COPYSLOT(tp_new); } *************** *** 1137,1149 **** wrap_init(PyObject *self, PyObject *args, void *wrapped) { ! ternaryfunc func = (ternaryfunc)wrapped; ! PyObject *res; /* XXX What about keyword arguments? */ ! res = (*func)(self, args, NULL); ! if (res == NULL) return NULL; - /* tp_construct doesn't return a new object; it just returns self, - un-INCREF-ed */ Py_INCREF(Py_None); return Py_None; --- 1156,1164 ---- wrap_init(PyObject *self, PyObject *args, void *wrapped) { ! initproc func = (initproc)wrapped; /* XXX What about keyword arguments? */ ! if (func(self, args, NULL) < 0) return NULL; Py_INCREF(Py_None); return Py_None; *************** *** 1243,1247 **** ADD(type->tp_descr_get, tab_descr_get); ADD(type->tp_descr_set, tab_descr_set); ! ADD(type->tp_construct, tab_init); return 0; --- 1258,1262 ---- ADD(type->tp_descr_get, tab_descr_get); ADD(type->tp_descr_set, tab_descr_set); ! ADD(type->tp_init, tab_init); return 0; *************** *** 1514,1519 **** } ! static PyObject * ! slot_tp_construct(PyObject *self, PyObject *args, PyObject *kwds) { PyObject *meth = PyObject_GetAttrString(self, "__init__"); --- 1529,1534 ---- } ! static int ! slot_tp_init(PyObject *self, PyObject *args, PyObject *kwds) { PyObject *meth = PyObject_GetAttrString(self, "__init__"); *************** *** 1521,1531 **** if (meth == NULL) ! return NULL; res = PyObject_Call(meth, args, kwds); Py_DECREF(meth); if (res == NULL) ! return NULL; Py_DECREF(res); ! return self; } --- 1536,1546 ---- if (meth == NULL) ! return -1; res = PyObject_Call(meth, args, kwds); Py_DECREF(meth); if (res == NULL) ! return -1; Py_DECREF(res); ! return 0; } *************** *** 1629,1632 **** TPSLOT(get, tp_descr_get); TPSLOT(set, tp_descr_set); ! TPSLOT(init, tp_construct); } --- 1644,1647 ---- TPSLOT(get, tp_descr_get); TPSLOT(set, tp_descr_set); ! TPSLOT(init, tp_init); } From gvanrossum@users.sourceforge.net Tue Jun 5 12:41:25 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 05 Jun 2001 04:41:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.26,2.16.8.27 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv30179/Objects Modified Files: Tag: descr-branch typeobject.c Log Message: Modernize type_init() -- it was still the old "constructor" code, returning NULL for errors instead -1. This was unfortunately masked by a cast. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.26 retrieving revision 2.16.8.27 diff -C2 -r2.16.8.26 -r2.16.8.27 *** typeobject.c 2001/06/05 10:49:24 2.16.8.26 --- typeobject.c 2001/06/05 11:41:23 2.16.8.27 *************** *** 147,155 **** /* TypeType's constructor is called when a type is subclassed */ ! static PyObject * ! type_init(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *name, *bases, *dict, *x, *slots; ! PyTypeObject *base; char *dummy = NULL; etype *et; --- 147,155 ---- /* TypeType's constructor is called when a type is subclassed */ ! static int ! type_init(PyObject *self, PyObject *args, PyObject *kwds) { PyObject *name, *bases, *dict, *x, *slots; ! PyTypeObject *type, *base; char *dummy = NULL; etype *et; *************** *** 157,178 **** int i, nslots, slotoffset, allocsize; /* Check arguments */ if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO", &dummy, &name, &bases, &dict)) ! return NULL; if (!PyTuple_Check(bases) || !PyDict_Check(dict)) { PyErr_SetString(PyExc_TypeError, "usage: TypeType(name, bases, dict) "); ! return NULL; } if (PyTuple_GET_SIZE(bases) > 1) { PyErr_SetString(PyExc_TypeError, "can't multiple-inherit from types"); ! return NULL; } if (PyTuple_GET_SIZE(bases) < 1) { PyErr_SetString(PyExc_TypeError, "can't create a new type without a base type"); ! return NULL; } base = (PyTypeObject *)PyTuple_GET_ITEM(bases, 0); --- 157,181 ---- int i, nslots, slotoffset, allocsize; + assert(PyType_Check(self)); + type = (PyTypeObject *)self; + /* Check arguments */ if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO", &dummy, &name, &bases, &dict)) ! return -1; if (!PyTuple_Check(bases) || !PyDict_Check(dict)) { PyErr_SetString(PyExc_TypeError, "usage: TypeType(name, bases, dict) "); ! return -1; } if (PyTuple_GET_SIZE(bases) > 1) { PyErr_SetString(PyExc_TypeError, "can't multiple-inherit from types"); ! return -1; } if (PyTuple_GET_SIZE(bases) < 1) { PyErr_SetString(PyExc_TypeError, "can't create a new type without a base type"); ! return -1; } base = (PyTypeObject *)PyTuple_GET_ITEM(bases, 0); *************** *** 180,189 **** PyErr_SetString(PyExc_TypeError, "base type must be a type"); ! return NULL; } if (base->tp_init == NULL) { PyErr_SetString(PyExc_TypeError, "base type must have a constructor slot"); ! return NULL; } --- 183,192 ---- PyErr_SetString(PyExc_TypeError, "base type must be a type"); ! return -1; } if (base->tp_init == NULL) { PyErr_SetString(PyExc_TypeError, "base type must have a constructor slot"); ! return -1; } *************** *** 198,202 **** slots = PySequence_Tuple(slots); if (slots == NULL) ! return NULL; nslots = PyTuple_GET_SIZE(slots); for (i = 0; i < nslots; i++) { --- 201,205 ---- slots = PySequence_Tuple(slots); if (slots == NULL) ! return -1; nslots = PyTuple_GET_SIZE(slots); for (i = 0; i < nslots; i++) { *************** *** 205,209 **** "__slots__ must be a sequence of strings"); Py_DECREF(slots); ! return NULL; } } --- 208,212 ---- "__slots__ must be a sequence of strings"); Py_DECREF(slots); ! return -1; } } *************** *** 214,239 **** nslots = 1; ! /* Allocate memory and construct a type object in it */ allocsize = sizeof(etype) + nslots*sizeof(struct memberlist); ! if (type == NULL) { ! et = PyObject_MALLOC(allocsize); ! if (et == NULL) ! return NULL; ! memset(et, '\0', allocsize); ! type = &et->type; ! PyObject_INIT(type, &PyType_Type); ! } ! else { ! if (type->ob_type->tp_basicsize < allocsize) { ! PyErr_Format( ! PyExc_SystemError, ! "insufficient allocated memory for subtype: " ! "allocated %d, needed %d", ! type->ob_type->tp_basicsize, ! allocsize); ! return NULL; ! } ! et = (etype *)type; } Py_INCREF(name); et->name = name; --- 217,232 ---- nslots = 1; ! /* Check allocation size and initialize the type object */ allocsize = sizeof(etype) + nslots*sizeof(struct memberlist); ! if (type->ob_type->tp_basicsize < allocsize) { ! PyErr_Format( ! PyExc_SystemError, ! "insufficient allocated memory for subtype: " ! "allocated %d, needed %d", ! type->ob_type->tp_basicsize, ! allocsize); ! return -1; } + et = (etype *)type; Py_INCREF(name); et->name = name; *************** *** 251,255 **** if (PyType_InitDict(type) < 0) { Py_DECREF(type); ! return NULL; } --- 244,248 ---- if (PyType_InitDict(type) < 0) { Py_DECREF(type); ! return -1; } *************** *** 293,301 **** if (x == NULL) { Py_DECREF(type); ! return NULL; } Py_DECREF(x); /* throw away None */ override_slots(type, dict); ! return (PyObject *)type; } --- 286,294 ---- if (x == NULL) { Py_DECREF(type); ! return -1; } Py_DECREF(x); /* throw away None */ override_slots(type, dict); ! return 0; } *************** *** 353,357 **** 0, /* tp_descr_set */ offsetof(PyTypeObject, tp_dict), /* tp_dictoffset */ ! (initproc)type_init, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ --- 346,350 ---- 0, /* tp_descr_set */ offsetof(PyTypeObject, tp_dict), /* tp_dictoffset */ ! type_init, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ From gvanrossum@users.sourceforge.net Tue Jun 5 13:45:48 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 05 Jun 2001 05:45:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects classobject.c,2.127.2.3,2.127.2.4 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv12535 Modified Files: Tag: descr-branch classobject.c Log Message: Make the class type callable, with a (name, bases, dict) signature. Had to change a few SystemError exceptions to TypeError. Index: classobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v retrieving revision 2.127.2.3 retrieving revision 2.127.2.4 diff -C2 -r2.127.2.3 -r2.127.2.4 *** classobject.c 2001/05/06 02:31:13 2.127.2.3 --- classobject.c 2001/06/05 12:45:46 2.127.2.4 *************** *** 37,46 **** } if (name == NULL || !PyString_Check(name)) { ! PyErr_SetString(PyExc_SystemError, "PyClass_New: name must be a string"); return NULL; } if (dict == NULL || !PyDict_Check(dict)) { ! PyErr_SetString(PyExc_SystemError, "PyClass_New: dict must be a dictionary"); return NULL; --- 37,46 ---- } if (name == NULL || !PyString_Check(name)) { ! PyErr_SetString(PyExc_TypeError, "PyClass_New: name must be a string"); return NULL; } if (dict == NULL || !PyDict_Check(dict)) { ! PyErr_SetString(PyExc_TypeError, "PyClass_New: dict must be a dictionary"); return NULL; *************** *** 68,72 **** int i; if (!PyTuple_Check(bases)) { ! PyErr_SetString(PyExc_SystemError, "PyClass_New: bases must be a tuple"); return NULL; --- 68,72 ---- int i; if (!PyTuple_Check(bases)) { ! PyErr_SetString(PyExc_TypeError, "PyClass_New: bases must be a tuple"); return NULL; *************** *** 75,79 **** while (--i >= 0) { if (!PyClass_Check(PyTuple_GetItem(bases, i))) { ! PyErr_SetString(PyExc_SystemError, "PyClass_New: base must be a class"); return NULL; --- 75,79 ---- while (--i >= 0) { if (!PyClass_Check(PyTuple_GetItem(bases, i))) { ! PyErr_SetString(PyExc_TypeError, "PyClass_New: base must be a class"); return NULL; *************** *** 107,110 **** --- 107,122 ---- } + static PyObject * + class_new(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + PyObject *name, *bases, *dict; + static char *kwlist[] = {"name", "bases", "dict", 0}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO", kwlist, + &name, &bases, &dict)) + return NULL; + return PyClass_New(bases, dict, name); + } + /* Class methods */ *************** *** 405,408 **** --- 417,436 ---- 0, /* tp_doc */ (traverseproc)class_traverse, /* 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 */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + class_new, /* tp_new */ }; From gvanrossum@users.sourceforge.net Tue Jun 5 13:48:13 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 05 Jun 2001 05:48:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.241.2.2,2.241.2.3 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv13364 Modified Files: Tag: descr-branch ceval.c Log Message: Greatly simplify build_class. It now always invokes the simplified "Don Beaudry hook": call the type of the first base. If there is no first base, default to PyClass_Type. New feature: if __metaclass__ is set in the dict, it overrides the metaclass choice. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.241.2.2 retrieving revision 2.241.2.3 diff -C2 -r2.241.2.2 -r2.241.2.3 *** ceval.c 2001/05/06 02:31:13 2.241.2.2 --- ceval.c 2001/06/05 12:48:11 2.241.2.3 *************** *** 3224,3270 **** build_class(PyObject *methods, PyObject *bases, PyObject *name) { ! int i, n; ! if (!PyTuple_Check(bases)) { ! PyErr_SetString(PyExc_SystemError, ! "build_class with non-tuple bases"); ! return NULL; } ! if (!PyDict_Check(methods)) { ! PyErr_SetString(PyExc_SystemError, ! "build_class with non-dictionary"); ! return NULL; ! } ! if (!PyString_Check(name)) { ! PyErr_SetString(PyExc_SystemError, ! "build_class with non-string name"); ! return NULL; ! } ! n = PyTuple_Size(bases); ! for (i = 0; i < n; i++) { ! PyObject *base = PyTuple_GET_ITEM(bases, i); ! if (!PyClass_Check(base)) { ! /* If the base is a type, call its base to clone it. ! This is a weaker form of the Don Beaudry hook ! that used to be here. It should be sufficient ! because types can now be subtyped. */ ! if (PyType_Check(base)) { ! PyObject *basetype = (PyObject *)base->ob_type; ! PyObject *args; ! PyObject *newclass = NULL; ! args = Py_BuildValue( ! "(OOO)", name, bases, methods); ! if (args != NULL) { ! newclass = PyEval_CallObject( ! basetype, args); ! Py_DECREF(args); ! } ! return newclass; ! } ! PyErr_SetString(PyExc_TypeError, ! "base is not a class object"); ! return NULL; ! } ! } ! return PyClass_New(bases, methods, name); } --- 3224,3240 ---- build_class(PyObject *methods, PyObject *bases, PyObject *name) { ! PyObject *metaclass = NULL; ! ! if (PyDict_Check(methods)) ! metaclass = PyDict_GetItemString(methods, "__metaclass__"); ! ! if (metaclass == NULL) { ! if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) ! metaclass = (PyObject *) ! PyTuple_GET_ITEM(bases, 0)->ob_type; ! else ! metaclass = (PyObject *) &PyClass_Type; } ! return PyObject_CallFunction(metaclass, "OOO", name, bases, methods); } From gvanrossum@users.sourceforge.net Tue Jun 5 16:30:41 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 05 Jun 2001 08:30:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.27,2.16.8.28 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv798 Modified Files: Tag: descr-branch typeobject.c Log Message: Allow creating subtypes without a base type (specifying an explicit __metaclass__). In this case, the base defaults to "object", whose C name has to be PyBaseObject_Type because PyObject_Type is an existing function. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.27 retrieving revision 2.16.8.28 diff -C2 -r2.16.8.27 -r2.16.8.28 *** typeobject.c 2001/06/05 11:41:23 2.16.8.27 --- typeobject.c 2001/06/05 15:30:39 2.16.8.28 *************** *** 58,62 **** if (type->tp_new == NULL) { PyErr_Format(PyExc_TypeError, ! "cannot construct '%.100s' instances", type->tp_name); return NULL; --- 58,62 ---- if (type->tp_new == NULL) { PyErr_Format(PyExc_TypeError, ! "cannot create '%.100s' instances", type->tp_name); return NULL; *************** *** 99,103 **** if (self == NULL) return NULL; ! if (type->tp_init(self, args, kwds) < 0) { Py_DECREF(self); return NULL; --- 99,103 ---- if (self == NULL) return NULL; ! if (type->tp_init != NULL && type->tp_init(self, args, kwds) < 0) { Py_DECREF(self); return NULL; *************** *** 112,124 **** { int dictoffset = self->ob_type->tp_dictoffset; ! PyTypeObject *base; destructor f; /* This exists so we can DECREF self->ob_type */ ! base = self->ob_type->tp_base; ! while ((f = base->tp_dealloc) == subtype_dealloc) base = base->tp_base; ! if (dictoffset && !base->tp_dictoffset) { PyObject **dictptr = (PyObject **) ((char *)self + dictoffset); PyObject *dict = *dictptr; --- 112,125 ---- { int dictoffset = self->ob_type->tp_dictoffset; ! PyTypeObject *type, *base; destructor f; /* This exists so we can DECREF self->ob_type */ ! type = self->ob_type; ! base = type->tp_base; ! while (base && (f = base->tp_dealloc) == subtype_dealloc) base = base->tp_base; ! if (dictoffset && (base == NULL || !base->tp_dictoffset)) { PyObject **dictptr = (PyObject **) ((char *)self + dictoffset); PyObject *dict = *dictptr; *************** *** 129,134 **** } f(self); ! if (self->ob_type->tp_flags & Py_TPFLAGS_HEAPTYPE) { ! Py_DECREF(self->ob_type); } } --- 130,136 ---- } f(self); ! /* Can't reference self beyond this point */ ! if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { ! Py_DECREF(type); } } *************** *** 146,150 **** } etype; ! /* TypeType's constructor is called when a type is subclassed */ static int type_init(PyObject *self, PyObject *args, PyObject *kwds) --- 148,152 ---- } etype; ! /* TypeType's initializer; called when a type is subclassed */ static int type_init(PyObject *self, PyObject *args, PyObject *kwds) *************** *** 152,156 **** PyObject *name, *bases, *dict, *x, *slots; PyTypeObject *type, *base; ! char *dummy = NULL; etype *et; struct memberlist *mp; --- 154,158 ---- PyObject *name, *bases, *dict, *x, *slots; PyTypeObject *type, *base; ! static char *kwlist[] = {"name", "bases", "dict", 0}; etype *et; struct memberlist *mp; *************** *** 161,165 **** /* Check arguments */ ! if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO", &dummy, &name, &bases, &dict)) return -1; --- 163,167 ---- /* Check arguments */ ! if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO", kwlist, &name, &bases, &dict)) return -1; *************** *** 170,192 **** } if (PyTuple_GET_SIZE(bases) > 1) { - PyErr_SetString(PyExc_TypeError, - "can't multiple-inherit from types"); - return -1; - } - if (PyTuple_GET_SIZE(bases) < 1) { - PyErr_SetString(PyExc_TypeError, - "can't create a new type without a base type"); - return -1; - } - base = (PyTypeObject *)PyTuple_GET_ITEM(bases, 0); - if (!PyType_Check((PyObject *)base)) { PyErr_SetString(PyExc_TypeError, ! "base type must be a type"); return -1; } ! if (base->tp_init == NULL) { ! PyErr_SetString(PyExc_TypeError, ! "base type must have a constructor slot"); ! return -1; } --- 172,193 ---- } if (PyTuple_GET_SIZE(bases) > 1) { PyErr_SetString(PyExc_TypeError, ! "can't multiple-inherit from types (yet)"); return -1; } ! if (PyTuple_GET_SIZE(bases) < 1) ! base = &PyBaseObject_Type; ! else { ! base = (PyTypeObject *)PyTuple_GET_ITEM(bases, 0); ! if (!PyType_Check((PyObject *)base)) { ! PyErr_SetString(PyExc_TypeError, ! "base type must be a type"); ! return -1; ! } ! if (base->tp_new == NULL) { ! PyErr_SetString(PyExc_TypeError, ! "base type must have a tp_new slot"); ! return -1; ! } } *************** *** 347,350 **** --- 348,402 ---- offsetof(PyTypeObject, tp_dict), /* tp_dictoffset */ type_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + }; + + + /* The base type of all types (eventually)... except itself. */ + + static void + object_dealloc(PyObject *self) + { + PyObject_Del(self); + } + + PyTypeObject PyBaseObject_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /* ob_size */ + "object", /* tp_name */ + sizeof(PyObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)object_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 */ + PyGeneric_GetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + "The most base type", /* 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 */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ From gvanrossum@users.sourceforge.net Tue Jun 5 16:35:39 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 05 Jun 2001 08:35:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.28,2.16.8.29 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv2102 Modified Files: Tag: descr-branch typeobject.c Log Message: subtype_dealloc() had a check for the case that base ends up NULL. Change this to an assertion, since this is now (again) an error. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.28 retrieving revision 2.16.8.29 diff -C2 -r2.16.8.28 -r2.16.8.29 *** typeobject.c 2001/06/05 15:30:39 2.16.8.28 --- typeobject.c 2001/06/05 15:35:37 2.16.8.29 *************** *** 119,125 **** type = self->ob_type; base = type->tp_base; ! while (base && (f = base->tp_dealloc) == subtype_dealloc) base = base->tp_base; ! if (dictoffset && (base == NULL || !base->tp_dictoffset)) { PyObject **dictptr = (PyObject **) ((char *)self + dictoffset); PyObject *dict = *dictptr; --- 119,127 ---- type = self->ob_type; base = type->tp_base; ! while ((f = base->tp_dealloc) == subtype_dealloc) { base = base->tp_base; ! assert(base); ! } ! if (dictoffset && !base->tp_dictoffset) { PyObject **dictptr = (PyObject **) ((char *)self + dictoffset); PyObject *dict = *dictptr; From bwarsaw@users.sourceforge.net Tue Jun 5 17:39:13 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 05 Jun 2001 09:39:13 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0006.txt,1.4,1.5 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv15535 Modified Files: pep-0006.txt Log Message: Updated Post-History: (long overdue). Index: pep-0006.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0006.txt,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** pep-0006.txt 2001/05/08 18:55:57 1.4 --- pep-0006.txt 2001/06/05 16:39:11 1.5 *************** *** 6,10 **** Type: Informational Created: 15-Mar-2001 ! Post-History: 15-Mar-2001 --- 6,10 ---- Type: Informational Created: 15-Mar-2001 ! Post-History: 15-Mar-2001 18-Apr-2001 From bwarsaw@users.sourceforge.net Tue Jun 5 17:42:30 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 05 Jun 2001 09:42:30 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0236.txt,1.6,1.7 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv16381 Modified Files: pep-0236.txt Log Message: This PEP is finished, so mark it as final. Index: pep-0236.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0236.txt,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -r1.6 -r1.7 *** pep-0236.txt 2001/03/25 05:54:08 1.6 --- pep-0236.txt 2001/06/05 16:42:27 1.7 *************** *** 4,8 **** Author: Tim Peters Python-Version: 2.1 ! Status: Active Type: Standards Track Created: 26-Feb-2001 --- 4,8 ---- Author: Tim Peters Python-Version: 2.1 ! Status: Final Type: Standards Track Created: 26-Feb-2001 *************** *** 355,358 **** --- 355,359 ---- existed in the standard distribution before the 2.1 release, and the double underscores make it a reserved name). + From bwarsaw@users.sourceforge.net Tue Jun 5 17:43:01 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 05 Jun 2001 09:43:01 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0000.txt,1.90,1.91 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv16584 Modified Files: pep-0000.txt Log Message: Mark PEP 236 as final. Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.90 retrieving revision 1.91 diff -C2 -r1.90 -r1.91 *** pep-0000.txt 2001/05/14 13:43:23 1.90 --- pep-0000.txt 2001/06/05 16:42:59 1.91 *************** *** 90,94 **** SF 232 pep-0232.txt Function Attributes Warsaw SF 235 pep-0235.txt Import on Case-Insensitive Platforms Peters ! S 236 pep-0236.txt Back to the __future__ Peters Empty PEPs (or containing only an abstract) --- 90,94 ---- SF 232 pep-0232.txt Function Attributes Warsaw SF 235 pep-0235.txt Import on Case-Insensitive Platforms Peters ! SF 236 pep-0236.txt Back to the __future__ Peters Empty PEPs (or containing only an abstract) *************** *** 157,161 **** S 234 pep-0234.txt Iterators Yee, van Rossum SF 235 pep-0235.txt Import on Case-Insensitive Platforms Peters ! S 236 pep-0236.txt Back to the __future__ Peters S 237 pep-0237.txt Unifying Long Integers and Integers Zadka S 238 pep-0238.txt Non-integer Division Zadka --- 157,161 ---- S 234 pep-0234.txt Iterators Yee, van Rossum SF 235 pep-0235.txt Import on Case-Insensitive Platforms Peters ! SF 236 pep-0236.txt Back to the __future__ Peters S 237 pep-0237.txt Unifying Long Integers and Integers Zadka S 238 pep-0238.txt Non-integer Division Zadka From bwarsaw@users.sourceforge.net Tue Jun 5 17:50:11 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 05 Jun 2001 09:50:11 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0211.txt,1.5,1.6 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv18171 Modified Files: pep-0211.txt Log Message: Long overdue update from Greg Wilson 22-Apr-2001 Index: pep-0211.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0211.txt,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** pep-0211.txt 2000/11/27 05:41:46 1.5 --- pep-0211.txt 2001/06/05 16:50:09 1.6 *************** *** 1,6 **** PEP: 211 ! Title: Adding New Linear Algebra Operators to Python Version: $Revision$ ! Author: gvwilson@nevex.com (Greg Wilson) Status: Draft Type: Standards Track --- 1,6 ---- PEP: 211 ! Title: Adding A New Outer Product Operator Version: $Revision$ ! Author: gvwilson@ddj.com (Greg Wilson) Status: Draft Type: Standards Track *************** *** 12,65 **** Introduction ! This PEP describes a conservative proposal to add linear algebra ! operators to Python 2.0. It discusses why such operators are ! desirable, and why a minimalist approach should be adopted at this ! point. This PEP summarizes discussions held in mailing list ! forums, and provides URLs for further information, where ! appropriate. The CVS revision history of this file contains the ! definitive historical record. ! ! ! Summary ! ! Add a single new infix binary operator '@' ("across"), and ! corresponding special methods "__across__()", "__racross__()", and ! "__iacross__()". This operator will perform mathematical matrix ! multiplication on NumPy arrays, and generate cross-products when ! applied to built-in sequence types. No existing operator ! definitions will be changed. Background ! The first high-level programming language, Fortran, was invented ! to do arithmetic. While this is now just a small part of ! computing, there are still many programmers who need to express ! complex mathematical operations in code. ! ! The most influential of Fortran's successors was APL [1]. Its ! author, Kenneth Iverson, designed the language as a notation for ! expressing matrix algebra, and received the 1980 Turing Award for ! his work. ! ! APL's operators supported both familiar algebraic operations, such ! as vector dot product and matrix multiplication, and a wide range ! of structural operations, such as stitching vectors together to ! create arrays. Even by programming's standards, APL is ! exceptionally cryptic: many of its symbols did not exist on ! standard keyboards, and expressions have to be read right to left. ! ! Most subsequent work numerical languages, such as Fortran-90, ! MATLAB, and Mathematica, have tried to provide the power of APL ! without the obscurity. Python's NumPy [2] has most of the ! features that users of such languages expect, but these are ! provided through named functions and methods, rather than ! overloaded operators. This makes NumPy clumsier than most ! alternatives. ! ! The author of this PEP therefore consulted the developers of GNU ! Octave [3], an open source clone of MATLAB. When asked how ! important it was to have infix operators for matrix solution, ! Prof. James Rawlings replied [4]: I DON'T think it's a must have, and I do a lot of matrix --- 12,62 ---- Introduction ! This PEP describes a proposal to define "@" (pronounced "across") ! as a new outer product operator in Python 2.2. When applied to ! sequences (or other iterable objects), this operator will combine ! their iterators, so that: ! ! for (i, j) in S @ T: ! pass ! ! will be equivalent to: ! ! for i in S: ! for j in T: ! pass ! ! Classes will be able to overload this operator using the special ! methods "__across__", "__racross__", and "__iacross__". In ! particular, the new Numeric module (PEP 0209) will overload this ! operator for multi-dimensional arrays to implement matrix ! multiplication. Background ! Number-crunching is now just a small part of computing, but many ! programmers --- including many Python users --- still need to ! express complex mathematical operations in code. Most numerical ! languages, such as APL, Fortran-90, MATLAB, IDL, and Mathematica, ! therefore provide two forms of the common arithmetic operators. ! One form works element-by-element, e.g. multiplies corresponding ! elements of its matrix arguments. The other implements the ! "mathematical" definition of that operation, e.g. performs ! row-column matrix multiplication. ! ! Zhu and Lielens have proposed doubling up Python's operators in ! this way [1]. Their proposal would create six new binary infix ! operators, and six new in-place operators. ! ! The original version of this proposal was much more conservative. ! The author consulted the developers of GNU Octave [2], an open ! source clone of MATLAB. Its developers agreed that providing an ! infix operator for matrix multiplication was important: numerical ! programmers really do care whether they have to write "mmul(A,B)" ! instead of "A op B". ! ! On the other hand, when asked how important it was to have infix ! operators for matrix solution and other operations, Prof. James ! Rawlings replied [3]: I DON'T think it's a must have, and I do a lot of matrix *************** *** 67,323 **** write inv(A)*b instead. I recommend dropping \. ! Rawlings' feedback on other operators was similar. It is worth ! noting in this context that notations such as "/" and "\" for ! matrix solution were invented by programmers, not mathematicians, ! and have not been adopted by the latter. - Based on this discussion, and feedback from classes at the US - national laboratories and elsewhere, we recommend only adding a - matrix multiplication operator to Python at this time. If there - is significant user demand for syntactic support for other - operations, these can be added in a later release. ! Requirements ! The most important requirement is minimal impact on existing ! Python programs and users: the proposal must not break existing ! code (except possibly NumPy). ! The second most important requirement is the ability to handle all ! common cases cleanly and clearly. There are nine such cases: ! |5 6| * 9 = |45 54| MS: matrix-scalar multiplication ! |7 8| |63 72| ! 9 * |5 6| = |45 54| SM: scalar-matrix multiplication ! |7 8| |63 72| ! |2 3| * |4 5| = |8 15| VE: vector elementwise multiplication ! |2 3| * |4| = 23 VD: vector dot product ! |5| ! |2| * |4 5| = | 8 10| VO: vector outer product ! |3| |12 15| ! |1 2| * |5 6| = | 5 12| ME: matrix elementwise multiplication ! |3 4| |7 8| |21 32| ! |1 2| * |5 6| = |19 22| MM: mathematical matrix multiplication ! |3 4| |7 8| |43 50| ! |1 2| * |5 6| = |19 22| VM: vector-matrix multiplication ! |7 8| ! |5 6| * |1| = |17| MV: matrix-vector multiplication ! |7 8| |2| |23| ! Note that 1-dimensional vectors are treated as rows in VM, as ! columns in MV, and as both in VD and VO. Both are special cases ! of 2-dimensional matrices (Nx1 and 1xN respectively). We will ! therefore define the new operator only for 2-dimensional arrays, ! and provide an easy (and efficient) way for users to treat ! 1-dimensional structures as 2-dimensional. ! Third, we must avoid confusion between Python's notation and those ! of MATLAB and Fortran-90. In particular, mathematical matrix ! multiplication (case MM) should not be represented as '.*', since: ! (a) MATLAB uses prefix-'.' forms to mean 'elementwise', and raw ! forms to mean "mathematical"; and ! (b) even if the Python parser can be taught how to handle dotted ! forms, '1.*A' will still be visually ambiguous. - Proposal - The meanings of all existing operators will be unchanged. In - particular, 'A*B' will continue to be interpreted elementwise. - This takes care of the cases MS, SM, VE, and ME, and ensures - minimal impact on existing programs. - - A new operator '@' (pronounced "across") will be added to Python, - along with special methods "__across__()", "__racross__()", and - "__iacross__()", with the usual semantics. (We recommend using - "@", rather than the times-like "><", because of the ease with - which the latter could be mis-typed as inequality "<>".) - - No new operators will be defined to mean "solve a set of linear - equations", or "invert a matrix". - - (Optional) When applied to sequences, the "@" operator will return - a tuple of tuples containing the cross-product of their elements - in left-to-right order: - - >>> [1, 2] @ (3, 4) - ((1, 3), (1, 4), (2, 3), (2, 4)) - - >>> [1, 2] @ (3, 4) @ (5, 6) - ((1, 3, 5), (1, 3, 6), - (1, 4, 5), (1, 4, 6), - (2, 3, 5), (2, 3, 6), - (2, 4, 5), (2, 4, 6)) - - This will require the same kind of special support from the parser - as chained comparisons (such as "a>> for (i, j) in [1, 2] @ [3, 4]: - >>> print i, j - 1 3 - 1 4 - 2 3 - 2 4 - - as a short-hand for the common nested loop idiom: - - >>> for i in [1, 2]: - >>> for j in [3, 4]: - >>> print i, j - - Response to the 'lockstep loop' questionnaire [5] indicated that - newcomers would be comfortable with this (so comfortable, in fact, - that most of them interpreted most multi-loop 'zip' syntaxes [6] - as implementing single-stage nesting). - - Alternatives - - 01. Don't add new operators. - - Python is not primarily a numerical language; it may not be worth - complexifying it for this special case. NumPy's success is proof - that users can and will use functions and methods for linear - algebra. However, support for real matrix multiplication is - frequently requested, as: - - * functional forms are cumbersome for lengthy formulas, and do not - respect the operator precedence rules of conventional mathematics; - and - - * method forms are asymmetric in their operands. - - What's more, the proposed semantics for "@" for built-in sequence - types would simplify expression of a very common idiom (nested - loops). User testing during discussion of 'lockstep loops' - indicated that both new and experienced users would understand - this immediately. - - 02. Introduce prefixed forms of all existing operators, such as - "~*" and "~+", as proposed in PEP 0225 [7]. - - This proposal would duplicate all built-in mathematical operators - with matrix equivalents, as in numerical languages such as - MATLAB. Our objections to this are: - - * Python is not primarily a numerical programming language. While - the (self-selected) participants in the discussions that led to - PEP 0225 may want all of these new operators, the majority of - Python users would be indifferent. The extra complexity they - would introduce into the language therefore does not seem - merited. (See also Rawlings' comments, quoted in the Background - section, about these operators not being essential.) - - * The proposed syntax is difficult to read (i.e. passes the "low - toner" readability test). - - 03. Retain the existing meaning of all operators, but create a - behavioral accessor for arrays, such that: ! A * B ! is elementwise multiplication (ME), but: ! A.m() * B.m() ! is mathematical multiplication (MM). The method "A.m()" would ! return an object that aliased A's memory (for efficiency), but ! which had a different implementation of __mul__(). ! ! This proposal was made by Moshe Zadka, and is also considered by ! PEP 0225 [7]. Its advantage is that it has no effect on the ! existing implementation of Python: changes are localized in the ! Numeric module. The disadvantages are ! ! * The semantics of "A.m() * B", "A + B.m()", and so on would have ! to be defined, and there is no "obvious" choice for them. ! ! * Aliasing objects to trigger different operator behavior feels ! less Pythonic than either calling methods (as in the existing ! Numeric module) or using a different operator. This PEP is ! primarily about look and feel, and about making Python more ! attractive to people who are not already using it. ! ! ! Related Proposals ! ! 0207 : Rich Comparisons ! ! It may become possible to overload comparison operators ! such as '<' so that an expression such as 'A < B' returns ! an array, rather than a scalar value. ! ! 0209 : Adding Multidimensional Arrays ! ! Multidimensional arrays are currently an extension to ! Python, rather than a built-in type. ! ! 0225 : Elementwise/Objectwise Operators ! ! A larger proposal that addresses the same subject, but ! which proposes many more additions to the language. Acknowledgments ! I am grateful to Huaiyu Zhu [8] for initiating this discussion, ! and for some of the ideas and terminology included below. References - - [1] http://www.acm.org/sigapl/whyapl.htm - [2] http://numpy.sourceforge.net - [3] http://bevo.che.wisc.edu/octave/ - [4] http://www.egroups.com/message/python-numeric/4 - [5] http://www.python.org/pipermail/python-dev/2000-July/013139.html - [6] PEP-0201.txt "Lockstep Iteration" - [7] http://www.python.org/pipermail/python-list/2000-August/112529.html - - - Appendix: NumPy - - NumPy will overload "@" to perform mathematical multiplication of - arrays where shapes permit, and to throw an exception otherwise. - Its implementation of "@" will treat built-in sequence types as if - they were column vectors. This takes care of the cases MM and MV. - - An attribute "T" will be added to the NumPy array type, such that - "m.T" is: - - (a) the transpose of "m" for a 2-dimensional array - - (b) the 1xN matrix transpose of "m" if "m" is a 1-dimensional - array; or - - (c) a runtime error for an array with rank >= 3. - - This attribute will alias the memory of the base object. NumPy's - "transpose()" function will be extended to turn built-in sequence - types into row vectors. This takes care of the VM, VD, and VO - cases. We propose an attribute because: - - (a) the resulting notation is similar to the 'superscript T' (at - least, as similar as ASCII allows), and - - (b) it signals that the transposition aliases the original object. ! NumPy will define a value "inv", which will be recognized by the ! exponentiation operator, such that "A ** inv" is the inverse of ! "A". This is similar in spirit to NumPy's existing "newaxis" ! value. --- 64,181 ---- write inv(A)*b instead. I recommend dropping \. ! Based on this discussion, and feedback from students at the US ! national laboratories and elsewhere, we recommended adding only ! one new operator, for matrix multiplication, to Python. + Iterators ! The planned addition of iterators to Python 2.2 opens up a broader ! scope for this proposal. As part of the discussion of PEP 0201 ! "Lockstep Iteration" [4], the author of this proposal conducted an ! informal usability experiment [5]. The results showed that users ! are psychologically receptive to "cross-product" loop syntax. For ! example, most users expected: ! S = [10, 20, 30] ! T = [1, 2, 3] ! for x in S; y in T: ! print x+y, ! to print "11 12 13 21 22 23 31 32 33". We believe that users will ! have the same reaction to: ! for (x, y) in S @ T: ! print x+y ! i.e. that they will naturally interpret this as a tidy way to ! write loop nests. ! This is where iterators come in. Actually constructing the ! cross-product of two (or more) sequences before executing the loop ! would be very expensive. On the other hand, "@" could be defined ! to get its arguments' iterators, and then create an outer iterator ! which returns tuples of the values returned by the inner ! iterators. ! Discussion ! 1. Adding a named function "across" would have less impact on ! Python than a new infix operator. However, this would not make ! Python more appealing to numerical programmers, who really do ! care whether they can write matrix multiplication using an ! operator, or whether they have to write it as a function call. ! 2. "@" would have be chainable in the same way as comparison ! operators, i.e.: ! (1, 2) @ (3, 4) @ (5, 6) ! would have to return (1, 3, 5) ... (2, 4, 6), and *not* ! ((1, 3), 5) ... ((2, 4), 6). This should not require special ! support from the parser, as the outer iterator created by the ! first "@" could easily be taught how to combine itself with ! ordinary iterators. ! 3. There would have to be some way to distinguish restartable ! iterators from ones that couldn't be restarted. For example, ! if S is an input stream (e.g. a file), and L is a list, then "S ! @ L" is straightforward, but "L @ S" is not, since iteration ! through the stream cannot be repeated. This could be treated ! as an error, or by having the outer iterator detect ! non-restartable inner iterators and cache their values. ! 4. Whiteboard testing of this proposal in front of three novice ! Python users (all of them experienced programmers) indicates ! that users will expect: ! "ab" @ "cd" ! to return four strings, not four tuples of pairs of ! characters. Opinion was divided on what: ! ("a", "b") @ "cd" + ought to return... Alternatives ! 1. Do nothing --- keep Python simple. ! This is always the default choice. ! 2. Add a named function instead of an operator. ! Python is not primarily a numerical language; it may not be worth ! complexifying it for this special case. However, support for real ! matrix multiplication *is* frequently requested, and the proposed ! semantics for "@" for built-in sequence types would simplify ! expression of a very common idiom (nested loops). ! ! 3. Introduce prefixed forms of all existing operators, such as ! "~*" and "~+", as proposed in PEP 0225 [1]. ! ! Our objections to this are that there isn't enough demand to ! justify the additional complexity (see Rawlings' comments [3]), ! and that the proposed syntax fails the "low toner" readability ! test. Acknowledgments ! I am grateful to Huaiyu Zhu for initiating this discussion, and to ! James Rawlings and students in various Python courses for their ! discussions of what numerical programmers really care about. References ! [1] http://python.sourceforge.net/peps/pep-0225.html ! [2] http://bevo.che.wisc.edu/octave/ ! [3] http://www.egroups.com/message/python-numeric/4 ! [4] http://python.sourceforge.net/peps/pep-0201.html ! [5] http://mail.python.org/pipermail/python-dev/2000-July/006427.html From bwarsaw@users.sourceforge.net Tue Jun 5 17:51:10 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 05 Jun 2001 09:51:10 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0000.txt,1.91,1.92 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv18335 Modified Files: pep-0000.txt Log Message: PEP 211 update from Greg Wilson, includes a name change, and a change to Greg's email address. Also, I moved the PEP to "Active for 2.2" and un-deferred it. Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.91 retrieving revision 1.92 diff -C2 -r1.91 -r1.92 *** pep-0000.txt 2001/06/05 16:42:59 1.91 --- pep-0000.txt 2001/06/05 16:51:08 1.92 *************** *** 39,42 **** --- 39,43 ---- I 42 pep-0042.txt Small Feature Requests Hylton + S 211 pep-0211.txt Adding A New Outer Product Operator Wilson S 234 pep-0234.txt Iterators Yee, van Rossum S 237 pep-0237.txt Unifying Long Integers and Integers Zadka *************** *** 59,63 **** I 206 pep-0206.txt 2.0 Batteries Included Zadka S 209 pep-0209.txt Adding Multidimensional Arrays Barrett, Oliphant - SD 211 pep-0211.txt Adding New Linear Algebra Operators Wilson SD 212 pep-0212.txt Loop Counter Iteration Schneider-Kamp SD 213 pep-0213.txt Attribute Access Handlers Prescod --- 60,63 ---- *************** *** 132,136 **** S 209 pep-0209.txt Adding Multidimensional Arrays Barrett, Oliphant SD 210 pep-0210.txt Decoupling the Interpreter Loop Ascher ! SD 211 pep-0211.txt Adding New Linear Algebra Operators Wilson SD 212 pep-0212.txt Loop Counter Iteration Schneider-Kamp SD 213 pep-0213.txt Attribute Access Handlers Prescod --- 132,136 ---- S 209 pep-0209.txt Adding Multidimensional Arrays Barrett, Oliphant SD 210 pep-0210.txt Decoupling the Interpreter Loop Ascher ! SD 211 pep-0211.txt Adding A New Outer Product Operator Wilson SD 212 pep-0212.txt Loop Counter Iteration Schneider-Kamp SD 213 pep-0213.txt Attribute Access Handlers Prescod *************** *** 214,218 **** Schneider-Kamp, Peter nowonder@nowonder.de Warsaw, Barry barry@digicool.com ! Wilson, Greg gvwilson@nevex.com Wouters, Thomas thomas@xs4all.net Yee, Ka-Ping ping@lfw.org --- 214,218 ---- Schneider-Kamp, Peter nowonder@nowonder.de Warsaw, Barry barry@digicool.com ! Wilson, Greg gvwilson@ddj.com Wouters, Thomas thomas@xs4all.net Yee, Ka-Ping ping@lfw.org From bwarsaw@users.sourceforge.net Tue Jun 5 17:57:07 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 05 Jun 2001 09:57:07 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0000.txt,1.92,1.93 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv19458 Modified Files: pep-0000.txt Log Message: Move PEP 218 from py-in-the-sky to active-for-2.2 Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.92 retrieving revision 1.93 diff -C2 -r1.92 -r1.93 *** pep-0000.txt 2001/06/05 16:51:08 1.92 --- pep-0000.txt 2001/06/05 16:57:05 1.93 *************** *** 40,43 **** --- 40,44 ---- I 42 pep-0042.txt Small Feature Requests Hylton S 211 pep-0211.txt Adding A New Outer Product Operator Wilson + S 218 pep-0218.txt Adding a Built-In Set Object Type Wilson S 234 pep-0234.txt Iterators Yee, van Rossum S 237 pep-0237.txt Unifying Long Integers and Integers Zadka *************** *** 64,68 **** S 215 pep-0215.txt String Interpolation Yee I 216 pep-0216.txt Docstring Format Zadka - SD 218 pep-0218.txt Adding a Built-In Set Object Type Wilson SD 219 pep-0219.txt Stackless Python McMillan S 222 pep-0222.txt Web Library Enhancements Kuchling --- 65,68 ---- From bwarsaw@users.sourceforge.net Tue Jun 5 18:01:57 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 05 Jun 2001 10:01:57 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0250.txt,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv20523 Modified Files: pep-0250.txt Log Message: Paul Moore's latest update Index: pep-0250.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0250.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** pep-0250.txt 2001/04/18 10:28:11 1.1 --- pep-0250.txt 2001/06/05 17:01:55 1.2 *************** *** 7,11 **** Created: 2001-03-30 Python-Version: 2.2 ! Post-History: --- 7,11 ---- Created: 2001-03-30 Python-Version: 2.2 ! Post-History: 30-Mar-2001 *************** *** 70,74 **** else: ! sitedirs == [makepath(prefix, "lib", "site-packages")] Changes would also be required to distutils, in the sysconfig.py --- 70,74 ---- else: ! sitedirs == [prefix, makepath(prefix, "lib", "site-packages")] Changes would also be required to distutils, in the sysconfig.py *************** *** 80,96 **** Notes ! 1. It would be better if this change could be included in Python ! 2.1, as changing something of this nature is better done ! sooner, rather than later, to reduce the backward-compatibility ! burden. This is extremely unlikely to happen at this late stage ! in the release cycle, however. ! ! 2. This change does not preclude packages using the current ! location -- the change only adds a directory to sys.path, it ! does not remove anything. ! ! 3. In the Windows distribution of Python 2.1 (beta 1), the ! Lib\site-packages directory has been removed. It would need to ! be reinstated. --- 80,119 ---- Notes ! - This change does not preclude packages using the current ! location -- the change only adds a directory to sys.path, it ! does not remove anything. ! ! - Both the current location (sys.prefix) and the new directory ! (site-packages) are included in sitedirs, so that .pth files ! will be recognized in either location. ! ! - This proposal adds a single additional site-packages directory ! to sitedirs. On Unix platforms, two directories are added, one ! for version-independent files (Python code) and one for ! version-dependent code (C extensions). This is necessary on ! Unix, as the sitedirs include a common (across Python versions) ! package location, in /usr/local by default. As there is no such ! common location available on Windows, there is also no need for ! having two separate package directories. ! ! - If users want to keep DLLs in a single location on Windows, ! rather than keeping them in the package directory, the DLLs ! subdirectory of the Python install directory is available for ! that purpose. Adding an extra directory solely for DLLs should ! not be necessary. ! ! ! Open Issues ! ! - There have been no comments on this proposal from non-Windows ! users. In the absence of such comments, it is assumed that there ! will be no adverse effects on such platforms caused by the ! proposed change. (The author knows of no reason why there should ! be). ! ! - There could be issues with applications which embed Python. To ! the author's knowledge, there should be no problem as a result ! of this change. Again, there have been no comments (supportive ! or otherwise) from users who embed Python. From bwarsaw@users.sourceforge.net Tue Jun 5 18:11:32 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 05 Jun 2001 10:11:32 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0255.txt,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv22547 Added Files: pep-0255.txt Log Message: Magnus Lie Hetland's first version of this pep. --- NEW FILE: pep-0255.txt --- PEP: 255 Title: Simple Generators Version: $Revision: 1.1 $ Author: nas@python.ca (Neil Schemenauer), tim.one@home.com (Tim Peters), magnus@hetland.org (Magnus Lie Hetland) Discussion-To: python-iterators@lists.sourceforge.net Status: Draft Type: Standards Track Requires: 234 Created: 18-May-2001 Python-Version: 2.2 Post-History: Abstract This PEP introduces the concept of generators to Python, as well as a new statement used in conjunction with them, the "yield" statement. Motivation When a producer function has a hard enough job that it requires maintaining state between values produced, most programming languages offer no pleasant and efficient solution beyond adding a callback function to the producer's argument list, to be called with each value produced. For example, tokenize.py in the standard library takes this approach: the caller must pass a "tokeneater" function to tokenize(), called whenever tokenize() finds the next token. This allows tokenize to be coded in a natural way, but programs calling tokenize are typically convoluted by the need to remember between callbacks which token(s) were seen last. The tokeneater function in tabnanny.py is a good example of that, maintaining a state machine in global variables, to remember across callbacks what it has already seen and what it hopes to see next. This was difficult to get working correctly, and is still difficult for people to understand. Unfortunately, that's typical of this approach. An alternative would have been for tokenize to produce an entire parse of the Python program at once, in a large list. Then tokenize clients could be written in a natural way, using local variables and local control flow (such as loops and nested if statements) to keep track of their state. But this isn't practical: programs can be very large, so no a priori bound can be placed on the memory needed to materialize the whole parse; and some tokenize clients only want to see whether something specific appears early in the program (e.g., a future statement, or, as is done in IDLE, just the first indented statement), and then parsing the whole program first is a severe waste of time. Another alternative would be to make tokenize an iterator[1], delivering the next token whenever its .next() method is invoked. This is pleasant for the caller in the same way a large list of results would be, but without the memory and "what if I want to get out early?" drawbacks. However, this shifts the burden on tokenize to remember *its* state between .next() invocations, and the reader need only glance at tokenize.tokenize_loop() to realize what a horrid chore that would be. Or picture a recursive algorithm for producing the nodes of a general tree structure: to cast that into an iterator framework requires removing the recursion manually and maintaining the state of the traversal by hand. A fourth option is to run the producer and consumer in separate threads. This allows both to maintain their states in natural ways, and so is pleasant for both. Indeed, Demo/threads/Generator.py in the Python source distribution provides a usable synchronized-communication class for doing that in a general way. This doesn't work on platforms without threads, though, and is very slow on platforms that do (compared to what is achievable without threads). A final option is to use the Stackless[2][3] variant implementation of Python instead, which supports lightweight coroutines. This has much the same programmatic benefits as the thread option, but is much more efficient. However, Stackless is a radical and controversial rethinking of the Python core, and it may not be possible for Jython to implement the same semantics. This PEP isn't the place to debate that, so suffice it to say here that generators provide a useful subset of Stackless functionality in a way that fits easily into the current Python implementation. That exhausts the current alternatives. Some other high-level languages provide pleasant solutions, notably iterators in Sather[4], which were inspired by iterators in CLU; and generators in Icon[5], a novel language where every expression "is a generator". There are differences among these, but the basic idea is the same: provide a kind of function that can return an intermediate result ("the next value") to its caller, but maintaining the function's local state so that the function can be resumed again right where it left off. A very simple example: def fib(): a, b = 0, 1 while 1: yield b a, b = b, a+b When fib() is first invoked, it sets a to 0 and b to 1, then yields b back to its caller. The caller sees 1. When fib is resumed, from its point of view the yield statement is really the same as, say, a print statement: fib continues after the yield with all local state intact. a and b then become 1 and 1, and fib loops back to the yield, yielding 1 to its invoker. And so on. From fib's point of view it's just delivering a sequence of results, as if via callback. But from its caller's point of view, the fib invocation is an iterable object that can be resumed at will. As in the thread approach, this allows both sides to be coded in the most natural ways; but unlike the thread approach, this can be done efficiently and on all platforms. Indeed, resuming a generator should be no more expensive than a function call. The same kind of approach applies to many producer/consumer functions. For example, tokenize.py could yield the next token instead of invoking a callback function with it as argument, and tokenize clients could iterate over the tokens in a natural way: a Python generator is a kind of Python iterator[1], but of an especially powerful kind. Specification A new statement, the "yield" statement, is introduced: yield_stmt: "yield" [expression_list] This statement may only be used inside functions. A function which contains a yield statement is a so-called "generator function". A generator function may not contain return statements of the form: "return" expression_list It may, however, contain return statements of the form: "return" When a generator function is called, an iterator[6] is returned. Each time the .next() method of this iterator is called, the code in the body of the generator function is executed until a yield statement or a return statement is encountered, or until the end of the body is reached. If a yield statement is encountered during this execution, the state of the function is frozen, and a value is returned to the object calling .next(). If an empty yield statement was encountered, None is returned; otherwise, the given expression(s) is (are) returned. If an empty return statement is encountered, nothing is returned; however, a StopIteration exception is raised, signalling that the iterator is exhausted. An example of how generators may be used is given below: # A binary tree class class Tree: def __init__(self, label, left=None, right=None): self.label = label self.left = left self.right = right def __repr__(self, level=0, indent=" "): s = level*indent + `self.label` if self.left: s = s + "\n" + self.left.__repr__(level+1, indent) if self.right: s = s + "\n" + self.right.__repr__(level+1, indent) return s def __iter__(self): return inorder(self) # A function that creates a tree from a list def tree(list): if not len(list): return [] i = len(list)/2 return Tree(list[i], tree(list[:i]), tree(list[i+1:])) # A recursive generator that generates the tree leaves in in-order def inorder(t): if t: for x in inorder(t.left): yield x yield t.label for x in inorder(t.right): yield x # Show it off: create a tree t = tree("ABCDEFGHIJKLMNOPQRSTUVWXYZ") # Print the nodes of the tree in in-order for x in t: print x, print # A non-recursive generator. def inorder(node): stack = [] while node: while node.left: stack.append(node) node = node.left yield node.label while not node.right: try: node = stack.pop() except IndexError: return yield node.label node = node.right # Exercise the non-recursive generator for x in t: print x, print Reference Implementation A preliminary patch against the CVS Python source is available[7]. Footnotes and References [1] PEP 234, http://python.sourceforge.net/peps/pep-0234.html [2] http://www.stackless.com/ [3] PEP 219, http://python.sourceforge.net/peps/pep-0219.html [4] "Iteration Abstraction in Sather" Murer , Omohundro, Stoutamire and Szyperski http://www.icsi.berkeley.edu/~sather/Publications/toplas.html [5] http://www.cs.arizona.edu/icon/ [6] The concept of iterators is described in PEP 234 http://python.sourceforge.net/peps/pep-0234.html [7] http://python.ca/nas/python/generator.diff Copyright This document has been placed in the public domain. Local Variables: mode: indented-text indent-tabs-mode: nil End: From bwarsaw@users.sourceforge.net Tue Jun 5 18:11:52 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 05 Jun 2001 10:11:52 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0000.txt,1.93,1.94 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv22624 Modified Files: pep-0000.txt Log Message: Added pep 255, Simple Generators Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.93 retrieving revision 1.94 diff -C2 -r1.93 -r1.94 *** pep-0000.txt 2001/06/05 16:57:05 1.93 --- pep-0000.txt 2001/06/05 17:11:50 1.94 *************** *** 56,59 **** --- 56,61 ---- S 252 pep-0252.txt Making Types Look More Like Classes van Rossum S 253 pep-0253.txt Subtyping Built-in Types van Rossum + S 254 pep-0254.txt Making Classes Look More Like Types van Rossum + S 255 pep-0255.txt Simple Generators Schemenauer, et al Py-in-the-sky PEPs (not ready; may become active yet) *************** *** 175,178 **** --- 177,182 ---- S 252 pep-0252.txt Making Types Look More Like Classes van Rossum S 253 pep-0253.txt Subtyping Built-in Types van Rossum + S 254 pep-0254.txt Making Classes Look More Like Types van Rossum + S 255 pep-0255.txt Simple Generators Schemenauer, et al From bwarsaw@users.sourceforge.net Tue Jun 5 18:21:21 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 05 Jun 2001 10:21:21 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep2html.py,1.24,1.25 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv24183 Modified Files: pep2html.py Log Message: fixanchor(): Use a module global RFCURL template for RFC urls. Change this template to point at the nice faqs.org html-ified RFCs. Index: pep2html.py =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep2html.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -r1.24 -r1.25 *** pep2html.py 2001/05/01 17:53:52 1.24 --- pep2html.py 2001/06/05 17:21:19 1.25 *************** *** 35,38 **** --- 35,39 ---- PROGRAM = sys.argv[0] + RFCURL = 'http://www.faqs.org/rfcs/rfc%d.html' *************** *** 72,76 **** elif text[:3] == 'RFC': rfcnum = int(match.group('rfcnum'), 10) ! link = 'http://www.rfc-editor.org/rfc/rfc%04d.txt' % rfcnum if link: return "%s" % (link, cgi.escape(text)) --- 73,77 ---- elif text[:3] == 'RFC': rfcnum = int(match.group('rfcnum'), 10) ! link = RFCURL % rfcnum if link: return "%s" % (link, cgi.escape(text)) From gvanrossum@users.sourceforge.net Tue Jun 5 20:31:58 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 05 Jun 2001 12:31:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.29,2.16.8.30 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv18671/Objects Modified Files: Tag: descr-branch typeobject.c Log Message: Add type_new(), a slot for tp_new of PyType_Type that chooses the most derived metatype amongst the available metatypes (the explicit __metatype__ variable or the types of the provided bases). This will raise a mysterious type error ("metaclass conflict among bases") if there is no available metatype that derives from all others. Note that there always is at most one uniqe solution (since the "derives from" graph has no cycles). Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.29 retrieving revision 2.16.8.30 diff -C2 -r2.16.8.29 -r2.16.8.30 *** typeobject.c 2001/06/05 15:35:37 2.16.8.29 --- typeobject.c 2001/06/05 19:31:56 2.16.8.30 *************** *** 296,299 **** --- 296,345 ---- } + static int + issubtype(PyTypeObject *a, PyTypeObject *b) + { + while (a != b) { + a = a->tp_base; + if (a == NULL) + return 0; + } + return 1; + } + + #define ISSUBTYPE(a, b) issubtype(a, b) + + static PyObject * + type_new(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + PyObject *name, *bases, *dict; + static char *kwlist[] = {"name", "bases", "dict", 0}; + + /* Check arguments (again?!?! yes, alas -- we need the bases!) */ + if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO", kwlist, + &name, &bases, &dict)) + return NULL; + if (PyTuple_Check(bases)) { + PyTypeObject *metatype = type; + int i, n; + n = PyTuple_GET_SIZE(bases); + for (i = 0; i < n; i++) { + PyObject *base_i = PyTuple_GET_ITEM(bases, i); + PyTypeObject *type_i = base_i->ob_type; + if (ISSUBTYPE(metatype, type_i)) + continue; + if (ISSUBTYPE(type_i, metatype)) { + metatype = type_i; + continue; + } + PyErr_SetString(PyExc_TypeError, + "metaclass conflict among bases"); + return NULL; + } + if (metatype->tp_new != type_new) + return metatype->tp_new(type, args, kwds); + } + return PyType_GenericNew(type, args, kwds); + } + static void type_dealloc(PyTypeObject *type) *************** *** 351,355 **** type_init, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ ! PyType_GenericNew, /* tp_new */ }; --- 397,401 ---- type_init, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ ! type_new, /* tp_new */ }; From gvanrossum@users.sourceforge.net Wed Jun 6 02:02:23 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 05 Jun 2001 18:02:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.30,2.16.8.31 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv29594/Objects Modified Files: Tag: descr-branch typeobject.c Log Message: A VERY preliminary of multiple inheritance. Lots of stuff doesn't work (hey, __bases__ doesn't even reflect the auxiliary base classes!) but it allows me to write and test some simple mix-in classes. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.30 retrieving revision 2.16.8.31 diff -C2 -r2.16.8.30 -r2.16.8.31 *** typeobject.c 2001/06/05 19:31:56 2.16.8.30 --- typeobject.c 2001/06/06 01:02:20 2.16.8.31 *************** *** 139,142 **** --- 139,143 ---- staticforward void override_slots(PyTypeObject *type, PyObject *dict); + staticforward PyTypeObject *solid_base(PyTypeObject *type); typedef struct { *************** *** 150,153 **** --- 151,167 ---- } etype; + static int + issubtype(PyTypeObject *a, PyTypeObject *b) + { + if (b == &PyBaseObject_Type) + return 1; /* Every type is an implicit subtype of this */ + while (a != NULL) { + if (a == b) + return 1; + a = a->tp_base; + } + return 0; + } + /* TypeType's initializer; called when a type is subclassed */ static int *************** *** 159,163 **** etype *et; struct memberlist *mp; ! int i, nslots, slotoffset, allocsize; assert(PyType_Check(self)); --- 173,177 ---- etype *et; struct memberlist *mp; ! int i, n, nslots, slotoffset, allocsize; assert(PyType_Check(self)); *************** *** 172,196 **** "usage: TypeType(name, bases, dict) "); return -1; - } - if (PyTuple_GET_SIZE(bases) > 1) { - PyErr_SetString(PyExc_TypeError, - "can't multiple-inherit from types (yet)"); - return -1; } ! if (PyTuple_GET_SIZE(bases) < 1) ! base = &PyBaseObject_Type; ! else { base = (PyTypeObject *)PyTuple_GET_ITEM(bases, 0); ! if (!PyType_Check((PyObject *)base)) { ! PyErr_SetString(PyExc_TypeError, ! "base type must be a type"); ! return -1; ! } ! if (base->tp_new == NULL) { ! PyErr_SetString(PyExc_TypeError, ! "base type must have a tp_new slot"); ! return -1; } } /* Check for a __slots__ sequence variable in dict, and count it */ --- 186,226 ---- "usage: TypeType(name, bases, dict) "); return -1; } ! n = PyTuple_GET_SIZE(bases); ! if (n > 0) { ! PyTypeObject *winner, *candidate, *base_i; base = (PyTypeObject *)PyTuple_GET_ITEM(bases, 0); ! winner = &PyBaseObject_Type; ! for (i = 0; i < n; i++) { ! base_i = (PyTypeObject *)PyTuple_GET_ITEM(bases, i); ! if (!PyType_Check((PyObject *)base_i)) { ! PyErr_SetString( ! PyExc_TypeError, ! "bases must be types"); ! return -1; ! } ! candidate = solid_base(base_i); ! if (issubtype(winner, candidate)) ! ; ! else if (issubtype(candidate, winner)) { ! winner = candidate; ! base = base_i; ! } ! else { ! PyErr_SetString( ! PyExc_TypeError, ! "multiple bases have " ! "instance lay-out conflict"); ! return -1; ! } } } + else + base = &PyBaseObject_Type; + if (base->tp_new == NULL) { + PyErr_SetString(PyExc_TypeError, + "base type must have a tp_new slot"); + return -1; + } /* Check for a __slots__ sequence variable in dict, and count it */ *************** *** 286,289 **** --- 316,333 ---- add_members(type, et->members); + /* XXX This is close, but not quite right! */ + if (n > 1) { + PyTypeObject *t; + for (i = n; --i >= 0; ) { + t = (PyTypeObject *) PyTuple_GET_ITEM(bases, i); + x = PyObject_CallMethod(type->tp_dict, + "update", "O", t->tp_dict); + if (x == NULL) { + Py_DECREF(type); + return -1; + } + } + } + x = PyObject_CallMethod(type->tp_dict, "update", "O", dict); if (x == NULL) { *************** *** 297,311 **** static int ! issubtype(PyTypeObject *a, PyTypeObject *b) { ! while (a != b) { ! a = a->tp_base; ! if (a == NULL) ! return 0; ! } return 1; } ! #define ISSUBTYPE(a, b) issubtype(a, b) static PyObject * --- 341,380 ---- static int ! extra_ivars(PyTypeObject *type, PyTypeObject *base) { ! int t_size = type->tp_basicsize; ! int b_size = base->tp_basicsize; ! ! /* XXX what about tp_itemsize? */ ! assert((type->tp_flags & Py_TPFLAGS_GC) >= ! (base->tp_flags & Py_TPFLAGS_GC)); /* base has GC, type not! */ ! if (type->tp_flags & Py_TPFLAGS_GC) ! t_size -= PyGC_HEAD_SIZE; ! if (base->tp_flags & Py_TPFLAGS_GC) ! b_size -= PyGC_HEAD_SIZE; ! assert(t_size >= b_size); /* type smaller than base! */ ! if (t_size == b_size) ! return 0; ! 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; } ! static PyTypeObject * ! solid_base(PyTypeObject *type) ! { ! PyTypeObject *base; ! ! if (type->tp_base) ! base = solid_base(type->tp_base); ! else ! base = &PyBaseObject_Type; ! if (extra_ivars(type, base)) ! return type; ! else ! return base; ! } static PyObject * *************** *** 326,332 **** PyObject *base_i = PyTuple_GET_ITEM(bases, i); PyTypeObject *type_i = base_i->ob_type; ! if (ISSUBTYPE(metatype, type_i)) continue; ! if (ISSUBTYPE(type_i, metatype)) { metatype = type_i; continue; --- 395,401 ---- PyObject *base_i = PyTuple_GET_ITEM(bases, i); PyTypeObject *type_i = base_i->ob_type; ! if (issubtype(metatype, type_i)) continue; ! if (issubtype(type_i, metatype)) { metatype = type_i; continue; From gvanrossum@users.sourceforge.net Wed Jun 6 02:03:16 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 05 Jun 2001 18:03:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.1.2.10,1.1.2.11 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv16053 Modified Files: Tag: descr-branch test_descr.py Log Message: Testing __metaclass__ and multiple inheritance (for mix-ins). Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_descr.py,v retrieving revision 1.1.2.10 retrieving revision 1.1.2.11 diff -C2 -r1.1.2.10 -r1.1.2.11 *** test_descr.py 2001/06/05 10:49:24 1.1.2.10 --- test_descr.py 2001/06/06 01:03:14 1.1.2.11 *************** *** 339,342 **** --- 339,370 ---- ("delattr", "foo")], log) + def baseless(): + if verbose: print "Testing __metaclass__ and mix-ins..." + global C + class C: + __metaclass__ = type(type(0)) + def __init__(self): + self.__state = 0 + def getstate(self): + return self.__state + def setstate(self, state): + self.__state = state + a = C() + verify(a.getstate() == 0) + a.setstate(10) + verify(a.getstate() == 10) + class D(type({}), C): + def __init__(self): + type({}).__init__(self) + C.__init__(self) + d = D() + verify(d.keys() == []) + d["hello"] = "world" + verify(d.items() == [("hello", "world")]) + verify(d["hello"] == "world") + verify(d.getstate() == 0) + d.setstate(10) + verify(d.getstate() == 10) + def all(): lists() *************** *** 349,352 **** --- 377,381 ---- pydicts() pymods() + baseless() all() From loewis@users.sourceforge.net Wed Jun 6 07:24:40 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Tue, 05 Jun 2001 23:24:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib glob.py,1.9,1.10 fnmatch.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv4997 Modified Files: glob.py fnmatch.py Log Message: Patch #409973: Speedup glob.glob, add fnmatch.filter. Index: glob.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/glob.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -r1.9 -r1.10 *** glob.py 2001/01/20 23:34:12 1.9 --- glob.py 2001/06/06 06:24:38 1.10 *************** *** 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: fnmatch.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/fnmatch.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -r1.11 -r1.12 *** fnmatch.py 2001/03/21 18:05:48 1.11 --- fnmatch.py 2001/06/06 06:24:38 1.12 *************** *** 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. From loewis@users.sourceforge.net Wed Jun 6 07:25:42 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Tue, 05 Jun 2001 23:25:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.179,1.180 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv5840 Modified Files: NEWS Log Message: Report on fnmatch.filter. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.179 retrieving revision 1.180 diff -C2 -r1.179 -r1.180 *** NEWS 2001/06/02 05:27:19 1.179 --- NEWS 2001/06/06 06:25:40 1.180 *************** *** 125,128 **** --- 125,130 ---- Library + - A new function fnmatch.filter to filter lists of file names was added. + - calendar.py uses month and day names based on the current locale. From gvanrossum@users.sourceforge.net Wed Jun 6 14:30:57 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 06 Jun 2001 06:30:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.180,1.181 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv3188 Modified Files: NEWS Log Message: Added quopri codec. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.180 retrieving revision 1.181 diff -C2 -r1.180 -r1.181 *** NEWS 2001/06/06 06:25:40 1.180 --- NEWS 2001/06/06 13:30:54 1.181 *************** *** 30,33 **** --- 30,34 ---- uu | string | string | UU codec (e.g. for email) base64 | string | string | base64 codec + quopri | string | string | quoted-printable codec zlib | string | string | zlib compression hex | string | string | 2-byte hex codec From gvanrossum@users.sourceforge.net Wed Jun 6 15:26:14 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 06 Jun 2001 07:26:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include object.h,2.79.2.9,2.79.2.10 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv14559 Modified Files: Tag: descr-branch object.h Log Message: - Add the missing decl for PyBaseObject_Type. - Rename PyGeneric_{Get,Set}Attr to PyObject_Generic{Get,Set}Attr (more to follow for this one). Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.79.2.9 retrieving revision 2.79.2.10 diff -C2 -r2.79.2.9 -r2.79.2.10 *** object.h 2001/06/05 10:49:24 2.79.2.9 --- object.h 2001/06/06 14:26:12 2.79.2.10 *************** *** 289,292 **** --- 289,293 ---- extern DL_IMPORT(PyTypeObject) PyType_Type; /* Metatype */ + extern DL_IMPORT(PyTypeObject) PyBaseObject_Type; /* Most base object type */ #define PyType_Check(op) PyObject_TypeCheck(op, &PyType_Type) *************** *** 313,318 **** extern DL_IMPORT(int) PyObject_SetAttr(PyObject *, PyObject *, PyObject *); extern DL_IMPORT(int) PyObject_HasAttr(PyObject *, PyObject *); ! extern DL_IMPORT(PyObject *) PyGeneric_GetAttr(PyObject *, PyObject *); ! extern DL_IMPORT(int) PyGeneric_SetAttr(PyObject *, PyObject *, PyObject *); extern DL_IMPORT(long) PyObject_Hash(PyObject *); extern DL_IMPORT(int) PyObject_IsTrue(PyObject *); --- 314,320 ---- extern DL_IMPORT(int) PyObject_SetAttr(PyObject *, PyObject *, PyObject *); extern DL_IMPORT(int) PyObject_HasAttr(PyObject *, PyObject *); ! extern DL_IMPORT(PyObject *) PyObject_GenericGetAttr(PyObject *, PyObject *); ! extern DL_IMPORT(int) PyObject_GenericSetAttr(PyObject *, ! PyObject *, PyObject *); extern DL_IMPORT(long) PyObject_Hash(PyObject *); extern DL_IMPORT(int) PyObject_IsTrue(PyObject *); From gvanrossum@users.sourceforge.net Wed Jun 6 15:27:56 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 06 Jun 2001 07:27:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules spam.c,1.1.2.5,1.1.2.6 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv14862/Modules Modified Files: Tag: descr-branch spam.c Log Message: Rename PyGeneric_{Get,Set}Attr to PyObject_Genetic{Get,Set}Attr. Index: spam.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/Attic/spam.c,v retrieving revision 1.1.2.5 retrieving revision 1.1.2.6 diff -C2 -r1.1.2.5 -r1.1.2.6 *** spam.c 2001/06/05 10:49:24 1.1.2.5 --- spam.c 2001/06/06 14:27:54 1.1.2.6 *************** *** 65,69 **** 0, /* tp_call */ 0, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 65,69 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ *************** *** 159,163 **** 0, /* tp_call */ 0, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 159,163 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ From gvanrossum@users.sourceforge.net Wed Jun 6 15:27:57 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 06 Jun 2001 07:27:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects bufferobject.c,2.13.8.1,2.13.8.2 cellobject.c,1.2.4.1,1.2.4.2 complexobject.c,2.35.4.2,2.35.4.3 descrobject.c,1.1.2.8,1.1.2.9 dictobject.c,2.80.2.7,2.80.2.8 fileobject.c,2.112.2.2,2.112.2.3 floatobject.c,2.81.6.2,2.81.6.3 frameobject.c,2.49.4.2,2.49.4.3 funcobject.c,2.37.4.4,2.37.4.5 intobject.c,2.56.6.2,2.56.6.3 iterobject.c,1.3.2.1,1.3.2.2 listobject.c,2.92.6.5,2.92.6.6 longobject.c,1.71.6.1,1.71.6.2 methodobject.c,2.33.8.4,2.33.8.5 moduleobject.c,2.31.6.3,2.31.6.4 object.c,2.124.4.10,2.124.4.11 rangeobject.c,2.24.6.2,2.24.6.3 sliceobject.c,2.7.4.2,2.7.4.3 stringobject.c,2.103.2.3,2.103.2.4 tupleobject.c,2.48.6.1,2.48.6.2 typeobject.c,2.16.8.31,2.16.8.32 unicodeobject.c,2.87.2.2,2.87.2.3 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv14862/Objects Modified Files: Tag: descr-branch bufferobject.c cellobject.c complexobject.c descrobject.c dictobject.c fileobject.c floatobject.c frameobject.c funcobject.c intobject.c iterobject.c listobject.c longobject.c methodobject.c moduleobject.c object.c rangeobject.c sliceobject.c stringobject.c tupleobject.c typeobject.c unicodeobject.c Log Message: Rename PyGeneric_{Get,Set}Attr to PyObject_Genetic{Get,Set}Attr. Index: bufferobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/bufferobject.c,v retrieving revision 2.13.8.1 retrieving revision 2.13.8.2 diff -C2 -r2.13.8.1 -r2.13.8.2 *** bufferobject.c 2001/04/30 14:11:39 2.13.8.1 --- bufferobject.c 2001/06/06 14:27:54 2.13.8.2 *************** *** 550,554 **** 0, /* tp_call */ (reprfunc)buffer_str, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ &buffer_as_buffer, /* tp_as_buffer */ --- 550,554 ---- 0, /* tp_call */ (reprfunc)buffer_str, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ &buffer_as_buffer, /* tp_as_buffer */ Index: cellobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/cellobject.c,v retrieving revision 1.2.4.1 retrieving revision 1.2.4.2 diff -C2 -r1.2.4.1 -r1.2.4.2 *** cellobject.c 2001/04/30 14:23:32 1.2.4.1 --- cellobject.c 2001/06/06 14:27:54 1.2.4.2 *************** *** 107,111 **** 0, /* tp_call */ 0, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 107,111 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Index: complexobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/complexobject.c,v retrieving revision 2.35.4.2 retrieving revision 2.35.4.3 diff -C2 -r2.35.4.2 -r2.35.4.3 *** complexobject.c 2001/04/27 18:04:50 2.35.4.2 --- complexobject.c 2001/06/06 14:27:54 2.35.4.3 *************** *** 611,615 **** 0, /* tp_call */ (reprfunc)complex_str, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 611,615 ---- 0, /* tp_call */ (reprfunc)complex_str, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Index: descrobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/Attic/descrobject.c,v retrieving revision 1.1.2.8 retrieving revision 1.1.2.9 diff -C2 -r1.1.2.8 -r1.1.2.9 *** descrobject.c 2001/05/10 16:37:11 1.1.2.8 --- descrobject.c 2001/06/06 14:27:54 1.1.2.9 *************** *** 378,382 **** (ternaryfunc)descr_call, /* tp_call */ 0, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 378,382 ---- (ternaryfunc)descr_call, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ *************** *** 634,638 **** 0, /* tp_call */ (reprfunc)proxy_str, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 634,638 ---- 0, /* tp_call */ (reprfunc)proxy_str, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ *************** *** 747,751 **** (ternaryfunc)wrapper_call, /* tp_call */ 0, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 747,751 ---- (ternaryfunc)wrapper_call, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.80.2.7 retrieving revision 2.80.2.8 diff -C2 -r2.80.2.7 -r2.80.2.8 *** dictobject.c 2001/06/05 10:49:24 2.80.2.7 --- dictobject.c 2001/06/06 14:27:54 2.80.2.8 *************** *** 1310,1314 **** 0, /* tp_call */ 0, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 1310,1314 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ *************** *** 1473,1477 **** 0, /* tp_call */ 0, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 1473,1477 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Index: fileobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.112.2.2 retrieving revision 2.112.2.3 diff -C2 -r2.112.2.2 -r2.112.2.3 *** fileobject.c 2001/04/27 18:04:50 2.112.2.2 --- fileobject.c 2001/06/06 14:27:54 2.112.2.3 *************** *** 1317,1321 **** 0, /* tp_call */ 0, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 1317,1321 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Index: floatobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v retrieving revision 2.81.6.2 retrieving revision 2.81.6.3 diff -C2 -r2.81.6.2 -r2.81.6.3 *** floatobject.c 2001/04/30 14:08:33 2.81.6.2 --- floatobject.c 2001/06/06 14:27:54 2.81.6.3 *************** *** 680,684 **** 0, /* tp_call */ (reprfunc)float_str, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 680,684 ---- 0, /* tp_call */ (reprfunc)float_str, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Index: frameobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/frameobject.c,v retrieving revision 2.49.4.2 retrieving revision 2.49.4.3 diff -C2 -r2.49.4.2 -r2.49.4.3 *** frameobject.c 2001/04/27 18:04:51 2.49.4.2 --- frameobject.c 2001/06/06 14:27:54 2.49.4.3 *************** *** 108,113 **** 0, /* tp_call */ 0, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ ! PyGeneric_SetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ --- 108,113 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ ! PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ Index: funcobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/funcobject.c,v retrieving revision 2.37.4.4 retrieving revision 2.37.4.5 diff -C2 -r2.37.4.4 -r2.37.4.5 *** funcobject.c 2001/06/05 10:49:24 2.37.4.4 --- funcobject.c 2001/06/06 14:27:54 2.37.4.5 *************** *** 153,157 **** } ! return PyGeneric_GetAttr(op, name); } --- 153,157 ---- } ! return PyObject_GenericGetAttr(op, name); } *************** *** 204,208 **** } ! return PyGeneric_SetAttr(op, name, value); } --- 204,208 ---- } ! return PyObject_GenericSetAttr(op, name, value); } Index: intobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v retrieving revision 2.56.6.2 retrieving revision 2.56.6.3 diff -C2 -r2.56.6.2 -r2.56.6.3 *** intobject.c 2001/04/30 14:06:20 2.56.6.2 --- intobject.c 2001/06/06 14:27:54 2.56.6.3 *************** *** 806,810 **** 0, /* tp_call */ 0, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 806,810 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Index: iterobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/iterobject.c,v retrieving revision 1.3.2.1 retrieving revision 1.3.2.2 diff -C2 -r1.3.2.1 -r1.3.2.2 *** iterobject.c 2001/04/30 14:25:44 1.3.2.1 --- iterobject.c 2001/06/06 14:27:54 1.3.2.2 *************** *** 108,112 **** 0, /* tp_call */ 0, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 108,112 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ *************** *** 212,216 **** 0, /* tp_call */ 0, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 212,216 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Index: listobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v retrieving revision 2.92.6.5 retrieving revision 2.92.6.6 diff -C2 -r2.92.6.5 -r2.92.6.6 *** listobject.c 2001/06/05 10:49:24 2.92.6.5 --- listobject.c 2001/06/06 14:27:54 2.92.6.6 *************** *** 1568,1572 **** 0, /* tp_call */ 0, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 1568,1572 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ *************** *** 1654,1658 **** 0, /* tp_call */ 0, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 1654,1658 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.71.6.1 retrieving revision 1.71.6.2 diff -C2 -r1.71.6.1 -r1.71.6.2 *** longobject.c 2001/04/30 01:14:56 1.71.6.1 --- longobject.c 2001/06/06 14:27:54 1.71.6.2 *************** *** 1852,1874 **** PyTypeObject PyLong_Type = { PyObject_HEAD_INIT(&PyType_Type) ! 0, ! "long int", ! sizeof(PyLongObject) - sizeof(digit), ! sizeof(digit), ! (destructor)long_dealloc, /*tp_dealloc*/ ! 0, /*tp_print*/ ! 0, /*tp_getattr*/ ! 0, /*tp_setattr*/ ! (cmpfunc)long_compare, /*tp_compare*/ ! (reprfunc)long_repr, /*tp_repr*/ ! &long_as_number, /*tp_as_number*/ ! 0, /*tp_as_sequence*/ ! 0, /*tp_as_mapping*/ ! (hashfunc)long_hash, /*tp_hash*/ ! 0, /*tp_call*/ ! (reprfunc)long_str, /*tp_str*/ ! PyGeneric_GetAttr, /* tp_getattro */ ! 0, /*tp_setattro*/ ! 0, /*tp_as_buffer*/ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES /*tp_flags*/ }; --- 1852,1874 ---- PyTypeObject PyLong_Type = { PyObject_HEAD_INIT(&PyType_Type) ! 0, /* ob_size */ ! "long int", /* tp_name */ ! sizeof(PyLongObject) - sizeof(digit), /* tp_basicsize */ ! sizeof(digit), /* tp_itemsize */ ! (destructor)long_dealloc, /* tp_dealloc */ ! 0, /* tp_print */ ! 0, /* tp_getattr */ ! 0, /* tp_setattr */ ! (cmpfunc)long_compare, /* tp_compare */ ! (reprfunc)long_repr, /* tp_repr */ ! &long_as_number, /* tp_as_number */ ! 0, /* tp_as_sequence */ ! 0, /* tp_as_mapping */ ! (hashfunc)long_hash, /* tp_hash */ ! 0, /* tp_call */ ! (reprfunc)long_str, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ ! 0, /* tp_setattro */ ! 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */ }; Index: methodobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/methodobject.c,v retrieving revision 2.33.8.4 retrieving revision 2.33.8.5 diff -C2 -r2.33.8.4 -r2.33.8.5 *** methodobject.c 2001/05/05 11:37:29 2.33.8.4 --- methodobject.c 2001/06/06 14:27:54 2.33.8.5 *************** *** 206,210 **** meth_call, /* tp_call */ 0, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 206,210 ---- meth_call, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Index: moduleobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/moduleobject.c,v retrieving revision 2.31.6.3 retrieving revision 2.31.6.4 diff -C2 -r2.31.6.3 -r2.31.6.4 *** moduleobject.c 2001/06/05 10:49:24 2.31.6.3 --- moduleobject.c 2001/06/06 14:27:54 2.31.6.4 *************** *** 206,211 **** 0, /* tp_call */ 0, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ ! PyGeneric_SetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */ --- 206,211 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ ! PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */ Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.124.4.10 retrieving revision 2.124.4.11 diff -C2 -r2.124.4.10 -r2.124.4.11 *** object.c 2001/05/11 20:00:24 2.124.4.10 --- object.c 2001/06/06 14:27:54 2.124.4.11 *************** *** 1077,1081 **** PyObject * ! PyGeneric_GetAttr(PyObject *obj, PyObject *name) { PyTypeObject *tp = obj->ob_type; --- 1077,1081 ---- PyObject * ! PyObject_GenericGetAttr(PyObject *obj, PyObject *name) { PyTypeObject *tp = obj->ob_type; *************** *** 1124,1128 **** int ! PyGeneric_SetAttr(PyObject *obj, PyObject *name, PyObject *value) { PyTypeObject *tp = obj->ob_type; --- 1124,1128 ---- int ! PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value) { PyTypeObject *tp = obj->ob_type; Index: rangeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/rangeobject.c,v retrieving revision 2.24.6.2 retrieving revision 2.24.6.3 diff -C2 -r2.24.6.2 -r2.24.6.3 *** rangeobject.c 2001/04/27 18:04:51 2.24.6.2 --- rangeobject.c 2001/06/06 14:27:54 2.24.6.3 *************** *** 323,327 **** 0, /* tp_call */ 0, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 323,327 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Index: sliceobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/sliceobject.c,v retrieving revision 2.7.4.2 retrieving revision 2.7.4.3 diff -C2 -r2.7.4.2 -r2.7.4.3 *** sliceobject.c 2001/04/27 18:04:51 2.7.4.2 --- sliceobject.c 2001/06/06 14:27:54 2.7.4.3 *************** *** 176,180 **** 0, /* tp_call */ 0, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 176,180 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Index: stringobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v retrieving revision 2.103.2.3 retrieving revision 2.103.2.4 diff -C2 -r2.103.2.3 -r2.103.2.4 *** stringobject.c 2001/05/02 21:24:00 2.103.2.3 --- stringobject.c 2001/06/06 14:27:54 2.103.2.4 *************** *** 2377,2381 **** 0, /* tp_call */ (reprfunc)string_str, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ &string_as_buffer, /* tp_as_buffer */ --- 2377,2381 ---- 0, /* tp_call */ (reprfunc)string_str, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ &string_as_buffer, /* tp_as_buffer */ Index: tupleobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/tupleobject.c,v retrieving revision 2.48.6.1 retrieving revision 2.48.6.2 diff -C2 -r2.48.6.1 -r2.48.6.2 *** tupleobject.c 2001/04/30 14:26:18 2.48.6.1 --- tupleobject.c 2001/06/06 14:27:54 2.48.6.2 *************** *** 473,477 **** 0, /* tp_call */ 0, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 473,477 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.31 retrieving revision 2.16.8.32 diff -C2 -r2.16.8.31 -r2.16.8.32 *** typeobject.c 2001/06/06 01:02:20 2.16.8.31 --- typeobject.c 2001/06/06 14:27:54 2.16.8.32 *************** *** 246,250 **** } if (slots == NULL && base->tp_dictoffset == 0 && ! (base->tp_setattro == PyGeneric_SetAttr || base->tp_setattro == NULL)) nslots = 1; --- 246,250 ---- } if (slots == NULL && base->tp_dictoffset == 0 && ! (base->tp_setattro == PyObject_GenericSetAttr || base->tp_setattro == NULL)) nslots = 1; *************** *** 284,292 **** type->tp_dealloc = subtype_dealloc; if (type->tp_getattro == NULL) { ! type->tp_getattro = PyGeneric_GetAttr; type->tp_getattr = NULL; } if (type->tp_setattro == NULL) { ! type->tp_setattro = PyGeneric_SetAttr; type->tp_setattr = NULL; } --- 284,292 ---- type->tp_dealloc = subtype_dealloc; if (type->tp_getattro == NULL) { ! type->tp_getattro = PyObject_GenericGetAttr; type->tp_getattr = NULL; } if (type->tp_setattro == NULL) { ! type->tp_setattro = PyObject_GenericSetAttr; type->tp_setattr = NULL; } *************** *** 445,449 **** (ternaryfunc)type_call, /* tp_call */ 0, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 445,449 ---- (ternaryfunc)type_call, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ *************** *** 496,500 **** 0, /* tp_call */ 0, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 496,500 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.87.2.2 retrieving revision 2.87.2.3 diff -C2 -r2.87.2.2 -r2.87.2.3 *** unicodeobject.c 2001/04/27 18:04:51 2.87.2.2 --- unicodeobject.c 2001/06/06 14:27:54 2.87.2.3 *************** *** 5239,5243 **** 0, /* tp_call*/ (reprfunc) unicode_str, /* tp_str */ ! PyGeneric_GetAttr, /* tp_getattro */ 0, /* tp_setattro */ &unicode_as_buffer, /* tp_as_buffer */ --- 5239,5243 ---- 0, /* tp_call*/ (reprfunc) unicode_str, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ &unicode_as_buffer, /* tp_as_buffer */ From gvanrossum@users.sourceforge.net Wed Jun 6 15:34:15 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 06 Jun 2001 07:34:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects object.c,2.124.4.11,2.124.4.12 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv17474 Modified Files: Tag: descr-branch object.c Log Message: Add _PyObject_GetDictPtr() -- an internal API to get a pointer to where __dict__ is stored in an object. The simplest case is to add tp_dictoffset to the start of the object, but there are comlications: tp_flags may tell us that tp_dictoffset is not defined, or the offset may be negative: indexing from the end of the object, where tp_itemsize may have to be taken into account. Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.124.4.11 retrieving revision 2.124.4.12 diff -C2 -r2.124.4.11 -r2.124.4.12 *** object.c 2001/06/06 14:27:54 2.124.4.11 --- object.c 2001/06/06 14:34:13 2.124.4.12 *************** *** 1074,1077 **** --- 1074,1111 ---- } + /* Helper to get a pointer to an object's __dict__ slot, if any */ + + PyObject ** + _PyObject_GetDictPtr(PyObject *obj) + { + #define PTRSIZE (sizeof(PyObject *)) + + long dictoffset; + PyTypeObject *tp = obj->ob_type; + + if (!(tp->tp_flags & Py_TPFLAGS_HAVE_CLASS)) + return NULL; + dictoffset = tp->tp_dictoffset; + if (dictoffset == 0) + return NULL; + if (dictoffset < 0) { + dictoffset += tp->tp_basicsize; + assert(dictoffset > 0); /* Sanity check */ + if (tp->tp_itemsize > 0) { + int n = ((PyVarObject *)obj)->ob_size; + if (n > 0) { + dictoffset += tp->tp_itemsize * n; + /* Round up, if necessary */ + if (tp->tp_itemsize % PTRSIZE != 0) { + dictoffset += PTRSIZE - 1; + dictoffset /= PTRSIZE; + dictoffset *= PTRSIZE; + } + } + } + } + return (PyObject **) ((char *)obj + dictoffset); + } + /* Generic GetAttr functions - put these in your tp_[gs]etattro slot */ *************** *** 1082,1086 **** PyObject *descr; descrgetfunc f; ! int dictoffset; if (tp->tp_dict == NULL) { --- 1116,1120 ---- PyObject *descr; descrgetfunc f; ! PyObject **dictptr; if (tp->tp_dict == NULL) { *************** *** 1097,1103 **** } ! dictoffset = tp->tp_dictoffset; ! if (dictoffset != 0) { ! PyObject *dict = * (PyObject **) ((char *)obj + dictoffset); if (dict != NULL) { PyObject *res = PyDict_GetItem(dict, name); --- 1131,1137 ---- } ! dictptr = _PyObject_GetDictPtr(obj); ! if (dictptr != NULL) { ! PyObject *dict = *dictptr; if (dict != NULL) { PyObject *res = PyDict_GetItem(dict, name); *************** *** 1129,1133 **** PyObject *descr; descrsetfunc f; ! int dictoffset; if (tp->tp_dict == NULL) { --- 1163,1167 ---- PyObject *descr; descrsetfunc f; ! PyObject **dictptr; if (tp->tp_dict == NULL) { *************** *** 1143,1149 **** } ! dictoffset = tp->tp_dictoffset; ! if (dictoffset != 0) { ! PyObject **dictptr = (PyObject **) ((char *)obj + dictoffset); PyObject *dict = *dictptr; if (dict == NULL && value != NULL) { --- 1177,1182 ---- } ! dictptr = _PyObject_GetDictPtr(obj); ! if (dictptr != NULL) { PyObject *dict = *dictptr; if (dict == NULL && value != NULL) { From gvanrossum@users.sourceforge.net Wed Jun 6 15:34:59 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 06 Jun 2001 07:34:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include object.h,2.79.2.10,2.79.2.11 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv17822 Modified Files: Tag: descr-branch object.h Log Message: Add _PyObject_GetDictPtr() -- an internal API to get a pointer to where __dict__ is stored in an object. The simplest case is to add tp_dictoffset to the start of the object, but there are comlications: tp_flags may tell us that tp_dictoffset is not defined, or the offset may be negative: indexing from the end of the object, where tp_itemsize may have to be taken into account. Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.79.2.10 retrieving revision 2.79.2.11 diff -C2 -r2.79.2.10 -r2.79.2.11 *** object.h 2001/06/06 14:26:12 2.79.2.10 --- object.h 2001/06/06 14:34:57 2.79.2.11 *************** *** 314,317 **** --- 314,318 ---- extern DL_IMPORT(int) PyObject_SetAttr(PyObject *, PyObject *, PyObject *); extern DL_IMPORT(int) PyObject_HasAttr(PyObject *, PyObject *); + extern DL_IMPORT(PyObject **) _PyObject_GetDictPtr(PyObject *); extern DL_IMPORT(PyObject *) PyObject_GenericGetAttr(PyObject *, PyObject *); extern DL_IMPORT(int) PyObject_GenericSetAttr(PyObject *, From gvanrossum@users.sourceforge.net Wed Jun 6 15:41:47 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 06 Jun 2001 07:41:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include object.h,2.79.2.11,2.79.2.12 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv20162 Modified Files: Tag: descr-branch object.h Log Message: Add three new slots: tp_bases, tp_mro (method resolution), and tp_introduced (introduced methods, as opposed to supported methods, which are in __dict__). Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.79.2.11 retrieving revision 2.79.2.12 diff -C2 -r2.79.2.11 -r2.79.2.12 *** object.h 2001/06/06 14:34:57 2.79.2.11 --- object.h 2001/06/06 14:41:45 2.79.2.12 *************** *** 260,264 **** iternextfunc tp_iternext; ! /* Attribute descriptor stuff */ struct PyMethodDef *tp_methods; struct memberlist *tp_members; --- 260,264 ---- iternextfunc tp_iternext; ! /* Attribute descriptor and subclassing stuff */ struct PyMethodDef *tp_methods; struct memberlist *tp_members; *************** *** 272,275 **** --- 272,278 ---- allocfunc tp_alloc; allocfunc tp_new; + PyObject *tp_bases; + PyObject *tp_mro; /* method resolution order */ + PyObject *tp_introduced; #ifdef COUNT_ALLOCS From gvanrossum@users.sourceforge.net Wed Jun 6 16:40:40 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 06 Jun 2001 08:40:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.32,2.16.8.33 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv9395 Modified Files: Tag: descr-branch typeobject.c Log Message: - Correct __bases__ calculation: take multiple bases into account, and make sure every type (except PyBaseObject_Type) is a subtype of PyBaseObject_Type. - New slots for type objects: __basicsize__, __itemsize__, __flags__, __weaklistoffset__, __dictoffset__. - Initialize a type's __dict__ when it's asked for. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.32 retrieving revision 2.16.8.33 diff -C2 -r2.16.8.32 -r2.16.8.33 *** typeobject.c 2001/06/06 14:27:54 2.16.8.32 --- typeobject.c 2001/06/06 15:40:38 2.16.8.33 *************** *** 9,13 **** --- 9,20 ---- struct memberlist type_members[] = { {"__name__", T_STRING, offsetof(PyTypeObject, tp_name), READONLY}, + {"__basicsize__", T_INT, offsetof(PyTypeObject,tp_basicsize),READONLY}, + {"__itemsize__", T_INT, offsetof(PyTypeObject, tp_itemsize), READONLY}, + {"__flags__", T_LONG, offsetof(PyTypeObject, tp_flags), READONLY}, {"__doc__", T_STRING, offsetof(PyTypeObject, tp_doc), READONLY}, + {"__weaklistoffset__", T_LONG, + offsetof(PyTypeObject, tp_weaklistoffset), READONLY}, + {"__dictoffset__", T_LONG, + offsetof(PyTypeObject, tp_dictoffset), READONLY}, {0} }; *************** *** 16,23 **** type_bases(PyTypeObject *type, void *context) { ! if (type->tp_base == NULL) ! return PyTuple_New(0); ! else ! return Py_BuildValue("(O)", type->tp_base); } --- 23,41 ---- type_bases(PyTypeObject *type, void *context) { ! PyObject *bases; ! PyTypeObject *base; ! ! bases = type->tp_bases; ! if (bases != NULL) { ! Py_INCREF(bases); ! return bases; ! } ! base = type->tp_base; ! if (base == NULL) { ! if (type == &PyBaseObject_Type) ! return PyTuple_New(0); ! base = &PyBaseObject_Type; ! } ! return Py_BuildValue("(O)", base); } *************** *** 32,37 **** { if (type->tp_dict == NULL) { ! Py_INCREF(Py_None); ! return Py_None; } return PyDictProxy_New(type->tp_dict); --- 50,59 ---- { if (type->tp_dict == NULL) { ! if (PyType_InitDict(type) < 0) ! return NULL; ! if (type->tp_dict == NULL) { ! Py_INCREF(Py_None); ! return Py_None; ! } } return PyDictProxy_New(type->tp_dict); *************** *** 154,157 **** --- 176,183 ---- 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 */ *************** *** 159,163 **** --- 185,203 ---- 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; *************** *** 272,278 **** type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE; ! /* Copy slots and dict from the base type */ Py_INCREF(base); type->tp_base = base; if (PyType_InitDict(type) < 0) { Py_DECREF(type); --- 312,325 ---- type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE; ! /* Set tp_base and tp_bases properly */ ! if (PyTuple_GET_SIZE(bases) == 0) ! bases = Py_BuildValue("(O)", &PyBaseObject_Type); ! else ! Py_INCREF(bases); ! type->tp_bases = bases; Py_INCREF(base); type->tp_base = base; + + /* Copy slots and dict from the base type */ if (PyType_InitDict(type) < 0) { Py_DECREF(type); *************** *** 346,350 **** int b_size = base->tp_basicsize; - /* XXX what about tp_itemsize? */ assert((type->tp_flags & Py_TPFLAGS_GC) >= (base->tp_flags & Py_TPFLAGS_GC)); /* base has GC, type not! */ --- 393,396 ---- *************** *** 354,357 **** --- 400,408 ---- b_size -= PyGC_HEAD_SIZE; assert(t_size >= b_size); /* type smaller than base! */ + if (type->tp_itemsize || base->tp_itemsize) { + /* If itemsize is involved, stricter rules */ + return t_size != b_size || + type->tp_itemsize != base->tp_itemsize; + } if (t_size == b_size) return 0; *************** *** 384,387 **** --- 435,446 ---- static char *kwlist[] = {"name", "bases", "dict", 0}; + if (PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 && + (kwds == NULL || (PyDict_Check(kwds) && PyDict_Size(kwds) == 0))) { + /* type(x) -> x.__class__ */ + PyObject *x = PyTuple_GET_ITEM(args, 0); + Py_INCREF(x->ob_type); + return (PyObject *) x->ob_type; + } + /* Check arguments (again?!?! yes, alas -- we need the bases!) */ if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO", kwlist, *************** *** 429,436 **** PyTypeObject PyType_Type = { PyObject_HEAD_INIT(&PyType_Type) ! 0, /* Number of items for varobject */ ! "type", /* Name of this type */ ! sizeof(etype) + sizeof(struct memberlist), /* Basic object size */ ! 0, /* Item size for varobject */ (destructor)type_dealloc, /* tp_dealloc */ 0, /* tp_print */ --- 488,495 ---- PyTypeObject PyType_Type = { PyObject_HEAD_INIT(&PyType_Type) ! 0, /* ob_size */ ! "type", /* tp_name */ ! sizeof(etype) + sizeof(struct memberlist), /* tp_basicsize */ ! 0, /* tp_itemsize */ (destructor)type_dealloc, /* tp_dealloc */ 0, /* tp_print */ *************** *** 445,449 **** (ternaryfunc)type_call, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 504,508 ---- (ternaryfunc)type_call, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ *************** *** 496,500 **** 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 555,559 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ From gvanrossum@users.sourceforge.net Wed Jun 6 16:41:04 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 06 Jun 2001 08:41:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib types.py,1.14.10.2,1.14.10.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv9590 Modified Files: Tag: descr-branch types.py Log Message: Added ObjectType, (the most basic type) now that it's accessible. Index: types.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/types.py,v retrieving revision 1.14.10.2 retrieving revision 1.14.10.3 diff -C2 -r1.14.10.2 -r1.14.10.3 *** types.py 2001/05/06 02:31:13 1.14.10.2 --- types.py 2001/06/06 15:41:02 1.14.10.3 *************** *** 8,11 **** --- 8,12 ---- NoneType = type(None) TypeType = type(NoneType) + ObjectType = NoneType.__bases__[0] IntType = type(0) From fdrake@users.sourceforge.net Wed Jun 6 16:59:06 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 06 Jun 2001 08:59:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/templates howto.tex,1.4,1.5 manual.tex,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/templates In directory usw-pr-cvs1:/tmp/cvs-serv16121 Modified Files: howto.tex manual.tex Log Message: Add references to the documentation for the Python documentation markup. Suggested by the comments in SF bug #430627. Index: howto.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/templates/howto.tex,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** howto.tex 1999/03/16 16:10:31 1.4 --- howto.tex 2001/06/06 15:59:04 1.5 *************** *** 1,2 **** --- 1,9 ---- + % Complete documentation on the extended LaTeX markup used for Python + % documentation is available in ``Documenting Python'', which is part + % of the standard documentation for Python. It may be found online + % at: + % + % http://www.python.org/doc/current/doc/doc.html + \documentclass{howto} Index: manual.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/templates/manual.tex,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** manual.tex 1999/05/17 16:02:38 1.2 --- manual.tex 2001/06/06 15:59:04 1.3 *************** *** 1,2 **** --- 1,9 ---- + % Complete documentation on the extended LaTeX markup used for Python + % documentation is available in ``Documenting Python'', which is part + % of the standard documentation for Python. It may be found online + % at: + % + % http://www.python.org/doc/current/doc/doc.html + \documentclass{manual} From fdrake@users.sourceforge.net Wed Jun 6 17:02:49 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 06 Jun 2001 09:02:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/templates module.tex,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/templates In directory usw-pr-cvs1:/tmp/cvs-serv17398 Modified Files: module.tex Log Message: Typo: "descrition" --> "description" Add reference to the documentation for the Python documentation markup. Fixed up a couple of descriptions. This closes SF bug #430627. Index: module.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/templates/module.tex,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -r1.21 -r1.22 *** module.tex 2000/07/06 16:12:47 1.21 --- module.tex 2001/06/06 16:02:47 1.22 *************** *** 1,4 **** --- 1,11 ---- % Template for a library manual section. % PLEASE REMOVE THE COMMENTS AFTER USING THE TEMPLATE + % + % Complete documentation on the extended LaTeX markup used for Python + % documentation is available in ``Documenting Python'', which is part + % of the standard documentation for Python. It may be found online + % at: + % + % http://www.python.org/doc/current/doc/doc.html % ==== 0. ==== *************** *** 14,18 **** \section{\module{spam} --- ! Short descrition, for section title} % Choose one of these to specify the module module name. If there's --- 21,25 ---- \section{\module{spam} --- ! Short description, for section title and table of contents} % Choose one of these to specify the module module name. If there's *************** *** 32,38 **** % is omitted, no availability statement is produced or implied. % ! % \platform{UNIX} ! % These apply to all modules: \moduleauthor{name}{email} % Author of the module code; --- 39,45 ---- % is omitted, no availability statement is produced or implied. % ! % \platform{Unix} ! % These apply to all modules, and may be given more than once: \moduleauthor{name}{email} % Author of the module code; From fdrake@users.sourceforge.net Wed Jun 6 17:09:56 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 06 Jun 2001 09:09:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/templates howto.tex,1.4,1.4.12.1 manual.tex,1.2,1.2.12.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/templates In directory usw-pr-cvs1:/tmp/cvs-serv19574 Modified Files: Tag: release21-maint howto.tex manual.tex Log Message: Add references to the documentation for the Python documentation markup. Suggested by the comments in SF bug #430627. Index: howto.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/templates/howto.tex,v retrieving revision 1.4 retrieving revision 1.4.12.1 diff -C2 -r1.4 -r1.4.12.1 *** howto.tex 1999/03/16 16:10:31 1.4 --- howto.tex 2001/06/06 16:09:54 1.4.12.1 *************** *** 1,2 **** --- 1,9 ---- + % Complete documentation on the extended LaTeX markup used for Python + % documentation is available in ``Documenting Python'', which is part + % of the standard documentation for Python. It may be found online + % at: + % + % http://www.python.org/doc/current/doc/doc.html + \documentclass{howto} Index: manual.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/templates/manual.tex,v retrieving revision 1.2 retrieving revision 1.2.12.1 diff -C2 -r1.2 -r1.2.12.1 *** manual.tex 1999/05/17 16:02:38 1.2 --- manual.tex 2001/06/06 16:09:54 1.2.12.1 *************** *** 1,2 **** --- 1,9 ---- + % Complete documentation on the extended LaTeX markup used for Python + % documentation is available in ``Documenting Python'', which is part + % of the standard documentation for Python. It may be found online + % at: + % + % http://www.python.org/doc/current/doc/doc.html + \documentclass{manual} From fdrake@users.sourceforge.net Wed Jun 6 17:10:40 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 06 Jun 2001 09:10:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/templates module.tex,1.21,1.21.6.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/templates In directory usw-pr-cvs1:/tmp/cvs-serv19811 Modified Files: Tag: release21-maint module.tex Log Message: Typo: "descrition" --> "description" Add reference to the documentation for the Python documentation markup. Fixed up a couple of descriptions. This closes SF bug #430627. Index: module.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/templates/module.tex,v retrieving revision 1.21 retrieving revision 1.21.6.1 diff -C2 -r1.21 -r1.21.6.1 *** module.tex 2000/07/06 16:12:47 1.21 --- module.tex 2001/06/06 16:10:38 1.21.6.1 *************** *** 1,4 **** --- 1,11 ---- % Template for a library manual section. % PLEASE REMOVE THE COMMENTS AFTER USING THE TEMPLATE + % + % Complete documentation on the extended LaTeX markup used for Python + % documentation is available in ``Documenting Python'', which is part + % of the standard documentation for Python. It may be found online + % at: + % + % http://www.python.org/doc/current/doc/doc.html % ==== 0. ==== *************** *** 14,18 **** \section{\module{spam} --- ! Short descrition, for section title} % Choose one of these to specify the module module name. If there's --- 21,25 ---- \section{\module{spam} --- ! Short description, for section title and table of contents} % Choose one of these to specify the module module name. If there's *************** *** 32,38 **** % is omitted, no availability statement is produced or implied. % ! % \platform{UNIX} ! % These apply to all modules: \moduleauthor{name}{email} % Author of the module code; --- 39,45 ---- % is omitted, no availability statement is produced or implied. % ! % \platform{Unix} ! % These apply to all modules, and may be given more than once: \moduleauthor{name}{email} % Author of the module code; From gvanrossum@users.sourceforge.net Wed Jun 6 18:17:16 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 06 Jun 2001 10:17:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.33,2.16.8.34 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv772 Modified Files: Tag: descr-branch typeobject.c Log Message: Improve the docstring and argument checking error messages slightly. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.33 retrieving revision 2.16.8.34 diff -C2 -r2.16.8.33 -r2.16.8.34 *** typeobject.c 2001/06/06 15:40:38 2.16.8.33 --- typeobject.c 2001/06/06 17:17:14 2.16.8.34 *************** *** 219,223 **** /* Check arguments */ ! if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO", kwlist, &name, &bases, &dict)) return -1; --- 219,223 ---- /* Check arguments */ ! if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO:type", kwlist, &name, &bases, &dict)) return -1; *************** *** 444,448 **** /* Check arguments (again?!?! yes, alas -- we need the bases!) */ ! if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO", kwlist, &name, &bases, &dict)) return NULL; --- 444,448 ---- /* Check arguments (again?!?! yes, alas -- we need the bases!) */ ! if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO:type", kwlist, &name, &bases, &dict)) return NULL; *************** *** 486,489 **** --- 486,493 ---- } + static char type_doc[] = + "type(object) -> the object's type\n" + "type(name, bases, dict) -> a new type"; + PyTypeObject PyType_Type = { PyObject_HEAD_INIT(&PyType_Type) *************** *** 508,512 **** 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ ! "Define the behavior of a particular type of object.", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ --- 512,516 ---- 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ ! type_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ From gvanrossum@users.sourceforge.net Wed Jun 6 18:34:16 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 06 Jun 2001 10:34:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects listobject.c,2.92.6.6,2.92.6.7 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv4094 Modified Files: Tag: descr-branch listobject.c Log Message: Make the list constructor initialize the list from an optional 'sequence' argument. Also add a proper docstring, making this a drop-in replacement for the built-in list() function. Index: listobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v retrieving revision 2.92.6.6 retrieving revision 2.92.6.7 diff -C2 -r2.92.6.6 -r2.92.6.7 *** listobject.c 2001/06/06 14:27:54 2.92.6.6 --- listobject.c 2001/06/06 17:34:14 2.92.6.7 *************** *** 1497,1505 **** } static int list_init(PyListObject *self, PyObject *args, PyObject *kw) { ! self->ob_size = 0; ! self->ob_item = NULL; return 0; } --- 1497,1589 ---- } + /* Adapted from newer code by Tim */ static int + list_fill(PyListObject *result, PyObject *v) + { + PyObject *it; /* iter(v) */ + int n; /* guess for result list size */ + int i; + + n = result->ob_size; + + /* Special-case list(a_list), for speed. */ + if (PyList_Check(v)) { + if (v == (PyObject *)result) + return 0; /* source is destination, we're done */ + return list_ass_slice(result, 0, n, v); + } + + /* Empty previous contents */ + if (n != 0) { + if (list_ass_slice(result, 0, n, (PyObject *)NULL) != 0) + return -1; + } + + /* 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 -1; + + /* 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 */ + NRESIZE(result->ob_item, PyObject*, n); + if (result->ob_item == NULL) + goto error; + result->ob_size = n; + + /* Run iterator to exhaustion. */ + for (i = 0; ; i++) { + PyObject *item = PyIter_Next(it); + if (item == NULL) { + if (PyErr_Occurred()) + goto error; + break; + } + if (i < n) + PyList_SET_ITEM(result, i, item); /* steals ref */ + else { + int status = ins1(result, result->ob_size, item); + Py_DECREF(item); /* append creates a new ref */ + if (status < 0) + goto error; + } + } + + /* Cut back result list if initial guess was too large. */ + if (i < n && result != NULL) { + if (list_ass_slice(result, i, n, (PyObject *)NULL) != 0) + goto error; + } + Py_DECREF(it); + return 0; + + error: + Py_DECREF(it); + return -1; + } + + static int list_init(PyListObject *self, PyObject *args, PyObject *kw) { ! PyObject *arg = NULL; ! static char *kwlist[] = {"sequence", 0}; ! ! if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:list", kwlist, &arg)) ! return -1; ! if (arg != NULL) ! return list_fill(self, arg); ! if (self->ob_size > 0) ! return list_ass_slice(self, 0, self->ob_size, (PyObject*)NULL); return 0; } *************** *** 1550,1553 **** --- 1634,1641 ---- }; + static char list_doc[] = + "list() -> new list\n" + "list(sequence) -> new list initialized from sequence's items"; + PyTypeObject PyList_Type = { PyObject_HEAD_INIT(&PyType_Type) *************** *** 1572,1576 **** 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */ ! 0, /* tp_doc */ (traverseproc)list_traverse, /* tp_traverse */ (inquiry)list_clear, /* tp_clear */ --- 1660,1664 ---- 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */ ! list_doc, /* tp_doc */ (traverseproc)list_traverse, /* tp_traverse */ (inquiry)list_clear, /* tp_clear */ *************** *** 1658,1662 **** 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */ ! 0, /* tp_doc */ (traverseproc)list_traverse, /* tp_traverse */ 0, /* tp_clear */ --- 1746,1750 ---- 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */ ! list_doc, /* tp_doc */ (traverseproc)list_traverse, /* tp_traverse */ 0, /* tp_clear */ From gvanrossum@users.sourceforge.net Wed Jun 6 18:43:44 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 06 Jun 2001 10:43:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.198,2.198.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv5779 Modified Files: Tag: descr-branch bltinmodule.c Log Message: A first step towards an idea that received much enthusiasm on python-dev: instead of having built-in functions list and type, use the built-in types list and type, whose API has been extended to accommodate this usage. Also added object and dictionary (not dict, that's too common a local variable name). (For now, the API for dictionary() is undecided.) Many more will follow in due time(tuple, xrange, str, unicode, int, long, float, complex, slice, maybe iter, maybe open), but first I need to get back to doing multiple inheritance right. Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.198 retrieving revision 2.198.2.1 diff -C2 -r2.198 -r2.198.2.1 *** bltinmodule.c 2001/04/20 19:13:02 2.198 --- bltinmodule.c 2001/06/06 17:43:42 2.198.2.1 *************** *** 1359,1378 **** static PyObject * - builtin_list(PyObject *self, PyObject *args) - { - PyObject *v; - - if (!PyArg_ParseTuple(args, "O:list", &v)) - return NULL; - return PySequence_List(v); - } - - static char list_doc[] = - "list(sequence) -> list\n\ - \n\ - Return a new list whose items are the same as those of the argument sequence."; - - - static PyObject * builtin_slice(PyObject *self, PyObject *args) { --- 1359,1362 ---- *************** *** 1992,2013 **** static PyObject * - builtin_type(PyObject *self, PyObject *args) - { - PyObject *v; - - if (!PyArg_ParseTuple(args, "O:type", &v)) - return NULL; - v = (PyObject *)v->ob_type; - Py_INCREF(v); - return v; - } - - static char type_doc[] = - "type(object) -> type object\n\ - \n\ - Return the type of the object."; - - - static PyObject * builtin_vars(PyObject *self, PyObject *args) { --- 1976,1979 ---- *************** *** 2177,2181 **** {"iter", builtin_iter, 1, iter_doc}, {"len", builtin_len, 1, len_doc}, - {"list", builtin_list, 1, list_doc}, {"locals", builtin_locals, 1, locals_doc}, {"long", builtin_long, 1, long_doc}, --- 2143,2146 ---- *************** *** 2197,2201 **** {"str", builtin_str, 1, str_doc}, {"tuple", builtin_tuple, 1, tuple_doc}, - {"type", builtin_type, 1, type_doc}, {"unicode", builtin_unicode, 1, unicode_doc}, {"unichr", builtin_unichr, 1, unichr_doc}, --- 2162,2165 ---- *************** *** 2227,2230 **** --- 2191,2204 ---- if (PyDict_SetItemString(dict, "NotImplemented", Py_NotImplemented) < 0) + return NULL; + if (PyDict_SetItemString(dict, "dictionary", + (PyObject *) &PyDict_Type) < 0) + return NULL; + if (PyDict_SetItemString(dict, "list", (PyObject *) &PyList_Type) < 0) + return NULL; + if (PyDict_SetItemString(dict, "object", + (PyObject *) &PyBaseObject_Type) < 0) + return NULL; + if (PyDict_SetItemString(dict, "type", (PyObject *) &PyType_Type) < 0) return NULL; debug = PyInt_FromLong(Py_OptimizeFlag == 0); From gvanrossum@users.sourceforge.net Wed Jun 6 18:51:59 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 06 Jun 2001 10:51:59 -0700 Subject: [Python-checkins] CVS: python/dist/src Makefile.pre.in,1.38,1.39 .cvsignore,2.2,2.3 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv7631 Modified Files: Makefile.pre.in .cvsignore Log Message: Acknowledge the existence of the 'platform' file, generated by the Makefile and used by the setup.py script. Ignore it in .cvsignore; remove it in "make clobber". Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -r1.38 -r1.39 *** Makefile.pre.in 2001/06/02 06:16:02 1.38 --- Makefile.pre.in 2001/06/06 17:51:57 1.39 *************** *** 764,768 **** tags TAGS \ config.cache config.log config.h Modules/config.c ! -rm -rf build # Make things extra clean, before making a distribution: --- 764,768 ---- tags TAGS \ config.cache config.log config.h Modules/config.c ! -rm -rf build platform # Make things extra clean, before making a distribution: Index: .cvsignore =================================================================== RCS file: /cvsroot/python/python/dist/src/.cvsignore,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -r2.2 -r2.3 *** .cvsignore 2001/05/15 01:53:40 2.2 --- .cvsignore 2001/06/06 17:51:57 2.3 *************** *** 9,10 **** --- 9,11 ---- build Makefile.pre + platform From gvanrossum@users.sourceforge.net Wed Jun 6 18:59:43 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 06 Jun 2001 10:59:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects abstract.c,2.60.2.2,2.60.2.3 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv9436 Modified Files: Tag: descr-branch abstract.c Log Message: Stamp out duplicate code: PySequence_List(x) should call list(x). Index: abstract.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v retrieving revision 2.60.2.2 retrieving revision 2.60.2.3 diff -C2 -r2.60.2.2 -r2.60.2.3 *** abstract.c 2001/05/05 11:37:29 2.60.2.2 --- abstract.c 2001/06/06 17:59:41 2.60.2.3 *************** *** 1237,1286 **** PySequence_List(PyObject *v) { - PySequenceMethods *m; - if (v == NULL) return null_error(); ! ! if (PyList_Check(v)) ! return PyList_GetSlice(v, 0, PyList_GET_SIZE(v)); ! ! m = v->ob_type->tp_as_sequence; ! if (m && m->sq_item) { ! int i; ! PyObject *l; ! int n = PySequence_Size(v); ! if (n < 0) ! return NULL; ! l = PyList_New(n); ! if (l == 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(l); ! l = NULL; ! } ! break; ! } ! if (i < n) ! PyList_SET_ITEM(l, i, item); ! else if (PyList_Append(l, item) < 0) { ! Py_DECREF(l); ! l = NULL; ! break; ! } ! } ! if (i < n && l != NULL) { ! if (PyList_SetSlice(l, i, n, (PyObject *)NULL) != 0) { ! Py_DECREF(l); ! l = NULL; ! } ! } ! return l; ! } ! return type_error("list() argument must be a sequence"); } --- 1237,1243 ---- PySequence_List(PyObject *v) { if (v == NULL) return null_error(); ! return PyObject_CallFunction((PyObject *) &PyList_Type, "(O)", v); } From fdrake@users.sourceforge.net Wed Jun 6 19:26:13 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 06 Jun 2001 11:26:13 -0700 Subject: [Python-checkins] CVS: python/nondist/sftools - New directory Message-ID: Update of /cvsroot/python/python/nondist/sftools In directory usw-pr-cvs1:/tmp/cvs-serv15001/sftools Log Message: Directory /cvsroot/python/python/nondist/sftools added to the repository From fdrake@users.sourceforge.net Wed Jun 6 19:28:02 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 06 Jun 2001 11:28:02 -0700 Subject: [Python-checkins] CVS: python/nondist/sftools README.txt,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/sftools In directory usw-pr-cvs1:/tmp/cvs-serv15278 Added Files: README.txt Log Message: A description of what can be found in this directory. --- NEW FILE: README.txt --- This directory contains some scripts that Jeremy Hylton wrote for working with the SourceForge bug manager. They do two things: 1. Yank data from a JitterBug database and upload it to SourceForge. This isn't needed for Python anymore, but it may still be useful for someone. 2. Pull data from the SourceForge bug manager and populate a local database with the information. Data is extracted by scraping the SourceForge HTML responses for actual information. The local database can be used to efficiently process ad hoc queries that would be difficult to perform using SourceForge directly, and would have been impossible at the time these scripts were first written. The catch: these scripts were written before SourceForge merged their bug and patch managers to create their general "tracker" facility, and before their framework became as skinnable as it is today. This code will need some measure of revision before it can be used again, but should serve as a nice start for creating an updated form of such tools. From fdrake@users.sourceforge.net Wed Jun 6 19:29:13 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 06 Jun 2001 11:29:13 -0700 Subject: [Python-checkins] CVS: python/nondist/sftools bug.py,NONE,1.1 buglib.py,NONE,1.1 jitterbuglib.py,NONE,1.1 login.py,NONE,1.1 patchtool.py,NONE,1.1 pest.py,NONE,1.1 sf-schema.txt,NONE,1.1 sfdb.py,NONE,1.1 sflib.py,NONE,1.1 upload.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/sftools In directory usw-pr-cvs1:/tmp/cvs-serv15643 Added Files: bug.py buglib.py jitterbuglib.py login.py patchtool.py pest.py sf-schema.txt sfdb.py sflib.py upload.py Log Message: Jeremy's original code to work with the SourceForge bug manager from Python. --- NEW FILE: bug.py --- #! /usr/bin/env python """Update one or more bugs""" import buglib import login import sfdb import getopt import sys # flags: do we use each of the following? LOCAL_DATABASE = 1 SOURCEFORGE = 1 VERBOSE = 0 LOGIN = None PASSWORD = None FIELDS = ("summary", "bug_group_id", "category_id", "resolution_id", "status_id", "assigned_to", "priority", "details") argnames = {} for field in FIELDS: argnames['--' + field] = field def main(bug_ids, updates): """Update one or more bugs using the fields in udpates bug_ids -- list of SF bug_ids updates -- keys are SF field names, values are the strings to put there """ bug_ids = [int(bug) for bug in bug_ids] session = login.Login(LOGIN, PASSWORD) db = sfdb.BugDBInterface() update_ids = translate_updates(db, updates) for bug in bug_ids: b = db.get(bug) for k, v in update_ids.items(): if k == 'assigned_to': b.assign(v) else: b.set(k, v) b.flush() buglib.update_bug(b.get_form_data(), session) if VERBOSE: print bug def translate_updates(db, updates): trans = {} for k, v in updates.items(): if k in ('summary', 'assigned_to', 'details'): trans[k] = v continue table = k[:-3] mapping = getattr(db, table) trans[k] = mapping.lookup(v) if VERBOSE: print trans return trans if __name__ == "__main__": field_args = [field + "=" for field in FIELDS] opts, args = getopt.getopt(sys.argv[1:], 'v', ["verbose", "login=", "password="] \ + field_args) updates = {} for k, v in opts: if k in ('-v', '--verbose'): VERBOSE = 1 elif argnames.has_key(k): updates[argnames[k]] = v elif k == '--login': LOGIN = v elif k == '--password': PASSWORD = v assert len(args) > 0, "Must specify at least one bug id" if LOGIN is None: LOGIN = raw_input("SF username: ") if PASSWORD is None: import getpass PASSWORD = getpass.getpass("SF Password: ") main(args, updates) --- NEW FILE: buglib.py --- """Tools to interact with SF Bug Tracker""" import formatter import getpass import htmllib import httplib import urllib import urlparse try: import cPickle except ImportError: import pickle else: pickle = cPickle import pg import login import sflib import sfdb BUG_SUMMARY_URL = "http://sourceforge.net/bugs/?group_id=5470&set=custom&_assigned_to=0&_status=1&_category=100&_bug_group=100&SUBMIT=Browse" BUG_LOAD_URL = "http://sourceforge.net/bugs/index.php?group_id=5470&func=detailbug&bug_id=%s" BUG_POST_URL = "http://sourceforge.net/bugs/index.php" VERBOSE = 1 class BugParser(htmllib.HTMLParser): __super_init = htmllib.HTMLParser.__init__ VERBOSE = 0 def __init__(self, formatter, verbose=None): self.__super_init(formatter) self.fields = {} self.current_field = None self.current_field_value = None self.summary = None self.bug_id = None if verbose is not None: self.VERBOSE = verbose def start_select(self, attrs): if self.VERBOSE: print "SELECT", attrs for k, v in attrs: if k == 'name': self.current_field = v assert self.current_field is not None def end_select(self): self.current_field = None def start_option(self, attrs): if self.VERBOSE: print "OPTION", attrs assert self.current_field_value is None selected = 0 for k, v in attrs: if k == 'value': value = v if k == 'selected': selected = 1 if selected: self.current_field_value = value self.save_bgn() def end_option(self): if self.current_field_value is not None: label = self.save_end() self.fields[self.current_field] = (label, self.current_field_value) self.current_field_value = None def start_input(self, attrs): summary = 0 bug_id = 0 value = None for k, v in attrs: if k == 'name' and v == 'summary': summary = 1 elif k == 'value': value = v elif k == 'name' and v == 'bug_id': bug_id = 1 if summary: assert self.summary is None assert value is not None self.summary = value if bug_id: assert self.bug_id is None assert value is not None self.bug_id = value def get_bug_urls(): urls = [] p = sflib.SummaryParser(BUG_SUMMARY_URL, ('detailbug',)) p.load(BUG_SUMMARY_URL) for path, query, frag in p.hrefs: url = urlparse.urljoin(BUG_SUMMARY_URL, path) urls.append(url) if VERBOSE: print "%d bugs found" % len(urls) return urls def http_get(url, session): try: f = session.get(url) buf = f.read() f.close() except httplib.HTTPException, err: print "Error occurred loading %s" % url print err print return None return buf def load_bug(url, session): for i in range(3): buf = http_get(url, session) if buf is not None: break time.sleep(10) else: raise RuntimeError, "could not load %s" % url p = BugParser(formatter.NullFormatter()) p.feed(buf) return p.bug_id, p.summary, p.fields # a list of fields in the bug submission form that are currently # ignored and what value should be used for them on submission _ignored_fields = [("canned_response", "100"), ("dependent_on_task[]", "100"), ("dependent_on_bug[]", "100"), ] def update_bug(bug_info, session): """Update SF bug tracker with new bug_info bug_info is a dictionary returned from the local database session is the login session returned by login.Login """ form = {'func': 'postmodbug', 'group_id': '5470', 'submit': 'Submit Changes', } for k, v in bug_info.items(): form[k] = str(v) # fill in blank values for everything else for k, v in _ignored_fields: form[k] = v body = urllib.urlencode(form) headers = {'Content-Type': 'application/x-www-form-urlencoded', } return session.get(BUG_POST_URL, "POST", headers, body) def make_bug_urls(bugs): return [BUG_LOAD_URL % bug for bug in bugs] def main(bugs=None): session = login.Login("jhylton", getpass.getpass()) db = sfdb.BugDBInterface(pg.connect()) if bugs: urls = make_bug_urls(bugs) else: urls = get_bug_urls() for url in urls: if VERBOSE: print url bug_id, summary, fields = load_bug(url, session) if VERBOSE: print bug_id, summary print if db.exists(bug_id): db.update(bug_id, summary, fields) else: db.insert(bug_id, summary, fields) if __name__ == "__main__": import sys if len(sys.argv) > 1: main(sys.argv[1:]) else: main() --- NEW FILE: jitterbuglib.py --- """Library for reading Jitterbug records and submitting them to SF A Jitterbug database has one or more categories of bugs, like incoming, open, resolved, etc. Each category is represented by a directory. Each bug is stored in one or more files in that directory; each bug has a unique id. The files for bug NNN are * NNN: A mail message containing the bug report * NNN.notes: Any notes entered via the Jitterbug Web interface * NNN.audit: A log of changes to the bug record; one per line * NNN.followup.I: one or more followup mail messages; first one is numbered 1 * NNN.reply.I: one or more replies entered throught the Web form; first one is numbered 1 This program loads each bug report for a category into the SF Bug Tracker. """ import cgi import os import re import rfc822 import urllib import urlparse try: from cStringIO import StringIO except ImportError: from StringIO import StringIO import sflib VERBOSE = 0 SF_SUBMIT_URL = "http://sourceforge.net/bugs/index.php" class BugLabels: PROJECT_GROUP_ID = None ASSIGNMENT = "100" CATEGORY = "100" GROUP = "100" PRIORITY = "5" def set_label(label, val): setattr(BugLabels, label, val) class Message: def __init__(self, path): self.path = path f = open(path) self.msg = rfc822.Message(f) self.body = self.msg.fp.read() f.close() def __getattr__(self, attr): return getattr(self.msg, attr) def dump(self): """Return a string with a minimal copy of the message""" headers = [] for field in "From", "Subject", "Date": val = self.msg.getheader(field) if val: headers.append("%s: %s" % (field, val)) return "\n".join(headers) + "\n\n" + self.body class Notes: def __init__(self, buf): self.buf = buf def dump(self): return self.buf class Bug: def __init__(self, dir, bug_id): self.id = bug_id self.dir = dir self.root = os.path.join(dir, bug_id) self._load() def _load(self): self._load_root() self._load_audit() self._load_followups() self._load_replys() self._load_notes() def _load_root(self): f = open(self.root) self.msg = rfc822.Message(f) # The body of a Jitterbug mail message has four more rfc822 # headers. Parse these as another message object, then get # the real body out of the second Message object. g = StringIO(self.msg.fp.read()) self.msg_headers = rfc822.Message(g) self.msg_body = self.msg_headers.fp.read() g.close() f.close() def _load_audit(self): audit_path = self.root + ".audit" if not os.path.exists(audit_path): self.audit = None else: f = open(audit_path) self.audit = f.read() f.close() def _load_notes(self): notes_path = self.root + ".notes" if not os.path.exists(notes_path): self.notes = None else: f = open(notes_path) self.notes = f.read() f.close() def _load_numbered(self, name): rx = re.compile("%s.%s.(\d+)" % (self.id, name)) elts = {} for file in os.listdir(self.dir): mo = rx.match(file) if not mo: continue msg = Message(os.path.join(self.dir, file)) elts[int(mo.group(1))] = msg if elts: l = elts.items() l.sort() l = map(lambda x:x[1], l) else: l = [] return l def _load_followups(self): self.followups = self._load_numbered('followup') def _load_replys(self): self.replys = self._load_numbered('reply') def dump(self, io): template = """Jitterbug-Id: %(jid)s Submitted-By: %(sender)s Date: %(date)s Version: %(version)s OS: %(os)s %(body)s ==================================================================== Audit trail: %(audit)s """ jid = self.id sender = self.msg.getheader('from') date = self.msg.getheader('date') version = self.msg_headers.getheader('version') os = self.msg_headers.getheader('os') body = self.msg_body audit = self.audit io.write(template % vars()) def submit(self, url): buf = self.submit_initial(url) if not (self.followups or self.replys or self.notes): if VERBOSE: print "Done" return # find the SF bug id and post comments for each reply or # followup p = self._load_bug_summary(url, buf) self.submit_followups(url) def submit_initial(self, url): if VERBOSE: print "Submitting bug PR#%s" % self.id data = self.encode_initial_bug_report() f = urllib.urlopen(url, data) resp = f.read() f.close() return resp def submit_followups(self, url): bug_id = self.find_bug_id(url) if bug_id is None: print "Error entering bug PR#%s" % self.id return i = 0 for msg in self.replys + self.followups: i = i + 1 data = self.encode_followup_comment(bug_id, msg) if VERBOSE: print "Submitting followup/reply", i urllib.urlopen(url, data) if self.notes: if VERBOSE: print "Submitting notes" data = self.encode_followup_comment(bug_id, Notes(self.notes)) urllib.urlopen(url, data) def find_bug_id(self, url): try: return self._bsp.get_sf_bug_id(self.id) except KeyError: return None def _load_bug_summary(self, url, buf): """Load a bug summary start with the HTML response in buf""" self._bsp = BugSummaryParser() self._bsp.parse(buf) def encode_initial_bug_report(self): # the form vars definitions are defined by the form used to # submit bugs on SF form_vars = {'func': 'postaddbug', 'group_id': BugLabels.PROJECT_GROUP_ID, 'category': BugLabels.CATEGORY, 'bug_group_id': BugLabels.GROUP, 'priority': BugLabels.PRIORITY, 'assigned_to': BugLabels.ASSIGNMENT, } form_vars['summary'] = "%s (PR#%s)" % \ (self.msg.getheader('subject'), self.id) collector = StringIO() self.dump(collector) collector.seek(0, 0) form_vars['details'] = collector.read().strip() return urllib.urlencode(form_vars) def encode_followup_comment(self, bug_id, msg): form_vars = {'func': 'postaddcomment', 'group_id': BugLabels.PROJECT_GROUP_ID, 'bug_id': bug_id, } form_vars['details'] = msg.dump() return urllib.urlencode(form_vars) class BugSummaryParser: """Parse the bug summary page from sourceforge Specific intent of this class is to extract the SF bug id associated with a newly entered jitterbug record. We identify the Jitterbug record by the (PR#NNN) string in the details line. The Requires that each bug is on its own line in the HTML table. If SF changes its output, all bets are off. """ def __init__(self): self.bugs = {} self.parser = sflib.SummaryParser(SF_SUBMIT_URL, ('detailbug',)) def get_sf_bug_id(self, pr_id): return self.bugs[pr_id] rx_pr = re.compile('\(PR#(\d+)\)') def parse(self, buf): self.parser.parse(buf) self._load_hrefs() def _load_hrefs(self): """Load hrefs from the parser object inecto self.bugs""" for href, query_dict, line in self.parser.get_hrefs(): mo = self.rx_pr.search(line) if not mo: continue pr_id = mo.group(1) bug_id = query_dict['bug_id'] self.bugs[pr_id] = bug_id --- NEW FILE: login.py --- import httplib import re import urllib SF_HOST = "sourceforge.net" FORM_URL = "http://sourceforge.net/account/login.php" test_url = "http://sourceforge.net/bugs/?func=detailbug&group_id=5470&bug_id=112628" class Session: def __init__(self, username, password): self.session_hash = None self._do_login(username, password) if self.session_hash is None: raise ValueError, "invalid username and password" def _do_login(self, username, password): form = {'return_to': '', 'form_loginname': username, 'form_pw': password, 'stay_in_ssl': '1', 'login': 'Login', } query = urllib.urlencode(form) headers = {'Content-Type': 'application/x-www-form-urlencoded', } c = httplib.HTTPConnection(SF_HOST) c.connect() c.request('POST', FORM_URL, query, headers) resp = c.getresponse() cookie = resp.msg.getheader('set-cookie') if cookie is None: raise ValueError, "invalid name/password: %s" % resp.read() self.session_hash = self._get_session_hash(cookie) _rx_sess_hash = re.compile('(session_hash=[a-z0-9]+);') def _get_session_hash(self, cookie): mo = self._rx_sess_hash.search(cookie) if mo: return mo.group(1) raise ValueError, "could not find session_hash in %s" % repr(cookie) def get(self, url, method="GET", headers={}, body=None): c = httplib.HTTPConnection(SF_HOST) c.set_debuglevel(1) c.connect() _headers = {'Cookie': self.session_hash} if headers: _headers.update(headers) if body: c.request(method, url, body, _headers) else: c.request(method, url, headers=_headers) resp = c.getresponse() return resp def Login(username, password): return Session(username, password) --- NEW FILE: patchtool.py --- """Screen scraper for Patch Manager interface The patch form URL is http://www.sourceforge.net/patch/index.php. GET method If I'm lucky, it can be used without authentication. the input fields are: (* means hidden field) *group_id=5470 *custom=set _assigned_to=None _status=None This script produces the following HTML for each entry: 100518 fix bltinmodule.c for 64-bit platforms 2000-Jun-07 03:21 gvanrossum tmick If there are more than 50 patches, the following HTML is produced:   Next 50 --> Future plans: support authentication command-line interface for modifying patches """ import cgi import re import types from urllib import urlencode from urlparse import urljoin from urllib import urlopen import pg from sfdb import PatchDBInterface VERBOSE = 0 DATABASE = None class PatchListParser: """Minimal re-based parsed that grabs relevant URLs from summary""" rx_href = re.compile('HREF="([?/=&_A-Za-z0-9]+)"') def parse_hrefs(self, buf): hrefs = [] offset = 0 while 1: mo = self.rx_href.search(buf, offset) if mo is None: break offset = mo.end(1) hrefs.append(mo.group(1)) return hrefs def get_query_hrefs(self, buf): queries = [] for href in self.parse_hrefs(buf): if href[0] == '?': queries.append(href) return queries class PatchParser: """Minimal re-based parser that pulls key-values from patch page""" rx_entry = re.compile(']*>(.+):
(.+)') def parse(self, buf): entries = {} offset = 0 while 1: mo = self.rx_entry.search(buf, offset) if mo is None: break offset = mo.end(2) k, v = mo.group(1, 2) entries[k] = v return entries def urldecode(query): d = cgi.parse_qs(query) for k, v in d.items(): if len(v) != 1: raise ValueError, "unexpected duplicate entry" d[k] = v[0] return d class PatchManager: url = "http://www.sourceforge.net/patch/index.php" group_id = 5470 list_parser = PatchListParser() patch_parser = PatchParser() # XXX to get the right numeric values for assigned_to and status, # would need to scrape them out of the form... def get_patches(self, assigned_to='0', status='0'): assert type(assigned_to) == types.StringType assert type(status) == types.StringType url = self._get_initial_query(assigned_to, status) patch_list = self._load_patch_summary(url) patches = {} for patch_id, p in patch_list: patches[patch_id] = self._load_patch_detail(p) return patches def _get_initial_query(self, assigned_to, status): dict = {'group_id': self.group_id, 'set': 'custom', 'SUBMIT': 'Browse', '_assigned_to': assigned_to, '_status': status, } query = urlencode(dict) return "%s?%s" % (self.url, query) def _load_patch_summary(self, url): todo = [(url, 0)] patches = [] offset = 0 while todo: url, offset = todo[0] del todo[0] if VERBOSE: print "load %s" % url buf = urlopen(url).read() for href in self.list_parser.get_query_hrefs(buf): d = urldecode(href[1:]) if d['func'] == 'detailpatch': patches.append((int(d['patch_id']), urljoin(self.url, href))) elif d['func'] == 'browse': new_offset = int(d['offset']) if new_offset > offset: todo.append((urljoin(self.url, href), new_offset)) return patches def _load_patch_detail(self, url): if VERBOSE: print "load %s" % url buf = urlopen(url).read() return self.patch_parser.parse(buf) if __name__ == "__main__": import sys import getopt opts, args = getopt.getopt(sys.argv[1:], 'vd:') assert len(args) == 0 for k, v in opts: if k == '-v': VERBOSE = 1 elif k == '-d': DATABASE = v pmgr = PatchManager() if VERBOSE: print "Loading patches" p = pmgr.get_patches() if VERBOSE: print "Retrieved %d patches" % len(p) if VERBOSE: print "Inserting into local database" if DATABASE: db = pg.connect(DATABASE) else: db = pg.connect() pdbi = PatchDBInterface(db) for p_id, attrs in p.items(): pdbi.update(p_id, attrs) if VERBOSE: new = len(p) - pdbi.num_deletes print "Found %d new patches" % new print "Updated %d existing patches" % pdbi.num_deletes --- NEW FILE: pest.py --- #! /usr/bin/env python """Pest people about patches that aren't closed""" import os import pg import smtplib from patchdb import PatchDBInterface SF_MAIL_SERVER = "ns1.varesearch.com" VERBOSE = 1 QUERY = "SELECT * FROM patches_t WHERE assigned_to = %d " \ "AND status = %d" HEADER = " user open accepted\n" \ "---------------+------+-----------" ENTRY = "%-15.15s|%5d | %6d" FROM = "Jeremy Hylton " MSG_TEMPLATE = """From: Jeremy Hylton To: %(user)s Subject: Open and Accepted patches reminder This message is automatically generated using the SF Patch Manager database. The database shows that you have %(count)s patches. Open patches need to be resolved -- either accepted, rejected, or postponed. Accepted patches need to be applied and closed. The sooner this can be done the better. Open patches should be resolved by the end of August in order to meet the 2.0b1 release deadline. The specific patches assigned to you are: """ MSG_ENTRY_TEMPLATE = """Patch #%(patch_id)s: %(summary)s http://sourceforge.net/patch/?func=detailpatch&group_id=5470&patch_id=%(patch_id)s """ def send_pest_mail(user, open, accepted): user = user + "@users.sourceforge.net" n_open = len(open) n_accepted = len(accepted) if n_open: if n_accepted: count = "%d open and %d accepted" % (n_open, n_accepted) else: count = "%d open" % n_open else: if n_accepted: count = "%d accepted" % n_accepted else: raise ValueError, "both open and accepted were empty" msg = MSG_TEMPLATE % locals() status = [] for patch_info in open + accepted: patch_id, summary = patch_info[:2] status.append(MSG_ENTRY_TEMPLATE % locals()) msg = msg + "\n".join(status) s = smtplib.SMTP("smtp.concentric.net") # s.set_debuglevel(1) s.sendmail(FROM, (user,), msg) # s.sendmail(FROM, ("jhylton@users.sourceforge.net",), msg) s.close() def main(): dbname = os.environ['USER'] db = PatchDBInterface(pg.connect(dbname)) st_open = db.status.lookup('Open') st_accepted = db.status.lookup('Accepted') if VERBOSE: print HEADER for user, user_id in db.users.get_dict().items(): if user_id <= 100: # system-defined user ids continue open = db.query(QUERY % (user_id, st_open)).getresult() accepted = db.query(QUERY % (user_id, st_accepted)).getresult() if not (open or accepted): if VERBOSE: print ENTRY % (user, 0, 0) continue if VERBOSE: print ENTRY % (user, len(open), len(accepted)) send_pest_mail(user, open, accepted) if __name__ == "__main__": main() --- NEW FILE: sf-schema.txt --- CREATE TABLE users_t ( user_id int PRIMARY KEY, username text NOT NULL ); CREATE TABLE status_t ( status_id int PRIMARY KEY, name text NOT NULL ); CREATE TABLE patches_t ( patch_id int PRIMARY KEY, summary text, status int REFERENCES status_t, category text, date text, submitted_by int REFERENCES users_t, assigned_to int REFERENCES users_t, summary_url text ); CREATE TABLE category_t ( category_id int PRIMARY KEY, name text NOT NULL ); CREATE TABLE resolution_t ( resolution_id int PRIMARY KEY, name text NOT NULL ); CREATE TABLE bug_group_t ( bug_group_id int PRIMARY KEY, name text NOT NULL ); CREATE TABLE bug_t ( bug_id int PRIMARY KEY, summary text, bug_group_id int REFERENCES bug_group_t, category_id int REFERENCES category_t, resolution_id int REFERENCES resolution_t, status_id int REFERENCES status_t, assigned_to int REFERENCES users_t, priority int ); --- NEW FILE: sfdb.py --- import pg import re def quote(s): return re.sub("'", r"\'", s) class QueryResult: def __init__(self, result): self.__result = result self.__tuple = None def getresult(self): if self.__tuple is None: self.__tuple = self.__result.getresult() return self.__tuple def __len__(self): return len(self.getresult()) def __getattr__(self, attr): return getattr(self.__result, attr) class SQLMapping: """Decode a simple mapping from an SQL table An interface for a simple SQL table of the following sort: CREATE TABLE bug_group_t ( bug_group_id int PRIMARY KEY, name text NOT NULL ); The chief requirements are that the types of the two fields match the example above. Assumes that the keys and values are disjoint, so that a single interface can resolve in either direction. """ def __init__(self, db, table, fields="*"): self.dict1 = {} self.dict2 = {} self.__db = db self.__table = table r = db.query("SELECT %s FROM %s" % (fields, table)).getresult() for key, val in r: assert None not in (key, val) self.dict1[key] = val self.dict2[val] = key def lookup(self, kv): r = self.dict1.get(kv) if r is None: r = self.dict2.get(kv) return r def get_dict(self): """Return dict mapping key to value""" return self.dict2 __insert_q = "INSERT INTO %(table)s VALUES (%(key)s, '%(value)s')" def insert(self, key, value): table = self.__table value = quote(value) query = self.__insert_q % locals() self.__db.query(query) self.dict1[key] = value self.dict2[value] = key class PatchDBInterface: """Interface between the PatchManager and the SQL database Scheme for the patches table is: CREATE TABLE patches_t ( patch_id int PRIMARY KEY, summary text, status int REFERENCES status_t, category text, date text, submitted_by int REFERENCES users_t, assigned_to int REFERENCES users_t, summary_url text ); """ def __init__(self, db=None): db = db or pg.connect() self.db = db self.users = SQLMapping(db, 'users_t') self.status = SQLMapping(db, 'status_t') self.num_deletes = 0 def update(self, patch_id, attrs): # resolve REFERENCES status = self.status.lookup(attrs['Status']) submitted_by = self.users.lookup(attrs['Submitted By']) if submitted_by is None: submitted_by = 0 assigned_to = self.users.lookup(attrs['Assigned To']) if assigned_to is None: assigned_to = 100 # delete old version if necessary if self.has_patch(patch_id): q = "DELETE FROM patches_t WHERE patch_id = %(patch_id)d" self.db.query(q % locals()) self.num_deletes = self.num_deletes + 1 d = locals() del d['attrs'] # just to make debugging prints clearer for k, v in attrs.items(): d[k] = pg._quote(v, 0) q = "INSERT INTO patches_t VALUES (%(patch_id)d," \ " %(Summary)s, %(status)d, %(Category)s, %(Date)s," \ " %(submitted_by)d, %(assigned_to)d)" self.db.query(q % d) def has_patch(self, patch_id): r = self.db.query("SELECT * FROM patches_t" \ " WHERE patch_id = %d" % patch_id).getresult() if r: return 1 else: return 0 def query(self, query): return self.db.query(query) class Bug: """Interface to bug_t row""" def __init__(self, bug_info, db): self.__db = db self.__dict = bug_info self.__clean = 1 # Keep this one around solely for the benefit of the SF Web # interface; the local database ignores it. self.__details = None def get(self, attr): """Get an attribute of the bug This method understands a few different kinds of keys: names of bug_t columns, e.g. summary, status_id, etc. names of bug_t references, e.g. status returns the value referred to by status_id """ if self.__dict.has_key(attr): return self.__dict[attr] ref = attr + "_id" if self.__dict.has_key(ref): return self.__get_ref(attr, ref) if attr == "details": return self.__details raise KeyError, "no attribute: %s" % attr def __get_mapping(self, table): try: mapping = getattr(self.__db, table) except AttributeError: raise KeyError, "no table for attribute: %s" % table return mapping def __get_ref(self, table, id): mapping = self.__get_mapping(table) return mapping.lookup(self.__dict[id]) def set(self, attr, value): if attr == 'details': self.__details = value return if self.__dict.has_key(attr): self.__clean = 0 self.__dict[attr] = value return ref = attr + "_id" if self.__dict.has_key(ref): self.__set_ref(attr, ref, value) return raise KeyError, "no attribute: %s" % attr def __set_ref(self, table, id, value): mapping = self.__get_mapping(table) key = mapping.lookup(value) if key is None: raise ValueError, "invalid attribute for table %s: %s" % \ (table, value) # __dict holds keys to values in the mapping self.__clean = 0 self.__dict[id] = key def assign(self, username): # the set interface does not work well here self.__set_ref("users", "assigned_to", username) _update_ids = ('bug_group_id', 'status_id', 'category_id', 'resolution_id') def get_update_data(self): """Return data in the format expected by db update method""" d = {} for attr in Bug._update_ids: attr_value = attr[:-3] key = self.get(attr_value) if key is not None: d[attr] = key, self.get(attr) d['priority'] = self.get('priority'), self.get('priority') user = self.__get_ref('users', 'assigned_to') if user is not None: d['assigned_to'] = user, self.get('assigned_to') for attr, (k, v) in d.items(): d[attr] = k, str(v) return self.__dict['bug_id'], self.__dict['summary'], d _form_keys = ('bug_id', 'summary', 'category_id', 'priority', 'bug_group_id', 'resolution_id', 'assigned_to', 'status_id') def get_form_data(self): d = {} for name in Bug._form_keys: val = self.get(name) if val is None: val = 100 s = str(val) d[name] = s if self.__details is not None: d['details'] = self.__details return d def flush_sf(self): # XXX not sure what to do here... pass def flush_local(self): args = self.get_update_data() self.__db.update(*args) def flush(self): if not self.__clean: self.flush_sf() self.flush_local() self.__clean = 1 class BugDBInterface: """Interface to bug_t""" def __init__(self, db=None): db = db or pg.connect() self.__db = db self.bug_group = SQLMapping(db, "bug_group_t") self.category = SQLMapping(db, "category_t") self.status = SQLMapping(db, "status_t") self.users = SQLMapping(db, "users_t") self.resolution = SQLMapping(db, "resolution_t") def __query(self, query): print query return QueryResult(self.__db.query(query)) def get(self, bug_id): r = self.__query('select * from bug_t where bug_id = %s' % bug_id) if len(r) == 0: return None assert len(r) == 1 return Bug(r.dictresult()[0], self) def insert(self, bug_id, summary, attrs): """Load bug using the info from the buglig BugParser""" self._do_bug_query(bug_id, summary, attrs, self.__insert_q) def update(self, bug_id, summary, attrs): """Update existing bug using info from buglib BugParser""" self.__query("BEGIN WORK") sql = 'DELETE FROM bug_t WHERE bug_id = %(bug_id)s' % locals() self.__query(sql) self.insert(bug_id, summary, attrs) self.__query("COMMIT WORK") __insert_q = "INSERT INTO bug_t (bug_id, summary, " \ "%(optional_keys)s, priority) VALUES " \ "(%(bug_id)s, '%(summary)s', %(optional_values)s, " \ "%(priority)s)" def _do_bug_query(self, bug_id, summary, attrs, query): summary = quote(summary) priority = int(attrs["priority"][1]) optional_keys, optional_values = self._prep_query_refs(attrs) sql = self.__insert_q % locals() self.__query(sql) def _prep_query_refs(self, attrs): self._new_query() self._lookup_ref(self.bug_group, attrs, "bug_group_id") self._lookup_ref(self.category, attrs, "category_id") self._lookup_ref(self.resolution, attrs, "resolution_id") self._lookup_ref(self.status, attrs, "status_id") self._lookup_ref(self.users, attrs, "assigned_to") # now figure out which of the optional fields have values (yuck) for k, v in self.refs.items(): if v is None: del self.refs[k] optional_keys = ", ".join(self.refs.keys()) optional_values = ", ".join(map(str, self.refs.values())) return optional_keys, optional_values __exists_q = "SELECT * FROM bug_t WHERE bug_id = %(bug_id)s" def exists(self, bug_id): if self.__query(self.__exists_q % locals()): return 1 else: return 0 def _new_query(self): self.refs = {} def _lookup_ref(self, table, attrs, attrname): pair = attrs.get(attrname) if pair is None: self.refs[attrname] = None return None value, key = pair id = table.lookup(value) if id is None: id = int(key) table.insert(id, value) self.refs[attrname] = id return id --- NEW FILE: sflib.py --- """Routines for interacting with SourceForge interfaces""" import cgi import re import urllib import urlparse def urldecode(query): d = cgi.parse_qs(query) for k, v in d.items(): if len(v) != 1: raise ValueError, "unexpected duplicate entry" d[k] = v[0] return d class SummaryParser: rx_href = re.compile('HREF="(\S*\?[A-Za-z0-9=&_]+)"') VERBOSE = 0 def __init__(self, root_url, funcs, verbose=None): if verbose: self.VERBOSE = verbose self.root_url = root_url self.offset = 0 self.hrefs = [] self.funcs = {} self.next = None for func in funcs: self.funcs[func] = 1 def get_hrefs(self): return self.hrefs def load(self, _url, offset=None): url = urlparse.urljoin(self.root_url, _url) if self.VERBOSE: print "loading", url if offset is not None: self.offset = offset f = urllib.urlopen(url) resp = f.read() f.close() self.parse(resp) def parse(self, buf): for line in buf.split("\n"): line_offset = 0 while 1: mo = self.rx_href.search(line, line_offset) if mo: self.handle_href_match(mo, line) line_offset = mo.end(1) else: break if self.VERBOSE: print "found %d hrefs" % len(self.hrefs) if self.next: self.load_next() def handle_href_match(self, mo, line): query = mo.group(1) d = self.parse_query(query) self.handle_query(query, d, line) def handle_query(self, query, dict, line): if self.VERBOSE: print query if not dict.has_key('func'): return if dict['func'] == 'browse' and dict.has_key('offset'): off = int(dict['offset']) if off > self.offset: self.next = query, dict if self.keep_func(dict['func']): self.hrefs.append((query, dict, line)) def keep_func(self, func): if self.funcs.has_key(func): return 1 def parse_query(self, href): i = href.find("?") return urldecode(href[i+1:]) def load_next(self): assert self.next is not None query, dict = self.next self.next = None new_offset = int(dict['offset']) self.load(query, new_offset) --- NEW FILE: upload.py --- #! /usr/bin/env python """Enter Jitterbug reports into the SF Bug Tracker upload.py [OPTIONS] [jitterbug_path] This script reads Jitterbug data from its filesystem representation and uploads each bug report to the SourceForge Bug Tracker. Jitterbug stores each of its bug categories in a separate directory (e.g. open, notabug, etc.). This script reads all of the bug files from a single directory. To upload an entire Jitterbug database, the script must be run once on each directory. The command-line options are used to specify metadata for SF. For each option, you must specify the SF id for the field, which you can find by viewing the source of the standard bug submission form. -P [project_group_id] which project to add bugs to (REQUIRED) -p [1..10] bug priority (default 5) -c [category_id] SF bug category -g [group_id] SF bug group The -v option provides verbose output. The -h option prints this message. """ import sys import os import re import getopt import jitterbuglib VERBOSE = 0 _rx_num = re.compile('\d+$') def find_bugs(dir): """Return a list of the bug ids contained in dir""" bug_ids = [] for file in os.listdir(dir): mo = _rx_num.match(file) if mo: bug_ids.append(file) bug_ids.sort() return bug_ids def main(dir): bug_ids = find_bugs(dir) for bid in bug_ids: bug = jitterbuglib.Bug(dir, bid) if VERBOSE: print "loaded PR#%s" % bid bug.submit(jitterbuglib.SF_SUBMIT_URL) def usage(code, msg=''): print >> sys.stderr, __doc__ if msg: print >> sys.stderr, msg sys.exit(code) if __name__ == "__main__": proj_group_set = 0 try: opts, args = getopt.getopt(sys.argv[1:], 'P:g:vp:hc:') except getopt.error, msg: usage(1, msg) if len(args) > 1: usage(1, 'unexpected arguments: ' + ' '.join(args[1:])) if len(args) == 0: usage(1, 'jitterbug_path missing') for k, v in opts: if k == '-v': VERBOSE = 1 elif k == '-h': usage(0) elif k == '-g': jitterbuglib.set_label("GROUP", v) elif k == '-p': jitterbuglib.set_label("PRIORITY", v) elif k == '-P': jitterbuglib.set_label("PROJECT_GROUP_ID", v) proj_group_set = 1 elif k == '-c': jitterbuglib.set_label("CATEGORY", v) if not proj_group_set: usage(1, '-P option is required') # all's well main(args[0]) From gvanrossum@users.sourceforge.net Wed Jun 6 20:00:35 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 06 Jun 2001 12:00:35 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.34,2.16.8.35 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv21388 Modified Files: Tag: descr-branch typeobject.c Log Message: Bugfix in type_init(): when merging the dicts of multiple base classes, don't call d1.update(d2) when d2 is NULL! Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.34 retrieving revision 2.16.8.35 diff -C2 -r2.16.8.34 -r2.16.8.35 *** typeobject.c 2001/06/06 17:17:14 2.16.8.34 --- typeobject.c 2001/06/06 19:00:33 2.16.8.35 *************** *** 368,371 **** --- 368,373 ---- for (i = n; --i >= 0; ) { t = (PyTypeObject *) PyTuple_GET_ITEM(bases, i); + if (t->tp_dict == NULL) + continue; x = PyObject_CallMethod(type->tp_dict, "update", "O", t->tp_dict); From loewis@users.sourceforge.net Thu Jun 7 06:49:07 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 06 Jun 2001 22:49:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib pstats.py,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv21211 Modified Files: pstats.py Log Message: Patch #416220: Fix misplaced paren. Index: pstats.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pstats.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -r1.17 -r1.18 *** pstats.py 2001/05/11 19:21:41 1.17 --- pstats.py 2001/06/07 05:49:05 1.18 *************** *** 614,618 **** 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: From loewis@users.sourceforge.net Thu Jun 7 06:49:07 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 06 Jun 2001 22:49:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/xml/sax xmlreader.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/xml/sax In directory usw-pr-cvs1:/tmp/cvs-serv21211/xml/sax Modified Files: xmlreader.py Log Message: Patch #416220: Fix misplaced paren. Index: xmlreader.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xml/sax/xmlreader.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -r1.14 -r1.15 *** xmlreader.py 2001/03/14 22:43:47 1.14 --- xmlreader.py 2001/06/07 05:49:05 1.15 *************** *** 3,9 **** import handler ! ! from _exceptions import SAXNotSupportedException, SAXNotRecognizedException ! # ===== XMLREADER ===== --- 3,7 ---- import handler ! from _exceptions import * # ===== XMLREADER ===== From nowonder@users.sourceforge.net Thu Jun 7 06:51:39 2001 From: nowonder@users.sourceforge.net (Peter Schneider-Kamp) Date: Wed, 06 Jun 2001 22:51:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules binascii.c,2.28,2.29 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv21401 Modified Files: binascii.c Log Message: This closes bug #430849 (internal error produced by binascii.a2b_base64) Index: binascii.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/binascii.c,v retrieving revision 2.28 retrieving revision 2.29 diff -C2 -r2.28 -r2.29 *** binascii.c 2001/01/09 02:11:57 2.28 --- binascii.c 2001/06/07 05:51:36 2.29 *************** *** 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 */ From loewis@users.sourceforge.net Thu Jun 7 06:52:19 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 06 Jun 2001 22:52:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/xml/sax xmlreader.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/xml/sax In directory usw-pr-cvs1:/tmp/cvs-serv21571 Modified Files: xmlreader.py Log Message: Previous check-in was by mistake, undo it. Index: xmlreader.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xml/sax/xmlreader.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -r1.15 -r1.16 *** xmlreader.py 2001/06/07 05:49:05 1.15 --- xmlreader.py 2001/06/07 05:52:17 1.16 *************** *** 3,7 **** import handler ! from _exceptions import * # ===== XMLREADER ===== --- 3,9 ---- import handler ! ! from _exceptions import SAXNotSupportedException, SAXNotRecognizedException ! # ===== XMLREADER ===== From gvanrossum@users.sourceforge.net Thu Jun 7 12:28:08 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 07 Jun 2001 04:28:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python getargs.c,2.54,2.54.6.1 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv4406 Modified Files: Tag: descr-branch getargs.c Log Message: Use PyObject_TypeCheck() for O! rather than a straight comparison. Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.54 retrieving revision 2.54.6.1 diff -C2 -r2.54 -r2.54.6.1 *** getargs.c 2001/02/12 22:13:26 2.54 --- getargs.c 2001/06/07 11:28:06 2.54.6.1 *************** *** 858,862 **** p = va_arg(*p_va, PyObject **); format++; ! if (arg->ob_type == type) *p = arg; else --- 858,862 ---- p = va_arg(*p_va, PyObject **); format++; ! if (PyObject_TypeCheck(arg, type)) *p = arg; else From gvanrossum@users.sourceforge.net Thu Jun 7 12:38:57 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 07 Jun 2001 04:38:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.80.2.8,2.80.2.9 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv5732 Modified Files: Tag: descr-branch dictobject.c Log Message: Make PyDict_SetItem() and PyDict_DelItem() call on their PyObject_ cousins when the type is a derived type from PyDict_Type -- this makes it possible to create a derived dictionary class that implements restrictions on item assignments and pass that as the dict to exec/eval, for example. Don't do this for PyDict_Clear(). It's trickier there: there's no PyObject_Clear(), and calling self.clear() might recurse right into PyDict_Clear(). PyDict_Clear() is only used by the standard library in a few places, and in at least one of those (GC) setting a trap would be inappropriate anyway. Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.80.2.8 retrieving revision 2.80.2.9 diff -C2 -r2.80.2.8 -r2.80.2.9 *** dictobject.c 2001/06/06 14:27:54 2.80.2.8 --- dictobject.c 2001/06/07 11:38:55 2.80.2.9 *************** *** 424,428 **** register int n_used; ! if (!PyDict_Check(op)) { PyErr_BadInternalCall(); return -1; --- 424,430 ---- register int n_used; ! if (op->ob_type != &PyDict_Type) { ! if (PyDict_Check(op)) ! return PyObject_SetItem(op, key, value); PyErr_BadInternalCall(); return -1; *************** *** 486,490 **** PyObject *old_value, *old_key; ! if (!PyDict_Check(op)) { PyErr_BadInternalCall(); return -1; --- 488,494 ---- PyObject *old_value, *old_key; ! if (op->ob_type != &PyDict_Type) { ! if (PyDict_Check(op)) ! return PyObject_DelItem(op, key); PyErr_BadInternalCall(); return -1; From gvanrossum@users.sourceforge.net Thu Jun 7 12:50:07 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 07 Jun 2001 04:50:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.80.2.9,2.80.2.10 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv7612 Modified Files: Tag: descr-branch dictobject.c Log Message: Ow! Undo the last change. It causes infinite recursion in certain cases and I don't know how to fix that right now. Later, maybe. Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.80.2.9 retrieving revision 2.80.2.10 diff -C2 -r2.80.2.9 -r2.80.2.10 *** dictobject.c 2001/06/07 11:38:55 2.80.2.9 --- dictobject.c 2001/06/07 11:50:05 2.80.2.10 *************** *** 424,430 **** register int n_used; ! if (op->ob_type != &PyDict_Type) { ! if (PyDict_Check(op)) ! return PyObject_SetItem(op, key, value); PyErr_BadInternalCall(); return -1; --- 424,428 ---- register int n_used; ! if (!PyDict_Check(op)) { PyErr_BadInternalCall(); return -1; *************** *** 488,494 **** PyObject *old_value, *old_key; ! if (op->ob_type != &PyDict_Type) { ! if (PyDict_Check(op)) ! return PyObject_DelItem(op, key); PyErr_BadInternalCall(); return -1; --- 486,490 ---- PyObject *old_value, *old_key; ! if (!PyDict_Check(op)) { PyErr_BadInternalCall(); return -1; From lemburg@users.sourceforge.net Thu Jun 7 13:26:59 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Thu, 07 Jun 2001 05:26:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects unicodeobject.c,2.92,2.93 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv12368 Modified Files: unicodeobject.c Log Message: Fixes [ #430986 ] Buglet in PyUnicode_FromUnicode. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.92 retrieving revision 2.93 diff -C2 -r2.92 -r2.93 *** unicodeobject.c 2001/05/29 17:13:15 2.92 --- unicodeobject.c 2001/06/07 12:26:56 2.93 *************** *** 298,304 **** if (!unicode) { unicode = _PyUnicode_New(1); - unicode->str[0] = *u; if (!unicode) return NULL; unicode_latin1[*u] = unicode; } --- 298,304 ---- if (!unicode) { unicode = _PyUnicode_New(1); if (!unicode) return NULL; + unicode->str[0] = *u; unicode_latin1[*u] = unicode; } From gvanrossum@users.sourceforge.net Thu Jun 7 16:45:06 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 07 Jun 2001 08:45:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.1.2.11,1.1.2.12 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv30314 Modified Files: Tag: descr-branch test_descr.py Log Message: Change type({}) to dictionary. Rename the baseless() test to metaclass(), and test only that. Add a new test for multiple inheritance. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_descr.py,v retrieving revision 1.1.2.11 retrieving revision 1.1.2.12 diff -C2 -r1.1.2.11 -r1.1.2.12 *** test_descr.py 2001/06/06 01:03:14 1.1.2.11 --- test_descr.py 2001/06/07 15:45:04 1.1.2.12 *************** *** 117,121 **** verify(l == l1) l = [] ! for i in type({}).__iter__(d): l.append(i) verify(l == l1) testunop({1:2,3:4}, 2, "len(a)", "__len__") --- 117,121 ---- verify(l == l1) l = [] ! for i in dictionary.__iter__(d): l.append(i) verify(l == l1) testunop({1:2,3:4}, 2, "len(a)", "__len__") *************** *** 256,270 **** "a[b]=c", "__setitem__") - DT = type({}) - def pydicts(): if verbose: print "Testing Python subclass of dict..." ! verify(issubclass(DT, DT)) ! verify(isinstance({}, DT)) ! d = DT() verify(d == {}) ! verify(d.__class__ is DT) ! verify(isinstance(d, DT)) ! class C(DT): state = -1 def __init__(self, *a, **kw): --- 256,268 ---- "a[b]=c", "__setitem__") def pydicts(): if verbose: print "Testing Python subclass of dict..." ! verify(issubclass(dictionary, dictionary)) ! verify(isinstance({}, dictionary)) ! d = dictionary() verify(d == {}) ! verify(d.__class__ is dictionary) ! verify(isinstance(d, dictionary)) ! class C(dictionary): state = -1 def __init__(self, *a, **kw): *************** *** 278,287 **** def __setitem__(self, key, value): assert isinstance(key, type(0)) ! DT.__setitem__(self, key, value) def setstate(self, state): self.state = state def getstate(self): return self.state ! verify(issubclass(C, DT)) a1 = C(12) verify(a1.state == 12) --- 276,285 ---- def __setitem__(self, key, value): assert isinstance(key, type(0)) ! dictionary.__setitem__(self, key, value) def setstate(self, state): self.state = state def getstate(self): return self.state ! verify(issubclass(C, dictionary)) a1 = C(12) verify(a1.state == 12) *************** *** 309,312 **** --- 307,326 ---- verify(a[i][j] == i*j) + def metaclass(): + if verbose: print "Testing __metaclass__..." + global C + class C: + __metaclass__ = type(type(0)) + def __init__(self): + self.__state = 0 + def getstate(self): + return self.__state + def setstate(self, state): + self.__state = state + a = C() + verify(a.getstate() == 0) + a.setstate(10) + verify(a.getstate() == 10) + import sys MT = type(sys) *************** *** 339,347 **** ("delattr", "foo")], log) ! def baseless(): ! if verbose: print "Testing __metaclass__ and mix-ins..." global C ! class C: ! __metaclass__ = type(type(0)) def __init__(self): self.__state = 0 --- 353,360 ---- ("delattr", "foo")], log) ! def multi(): ! if verbose: print "Testing multiple inheritance..." global C ! class C(object): def __init__(self): self.__state = 0 *************** *** 354,358 **** a.setstate(10) verify(a.getstate() == 10) ! class D(type({}), C): def __init__(self): type({}).__init__(self) --- 367,371 ---- a.setstate(10) verify(a.getstate() == 10) ! class D(dictionary, C): def __init__(self): type({}).__init__(self) *************** *** 376,381 **** spamdicts() pydicts() pymods() ! baseless() all() --- 389,395 ---- spamdicts() pydicts() + metaclass() pymods() ! multi() all() From loewis@users.sourceforge.net Thu Jun 7 18:17:02 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Thu, 07 Jun 2001 10:17:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/scripts ftpmirror.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory usw-pr-cvs1:/tmp/cvs-serv16324 Modified Files: ftpmirror.py Log Message: Patch #430754: Makes ftpmirror.py .netrc aware Index: ftpmirror.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/scripts/ftpmirror.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -r1.13 -r1.14 *** ftpmirror.py 2001/01/17 08:48:39 1.13 --- ftpmirror.py 2001/06/07 17:17:00 1.14 *************** *** 12,16 **** -n: don't log in -r: remove local files/directories no longer pertinent ! -l username [-p passwd [-a account]]: login info (default anonymous ftp) -s pat: skip files matching pattern hostname: remote host --- 12,16 ---- -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 *************** *** 25,28 **** --- 25,29 ---- import string import ftplib + import netrc from fnmatch import fnmatch *************** *** 51,54 **** --- 52,63 ---- 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 *************** *** 62,67 **** if o == '-r': rmok = 1 if o == '-s': skippats.append(a) - if not args: usage('hostname missing') - host = args[0] remotedir = '' localdir = '' --- 71,74 ---- From gvanrossum@users.sourceforge.net Thu Jun 7 19:31:57 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 07 Jun 2001 11:31:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects object.c,2.124.4.12,2.124.4.13 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv31479/Objects Modified Files: Tag: descr-branch object.c Log Message: Change the signature of _PyObject_TypeCheck() to take two type objects; change PyObject_TypeCheck() to hide the change from its users. This might generate faster code if the compiler notices that (ob)->ob_type is loaded twice. It also (and this was the real reason to do this now) avoids warnings when op is not a PyObject * but a derived object, e.g. a PyTypeObject *. Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.124.4.12 retrieving revision 2.124.4.13 diff -C2 -r2.124.4.12 -r2.124.4.13 *** object.c 2001/06/06 14:34:13 2.124.4.12 --- object.c 2001/06/07 18:31:55 2.124.4.13 *************** *** 1327,1334 **** int ! _PyObject_TypeCheck(PyObject *obj, PyTypeObject *type) { - PyTypeObject *tp = obj->ob_type; - do { if (tp == type) --- 1327,1332 ---- int ! _PyObject_TypeCheck(PyTypeObject *tp, PyTypeObject *type) { do { if (tp == type) From gvanrossum@users.sourceforge.net Thu Jun 7 19:31:57 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 07 Jun 2001 11:31:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include object.h,2.79.2.12,2.79.2.13 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv31479/Include Modified Files: Tag: descr-branch object.h Log Message: Change the signature of _PyObject_TypeCheck() to take two type objects; change PyObject_TypeCheck() to hide the change from its users. This might generate faster code if the compiler notices that (ob)->ob_type is loaded twice. It also (and this was the real reason to do this now) avoids warnings when op is not a PyObject * but a derived object, e.g. a PyTypeObject *. Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.79.2.12 retrieving revision 2.79.2.13 diff -C2 -r2.79.2.12 -r2.79.2.13 *** object.h 2001/06/06 14:41:45 2.79.2.12 --- object.h 2001/06/07 18:31:55 2.79.2.13 *************** *** 287,293 **** /* Generic type check */ ! extern DL_IMPORT(int) _PyObject_TypeCheck(PyObject *, PyTypeObject *); #define PyObject_TypeCheck(ob, tp) \ ! ((ob)->ob_type == (tp) || _PyObject_TypeCheck(ob, tp)) extern DL_IMPORT(PyTypeObject) PyType_Type; /* Metatype */ --- 287,293 ---- /* 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 */ From nowonder@users.sourceforge.net Thu Jun 7 19:56:15 2001 From: nowonder@users.sourceforge.net (Peter Schneider-Kamp) Date: Thu, 07 Jun 2001 11:56:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib base64.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv3615 Modified Files: base64.py Log Message: check in for patch #430846 use faster code for base64.encodestring (courtesy of Mr. Tim Peters) and for base64.decodestring (courtesy of Anthony Baxter) Index: base64.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/base64.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -r1.11 -r1.12 *** base64.py 2001/01/20 19:54:20 1.11 --- base64.py 2001/06/07 18:56:13 1.12 *************** *** 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(): From loewis@users.sourceforge.net Thu Jun 7 20:01:26 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Thu, 07 Jun 2001 12:01:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libfnmatch.tex,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv4830 Modified Files: libfnmatch.tex Log Message: Document filter. Index: libfnmatch.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfnmatch.tex,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -r1.17 -r1.18 *** libfnmatch.tex 2000/10/09 18:12:29 1.17 --- libfnmatch.tex 2001/06/07 19:01:24 1.18 *************** *** 44,47 **** --- 44,52 ---- \end{funcdesc} + \begin{funcdesc}{filter}{names, pattern} + Return the subset of the list of \var{names} that match \var{pattern}. + It is the same as \code{[n for n in names if fnmatch(n, pattern)]}, but + implemented more efficiently. + \end{funcdesc} \begin{seealso} From gvanrossum@users.sourceforge.net Thu Jun 7 20:03:11 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 07 Jun 2001 12:03:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib types.py,1.14.10.3,1.14.10.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv5199 Modified Files: Tag: descr-branch types.py Log Message: Use type, object, list, dictionary built-ins. Index: types.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/types.py,v retrieving revision 1.14.10.3 retrieving revision 1.14.10.4 diff -C2 -r1.14.10.3 -r1.14.10.4 *** types.py 2001/06/06 15:41:02 1.14.10.3 --- types.py 2001/06/07 19:03:08 1.14.10.4 *************** *** 7,12 **** NoneType = type(None) ! TypeType = type(NoneType) ! ObjectType = NoneType.__bases__[0] IntType = type(0) --- 7,12 ---- NoneType = type(None) ! TypeType = type ! ObjectType = object IntType = type(0) *************** *** 23,28 **** TupleType = type(()) ! ListType = type([]) ! DictType = DictionaryType = type({}) def _f(): pass --- 23,28 ---- TupleType = type(()) ! ListType = list ! DictType = DictionaryType = dictionary def _f(): pass From gvanrossum@users.sourceforge.net Thu Jun 7 20:14:47 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 07 Jun 2001 12:14:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.35,2.16.8.36 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv7429 Modified Files: Tag: descr-branch typeobject.c Log Message: Better multiple inheritance, using the method resolution order specification from "Putting Metaclasses to Work" by Forman and Danforth (Addison-Wesley 1999). The functions type_init() and PyType_InitDict() are quite different now. __bases__ and tp_base are now set properly by PyType_InitDict() to make the default base class 'object'; thus the __bases__ descriptor can be simpler. New standard attributes of type objects: - __base__ (singular!), the unique base class on the path to the root that has all the instance variable additions; - __mro__, the method resolution order (a tuple of classes starting with type type itself and ending with 'object'); - __introduced__, a read-only proxy for the dictionary of methods and slots introduced by this class (possibly overriding or extending an inherited method, but not *just* inherited). The former "intrinsic attributes" of objects are now inherited from 'object'. The 'object' type now has a (no-op) constructor, so that every type now has an __init__ method! The helper functions add_methods(), add_wrappers(), add_members() and add_getset() now update tp_introduced instead of tp_dict, and don't overwrite existing keys. There's still a lot to do! E.g. the method resolution order computation doesn't even check for errors. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.35 retrieving revision 2.16.8.36 diff -C2 -r2.16.8.35 -r2.16.8.36 *** typeobject.c 2001/06/06 19:00:33 2.16.8.35 --- typeobject.c 2001/06/07 19:14:45 2.16.8.36 *************** *** 15,44 **** {"__weaklistoffset__", T_LONG, offsetof(PyTypeObject, tp_weaklistoffset), READONLY}, {"__dictoffset__", T_LONG, offsetof(PyTypeObject, tp_dictoffset), READONLY}, {0} }; static PyObject * - type_bases(PyTypeObject *type, void *context) - { - PyObject *bases; - PyTypeObject *base; - - bases = type->tp_bases; - if (bases != NULL) { - Py_INCREF(bases); - return bases; - } - base = type->tp_base; - if (base == NULL) { - if (type == &PyBaseObject_Type) - return PyTuple_New(0); - base = &PyBaseObject_Type; - } - return Py_BuildValue("(O)", base); - } - - static PyObject * type_module(PyTypeObject *type, void *context) { --- 15,27 ---- {"__weaklistoffset__", T_LONG, offsetof(PyTypeObject, tp_weaklistoffset), READONLY}, + {"__base__", T_OBJECT, offsetof(PyTypeObject, tp_base), READONLY}, {"__dictoffset__", T_LONG, offsetof(PyTypeObject, tp_dictoffset), READONLY}, + {"__bases__", T_OBJECT, offsetof(PyTypeObject, tp_bases), READONLY}, + {"__mro__", T_OBJECT, offsetof(PyTypeObject, tp_mro), READONLY}, {0} }; static PyObject * type_module(PyTypeObject *type, void *context) { *************** *** 50,67 **** { if (type->tp_dict == NULL) { ! if (PyType_InitDict(type) < 0) ! return NULL; ! if (type->tp_dict == NULL) { ! Py_INCREF(Py_None); ! return Py_None; ! } } return PyDictProxy_New(type->tp_dict); } struct getsetlist type_getsets[] = { - {"__bases__", (getter)type_bases, NULL, NULL}, {"__module__", (getter)type_module, NULL, NULL}, {"__dict__", (getter)type_dict, NULL, NULL}, {0} }; --- 33,56 ---- { if (type->tp_dict == NULL) { ! Py_INCREF(Py_None); ! return Py_None; } return PyDictProxy_New(type->tp_dict); } + static PyObject * + type_introduced(PyTypeObject *type, void *context) + { + if (type->tp_introduced == NULL) { + Py_INCREF(Py_None); + return Py_None; + } + return PyDictProxy_New(type->tp_introduced); + } + struct getsetlist type_getsets[] = { {"__module__", (getter)type_module, NULL, NULL}, {"__dict__", (getter)type_dict, NULL, NULL}, + {"__introduced__", (getter)type_introduced, NULL, NULL}, {0} }; *************** *** 204,217 **** } /* TypeType's initializer; called when a type is subclassed */ static int type_init(PyObject *self, PyObject *args, PyObject *kwds) { ! PyObject *name, *bases, *dict, *x, *slots; PyTypeObject *type, *base; static char *kwlist[] = {"name", "bases", "dict", 0}; etype *et; struct memberlist *mp; ! int i, n, nslots, slotoffset, allocsize; assert(PyType_Check(self)); --- 193,328 ---- } + /* Method resolution order algorithm from "Putting Metaclasses to Work" + by Forman and Danforth (Addison-Wesley 1999). */ + + static int + conservative_merge(PyObject *left, PyObject *right) + { + int left_size; + int right_size; + int i, j, r; + PyObject *temp, *rr; + + /* XXX add error checking */ + + again: + left_size = PyList_GET_SIZE(left); + right_size = PyList_GET_SIZE(right); + for (i = 0; i < left_size; i++) { + for (j = 0; j < right_size; j++) { + if (PyList_GET_ITEM(left, i) == + PyList_GET_ITEM(right, j)) { + /* found a merge point */ + temp = PyList_New(0); + for (r = 0; r < j; r++) { + rr = PyList_GET_ITEM(right, r); + if (!PySequence_Contains(left, rr)) + PyList_Append(temp, rr); + } + PyList_SetSlice(left, i, i, temp); + Py_DECREF(temp); + PyList_SetSlice(right, 0, j+1, NULL); + goto again; + } + } + } + return PyList_SetSlice(left, left_size, left_size, right); + } + + static int + serious_order_disagreements(PyObject *left, PyObject *right) + { + return 0; /* XXX later -- for now, we cheat: "don't do that" */ + } + + static PyObject * + method_resolution_order(PyTypeObject *type) + { + int i, n; + PyObject *bases; + PyObject *result; + + /* XXX add error checking */ + + if (type->tp_mro != NULL) + return PySequence_List(type->tp_mro); + + bases = type->tp_bases; + if (bases == NULL || !PyTuple_Check(bases)) + return NULL; + n = PyTuple_GET_SIZE(bases); + result = Py_BuildValue("[O]", type); + for (i = 0; i < n; i++) { + PyTypeObject *base = (PyTypeObject *) + PyTuple_GET_ITEM(bases, i); + PyObject *parentMRO = method_resolution_order(base); + if (parentMRO == NULL) { + Py_DECREF(result); + return NULL; + } + if (serious_order_disagreements(result, parentMRO)) { + Py_DECREF(result); + return NULL; + } + conservative_merge(result, parentMRO); + Py_DECREF(parentMRO); + } + if (result != NULL && type->tp_mro == NULL) + type->tp_mro = PySequence_Tuple(result); + return result; + } + + /* Calculate the best base amongst multiple base classes. + This is the first one that's on the path to the "solid base". */ + + static PyTypeObject * + best_base(PyObject *bases) + { + int i, n; + PyTypeObject *base, *winner, *candidate, *base_i; + + assert(PyTuple_Check(bases)); + n = PyTuple_GET_SIZE(bases); + assert(n > 0); + base = (PyTypeObject *)PyTuple_GET_ITEM(bases, 0); + winner = &PyBaseObject_Type; + for (i = 0; i < n; i++) { + base_i = (PyTypeObject *)PyTuple_GET_ITEM(bases, i); + if (!PyType_Check((PyObject *)base_i)) { + PyErr_SetString( + PyExc_TypeError, + "bases must be types"); + return NULL; + } + candidate = solid_base(base_i); + if (issubtype(winner, candidate)) + ; + else if (issubtype(candidate, winner)) { + winner = candidate; + base = base_i; + } + else { + PyErr_SetString( + PyExc_TypeError, + "multiple bases have " + "instance lay-out conflict"); + return NULL; + } + } + assert(base != NULL); + return base; + } + /* TypeType's initializer; called when a type is subclassed */ + static int type_init(PyObject *self, PyObject *args, PyObject *kwds) { ! PyObject *name, *bases, *dict, *slots; PyTypeObject *type, *base; static char *kwlist[] = {"name", "bases", "dict", 0}; etype *et; struct memberlist *mp; ! int i, nbases, nslots, slotoffset, allocsize; assert(PyType_Check(self)); *************** *** 227,267 **** return -1; } ! n = PyTuple_GET_SIZE(bases); ! if (n > 0) { ! PyTypeObject *winner, *candidate, *base_i; ! base = (PyTypeObject *)PyTuple_GET_ITEM(bases, 0); ! winner = &PyBaseObject_Type; ! for (i = 0; i < n; i++) { ! base_i = (PyTypeObject *)PyTuple_GET_ITEM(bases, i); ! if (!PyType_Check((PyObject *)base_i)) { ! PyErr_SetString( ! PyExc_TypeError, ! "bases must be types"); ! return -1; ! } ! candidate = solid_base(base_i); ! if (issubtype(winner, candidate)) ! ; ! else if (issubtype(candidate, winner)) { ! winner = candidate; ! base = base_i; ! } ! else { ! PyErr_SetString( ! PyExc_TypeError, ! "multiple bases have " ! "instance lay-out conflict"); ! return -1; ! } ! } } else ! base = &PyBaseObject_Type; ! if (base->tp_new == NULL) { PyErr_SetString(PyExc_TypeError, ! "base type must have a tp_new slot"); return -1; } /* Check for a __slots__ sequence variable in dict, and count it */ slots = PyDict_GetItemString(dict, "__slots__"); --- 338,368 ---- return -1; } ! ! /* Adjust empty bases */ ! nbases = PyTuple_GET_SIZE(bases); ! if (nbases == 0) { ! bases = Py_BuildValue("(O)", &PyBaseObject_Type); ! if (bases == NULL) ! return -1; ! nbases = 1; } else ! Py_INCREF(bases); ! ! /* Calculate best base */ ! base = best_base(bases); ! if (base == NULL) ! return -1; ! if (base->tp_init == NULL) { PyErr_SetString(PyExc_TypeError, ! "base type must have a constructor slot"); return -1; } + /* Set tp_base and tp_bases */ + type->tp_bases = bases; + Py_INCREF(base); + type->tp_base = base; + /* Check for a __slots__ sequence variable in dict, and count it */ slots = PyDict_GetItemString(dict, "__slots__"); *************** *** 312,330 **** type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE; - /* Set tp_base and tp_bases properly */ - if (PyTuple_GET_SIZE(bases) == 0) - bases = Py_BuildValue("(O)", &PyBaseObject_Type); - else - Py_INCREF(bases); - type->tp_bases = bases; - Py_INCREF(base); - type->tp_base = base; - - /* Copy slots and dict from the base type */ - if (PyType_InitDict(type) < 0) { - Py_DECREF(type); - return -1; - } - /* Override some slots with specific requirements */ if (type->tp_dealloc) --- 413,416 ---- *************** *** 338,346 **** type->tp_setattr = NULL; } ! /* Add custom slots */ mp = et->members; ! slotoffset = type->tp_basicsize; ! if (type->tp_flags & Py_TPFLAGS_GC) slotoffset -= PyGC_HEAD_SIZE; if (slots != NULL) { --- 424,437 ---- type->tp_setattr = NULL; } + + /* Initialize tp_introduced from passed-in dict */ + type->tp_introduced = dict = PyDict_Copy(dict); + if (dict == NULL) + return -1; ! /* Add descriptors for custom slots from __slots__, or for __dict__ */ mp = et->members; ! slotoffset = base->tp_basicsize; ! if (base->tp_flags & Py_TPFLAGS_GC) slotoffset -= PyGC_HEAD_SIZE; if (slots != NULL) { *************** *** 349,359 **** PyTuple_GET_ITEM(slots, i)); mp->type = T_OBJECT; ! mp->offset = slotoffset + i*sizeof(PyObject *); } - type->tp_basicsize += nslots*sizeof(PyObject *); } else if (nslots) { type->tp_dictoffset = slotoffset; ! type->tp_basicsize += sizeof(PyObject *); mp->name = "__dict__"; mp->type = T_OBJECT; --- 440,450 ---- PyTuple_GET_ITEM(slots, i)); mp->type = T_OBJECT; ! mp->offset = slotoffset; ! slotoffset += i*sizeof(PyObject *); } } else if (nslots) { type->tp_dictoffset = slotoffset; ! slotoffset += sizeof(PyObject *); mp->name = "__dict__"; mp->type = T_OBJECT; *************** *** 361,389 **** mp->readonly = 1; } add_members(type, et->members); ! /* XXX This is close, but not quite right! */ ! if (n > 1) { ! PyTypeObject *t; ! for (i = n; --i >= 0; ) { ! t = (PyTypeObject *) PyTuple_GET_ITEM(bases, i); ! if (t->tp_dict == NULL) ! continue; ! x = PyObject_CallMethod(type->tp_dict, ! "update", "O", t->tp_dict); ! if (x == NULL) { ! Py_DECREF(type); ! return -1; ! } ! } ! } ! ! x = PyObject_CallMethod(type->tp_dict, "update", "O", dict); ! if (x == NULL) { ! Py_DECREF(type); return -1; ! } ! Py_DECREF(x); /* throw away None */ ! override_slots(type, dict); return 0; } --- 452,464 ---- mp->readonly = 1; } + type->tp_basicsize = slotoffset; add_members(type, et->members); ! /* Initialize tp_bases, tp_dict, tp_introduced; inherit slots */ ! if (PyType_InitDict(type) < 0) return -1; ! ! /* Override slots that deserve it */ ! override_slots(type, type->tp_dict); return 0; } *************** *** 485,488 **** --- 560,564 ---- Py_XDECREF(et->name); Py_XDECREF(et->slots); + /* XXX more, e.g. bases, mro, introduced ... */ PyObject_DEL(type); } *************** *** 543,546 **** --- 619,633 ---- } + static struct memberlist object_members[] = { + {"__class__", T_OBJECT, offsetof(PyObject, ob_type), READONLY}, + {0} + }; + + static int + object_init(PyObject *self, PyObject *args, PyObject *kwds) + { + return 0; + } + PyTypeObject PyBaseObject_Type = { PyObject_HEAD_INIT(&PyType_Type) *************** *** 573,577 **** 0, /* tp_iternext */ 0, /* tp_methods */ ! 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ --- 660,664 ---- 0, /* tp_iternext */ 0, /* tp_methods */ ! object_members, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ *************** *** 580,584 **** 0, /* tp_descr_set */ 0, /* tp_dictoffset */ ! 0, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ --- 667,671 ---- 0, /* tp_descr_set */ 0, /* tp_dictoffset */ ! object_init, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ *************** *** 588,611 **** /* Initialize the __dict__ in a type object */ - static struct PyMethodDef intrinsic_methods[] = { - {0} - }; - - static struct memberlist intrinsic_members[] = { - {"__class__", T_OBJECT, offsetof(PyObject, ob_type), READONLY}, - {0} - }; - - static struct getsetlist intrinsic_getsets[] = { - {0} - }; - static int add_methods(PyTypeObject *type, PyMethodDef *meth) { ! PyObject *dict = type->tp_dict; for (; meth->ml_name != NULL; meth++) { ! PyObject *descr = PyDescr_NewMethod(type, meth); if (descr == NULL) return -1; --- 675,688 ---- /* Initialize the __dict__ in a type object */ static int add_methods(PyTypeObject *type, PyMethodDef *meth) { ! PyObject *dict = type->tp_introduced; for (; meth->ml_name != NULL; meth++) { ! PyObject *descr; ! if (PyDict_GetItemString(dict, meth->ml_name)) ! continue; ! descr = PyDescr_NewMethod(type, meth); if (descr == NULL) return -1; *************** *** 620,627 **** add_wrappers(PyTypeObject *type, struct wrapperbase *base, void *wrapped) { ! PyObject *dict = type->tp_dict; for (; base->name != NULL; base++) { ! PyObject *descr = PyDescr_NewWrapper(type, base, wrapped); if (descr == NULL) return -1; --- 697,707 ---- add_wrappers(PyTypeObject *type, struct wrapperbase *base, void *wrapped) { ! PyObject *dict = type->tp_introduced; for (; base->name != NULL; base++) { ! PyObject *descr; ! if (PyDict_GetItemString(dict, base->name)) ! continue; ! descr = PyDescr_NewWrapper(type, base, wrapped); if (descr == NULL) return -1; *************** *** 636,643 **** add_members(PyTypeObject *type, struct memberlist *memb) { ! PyObject *dict = type->tp_dict; for (; memb->name != NULL; memb++) { ! PyObject *descr = PyDescr_NewMember(type, memb); if (descr == NULL) return -1; --- 716,726 ---- add_members(PyTypeObject *type, struct memberlist *memb) { ! PyObject *dict = type->tp_introduced; for (; memb->name != NULL; memb++) { ! PyObject *descr; ! if (PyDict_GetItemString(dict, memb->name)) ! continue; ! descr = PyDescr_NewMember(type, memb); if (descr == NULL) return -1; *************** *** 652,659 **** add_getset(PyTypeObject *type, struct getsetlist *gsp) { ! PyObject *dict = type->tp_dict; for (; gsp->name != NULL; gsp++) { ! PyObject *descr = PyDescr_NewGetSet(type, gsp); if (descr == NULL) --- 735,745 ---- add_getset(PyTypeObject *type, struct getsetlist *gsp) { ! PyObject *dict = type->tp_introduced; for (; gsp->name != NULL; gsp++) { ! PyObject *descr; ! if (PyDict_GetItemString(dict, gsp->name)) ! continue; ! descr = PyDescr_NewGetSet(type, gsp); if (descr == NULL) *************** *** 836,866 **** PyType_InitDict(PyTypeObject *type) { ! PyObject *dict; ! PyTypeObject *base = type->tp_base; if (type->tp_dict != NULL) ! return 0; if (base) { if (PyType_InitDict(base) < 0) return -1; - dict = PyDict_Copy(base->tp_dict); } ! else dict = PyDict_New(); ! if (dict == NULL) ! return -1; ! type->tp_dict = dict; ! /* Add intrinsics */ ! if (add_methods(type, intrinsic_methods) < 0) ! return -1; ! if (add_members(type, intrinsic_members) < 0) ! return -1; ! if (add_getset(type, intrinsic_getsets) < 0) ! return -1; if (add_operators(type) < 0) return -1; - - /* Add type-specific descriptors */ if (type->tp_methods != NULL) { if (add_methods(type, type->tp_methods) < 0) --- 922,967 ---- PyType_InitDict(PyTypeObject *type) { ! PyObject *dict, *bases, *x; ! PyTypeObject *base; ! int i, n; if (type->tp_dict != NULL) ! return 0; /* Already initialized */ ! ! /* Initialize tp_base (defaults to BaseObject unless that's us) */ ! base = type->tp_base; ! if (base == NULL && type != &PyBaseObject_Type) ! base = type->tp_base = &PyBaseObject_Type; ! ! /* Initialize tp_bases */ ! bases = type->tp_bases; ! if (bases == NULL) { ! if (base == NULL) ! bases = PyTuple_New(0); ! else ! bases = Py_BuildValue("(O)", base); ! if (bases == NULL) ! return -1; ! type->tp_bases = bases; ! } ! ! /* Initialize the base class */ if (base) { if (PyType_InitDict(base) < 0) return -1; } ! ! /* Initialize tp_introduced */ ! dict = type->tp_introduced; ! if (dict == NULL) { dict = PyDict_New(); ! if (dict == NULL) ! return -1; ! type->tp_introduced = dict; ! } ! /* Add type-specific descriptors to tp_introduced */ if (add_operators(type) < 0) return -1; if (type->tp_methods != NULL) { if (add_methods(type, type->tp_methods) < 0) *************** *** 875,884 **** return -1; } ! /* Inherit base class slots and methods */ if (base) { if (inherit_slots(type, base) < 0) return -1; } return 0; --- 976,1022 ---- return -1; } + + /* Initialize tp_dict from tp_introduced */ + type->tp_dict = PyDict_Copy(dict); + if (type->tp_dict == NULL) + return -1; ! /* Inherit base class slots */ if (base) { if (inherit_slots(type, base) < 0) return -1; } + + /* Calculate method resolution order */ + x = method_resolution_order(type); + if (x == NULL) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_TypeError, + "method resolution order failed"); + return -1; + } + Py_DECREF(x); + + /* Inherit methods, updating from last base backwards */ + bases = type->tp_mro; + assert(bases != NULL); + assert(PyTuple_Check(bases)); + n = PyTuple_GET_SIZE(bases); + for (i = n; --i >= 0; ) { + base = (PyTypeObject *)PyTuple_GET_ITEM(bases, i); + assert(PyType_Check(base)); + x = base->tp_introduced; + if (x != NULL) { + x = PyObject_CallMethod(type->tp_dict, "update","O",x); + if (x == NULL) + return -1; + Py_DECREF(x); /* throw away None */ + } + } + + /* Inherit slots from direct base */ + if (type->tp_base != NULL) + if (inherit_slots(type, type->tp_base) < 0) + return -1; return 0; From gvanrossum@users.sourceforge.net Thu Jun 7 20:17:41 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 07 Jun 2001 12:17:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.1.2.12,1.1.2.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv8217 Modified Files: Tag: descr-branch test_descr.py Log Message: - Reduce the size of the pydict stress test (I got tired of waiting :-). The size is now parameterized through a local variable so it's easy to change. - Add a test for __mro__ to the multi() test. - Add diamond(), a test for proper method resolution order in diamond diagrams. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_descr.py,v retrieving revision 1.1.2.12 retrieving revision 1.1.2.13 diff -C2 -r1.1.2.12 -r1.1.2.13 *** test_descr.py 2001/06/07 15:45:04 1.1.2.12 --- test_descr.py 2001/06/07 19:17:39 1.1.2.13 *************** *** 299,308 **** verify(a[42] == 24) if verbose: print "pydict stress test ..." ! for i in range(100): a[i] = C() ! for j in range(100): a[i][j] = i*j ! for i in range(100): ! for j in range(100): verify(a[i][j] == i*j) --- 299,309 ---- verify(a[42] == 24) if verbose: print "pydict stress test ..." ! N = 50 ! for i in range(N): a[i] = C() ! for j in range(N): a[i][j] = i*j ! for i in range(N): ! for j in range(N): verify(a[i][j] == i*j) *************** *** 379,383 **** --- 380,416 ---- d.setstate(10) verify(d.getstate() == 10) + verify(D.__mro__ == (D, dictionary, C, object)) + def diamond(): + if verbose: print "Testing multiple inheritance special cases..." + class A(object): + def spam(self): return "A" + verify(A().spam() == "A") + class B(A): + def boo(self): return "B" + def spam(self): return "B" + verify(B().spam() == "B") + verify(B().boo() == "B") + class C(A): + def boo(self): return "C" + verify(C().spam() == "A") + verify(C().boo() == "C") + class D(B, C): pass + verify(D().spam() == "B") + verify(D().boo() == "B") + verify(D.__mro__ == (D, B, C, A, object)) + class E(C, B): pass + verify(E().spam() == "B") + verify(E().boo() == "C") + verify(E.__mro__ == (E, C, B, A, object)) + class F(D, E): pass + verify(F().spam() == "B") + verify(F().boo() == "B") + verify(F.__mro__ == (F, D, E, B, C, A, object)) + class G(E, D): pass + verify(G().spam() == "B") + verify(G().boo() == "C") + verify(G.__mro__ == (G, E, D, C, B, A, object)) + def all(): lists() *************** *** 392,395 **** --- 425,429 ---- pymods() multi() + diamond() all() From loewis@users.sourceforge.net Thu Jun 7 20:39:27 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Thu, 07 Jun 2001 12:39:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/encodings cp1140.py,NONE,1.1 aliases.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/encodings In directory usw-pr-cvs1:/tmp/cvs-serv12371 Modified Files: aliases.py Added Files: cp1140.py Log Message: Patch #429957: Add support for cp1140, which is identical to cp037, with the addition of the euro character. Also added a few EDBDIC aliases. --- NEW FILE: cp1140.py --- """ Python Character Mapping Codec for cp1140 Written by Brian Quinlan(brian@sweetapp.com). NO WARRANTY. """ import codecs import copy import cp037 ### 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 decoding_map = copy.copy(cp037.decoding_map) decoding_map.update({ 0x009f: 0x20ac # EURO SIGN }) ### Encoding Map encoding_map = codecs.make_encoding_map(decoding_map) Index: aliases.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/aliases.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** aliases.py 2001/06/04 02:31:23 1.7 --- aliases.py 2001/06/07 19:39:25 1.8 *************** *** 33,36 **** --- 33,41 ---- 'us_ascii': 'ascii', + # EBCDIC + 'ebcdic_cp_us': 'cp037', + 'ibm039': 'cp037', + 'ibm1140': 'cp1140', + # ISO '8859': 'latin_1', From fdrake@users.sourceforge.net Fri Jun 8 05:25:26 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 07 Jun 2001 21:25:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib profile.py,1.27,1.28 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv26018 Modified Files: profile.py Log Message: Performance improvements to the profiler: Ensure that all the default timers are called as functions, not an expensive method wrapper around a variety of different functions. Agressively avoid dictionary lookups. Modify the dispatch scheme (Profile.trace_dispatch_*(), where * is not 'call', 'exception' or 'return') so that the callables dispatched to are simple functions and not bound methods -- this reduces the number of layers of Python call machinery that gets touched. Remove a couple of duplicate imports from the "if __name__ == ..." section. This closes SF patch #430948. Index: profile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/profile.py,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -r1.27 -r1.28 *** profile.py 2001/03/14 20:01:19 1.27 --- profile.py 2001/06/08 04:25:24 1.28 *************** *** 90,93 **** --- 90,103 ---- + if os.name == "mac": + 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': --- 143,146 ---- *************** *** 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: --- 148,161 ---- 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 --- 163,200 ---- 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 --- 205,226 ---- 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 --- 229,239 ---- 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 --- 250,259 ---- 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 --- 271,276 ---- 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 --- 283,298 ---- 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 --- 328,332 ---- 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 --- 335,346 ---- 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) --- 389,397 ---- # 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 --- 443,462 ---- 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 **** --- 528,538 ---- + dispatch = { + "call": trace_dispatch_call, + "exception": trace_dispatch_exception, + "return": trace_dispatch_return, + } + + def snapshot_stats(self): self.stats = {} *************** *** 550,553 **** --- 581,591 ---- + 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] ..." --- 603,606 ---- From fdrake@users.sourceforge.net Fri Jun 8 05:33:11 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 07 Jun 2001 21:33:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.245,2.246 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv27000 Modified Files: ceval.c Log Message: call_trace(): Add an additional parameter -- pointer to a PyObject* that should be used to cache an interned version of the event string passed to the profile/trace function. call_trace() will create interned strings and cache them in using the storage specified by this additional parameter, avoiding a lot of string object creation at runtime when using the profiling or tracing functions. All call sites are modified to pass the additional parameter, and four static PyObject* variables are allocated to cache the interned string objects. This closes SF patch #431257. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.245 retrieving revision 2.246 diff -C2 -r2.245 -r2.246 *** ceval.c 2001/05/29 16:23:26 2.245 --- ceval.c 2001/06/08 04:33:09 2.246 *************** *** 63,67 **** static void call_exc_trace(PyObject **, PyObject**, PyFrameObject *); static int call_trace(PyObject **, PyObject **, ! PyFrameObject *, char *, PyObject *); static PyObject *loop_subscript(PyObject *, PyObject *); static PyObject *apply_slice(PyObject *, PyObject *, PyObject *); --- 63,67 ---- static void call_exc_trace(PyObject **, PyObject**, PyFrameObject *); static int call_trace(PyObject **, PyObject **, ! PyFrameObject *, char *, PyObject **, PyObject *); static PyObject *loop_subscript(PyObject *, PyObject *); static PyObject *apply_slice(PyObject *, PyObject *, PyObject *); *************** *** 98,101 **** --- 98,110 ---- #endif + /* Cached interned string objects used for calling the profile and + * trace functions. + */ + static PyObject *str_call = NULL; + static PyObject *str_exception = NULL; + static PyObject *str_line = NULL; + static PyObject *str_return = NULL; + + #ifdef WITH_THREAD *************** *** 646,650 **** is detected. */ if (call_trace(&tstate->sys_tracefunc, ! &f->f_trace, f, "call", Py_None/*XXX how to compute arguments now?*/)) { /* Trace function raised an error */ --- 655,659 ---- is detected. */ if (call_trace(&tstate->sys_tracefunc, ! &f->f_trace, f, "call", &str_call, Py_None/*XXX how to compute arguments now?*/)) { /* Trace function raised an error */ *************** *** 657,661 **** itself and isn't called for "line" events */ if (call_trace(&tstate->sys_profilefunc, ! (PyObject**)0, f, "call", Py_None/*XXX*/)) { goto fail; --- 666,670 ---- itself and isn't called for "line" events */ if (call_trace(&tstate->sys_profilefunc, ! (PyObject**)0, f, "call", &str_call, Py_None/*XXX*/)) { goto fail; *************** *** 1953,1957 **** f->f_lasti = INSTR_OFFSET(); err = call_trace(&f->f_trace, &f->f_trace, ! f, "line", Py_None); break; --- 1962,1966 ---- f->f_lasti = INSTR_OFFSET(); err = call_trace(&f->f_trace, &f->f_trace, ! f, "line", &str_line, Py_None); break; *************** *** 2298,2302 **** if (why == WHY_RETURN) { if (call_trace(&f->f_trace, &f->f_trace, f, ! "return", retval)) { Py_XDECREF(retval); retval = NULL; --- 2307,2311 ---- if (why == WHY_RETURN) { if (call_trace(&f->f_trace, &f->f_trace, f, ! "return", &str_return, retval)) { Py_XDECREF(retval); retval = NULL; *************** *** 2308,2312 **** if (tstate->sys_profilefunc && why == WHY_RETURN) { if (call_trace(&tstate->sys_profilefunc, (PyObject**)0, ! f, "return", retval)) { Py_XDECREF(retval); retval = NULL; --- 2317,2321 ---- if (tstate->sys_profilefunc && why == WHY_RETURN) { if (call_trace(&tstate->sys_profilefunc, (PyObject**)0, ! f, "return", &str_return, retval)) { Py_XDECREF(retval); retval = NULL; *************** *** 2576,2580 **** return; } ! err = call_trace(p_trace, p_newtrace, f, "exception", arg); Py_DECREF(arg); if (err == 0) --- 2585,2590 ---- return; } ! err = call_trace(p_trace, p_newtrace, f, ! "exception", &str_exception, arg); Py_DECREF(arg); if (err == 0) *************** *** 2589,2599 **** /* PyObject **p_trace: in/out; may not be NULL; may not point to NULL variable initially ! PyObject **p_newtrace: in/out; may be NULL; may point to NULL variable; ! may be same variable as p_newtrace */ static int call_trace(PyObject **p_trace, PyObject **p_newtrace, PyFrameObject *f, ! char *msg, PyObject *arg) { PyThreadState *tstate = f->f_tstate; --- 2599,2614 ---- /* PyObject **p_trace: in/out; may not be NULL; may not point to NULL variable initially ! PyObject **p_newtrace: in/out; may be NULL; may point to NULL variable; ! may be same variable as p_newtrace ! PyObject **p_omsg: in/out; may not be NULL; ! if non-null & *p_omsg == NULL, will be ! initialized with an interned string ! corresponding to msg. ! */ static int call_trace(PyObject **p_trace, PyObject **p_newtrace, PyFrameObject *f, ! char *msg, PyObject **p_omsg, PyObject *arg) { PyThreadState *tstate = f->f_tstate; *************** *** 2612,2619 **** args = PyTuple_New(3); if (args == NULL) - goto cleanup; - what = PyString_FromString(msg); - if (what == NULL) goto cleanup; Py_INCREF(f); PyTuple_SET_ITEM(args, 0, (PyObject *)f); --- 2627,2642 ---- args = PyTuple_New(3); if (args == NULL) goto cleanup; + if (*p_omsg != NULL) { + what = *p_omsg; + Py_INCREF(what); + } + else { + what = PyString_InternFromString(msg); + if (what == NULL) + goto cleanup; + *p_omsg = what; + Py_INCREF(what); + } Py_INCREF(f); PyTuple_SET_ITEM(args, 0, (PyObject *)f); From fdrake@users.sourceforge.net Fri Jun 8 06:04:22 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 07 Jun 2001 22:04:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libprofile.tex,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv30817/lib Modified Files: libprofile.tex Log Message: In the section on extending the profiler, add some additional discussion about setting up the dispatch table, and update the OldProfile and HotProfile classes to the current implementations, showing the adjusted construction for the dispatch table. Index: libprofile.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libprofile.tex,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -r1.32 -r1.33 *** libprofile.tex 2001/04/13 14:34:58 1.32 --- libprofile.tex 2001/06/08 05:04:19 1.33 *************** *** 656,667 **** returns a lone integer value will provide the best results in terms of low overhead during profiling. (\function{os.times()} is ! \emph{pretty} bad, 'cause it returns a tuple of floating point values, so all arithmetic is floating point in the profiler!). If you want to substitute a better timer in the cleanest fashion, you should derive a class, and simply put in the replacement dispatch method that better handles your timer call, along with the appropriate calibration ! constant :-). \subsection{OldProfile Class \label{profile-old}} --- 656,695 ---- returns a lone integer value will provide the best results in terms of low overhead during profiling. (\function{os.times()} is ! \emph{pretty} bad, as it returns a tuple of floating point values, so all arithmetic is floating point in the profiler!). If you want to substitute a better timer in the cleanest fashion, you should derive a class, and simply put in the replacement dispatch method that better handles your timer call, along with the appropriate calibration ! constant. + Note that subclasses which override any of the + \method{trace_dispatch_call()}, \method{trace_dispatch_exception()}, + or \method{trace_dispatch_return()} methods also need to specify a + dispatch table as well. The table, named \member{dispatch}, should + have the three keys \code{'call'}, \code{'exception'}, and + \code{'return'}, each giving the function of the corresponding + handler. Note that best performance is achieved by using the + \emph{function} objects for the handlers and not bound methods. This + is preferred since calling a simple function object executes less code + in the runtime than calling either bound or unbound methods. For + example, if the derived profiler overrides only one method, the + \member{dispatch} table can be built like this: + \begin{verbatim} + from profile import Profile + + class MyProfiler(Profile): + def trace_dispath_call(self, frame, t): + # do something interesting here + ... + + dispatch = { + 'call': trace_dispatch_call, + 'exception': Profile.__dict__['trace_dispatch_exception'], + 'return': Profile.__dict__['trace_dispatch_return'], + } + \end{verbatim} + + \subsection{OldProfile Class \label{profile-old}} *************** *** 685,689 **** def trace_dispatch_call(self, frame, t): fn = `frame.f_code` ! self.cur = (t, 0, 0, fn, frame, self.cur) if self.timings.has_key(fn): --- 713,717 ---- def trace_dispatch_call(self, frame, t): fn = `frame.f_code` ! self.cur = (t, 0, 0, fn, frame, self.cur) if self.timings.has_key(fn): *************** *** 711,714 **** --- 739,747 ---- return 1 + dispatch = { + "call": trace_dispatch_call, + "exception": trace_dispatch_exception, + "return": trace_dispatch_return, + } def snapshot_stats(self): *************** *** 716,729 **** for func in self.timings.keys(): tt, ct, callers = self.timings[func] ! nor_func = self.func_normalize(func) ! nor_callers = {} nc = 0 for func_caller in callers.keys(): - nor_callers[self.func_normalize(func_caller)] = \ - callers[func_caller] nc = nc + callers[func_caller] ! self.stats[nor_func] = nc, nc, tt, ct, nor_callers \end{verbatim} \subsection{HotProfile Class \label{profile-HotProfile}} --- 749,760 ---- for func in self.timings.keys(): tt, ct, callers = self.timings[func] ! callers = callers.copy() nc = 0 for func_caller in callers.keys(): nc = nc + callers[func_caller] ! self.stats[func] = nc, nc, tt, ct, callers \end{verbatim} + \subsection{HotProfile Class \label{profile-HotProfile}} *************** *** 764,767 **** --- 795,803 ---- return 1 + dispatch = { + "call": trace_dispatch_call, + "exception": trace_dispatch_exception, + "return": trace_dispatch_return, + } def snapshot_stats(self): *************** *** 769,773 **** for func in self.timings.keys(): nc, tt = self.timings[func] ! nor_func = self.func_normalize(func) ! self.stats[nor_func] = nc, nc, tt, 0, {} \end{verbatim} --- 805,808 ---- for func in self.timings.keys(): nc, tt = self.timings[func] ! self.stats[func] = nc, nc, tt, 0, {} \end{verbatim} From montanaro@users.sourceforge.net Fri Jun 8 15:40:30 2001 From: montanaro@users.sourceforge.net (Skip Montanaro) Date: Fri, 08 Jun 2001 07:40:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libdoctest.tex,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv24607 Modified Files: libdoctest.tex Log Message: add warning about situation where code may be executed twice, once when module is __main__ and once when module is imported. Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -r1.6 -r1.7 *** libdoctest.tex 2001/04/05 18:31:27 1.6 --- libdoctest.tex 2001/06/08 14:40:28 1.7 *************** *** 409,412 **** --- 409,422 ---- \end{enumerate} + \item Be careful if you have code that must only execute once. + + If you have module-level code that must only execute once, a more foolproof + definition of \function{_test} is + + \begin{verbatim} + def _test(): + import doctest, sys + doctest.testmod(sys.modules["__main__"]) + \end{verbatim} \subsection{Soapbox} From fdrake@users.sourceforge.net Fri Jun 8 17:25:01 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 08 Jun 2001 09:25:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tut tut.tex,1.136,1.137 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tut In directory usw-pr-cvs1:/tmp/cvs-serv13703/tut Modified Files: tut.tex Log Message: Text from Tim & Guido discussing floating point arithmetic and what users need to understand about the binary & decimal fp, so that representation weirdness is documented somewhere. This makes it easier to repond to "bug" reports caused by user confusion & ignorance of the issues. This closes SF patch #426208. Index: tut.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tut/tut.tex,v retrieving revision 1.136 retrieving revision 1.137 diff -C2 -r1.136 -r1.137 *** tut.tex 2001/05/22 06:54:14 1.136 --- tut.tex 2001/06/08 16:24:58 1.137 *************** *** 4086,4088 **** --- 4086,4353 ---- + \chapter{Floating Point Arithmetic: Issues and Limitations + \label{fp-issues}} + + Floating-point numbers are represented in computer hardware as + base 2 (binary) fractions. For example, the decimal fraction + + \begin{verbatim} + 0.125 + \end{verbatim} + + has value 1/10 + 2/100 + 5/1000, and in the same way the binary fraction + + \begin{verbatim} + 0.001 + \end{verbatim} + + has value 0/2 + 0/4 + 1/8. These two fractions have identical values, + the only real difference being that the first is written in base 10 + fractional notation, and the second in base 2. + + Unfortunately, most decimal fractions cannot be represented exactly as + binary fractions. A consequence is that, in general, the decimal + floating-point numbers you enter are only approximated by the binary + floating-point numbers actually stored in the machine. + + The problem is easier to understand at first in base 10. Consider the + fraction 1/3. You can approximate that as a base 10 fraction: + + \begin{verbatim} + 0.3 + \end{verbatim} + + or, better, + + \begin{verbatim} + 0.33 + \end{verbatim} + + or, better, + + \begin{verbatim} + 0.333 + \end{verbatim} + + and so on. No matter how many digits you're willing to write down, the + result will never be exactly 1/3, but will be an increasingly better + approximation to 1/3. + + In the same way, no matter how many base 2 digits you're willing to + use, the decimal value 0.1 cannot be represented exactly as a base 2 + fraction. In base 2, 1/10 is the infinitely repeating fraction + + \begin{verbatim} + 0.0001100110011001100110011001100110011001100110011... + \end{verbatim} + + Stop at any finite number of bits, and you get an approximation. This + is why you see things like: + + \begin{verbatim} + >>> 0.1 + 0.10000000000000001 + \end{verbatim} + + On most machines today, that is what you'll see if you enter 0.1 at + a Python prompt. You may not, though, because the number of bits + used by the hardware to store floating-point values can vary across + machines, and Python only prints a decimal approximation to the true + decimal value of the binary approximation stored by the machine. On + most machines, if Python were to print the true decimal value of + the binary approximation stored for 0.1, it would have to display + + \begin{verbatim} + >>> 0.1 + 0.1000000000000000055511151231257827021181583404541015625 + \end{verbatim} + + instead! The Python prompt (implicitly) uses the builtin + \function{repr()} function to obtain a string version of everything it + displays. For floats, \code{repr(\var{float})} rounds the true + decimal value to 17 significant digits, giving + + \begin{verbatim} + 0.10000000000000001 + \end{verbatim} + + \code{repr(\var{float})} produces 17 significant digits because it + turns out that's enough (on most machines) so that + \code{eval(repr(\var{x})) == \var{x}} exactly for all finite floats + \var{x}, but rounding to 16 digits is not enough to make that true. + + Note that this is in the very nature of binary floating-point: this is + not a bug in Python, it is not a bug in your code either, and you'll + see the same kind of thing in all languages that support your + hardware's floating-point arithmetic. + + Python's builtin \function{str()} function produces only 12 + significant digits, and you may wish to use that instead. It's + unusual for \code{eval(str(\var{x}))} to reproduce \var{x}, but the + output may be more pleasant to look at: + + \begin{verbatim} + >>> print str(0.1) + 0.1 + \end{verbatim} + + It's important to realize that this is, in a real sense, an illusion: + the value in the machine is not exactly 1/10, you're simply rounding + the \emph{display} of the true machine value. + + Other surprises follow from this one. For example, after seeing + + \begin{verbatim} + >>> 0.1 + 0.10000000000000001 + \end{verbatim} + + you may be tempted to use the \function{round()} function to chop it + back to the single digit you expect. But that makes no difference: + + \begin{verbatim} + >>> round(0.1, 1) + 0.10000000000000001 + \end{verbatim} + + The problem is that the binary floating-point value stored for "0.1" + was already the best possible binary approximation to 1/10, so trying + to round it again can't make it better: it was already as good as it + gets. + + Another consequence is that since 0.1 is not exactly 1/10, adding 0.1 + to itself 10 times may not yield exactly 1.0, either: + + \begin{verbatim} + >>> sum = 0.0 + >>> for i in range(10): + ... sum += 0.1 + ... + >>> sum + 0.99999999999999989 + \end{verbatim} + + Binary floating-point arithmetic holds many surprises like this. The + problem with "0.1" is explained in precise detail below, in the + "Representation Error" section. See + \citetitle[http://www.lahey.com/float.htm]{The Perils of Floating + Point} for a more complete account of other common surprises. + + As that says near the end, ``there are no easy answers.'' Still, + don't be unduly wary of floating-point! The errors in Python float + operations are inherited from the floating-point hardware, and on most + machines are on the order of no more than 1 part in 2**53 per + operation. That's more than adequate for most tasks, but you do need + to keep in mind that it's not decimal arithmetic, and that every float + operation can suffer a new rounding error. + + While pathological cases do exist, for most casual use of + floating-point arithmetic you'll see the result you expect in the end + if you simply round the display of your final results to the number of + decimal digits you expect. \function{str()} usually suffices, and for + finer control see the discussion of Pythons's \code{\%} format + operator: the \code{\%g}, \code{\%f} and \code{\%e} format codes + supply flexible and easy ways to round float results for display. + + + \section{Representation Error + \label{fp-error}} + + This section explains the ``0.1'' example in detail, and shows how + you can perform an exact analysis of cases like this yourself. Basic + familiarity with binary floating-point representation is assumed. + + \dfn{Representation error} refers to that some (most, actually) + decimal fractions cannot be represented exactly as binary (base 2) + fractions. This is the chief reason why Python (or Perl, C, \Cpp, + Java, Fortran, and many others) often won't display the exact decimal + number you expect: + + \begin{verbatim} + >>> 0.1 + 0.10000000000000001 + \end{verbatim} + + Why is that? 1/10 is not exactly representable as a binary fraction. + Almost all machines today (November 2000) use IEEE-754 floating point + arithmetic, and almost all platforms map Python floats to IEEE-754 + "double precision". 754 doubles contain 53 bits of precision, so on + input the computer strives to convert 0.1 to the closest fraction it can + of the form \var{J}/2**\var{N} where \var{J} is an integer containing + exactly 53 bits. Rewriting + + \begin{verbatim} + 1 / 10 ~= J / (2**N) + \end{verbatim} + + as + + \begin{verbatim} + J ~= 2**N / 10 + \end{verbatim} + + and recalling that \var{J} has exactly 53 bits (is \code{>= 2**52} but + \code{< 2**53}), the best value for \var{N} is 56: + + \begin{verbatim} + >>> 2L**52 + 4503599627370496L + >>> 2L**53 + 9007199254740992L + >>> 2L**56/10 + 7205759403792793L + \end{verbatim} + + That is, 56 is the only value for \var{N} that leaves \var{J} with + exactly 53 bits. The best possible value for \var{J} is then that + quotient rounded: + + \begin{verbatim} + >>> q, r = divmod(2L**56, 10) + >>> r + 6L + \end{verbatim} + + Since the remainder is more than half of 10, the best approximation is + obtained by rounding up: + + \begin{verbatim} + >>> q+1 + 7205759403792794L + \end{verbatim} + + Therefore the best possible approximation to 1/10 in 754 double + precision is that over 2**56, or + + \begin{verbatim} + 7205759403792794 / 72057594037927936 + \end{verbatim} + + Note that since we rounded up, this is actually a little bit larger than + 1/10; if we had not rounded up, the quotient would have been a little + bit smaller than 1/10. But in no case can it be *exactly* 1/10! + + So the computer never ``sees'' 1/10: what it sees is the exact + fraction given above, the best 754 double approximation it can get: + + \begin{verbatim} + >>> .1 * 2L**56 + 7205759403792794.0 + \end{verbatim} + + If we multiply that fraction by 10**30, we can see the (truncated) + value of its 30 most significant decimal digits: + + \begin{verbatim} + >>> 7205759403792794L * 10L**30 / 2L**56 + 100000000000000005551115123125L + \end{verbatim} + + meaning that the exact number stored in the computer is approximately + equal to the decimal value 0.100000000000000005551115123125. Rounding + that to 17 significant digits gives the 0.10000000000000001 that Python + displays (well, will display on any 754-conforming platform that does + best-possible input and output conversions in its C library --- yours may + not!). + \end{document} From fdrake@users.sourceforge.net Fri Jun 8 17:28:55 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 08 Jun 2001 09:28:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tut tut.tex,1.137,1.138 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tut In directory usw-pr-cvs1:/tmp/cvs-serv14450/tut Modified Files: tut.tex Log Message: Added credits in the right places. Index: tut.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tut/tut.tex,v retrieving revision 1.137 retrieving revision 1.138 diff -C2 -r1.137 -r1.138 *** tut.tex 2001/06/08 16:24:58 1.137 --- tut.tex 2001/06/08 16:28:53 1.138 *************** *** 4088,4091 **** --- 4088,4092 ---- \chapter{Floating Point Arithmetic: Issues and Limitations \label{fp-issues}} + \sectionauthor{Tim Peters}{tim_one@msn.com} Floating-point numbers are represented in computer hardware as *************** *** 4253,4256 **** --- 4254,4258 ---- \section{Representation Error \label{fp-error}} + \sectionauthor{Guido van Rossum}{guido@python.org} This section explains the ``0.1'' example in detail, and shows how From tim.one@home.com Fri Jun 8 17:58:52 2001 From: tim.one@home.com (Tim Peters) Date: Fri, 8 Jun 2001 12:58:52 -0400 Subject: [Python-checkins] CVS: python/dist/src/Doc/tut tut.tex,1.137,1.138 In-Reply-To: Message-ID: [Fred L. Drake] > Modified Files: > tut.tex > Log Message: > > Added credits in the right places. > > > Index: tut.tex > =================================================================== > RCS file: /cvsroot/python/python/dist/src/Doc/tut/tut.tex,v > retrieving revision 1.137 > retrieving revision 1.138 > diff -C2 -r1.137 -r1.138 > *** tut.tex 2001/06/08 16:24:58 1.137 > --- tut.tex 2001/06/08 16:28:53 1.138 > *************** > *** 4088,4091 **** > --- 4088,4092 ---- > \chapter{Floating Point Arithmetic: Issues and Limitations > \label{fp-issues}} > + \sectionauthor{Tim Peters}{tim_one@msn.com} tim.one@home.com is a better home address. OTOH, if people have questions about f.p., they're more likely to get further explanation by sending them to, say, floating_point_wizard@hotmail.com instead. > Floating-point numbers are represented in computer hardware as > *************** > *** 4253,4256 **** > --- 4254,4258 ---- > \section{Representation Error > \label{fp-error}} > + \sectionauthor{Guido van Rossum}{guido@python.org} Guido didn't write any of that -- 'twas another Uncle Timmy production. But feel free to attribute the first section to Guido too. the-goal-is-to-avoid-any-followups-to-me-ly y'rs - tim From fdrake@users.sourceforge.net Fri Jun 8 18:09:03 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 08 Jun 2001 10:09:03 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tut tut.tex,1.138,1.139 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tut In directory usw-pr-cvs1:/tmp/cvs-serv22259/tut Modified Files: tut.tex Log Message: Fix the attributions for the new floating point text. Index: tut.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tut/tut.tex,v retrieving revision 1.138 retrieving revision 1.139 diff -C2 -r1.138 -r1.139 *** tut.tex 2001/06/08 16:28:53 1.138 --- tut.tex 2001/06/08 17:09:01 1.139 *************** *** 4088,4092 **** \chapter{Floating Point Arithmetic: Issues and Limitations \label{fp-issues}} ! \sectionauthor{Tim Peters}{tim_one@msn.com} Floating-point numbers are represented in computer hardware as --- 4088,4092 ---- \chapter{Floating Point Arithmetic: Issues and Limitations \label{fp-issues}} ! \sectionauthor{Tim Peters}{tim.one@home.com} Floating-point numbers are represented in computer hardware as *************** *** 4254,4258 **** \section{Representation Error \label{fp-error}} - \sectionauthor{Guido van Rossum}{guido@python.org} This section explains the ``0.1'' example in detail, and shows how --- 4254,4257 ---- From fdrake@acm.org Fri Jun 8 18:12:20 2001 From: fdrake@acm.org (Fred L. Drake, Jr.) Date: Fri, 8 Jun 2001 13:12:20 -0400 (EDT) Subject: [Python-checkins] CVS: python/dist/src/Doc/tut tut.tex,1.137,1.138 In-Reply-To: References: Message-ID: <15137.1908.635915.418543@cj42289-a.reston1.va.home.com> Tim Peters writes: > tim.one@home.com is a better home address. OTOH, if people have questions > about f.p., they're more likely to get further explanation by sending them > to, say, floating_point_wizard@hotmail.com instead. Since your name and email don't appear in the formatted docs, I wouldn't be too worried about yet another email deluge. I'll be sure to forward all the queries I get at python-docs to floating_point_wizard@hotmail.com. ;-) > Guido didn't write any of that -- 'twas another Uncle Timmy production. But > feel free to attribute the first section to Guido too. Fixed; thanks! > the-goal-is-to-avoid-any-followups-to-me-ly y'rs - tim Either that or to give credit where it's due. Thanks! -Fred -- Fred L. Drake, Jr. PythonLabs at Digital Creations From tim.one@home.com Fri Jun 8 18:43:29 2001 From: tim.one@home.com (Tim Peters) Date: Fri, 8 Jun 2001 13:43:29 -0400 Subject: [Python-checkins] CVS: python/dist/src/Doc/tut tut.tex,1.137,1.138 In-Reply-To: <15137.1908.635915.418543@cj42289-a.reston1.va.home.com> Message-ID: [Fred] > Since your name and email don't appear in the formatted docs, I > wouldn't be too worried about yet another email deluge. Ah, excellent! In that case, put my name in every section . From gvanrossum@users.sourceforge.net Fri Jun 8 21:50:33 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 08 Jun 2001 13:50:33 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0252.txt,1.7,1.8 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv1144 Modified Files: pep-0252.txt Log Message: I just figured out how to make automatic hyperlinks to other PEPs. Index: pep-0252.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0252.txt,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** pep-0252.txt 2001/05/22 03:04:27 1.7 --- pep-0252.txt 2001/06/08 20:50:31 1.8 *************** *** 404,408 **** 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 --- 404,408 ---- Note: the code in this branch goes beyond this PEP; it is also ! on the way to implementing pep-0253 (Subtyping Built-in Types). References From loewis@users.sourceforge.net Sat Jun 9 08:34:07 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sat, 09 Jun 2001 00:34:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib UserList.py,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv9798/Lib Modified Files: UserList.py Log Message: Patch #424475: Speed-up tp_compare usage, by special-casing the common case of objects with equal types which support tp_compare. Give type objects a tp_compare function. Also add c<0 tests before a few PyErr_Occurred tests. Index: UserList.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/UserList.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -r1.16 -r1.17 *** UserList.py 2001/02/18 03:30:53 1.16 --- UserList.py 2001/06/09 07:34:05 1.17 *************** *** 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) From loewis@users.sourceforge.net Sat Jun 9 08:34:07 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sat, 09 Jun 2001 00:34:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects object.c,2.131,2.132 typeobject.c,2.16,2.17 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv9798/Objects Modified Files: object.c typeobject.c Log Message: Patch #424475: Speed-up tp_compare usage, by special-casing the common case of objects with equal types which support tp_compare. Give type objects a tp_compare function. Also add c<0 tests before a few PyErr_Occurred tests. Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.131 retrieving revision 2.132 diff -C2 -r2.131 -r2.132 *** object.c 2001/05/11 03:36:45 2.131 --- object.c 2001/06/09 07:34:05 2.132 *************** *** 478,491 **** 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); --- 478,481 ---- *************** *** 500,504 **** Py_DECREF(v); Py_DECREF(w); ! if (PyErr_Occurred()) return -2; return c < 0 ? -1 : c > 0 ? 1 : 0; --- 490,494 ---- Py_DECREF(v); Py_DECREF(w); ! if (c < 0 && PyErr_Occurred()) return -2; return c < 0 ? -1 : c > 0 ? 1 : 0; *************** *** 510,514 **** Py_DECREF(v); Py_DECREF(w); ! if (PyErr_Occurred()) return -2; return c < 0 ? 1 : c > 0 ? -1 : 0; /* negated! */ --- 500,504 ---- Py_DECREF(v); Py_DECREF(w); ! if (c < 0 && PyErr_Occurred()) return -2; return c < 0 ? 1 : c > 0 ? -1 : 0; /* negated! */ *************** *** 591,594 **** --- 581,586 ---- 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 *************** *** 596,600 **** --- 588,596 ---- { 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) *************** *** 761,774 **** 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; --- 757,763 ---- static PyObject * ! convert_3way_to_object(int op, int c) { PyObject *result; switch (op) { case Py_LT: c = c < 0; break; *************** *** 783,791 **** --- 772,820 ---- 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); Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16 retrieving revision 2.17 diff -C2 -r2.16 -r2.17 *** typeobject.c 2000/09/01 23:29:27 2.16 --- typeobject.c 2001/06/09 07:34:05 2.17 *************** *** 24,27 **** --- 24,37 ---- } + 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 *v) *************** *** 42,51 **** (getattrfunc)type_getattr, /*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*/ 0, /*tp_call*/ 0, /*tp_str*/ --- 52,61 ---- (getattrfunc)type_getattr, /*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*/ ! _Py_HashPointer, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ From loewis@users.sourceforge.net Sat Jun 9 08:59:45 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sat, 09 Jun 2001 00:59:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include cStringIO.h,2.14,2.15 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv15182 Modified Files: cStringIO.h Log Message: Cast the result of xxxPyCObject_Import to PycStringIO_CAPI*. This fixes bug #431557. Index: cStringIO.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/cStringIO.h,v retrieving revision 2.14 retrieving revision 2.15 diff -C2 -r2.14 -r2.15 *** cStringIO.h 2000/07/22 19:25:51 2.14 --- cStringIO.h 2001/06/09 07:59:43 2.15 *************** *** 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 */ From tim_one@users.sourceforge.net Sat Jun 9 10:26:23 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 09 Jun 2001 02:26:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.96,1.97 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv30667/python/dist/src/Misc Modified Files: ACKS Log Message: SF bug 430991: wrong co_lnotab Armin Rigo pointed out that the way the line-# table got built didn't work for lines generating more than 255 bytes of bytecode. Fixed as he suggested, plus corresponding changes to pyassem.py, plus added some long overdue docs about this subtle table to compile.c. Bugfix candidate (line numbers may be off in tracebacks under -O). Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.96 retrieving revision 1.97 diff -C2 -r1.96 -r1.97 *** ACKS 2001/04/24 05:16:29 1.96 --- ACKS 2001/06/09 09:26:21 1.97 *************** *** 320,323 **** --- 320,324 ---- Steven Reiz Jan Pieter Riegel + Armin Rigo Nicholas Riley Jean-Claude Rimbault From tim_one@users.sourceforge.net Sat Jun 9 10:26:23 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 09 Jun 2001 02:26:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/compiler/compiler pyassem.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/compiler/compiler In directory usw-pr-cvs1:/tmp/cvs-serv30667/python/dist/src/Tools/compiler/compiler Modified Files: pyassem.py Log Message: SF bug 430991: wrong co_lnotab Armin Rigo pointed out that the way the line-# table got built didn't work for lines generating more than 255 bytes of bytecode. Fixed as he suggested, plus corresponding changes to pyassem.py, plus added some long overdue docs about this subtle table to compile.c. Bugfix candidate (line numbers may be off in tracebacks under -O). Index: pyassem.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/compiler/compiler/pyassem.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -r1.19 -r1.20 *** pyassem.py 2001/04/12 20:21:39 1.19 --- pyassem.py 2001/06/09 09:26:21 1.20 *************** *** 614,619 **** """lnotab ! This class builds the lnotab, which is undocumented but described ! by com_set_lineno in compile.c. Here's an attempt at explanation: For each SET_LINENO instruction after the first one, two bytes are --- 614,619 ---- """lnotab ! This class builds the lnotab, which is documented in compile.c. ! Here's a brief recap: For each SET_LINENO instruction after the first one, two bytes are *************** *** 622,627 **** instruction for the last SET_LINENO and the current SET_LINENO. The second byte is offset in line numbers. If either offset is ! greater than 255, multiple two-byte entries are added -- one entry ! for each factor of 255. """ --- 622,627 ---- instruction for the last SET_LINENO and the current SET_LINENO. The second byte is offset in line numbers. If either offset is ! greater than 255, multiple two-byte entries are added -- see ! compile.c for the delicate details. """ *************** *** 658,674 **** # for the assignment. if line > 0: ! while addr > 0 or line > 0: ! # write the values in 1-byte chunks that sum ! # to desired value ! trunc_addr = addr ! trunc_line = line ! if trunc_addr > 255: ! trunc_addr = 255 ! if trunc_line > 255: ! trunc_line = 255 ! self.lnotab.append(trunc_addr) ! self.lnotab.append(trunc_line) ! addr = addr - trunc_addr ! line = line - trunc_line self.lastline = lineno self.lastoff = self.codeOffset --- 658,671 ---- # for the assignment. if line > 0: ! push = self.lnotab.append ! while addr > 255: ! push(255); push(0) ! addr -= 255 ! while line > 255: ! push(addr); push(255) ! line -= 255 ! addr = 0 ! if addr > 0 or line > 0: ! push(addr); push(line) self.lastline = lineno self.lastoff = self.codeOffset From tim_one@users.sourceforge.net Sat Jun 9 10:26:23 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 09 Jun 2001 02:26:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python compile.c,2.200,2.201 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv30667/python/dist/src/Python Modified Files: compile.c Log Message: SF bug 430991: wrong co_lnotab Armin Rigo pointed out that the way the line-# table got built didn't work for lines generating more than 255 bytes of bytecode. Fixed as he suggested, plus corresponding changes to pyassem.py, plus added some long overdue docs about this subtle table to compile.c. Bugfix candidate (line numbers may be off in tracebacks under -O). Index: compile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v retrieving revision 2.200 retrieving revision 2.201 diff -C2 -r2.200 -r2.201 *** compile.c 2001/05/09 18:53:51 2.200 --- compile.c 2001/06/09 09:26:21 2.201 *************** *** 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; From nowonder@users.sourceforge.net Sun Jun 10 17:45:10 2001 From: nowonder@users.sourceforge.net (Peter Schneider-Kamp) Date: Sun, 10 Jun 2001 09:45:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules mathmodule.c,2.58,2.59 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv2707 Modified Files: mathmodule.c Log Message: annoying whitespace inconsistency Index: mathmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/mathmodule.c,v retrieving revision 2.58 retrieving revision 2.59 diff -C2 -r2.58 -r2.59 *** mathmodule.c 2000/10/12 19:42:00 2.58 --- mathmodule.c 2001/06/10 16:45:08 2.59 *************** *** 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.") From loewis@users.sourceforge.net Sun Jun 10 18:27:38 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 10 Jun 2001 10:27:38 -0700 Subject: [Python-checkins] CVS: python/nondist/i18n/po python.pot,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/i18n/po In directory usw-pr-cvs1:/tmp/cvs-serv8954 Modified Files: python.pot Log Message: Install 2.1 version of doc string catalog. Index: python.pot =================================================================== RCS file: /cvsroot/python/python/nondist/i18n/po/python.pot,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** python.pot 2000/09/13 19:49:31 1.1 --- python.pot 2001/06/10 17:27:34 1.2 *************** *** 1,18 **** ! # Python Message Catalog ! # Copyright (c) 2000 BeOpen.com. ! # Copyright (c) 1995-2000 Corporation for National Research Initiatives. ! # Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, ! # The Netherlands. ! # # FIRST AUTHOR , YEAR. # # This version of the catalog contains only doc strings, which a # developer can access interactively during development. [...34507 lines suppressed...] ! #: Modules/zlibmodule.c:600 msgid "flush() -- Return a string containing any remaining decompressed data. The decompressor object can no longer be used after this call." msgstr "" ! #: Modules/zlibmodule.c:665 msgid "" "adler32(string) -- Compute an Adler-32 checksum of string, using a default starting value, and returning an integer value.\n" *************** *** 16665,16669 **** msgstr "" ! #: Modules/zlibmodule.c:734 msgid "" "crc32(string) -- Compute a CRC-32 checksum of string, using a default starting value, and returning an integer value.\n" --- 19633,19637 ---- msgstr "" ! #: Modules/zlibmodule.c:687 msgid "" "crc32(string) -- Compute a CRC-32 checksum of string, using a default starting value, and returning an integer value.\n" From tim_one@users.sourceforge.net Sun Jun 10 19:58:28 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 10 Jun 2001 11:58:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib traceback.py,1.25,1.26 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv22975/python/dist/src/lib Modified Files: traceback.py Log Message: SF bug 431772: traceback.print_exc() causes traceback Patch from Michael Hundson. format_exception_only() blew up when trying to report a SyntaxError from a string input (line is None in this case, but it assumed a string). Bugfix candidate. Index: traceback.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/traceback.py,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -r1.25 -r1.26 *** traceback.py 2001/03/29 04:36:08 1.25 --- traceback.py 2001/06/10 18:58:26 1.26 *************** *** 172,188 **** list.append(' File "%s", line %d\n' % (filename, lineno)) ! i = 0 ! while i < len(line) and line[i].isspace(): ! i = i+1 ! list.append(' %s\n' % line.strip()) ! if offset is not None: ! s = ' ' ! for c in line[i:offset-1]: ! if c.isspace(): ! s = s + c ! else: ! s = s + ' ' ! list.append('%s^\n' % s) ! value = msg s = _some_str(value) if s: --- 172,189 ---- list.append(' File "%s", line %d\n' % (filename, lineno)) ! if line is not None: ! i = 0 ! while i < len(line) and line[i].isspace(): ! i = i+1 ! list.append(' %s\n' % line.strip()) ! if offset is not None: ! s = ' ' ! for c in line[i:offset-1]: ! if c.isspace(): ! s = s + c ! else: ! s = s + ' ' ! list.append('%s^\n' % s) ! value = msg s = _some_str(value) if s: From jackjansen@users.sourceforge.net Sun Jun 10 22:43:30 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sun, 10 Jun 2001 14:43:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.17,2.18 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv18874/Python/Objects Modified Files: typeobject.c Log Message: Added a missing cast to the hashfunc initializer. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.17 retrieving revision 2.18 diff -C2 -r2.17 -r2.18 *** typeobject.c 2001/06/09 07:34:05 2.17 --- typeobject.c 2001/06/10 21:43:28 2.18 *************** *** 57,61 **** 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ ! _Py_HashPointer, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ --- 57,61 ---- 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ ! (hashfunc)_Py_HashPointer, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ From tim_one@users.sourceforge.net Mon Jun 11 00:40:21 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 10 Jun 2001 16:40:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.181,1.182 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv6496/python/dist/src/Misc Modified Files: NEWS Log Message: Initial support for 'q' and 'Q' struct format codes: for now, only in native mode, and only when config #defines HAVE_LONG_LONG. Standard mode will eventually treat them as 8-byte ints across all platforms, but that likely requires a new set of routines in longobject.c first (while sizeof(long) >= 4 is guaranteed by C, there's nothing in C we can rely on x-platform to hold 8 bytes of int, so we'll have to roll our own; I'm thinking of a simple pair of conversion functions, Python long to/from sized vector of unsigned bytes; that may be useful for GMP conversions too; std q/Q would call them with size fixed at 8). test_struct.py: In addition to adding some native-mode 'q' and 'Q' tests, got rid of unused code, and repaired a non-portable assumption about native sizeof(short) (it isn't 2 on some Cray boxes). libstruct.tex: In addition to adding a bit of 'q'/'Q' docs (more needed later), removed an erroneous footnote about 'I' behavior. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.181 retrieving revision 1.182 diff -C2 -r1.181 -r1.182 *** NEWS 2001/06/06 13:30:54 1.181 --- NEWS 2001/06/10 23:40:19 1.182 *************** *** 141,144 **** --- 141,152 ---- - pprint functions now much faster for large containers (tuple, list, dict). + - New 'q' and 'Q' format codes in the struct module, corresponding to C + types "long long" and "unsigned long long" (on Windows, __int64). In + native mode, these can be used only when the platform C compiler supports + these types (when HAVE_LONG_LONG is #define'd by the Python config + process), and then they inherit the sizes and alignments of the C types. + XXX TODO In standard mode, 'q' and 'Q' are supported on all platforms, and + XXX TODO are 8-byte integral types. + Tests From tim_one@users.sourceforge.net Mon Jun 11 00:40:21 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 10 Jun 2001 16:40:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libstruct.tex,1.26,1.27 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv6496/python/dist/src/Doc/lib Modified Files: libstruct.tex Log Message: Initial support for 'q' and 'Q' struct format codes: for now, only in native mode, and only when config #defines HAVE_LONG_LONG. Standard mode will eventually treat them as 8-byte ints across all platforms, but that likely requires a new set of routines in longobject.c first (while sizeof(long) >= 4 is guaranteed by C, there's nothing in C we can rely on x-platform to hold 8 bytes of int, so we'll have to roll our own; I'm thinking of a simple pair of conversion functions, Python long to/from sized vector of unsigned bytes; that may be useful for GMP conversions too; std q/Q would call them with size fixed at 8). test_struct.py: In addition to adding some native-mode 'q' and 'Q' tests, got rid of unused code, and repaired a non-portable assumption about native sizeof(short) (it isn't 2 on some Cray boxes). libstruct.tex: In addition to adding a bit of 'q'/'Q' docs (more needed later), removed an erroneous footnote about 'I' behavior. Index: libstruct.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstruct.tex,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -r1.26 -r1.27 *** libstruct.tex 2001/01/24 17:19:07 1.26 --- libstruct.tex 2001/06/10 23:40:19 1.27 *************** *** 54,60 **** \lineiv{H}{\ctype{unsigned short}}{integer}{} \lineiv{i}{\ctype{int}}{integer}{} ! \lineiv{I}{\ctype{unsigned int}}{long}{(1)} \lineiv{l}{\ctype{long}}{integer}{} \lineiv{L}{\ctype{unsigned long}}{long}{} \lineiv{f}{\ctype{float}}{float}{} \lineiv{d}{\ctype{double}}{float}{} --- 54,62 ---- \lineiv{H}{\ctype{unsigned short}}{integer}{} \lineiv{i}{\ctype{int}}{integer}{} ! \lineiv{I}{\ctype{unsigned int}}{long}{} \lineiv{l}{\ctype{long}}{integer}{} \lineiv{L}{\ctype{unsigned long}}{long}{} + \lineiv{q}{\ctype{long long}}{long}{(1)} + \lineiv{Q}{\ctype{unsigned long long}}{long}{(1)} \lineiv{f}{\ctype{float}}{float}{} \lineiv{d}{\ctype{double}}{float}{} *************** *** 69,76 **** \begin{description} \item[(1)] ! The \character{I} conversion code will convert to a Python long if ! the C \ctype{int} is the same size as a C \ctype{long}, which is ! typical on most modern systems. If a C \ctype{int} is smaller than ! a C \ctype{long}, an Python integer will be created instead. \end{description} --- 71,77 ---- \begin{description} \item[(1)] ! The \character{q} and \character{Q} conversion codes are available in ! native mode only if the platform C compiler supports C \ctype{long long}, ! or, on Windows, \ctype{__int64}. \end{description} From tim_one@users.sourceforge.net Mon Jun 11 00:40:21 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 10 Jun 2001 16:40:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules structmodule.c,2.42,2.43 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv6496/python/dist/src/Modules Modified Files: structmodule.c Log Message: Initial support for 'q' and 'Q' struct format codes: for now, only in native mode, and only when config #defines HAVE_LONG_LONG. Standard mode will eventually treat them as 8-byte ints across all platforms, but that likely requires a new set of routines in longobject.c first (while sizeof(long) >= 4 is guaranteed by C, there's nothing in C we can rely on x-platform to hold 8 bytes of int, so we'll have to roll our own; I'm thinking of a simple pair of conversion functions, Python long to/from sized vector of unsigned bytes; that may be useful for GMP conversions too; std q/Q would call them with size fixed at 8). test_struct.py: In addition to adding some native-mode 'q' and 'Q' tests, got rid of unused code, and repaired a non-portable assumption about native sizeof(short) (it isn't 2 on some Cray boxes). libstruct.tex: In addition to adding a bit of 'q'/'Q' docs (more needed later), removed an erroneous footnote about 'I' behavior. Index: structmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/structmodule.c,v retrieving revision 2.42 retrieving revision 2.43 diff -C2 -r2.42 -r2.43 *** structmodule.c 2001/04/08 23:39:38 2.42 --- structmodule.c 2001/06/10 23:40:19 2.43 *************** *** 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\ *************** *** 66,69 **** --- 68,83 ---- #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)) + + #else + static char qQ_error_msg[] = + "q and Q unavailable in native mode on this platform; use a standard mode.\0"; + + #endif + #define STRINGIFY(x) #x *************** *** 107,111 **** --- 121,212 ---- } + #ifdef HAVE_LONG_LONG + + /* Same, but handling native long long. */ + + static int + get_longlong(PyObject *v, LONG_LONG *p) + { + LONG_LONG x; + int v_needs_decref = 0; + + if (PyInt_Check(v)) { + x = (LONG_LONG)PyInt_AS_LONG(v); + *p = x; + return 0; + } + if (!PyLong_Check(v)) { + PyNumberMethods *m = v->ob_type->tp_as_number; + if (m != NULL && m->nb_long != NULL) { + v = m->nb_long(v); + if (v == NULL) + return -1; + v_needs_decref = 1; + } + if (!PyLong_Check(v)) { + PyErr_SetString(StructError, + "cannot convert argument to long"); + if (v_needs_decref) + Py_DECREF(v); + return -1; + } + } + assert(PyLong_Check(v)); + x = PyLong_AsLongLong(v); + if (v_needs_decref) + 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; + int v_needs_decref = 0; + + if (PyInt_Check(v)) { + long i = PyInt_AS_LONG(v); + if (i < 0) { + PyErr_SetString(StructError, "can't convert negative " + "int to unsigned"); + return -1; + } + x = (unsigned LONG_LONG)i; + *p = x; + return 0; + } + if (!PyLong_Check(v)) { + PyNumberMethods *m = v->ob_type->tp_as_number; + if (m != NULL && m->nb_long != NULL) { + v = m->nb_long(v); + if (v == NULL) + return -1; + v_needs_decref = 1; + } + if (!PyLong_Check(v)) { + PyErr_SetString(StructError, + "cannot convert argument to long"); + if (v_needs_decref) + Py_DECREF(v); + return -1; + } + } + assert(PyLong_Check(v)); + x = PyLong_AsUnsignedLongLong(v); + if (v_needs_decref) + Py_DECREF(v); + if (x == (unsigned LONG_LONG)-1 && PyErr_Occurred()) + return -1; + *p = x; + return 0; + } + + #endif + /* Floating point helpers */ *************** *** 396,399 **** --- 497,511 ---- } 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 **** --- 563,594 ---- } + /* 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); + } + + #else + + static PyObject * + nu_qQerror(const char *p, const formatdef *f) + { + PyErr_SetString(StructError, qQ_error_msg); + return NULL; + } + + #endif + static PyObject * nu_float(const char *p, const formatdef *f) *************** *** 586,590 **** --- 726,763 ---- } + #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; + } + + #else + + static int + np_qQerror(char *p, PyObject *v, const formatdef *f) + { + PyErr_SetString(StructError, qQ_error_msg); + return -1; + } + + #endif + + static int np_float(char *p, PyObject *v, const formatdef *f) { *************** *** 643,646 **** --- 816,831 ---- {'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}, + #else + /* n[pu]_qQerror just raise errors, but give them "the expected" size + and alignment anyway so that calcsize returns something reasonable, + and so unpack code that works on a 'long long' platform ends up in + the error routine instead of with a mysterious "unpack str size + does not match format" msg when run on a non-'long long' box. */ + {'q', 8, 8, nu_qQerror, np_qQerror}, + {'Q', 8, 8, nu_qQerror, np_qQerror}, + #endif {0} }; From tim_one@users.sourceforge.net Mon Jun 11 00:40:21 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 10 Jun 2001 16:40:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_struct.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv6496/python/dist/src/Lib/test Modified Files: test_struct.py Log Message: Initial support for 'q' and 'Q' struct format codes: for now, only in native mode, and only when config #defines HAVE_LONG_LONG. Standard mode will eventually treat them as 8-byte ints across all platforms, but that likely requires a new set of routines in longobject.c first (while sizeof(long) >= 4 is guaranteed by C, there's nothing in C we can rely on x-platform to hold 8 bytes of int, so we'll have to roll our own; I'm thinking of a simple pair of conversion functions, Python long to/from sized vector of unsigned bytes; that may be useful for GMP conversions too; std q/Q would call them with size fixed at 8). test_struct.py: In addition to adding some native-mode 'q' and 'Q' tests, got rid of unused code, and repaired a non-portable assumption about native sizeof(short) (it isn't 2 on some Cray boxes). libstruct.tex: In addition to adding a bit of 'q'/'Q' docs (more needed later), removed an erroneous footnote about 'I' behavior. Index: test_struct.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_struct.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** test_struct.py 2000/12/12 23:11:42 1.7 --- test_struct.py 2001/06/10 23:40:19 1.8 *************** *** 1,3 **** ! from test_support import TestFailed, verbose import struct ## import pdb --- 1,3 ---- ! from test_support import TestFailed, verbose, verify import struct ## import pdb *************** *** 13,17 **** ## pdb.set_trace() ! simple_err(struct.calcsize, 'Q') sz = struct.calcsize('i') --- 13,17 ---- ## pdb.set_trace() ! simple_err(struct.calcsize, 'Z') sz = struct.calcsize('i') *************** *** 94,106 **** ] ! 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: --- 94,99 ---- ] ! isbigendian = struct.pack('=i', 1)[0] == chr(0) for fmt, arg, big, lil, asy in tests: if verbose: *************** *** 120,121 **** --- 113,158 ---- raise TestFailed, "unpack(%s, %s) -> (%s,) # expected (%s,)" % ( `fmt`, `res`, `rev`, `arg`) + + # Some q/Q sanity checks. + + 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." + + simple_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 force_bigendian(value): + if isbigendian: + return value + chars = list(value) + chars.reverse() + return "".join(chars) + + if has_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) + bigexpected = force_bigendian(expected) + verify(got == bigexpected, + "%r-pack of %r gave %r, not %r" % + (format, input, got, bigexpected)) + retrieved = struct.unpack(format, got)[0] + verify(retrieved == input, + "%r-unpack of %r gave %r, not %r" % + (format, got, retrieved, input)) From tim_one@users.sourceforge.net Mon Jun 11 00:53:01 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 10 Jun 2001 16:53:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_struct.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv9934/python/dist/src/Lib/test Modified Files: test_struct.py Log Message: Renamed some stuff to tell the truth about what it does. Index: test_struct.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_struct.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** test_struct.py 2001/06/10 23:40:19 1.8 --- test_struct.py 2001/06/10 23:52:59 1.9 *************** *** 129,133 **** simple_err(struct.pack, "Q", "a") # ditto, but 'Q' ! def force_bigendian(value): if isbigendian: return value --- 129,133 ---- simple_err(struct.pack, "Q", "a") # ditto, but 'Q' ! def bigendian_to_native(value): if isbigendian: return value *************** *** 149,156 **** ('q', (1L << (8*bytes-1))-1, '\x7f' + '\xff' * (bytes - 1))): got = struct.pack(format, input) ! bigexpected = force_bigendian(expected) ! verify(got == bigexpected, "%r-pack of %r gave %r, not %r" % ! (format, input, got, bigexpected)) retrieved = struct.unpack(format, got)[0] verify(retrieved == input, --- 149,156 ---- ('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, From fdrake@users.sourceforge.net Mon Jun 11 15:55:03 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 11 Jun 2001 07:55:03 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libdoctest.tex,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv28494/lib Modified Files: libdoctest.tex Log Message: Fix recent changes so that this section will format again. Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** libdoctest.tex 2001/06/08 14:40:28 1.7 --- libdoctest.tex 2001/06/11 14:55:01 1.8 *************** *** 407,416 **** Simple fractions are also easier for people to understand, and that makes for better documentation. - \end{enumerate} \item Be careful if you have code that must only execute once. If you have module-level code that must only execute once, a more foolproof ! definition of \function{_test} is \begin{verbatim} --- 407,415 ---- Simple fractions are also easier for people to understand, and that makes for better documentation. \item Be careful if you have code that must only execute once. If you have module-level code that must only execute once, a more foolproof ! definition of \function{_test()} is \begin{verbatim} *************** *** 419,422 **** --- 418,423 ---- doctest.testmod(sys.modules["__main__"]) \end{verbatim} + \end{enumerate} + \subsection{Soapbox} From fdrake@users.sourceforge.net Mon Jun 11 15:57:09 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 11 Jun 2001 07:57:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libdoctest.tex,1.6,1.6.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv28910 Modified Files: Tag: release21-maint libdoctest.tex Log Message: Merge in recent changes from development branch: add warning about being sure that code only runs once when using the module as both a module and a script. Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.6 retrieving revision 1.6.2.1 diff -C2 -r1.6 -r1.6.2.1 *** libdoctest.tex 2001/04/05 18:31:27 1.6 --- libdoctest.tex 2001/06/11 14:57:07 1.6.2.1 *************** *** 407,410 **** --- 407,421 ---- Simple fractions are also easier for people to understand, and that makes for better documentation. + + \item Be careful if you have code that must only execute once. + + If you have module-level code that must only execute once, a more foolproof + definition of \function{_test()} is + + \begin{verbatim} + def _test(): + import doctest, sys + doctest.testmod(sys.modules["__main__"]) + \end{verbatim} \end{enumerate} From twouters@users.sourceforge.net Mon Jun 11 16:21:45 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Mon, 11 Jun 2001 08:21:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules termios.c,2.24.2.2,2.24.2.3 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv2209/Modules Modified Files: Tag: release21-maint termios.c Log Message: Protect the use of the VWERASE symbol by an #ifdef, it's apparently missing on (some versions of ?) AIX. Index: termios.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/termios.c,v retrieving revision 2.24.2.2 retrieving revision 2.24.2.3 diff -C2 -r2.24.2.2 -r2.24.2.3 *** termios.c 2001/05/23 11:32:06 2.24.2.2 --- termios.c 2001/06/11 15:21:43 2.24.2.3 *************** *** 543,547 **** --- 543,549 ---- {"VDISCARD", VDISCARD}, #endif + #ifdef VWERASE {"VWERASE", VWERASE}, + #endif {"VLNEXT", VLNEXT}, {"VEOL2", VEOL2}, From fdrake@users.sourceforge.net Mon Jun 11 16:21:50 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 11 Jun 2001 08:21:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libos.tex,1.56,1.57 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv2313/lib Modified Files: libos.tex Log Message: Fixed parameter order for os.popen2(), os.popen3(), and os.popen(4). Added a reference to these functions and popen() from the "Process Management" section. Based on a suggestion from comp.lang.python. Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.56 retrieving revision 1.57 diff -C2 -r1.56 -r1.57 *** libos.tex 2001/06/04 15:31:17 1.56 --- libos.tex 2001/06/11 15:21:48 1.57 *************** *** 315,319 **** for \var{mode} is \code{'t'}. ! \begin{funcdesc}{popen2}{cmd\optional{, bufsize\optional{, mode}}} Executes \var{cmd} as a sub-process. Returns the file objects \code{(\var{child_stdin}, \var{child_stdout})}. --- 315,319 ---- for \var{mode} is \code{'t'}. ! \begin{funcdesc}{popen2}{cmd\optional{, mode\optional{, bufsize}}} Executes \var{cmd} as a sub-process. Returns the file objects \code{(\var{child_stdin}, \var{child_stdout})}. *************** *** 321,325 **** \end{funcdesc} ! \begin{funcdesc}{popen3}{cmd\optional{, bufsize\optional{, mode}}} Executes \var{cmd} as a sub-process. Returns the file objects \code{(\var{child_stdin}, \var{child_stdout}, \var{child_stderr})}. --- 321,325 ---- \end{funcdesc} ! \begin{funcdesc}{popen3}{cmd\optional{, mode\optional{, bufsize}}} Executes \var{cmd} as a sub-process. Returns the file objects \code{(\var{child_stdin}, \var{child_stdout}, \var{child_stderr})}. *************** *** 327,331 **** \end{funcdesc} ! \begin{funcdesc}{popen4}{cmd\optional{, bufsize\optional{, mode}}} Executes \var{cmd} as a sub-process. Returns the file objects \code{(\var{child_stdin}, \var{child_stdout_and_stderr})}. --- 327,331 ---- \end{funcdesc} ! \begin{funcdesc}{popen4}{cmd\optional{, mode\optional{, bufsize}}} Executes \var{cmd} as a sub-process. Returns the file objects \code{(\var{child_stdin}, \var{child_stdout_and_stderr})}. *************** *** 928,931 **** --- 928,939 ---- Availability: \UNIX{}. \end{funcdesc} + + \begin{funcdescni}{popen}{\unspecified} + \funclineni{popen2}{\unspecified} + \funclineni{popen3}{\unspecified} + \funclineni{popen4}{\unspecified} + Run child processes, returning opened pipes for communications. These + functions are described in section \ref{os-newstreams}. + \end{funcdescni} \begin{funcdesc}{spawnv}{mode, path, args} From fdrake@users.sourceforge.net Mon Jun 11 16:22:25 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 11 Jun 2001 08:22:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libos.tex,1.53.4.3,1.53.4.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv2493/lib Modified Files: Tag: release21-maint libos.tex Log Message: Fixed parameter order for os.popen2(), os.popen3(), and os.popen(4). Added a reference to these functions and popen() from the "Process Management" section. Based on a suggestion from comp.lang.python. Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.53.4.3 retrieving revision 1.53.4.4 diff -C2 -r1.53.4.3 -r1.53.4.4 *** libos.tex 2001/06/04 15:30:41 1.53.4.3 --- libos.tex 2001/06/11 15:22:23 1.53.4.4 *************** *** 315,319 **** for \var{mode} is \code{'t'}. ! \begin{funcdesc}{popen2}{cmd\optional{, bufsize\optional{, mode}}} Executes \var{cmd} as a sub-process. Returns the file objects \code{(\var{child_stdin}, \var{child_stdout})}. --- 315,319 ---- for \var{mode} is \code{'t'}. ! \begin{funcdesc}{popen2}{cmd\optional{, mode\optional{, bufsize}}} Executes \var{cmd} as a sub-process. Returns the file objects \code{(\var{child_stdin}, \var{child_stdout})}. *************** *** 321,325 **** \end{funcdesc} ! \begin{funcdesc}{popen3}{cmd\optional{, bufsize\optional{, mode}}} Executes \var{cmd} as a sub-process. Returns the file objects \code{(\var{child_stdin}, \var{child_stdout}, \var{child_stderr})}. --- 321,325 ---- \end{funcdesc} ! \begin{funcdesc}{popen3}{cmd\optional{, mode\optional{, bufsize}}} Executes \var{cmd} as a sub-process. Returns the file objects \code{(\var{child_stdin}, \var{child_stdout}, \var{child_stderr})}. *************** *** 327,331 **** \end{funcdesc} ! \begin{funcdesc}{popen4}{cmd\optional{, bufsize\optional{, mode}}} Executes \var{cmd} as a sub-process. Returns the file objects \code{(\var{child_stdin}, \var{child_stdout_and_stderr})}. --- 327,331 ---- \end{funcdesc} ! \begin{funcdesc}{popen4}{cmd\optional{, mode\optional{, bufsize}}} Executes \var{cmd} as a sub-process. Returns the file objects \code{(\var{child_stdin}, \var{child_stdout_and_stderr})}. *************** *** 928,931 **** --- 928,939 ---- Availability: \UNIX{}. \end{funcdesc} + + \begin{funcdescni}{popen}{\unspecified} + \funclineni{popen2}{\unspecified} + \funclineni{popen3}{\unspecified} + \funclineni{popen4}{\unspecified} + Run child processes, returning opened pipes for communications. These + functions are described in section \ref{os-newstreams}. + \end{funcdescni} \begin{funcdesc}{spawnv}{mode, path, args} From twouters@users.sourceforge.net Mon Jun 11 16:25:18 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Mon, 11 Jun 2001 08:25:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules termios.c,2.29,2.30 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv3523/Modules Modified Files: termios.c Log Message: Protect the use of the VWERASE symbol by an #ifdef, it's apparently missing on (some versions of ?) AIX. Index: termios.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/termios.c,v retrieving revision 2.29 retrieving revision 2.30 diff -C2 -r2.29 -r2.30 *** termios.c 2001/05/22 15:44:15 2.29 --- termios.c 2001/06/11 15:25:16 2.30 *************** *** 543,547 **** --- 543,549 ---- {"VDISCARD", VDISCARD}, #endif + #ifdef VWERASE {"VWERASE", VWERASE}, + #endif {"VLNEXT", VLNEXT}, {"VEOL2", VEOL2}, From gvanrossum@users.sourceforge.net Mon Jun 11 16:29:55 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 11 Jun 2001 08:29:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.36,2.16.8.37 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv4951 Modified Files: Tag: descr-branch typeobject.c Log Message: More random modifications. Take away the default slots from object again; these were inherited by all other standard types, and that's not right (it was suddenly possible to create and subclass e.g. int, but the resulting objects were time bombs). Instead, type_new() provides some default slots to qualifying derived types. I have yet to develop a theory for this. Some things I'm happier with: best_base(): initialize the bases if needed. type_init(): refuse to re-initialize a previously initialized type object (there's too much damage it could do). type_new(): rename the first argument to metatype, which it is. Implement type_getattro() (the metatype's tp_getattro slot) as a wrapper around PyObject_GenericGetAttr() that initializes the type object first if it has to. Implement type_alloc() (the metatype's tp_alloc slot) as a wrapper around PyType_GenericAlloc() that sets tp_flags correctly, so we don't have to wave our hands so much in type_dealloc(). Inherit tp_getattr and tp_getattro as a pair; ditto for tp_setattr[o]; ditto for tp_compare and tp_richcompare (the latter conditional on Py_TPFLAGS_HAVE_RICHCOMPARE). Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.36 retrieving revision 2.16.8.37 diff -C2 -r2.16.8.36 -r2.16.8.37 *** typeobject.c 2001/06/07 19:14:45 2.16.8.36 --- typeobject.c 2001/06/11 15:29:53 2.16.8.37 *************** *** 295,298 **** --- 295,302 ---- return NULL; } + if (base_i->tp_dict == NULL) { + if (PyType_InitDict(base_i) < 0) + return NULL; + } candidate = solid_base(base_i); if (issubtype(winner, candidate)) *************** *** 316,319 **** --- 320,326 ---- /* TypeType's initializer; called when a type is subclassed */ + staticforward void object_dealloc(PyObject *); + staticforward int object_init(PyObject *, PyObject *, PyObject *); + static int type_init(PyObject *self, PyObject *args, PyObject *kwds) *************** *** 329,332 **** --- 336,346 ---- type = (PyTypeObject *)self; + /* Check this is a virginal type object */ + if (type->tp_dict != NULL) { + PyErr_SetString(PyExc_TypeError, + "can't re-initialize type objects"); + return -1; + } + /* Check arguments */ if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO:type", kwlist, *************** *** 335,339 **** if (!PyTuple_Check(bases) || !PyDict_Check(dict)) { PyErr_SetString(PyExc_TypeError, ! "usage: TypeType(name, bases, dict) "); return -1; } --- 349,353 ---- if (!PyTuple_Check(bases) || !PyDict_Check(dict)) { PyErr_SetString(PyExc_TypeError, ! "usage: type(name, bases, dict) "); return -1; } *************** *** 354,358 **** if (base == NULL) return -1; ! if (base->tp_init == NULL) { PyErr_SetString(PyExc_TypeError, "base type must have a constructor slot"); --- 368,372 ---- if (base == NULL) return -1; ! if (base->tp_init == NULL && base != &PyBaseObject_Type) { PyErr_SetString(PyExc_TypeError, "base type must have a constructor slot"); *************** *** 366,369 **** --- 380,384 ---- /* Check for a __slots__ sequence variable in dict, and count it */ + /* XXX This should move to type_alloc() */ slots = PyDict_GetItemString(dict, "__slots__"); nslots = 0; *************** *** 411,428 **** type->tp_as_buffer = &et->as_buffer; type->tp_name = PyString_AS_STRING(name); - type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE; - /* Override some slots with specific requirements */ - if (type->tp_dealloc) - type->tp_dealloc = subtype_dealloc; - if (type->tp_getattro == NULL) { - type->tp_getattro = PyObject_GenericGetAttr; - type->tp_getattr = NULL; - } - if (type->tp_setattro == NULL) { - type->tp_setattro = PyObject_GenericSetAttr; - type->tp_setattr = NULL; - } - /* Initialize tp_introduced from passed-in dict */ type->tp_introduced = dict = PyDict_Copy(dict); --- 426,430 ---- *************** *** 454,459 **** type->tp_basicsize = slotoffset; add_members(type, et->members); ! /* Initialize tp_bases, tp_dict, tp_introduced; inherit slots */ if (PyType_InitDict(type) < 0) return -1; --- 456,479 ---- type->tp_basicsize = slotoffset; add_members(type, et->members); + + /* Special case some slots */ + if (type->tp_dictoffset != 0) { + if (base->tp_getattr == NULL && base->tp_getattro == NULL) + type->tp_getattro = PyObject_GenericGetAttr; + if (base->tp_setattr == NULL && base->tp_setattro == NULL) + type->tp_setattro = PyObject_GenericSetAttr; + } + if (base->tp_dealloc == NULL) + type->tp_dealloc = object_dealloc; + else + type->tp_dealloc = subtype_dealloc; + if (base->tp_new == NULL) + type->tp_new = PyType_GenericNew; + if (base->tp_alloc == NULL) + type->tp_alloc = PyType_GenericAlloc; + if (base->tp_init == NULL) + type->tp_init = object_init; ! /* Initialize the rest */ if (PyType_InitDict(type) < 0) return -1; *************** *** 506,511 **** } static PyObject * ! type_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *name, *bases, *dict; --- 526,548 ---- } + static PyObject * + type_alloc(PyTypeObject *metatype, PyObject *args, PyObject *kwds) + { + PyTypeObject *type; + PyObject *name, *bases, *dict; + static char *kwlist[] = {"name", "bases", "dict", 0}; + + /* Check arguments (again?!?! yes, alas -- we need the dict!) */ + if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO:type", kwlist, + &name, &bases, &dict)) + return NULL; + type = (PyTypeObject *)PyType_GenericAlloc(metatype, args, kwds); + if (type != NULL) + type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE; + return (PyObject *)type; + } + static PyObject * ! type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) { PyObject *name, *bases, *dict; *************** *** 525,529 **** return NULL; if (PyTuple_Check(bases)) { - PyTypeObject *metatype = type; int i, n; n = PyTuple_GET_SIZE(bases); --- 562,565 ---- *************** *** 542,550 **** } if (metatype->tp_new != type_new) ! return metatype->tp_new(type, args, kwds); } ! return PyType_GenericNew(type, args, kwds); } static void type_dealloc(PyTypeObject *type) --- 578,596 ---- } if (metatype->tp_new != type_new) ! return metatype->tp_new(metatype, args, kwds); } ! return PyType_GenericNew(metatype, args, kwds); } + static PyObject * + type_getattro(PyTypeObject *type, PyObject *name) + { + if (type->tp_dict == NULL) { + if (PyType_InitDict(type) < 0) + return NULL; + } + return PyObject_GenericGetAttr((PyObject *)type, name); + } + static void type_dealloc(PyTypeObject *type) *************** *** 552,558 **** etype *et; ! /* Assert this is a heap-allocated type object, or uninitialized */ ! if (type->tp_flags != 0) ! assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE); et = (etype *)type; Py_XDECREF(type->tp_base); --- 598,603 ---- etype *et; ! /* Assert this is a heap-allocated type object */ ! assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE); et = (etype *)type; Py_XDECREF(type->tp_base); *************** *** 586,590 **** (ternaryfunc)type_call, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 631,635 ---- (ternaryfunc)type_call, /* tp_call */ 0, /* tp_str */ ! (getattrofunc)type_getattro, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ *************** *** 606,610 **** offsetof(PyTypeObject, tp_dict), /* tp_dictoffset */ type_init, /* tp_init */ ! PyType_GenericAlloc, /* tp_alloc */ type_new, /* tp_new */ }; --- 651,655 ---- offsetof(PyTypeObject, tp_dict), /* tp_dictoffset */ type_init, /* tp_init */ ! type_alloc, /* tp_alloc */ type_new, /* tp_new */ }; *************** *** 613,616 **** --- 658,667 ---- /* The base type of all types (eventually)... except itself. */ + static int + object_init(PyObject *self, PyObject *args, PyObject *kwds) + { + return 0; + } + static void object_dealloc(PyObject *self) *************** *** 624,633 **** }; - static int - object_init(PyObject *self, PyObject *args, PyObject *kwds) - { - return 0; - } - PyTypeObject PyBaseObject_Type = { PyObject_HEAD_INIT(&PyType_Type) --- 675,678 ---- *************** *** 636,640 **** sizeof(PyObject), /* tp_basicsize */ 0, /* tp_itemsize */ ! (destructor)object_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ --- 681,685 ---- sizeof(PyObject), /* tp_basicsize */ 0, /* tp_itemsize */ ! 0/*(destructor)object_dealloc*/, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ *************** *** 648,652 **** 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 693,697 ---- 0, /* tp_call */ 0, /* tp_str */ ! 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ *************** *** 667,673 **** 0, /* tp_descr_set */ 0, /* tp_dictoffset */ ! object_init, /* tp_init */ ! PyType_GenericAlloc, /* tp_alloc */ ! PyType_GenericNew, /* tp_new */ }; --- 712,718 ---- 0, /* tp_descr_set */ 0, /* tp_dictoffset */ ! 0, /* tp_init */ ! 0, /* tp_alloc */ ! 0, /* tp_new */ }; *************** *** 885,902 **** COPYSLOT(tp_dealloc); COPYSLOT(tp_print); ! COPYSLOT(tp_getattr); ! COPYSLOT(tp_setattr); ! COPYSLOT(tp_compare); COPYSLOT(tp_repr); COPYSLOT(tp_hash); COPYSLOT(tp_call); COPYSLOT(tp_str); - COPYSLOT(tp_getattro); - COPYSLOT(tp_setattro); COPYSLOT(tp_as_buffer); COPYSLOT(tp_flags); COPYSLOT(tp_doc); if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_RICHCOMPARE) { ! COPYSLOT(tp_richcompare); } if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_WEAKREFS) { --- 930,957 ---- COPYSLOT(tp_dealloc); COPYSLOT(tp_print); ! if (type->tp_getattr == NULL && type->tp_getattro == NULL) { ! type->tp_getattr = base->tp_getattr; ! type->tp_getattro = base->tp_getattro; ! } ! if (type->tp_setattr == NULL && type->tp_setattro == NULL) { ! type->tp_setattr = base->tp_setattr; ! type->tp_setattro = base->tp_setattro; ! } ! /* tp_compare see tp_richcompare */ COPYSLOT(tp_repr); COPYSLOT(tp_hash); COPYSLOT(tp_call); COPYSLOT(tp_str); COPYSLOT(tp_as_buffer); COPYSLOT(tp_flags); COPYSLOT(tp_doc); if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_RICHCOMPARE) { ! if (type->tp_compare == NULL && type->tp_richcompare == NULL) { ! type->tp_compare = base->tp_compare; ! type->tp_richcompare = base->tp_richcompare; ! } ! } ! else { ! COPYSLOT(tp_compare); } if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_WEAKREFS) { From tim_one@users.sourceforge.net Mon Jun 11 17:45:35 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 11 Jun 2001 09:45:35 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules structmodule.c,2.43,2.44 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv23133/python/dist/src/Modules Modified Files: structmodule.c Log Message: Make clear in the docstring that "std" applies to both size and alignment, not just to alignment. Spotted by Guido. Bugfix candidate. Index: structmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/structmodule.c,v retrieving revision 2.43 retrieving revision 2.44 diff -C2 -r2.43 -r2.44 *** structmodule.c 2001/06/10 23:40:19 2.43 --- structmodule.c 2001/06/11 16:45:33 2.44 *************** *** 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\ From tim_one@users.sourceforge.net Mon Jun 11 17:51:58 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 11 Jun 2001 09:51:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules structmodule.c,2.44,2.45 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv24678/python/dist/src/Modules Modified Files: structmodule.c Log Message: Simplify some convolution by simply not recognizing 'q' and 'Q' at all in native mode on platforms that don't HAVE_LONG_LONG. Index: structmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/structmodule.c,v retrieving revision 2.44 retrieving revision 2.45 diff -C2 -r2.44 -r2.45 *** structmodule.c 2001/06/11 16:45:33 2.44 --- structmodule.c 2001/06/11 16:51:56 2.45 *************** *** 73,81 **** typedef struct { char c; LONG_LONG x; } s_long_long; #define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(LONG_LONG)) - - #else - static char qQ_error_msg[] = - "q and Q unavailable in native mode on this platform; use a standard mode.\0"; - #endif --- 73,76 ---- *************** *** 579,592 **** return PyLong_FromUnsignedLongLong(*(unsigned LONG_LONG *)p); } - - #else - - static PyObject * - nu_qQerror(const char *p, const formatdef *f) - { - PyErr_SetString(StructError, qQ_error_msg); - return NULL; - } - #endif --- 574,577 ---- *************** *** 747,760 **** return 0; } - - #else - - static int - np_qQerror(char *p, PyObject *v, const formatdef *f) - { - PyErr_SetString(StructError, qQ_error_msg); - return -1; - } - #endif --- 732,735 ---- *************** *** 819,830 **** {'q', sizeof(LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong}, {'Q', sizeof(LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong}, - #else - /* n[pu]_qQerror just raise errors, but give them "the expected" size - and alignment anyway so that calcsize returns something reasonable, - and so unpack code that works on a 'long long' platform ends up in - the error routine instead of with a mysterious "unpack str size - does not match format" msg when run on a non-'long long' box. */ - {'q', 8, 8, nu_qQerror, np_qQerror}, - {'Q', 8, 8, nu_qQerror, np_qQerror}, #endif {0} --- 794,797 ---- From tim_one@users.sourceforge.net Mon Jun 11 17:57:35 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 11 Jun 2001 09:57:35 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules structmodule.c,2.45,2.46 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv25882/python/dist/src/Modules Modified Files: structmodule.c Log Message: Trimmed trailing whitespace. Index: structmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/structmodule.c,v retrieving revision 2.45 retrieving revision 2.46 diff -C2 -r2.45 -r2.46 *** structmodule.c 2001/06/11 16:51:56 2.45 --- structmodule.c 2001/06/11 16:57:33 2.46 *************** *** 47,51 **** /* ** 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 *************** *** 1113,1117 **** else num = 1; ! e = getentry(c, f); if (e == NULL) --- 1113,1117 ---- else num = 1; ! e = getentry(c, f); if (e == NULL) *************** *** 1173,1177 **** (n = PyTuple_Size(args)) < 1) { ! PyErr_SetString(PyExc_TypeError, "struct.pack requires at least one argument"); return NULL; --- 1173,1177 ---- (n = PyTuple_Size(args)) < 1) { ! PyErr_SetString(PyExc_TypeError, "struct.pack requires at least one argument"); return NULL; From fdrake@users.sourceforge.net Mon Jun 11 19:25:36 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 11 Jun 2001 11:25:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libos.tex,1.57,1.58 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv11909/lib Modified Files: libos.tex Log Message: Add the appropriate availability annotations for the popen*() family of functions -- these are not available on traditional Mac OS platforms. Corrected the version annotations for the spawn*() functions and related constants; these were added in Python 1.6, not 1.5.2. Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.57 retrieving revision 1.58 diff -C2 -r1.57 -r1.58 *** libos.tex 2001/06/11 15:21:48 1.57 --- libos.tex 2001/06/11 18:25:34 1.58 *************** *** 318,321 **** --- 318,322 ---- Executes \var{cmd} as a sub-process. Returns the file objects \code{(\var{child_stdin}, \var{child_stdout})}. + Availability: \UNIX{}, Windows. \versionadded{2.0} \end{funcdesc} *************** *** 324,327 **** --- 325,329 ---- Executes \var{cmd} as a sub-process. Returns the file objects \code{(\var{child_stdin}, \var{child_stdout}, \var{child_stderr})}. + Availability: \UNIX{}, Windows. \versionadded{2.0} \end{funcdesc} *************** *** 330,333 **** --- 332,336 ---- Executes \var{cmd} as a sub-process. Returns the file objects \code{(\var{child_stdin}, \var{child_stdout_and_stderr})}. + Availability: \UNIX{}, Windows. \versionadded{2.0} \end{funcdesc} *************** *** 945,949 **** listed below. Availability: \UNIX{}, Windows. ! \versionadded{1.5.2} \end{funcdesc} --- 948,952 ---- listed below. Availability: \UNIX{}, Windows. ! \versionadded{1.6} \end{funcdesc} *************** *** 956,960 **** constants are exposed to the Python programmer as listed below. Availability: \UNIX{}, Windows. ! \versionadded{1.5.2} \end{funcdesc} --- 959,963 ---- constants are exposed to the Python programmer as listed below. Availability: \UNIX{}, Windows. ! \versionadded{1.6} \end{funcdesc} *************** *** 965,969 **** and \function{spawnve()}. Availability: \UNIX{}, Windows. ! \versionadded{1.5.2} \end{datadesc} --- 968,972 ---- and \function{spawnve()}. Availability: \UNIX{}, Windows. ! \versionadded{1.6} \end{datadesc} *************** *** 974,978 **** above. Availability: Windows. ! \versionadded{1.5.2} \end{datadesc} --- 977,981 ---- above. Availability: Windows. ! \versionadded{1.6} \end{datadesc} From fdrake@users.sourceforge.net Mon Jun 11 19:26:07 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 11 Jun 2001 11:26:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libos.tex,1.53.4.4,1.53.4.5 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv12038/lib Modified Files: Tag: release21-maint libos.tex Log Message: Add the appropriate availability annotations for the popen*() family of functions -- these are not available on traditional Mac OS platforms. Corrected the version annotations for the spawn*() functions and related constants; these were added in Python 1.6, not 1.5.2. Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.53.4.4 retrieving revision 1.53.4.5 diff -C2 -r1.53.4.4 -r1.53.4.5 *** libos.tex 2001/06/11 15:22:23 1.53.4.4 --- libos.tex 2001/06/11 18:26:04 1.53.4.5 *************** *** 318,321 **** --- 318,322 ---- Executes \var{cmd} as a sub-process. Returns the file objects \code{(\var{child_stdin}, \var{child_stdout})}. + Availability: \UNIX{}, Windows. \versionadded{2.0} \end{funcdesc} *************** *** 324,327 **** --- 325,329 ---- Executes \var{cmd} as a sub-process. Returns the file objects \code{(\var{child_stdin}, \var{child_stdout}, \var{child_stderr})}. + Availability: \UNIX{}, Windows. \versionadded{2.0} \end{funcdesc} *************** *** 330,333 **** --- 332,336 ---- Executes \var{cmd} as a sub-process. Returns the file objects \code{(\var{child_stdin}, \var{child_stdout_and_stderr})}. + Availability: \UNIX{}, Windows. \versionadded{2.0} \end{funcdesc} *************** *** 945,949 **** listed below. Availability: \UNIX{}, Windows. ! \versionadded{1.5.2} \end{funcdesc} --- 948,952 ---- listed below. Availability: \UNIX{}, Windows. ! \versionadded{1.6} \end{funcdesc} *************** *** 956,960 **** constants are exposed to the Python programmer as listed below. Availability: \UNIX{}, Windows. ! \versionadded{1.5.2} \end{funcdesc} --- 959,963 ---- constants are exposed to the Python programmer as listed below. Availability: \UNIX{}, Windows. ! \versionadded{1.6} \end{funcdesc} *************** *** 965,969 **** and \function{spawnve()}. Availability: \UNIX{}, Windows. ! \versionadded{1.5.2} \end{datadesc} --- 968,972 ---- and \function{spawnve()}. Availability: \UNIX{}, Windows. ! \versionadded{1.6} \end{datadesc} *************** *** 974,978 **** above. Availability: Windows. ! \versionadded{1.5.2} \end{datadesc} --- 977,981 ---- above. Availability: Windows. ! \versionadded{1.6} \end{datadesc} From gvanrossum@users.sourceforge.net Mon Jun 11 19:40:40 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 11 Jun 2001 11:40:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects frameobject.c,2.49.4.3,2.49.4.4 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv14923 Modified Files: Tag: descr-branch frameobject.c Log Message: By mistake there were two definitions for f_locals: a simple descriptor in the list of members, and a getter function. Recent changes in typeobject.c changed the precedence between these, and the one from the memberlist took precedence. But it's bogus, so get rid of it. (This caused test_inspect.py to fail.) Index: frameobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/frameobject.c,v retrieving revision 2.49.4.3 retrieving revision 2.49.4.4 diff -C2 -r2.49.4.3 -r2.49.4.4 *** frameobject.c 2001/06/06 14:27:54 2.49.4.3 --- frameobject.c 2001/06/11 18:40:38 2.49.4.4 *************** *** 16,20 **** {"f_builtins", T_OBJECT, OFF(f_builtins),RO}, {"f_globals", T_OBJECT, OFF(f_globals), RO}, - {"f_locals", T_OBJECT, OFF(f_locals), RO}, {"f_lasti", T_INT, OFF(f_lasti), RO}, {"f_lineno", T_INT, OFF(f_lineno), RO}, --- 16,19 ---- From gvanrossum@users.sourceforge.net Mon Jun 11 19:45:12 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 11 Jun 2001 11:45:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.37,2.16.8.38 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv16077 Modified Files: Tag: descr-branch typeobject.c Log Message: The wrapper function for tp_iternext can't be wrap_unaryfunc, because the tp_iternext slot doesn't always set the exception. Fix this by adding a custom wrapper, wrap_next(). Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.37 retrieving revision 2.16.8.38 diff -C2 -r2.16.8.37 -r2.16.8.38 *** typeobject.c 2001/06/11 15:29:53 2.16.8.37 --- typeobject.c 2001/06/11 18:45:10 2.16.8.38 *************** *** 1540,1545 **** }; static struct wrapperbase tab_next[] = { ! {"next", (wrapperfunc)wrap_unaryfunc, "x.next() -> next value"}, {0} }; --- 1540,1559 ---- }; + static PyObject * + wrap_next(PyObject *self, PyObject *args, void *wrapped) + { + unaryfunc func = (unaryfunc)wrapped; + PyObject *res; + + if (!PyArg_ParseTuple(args, "")) + return NULL; + res = (*func)(self); + if (res == NULL && !PyErr_Occurred()) + PyErr_SetNone(PyExc_StopIteration); + return res; + } + static struct wrapperbase tab_next[] = { ! {"next", (wrapperfunc)wrap_next, "x.next() -> next value"}, {0} }; From gvanrossum@users.sourceforge.net Mon Jun 11 20:05:30 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 11 Jun 2001 12:05:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_iter.py,1.2,1.2.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv20536 Modified Files: Tag: descr-branch test_iter.py Log Message: Add test_builtin_list() to test that list() of an iterator works. Index: test_iter.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_iter.py,v retrieving revision 1.2 retrieving revision 1.2.2.1 diff -C2 -r1.2 -r1.2.2.1 *** test_iter.py 2001/04/21 13:33:54 1.2 --- test_iter.py 2001/06/11 19:05:28 1.2.2.1 *************** *** 244,246 **** --- 244,278 ---- pass + # Test list()'s use of iterators. + def test_builtin_list(self): + self.assertEqual(list(SequenceClass(5)), range(5)) + self.assertEqual(list(SequenceClass(0)), []) + self.assertEqual(list(()), []) + self.assertEqual(list(range(10, -1, -1)), range(10, -1, -1)) + + d = {"one": 1, "two": 2, "three": 3} + self.assertEqual(list(d), d.keys()) + + self.assertRaises(TypeError, list, list) + self.assertRaises(TypeError, list, 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(list(f), ["0\n", "1\n", "2\n", "3\n", "4\n"]) + f.seek(0, 0) + self.assertEqual(list(f.xreadlines()), + ["0\n", "1\n", "2\n", "3\n", "4\n"]) + finally: + f.close() + try: + unlink(TESTFN) + except OSError: + pass + run_unittest(TestCase) From gvanrossum@users.sourceforge.net Mon Jun 11 20:06:46 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 11 Jun 2001 12:06:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects listobject.c,2.92.6.7,2.92.6.8 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv20784 Modified Files: Tag: descr-branch listobject.c Log Message: list_fill(): initialize the list items after NRESIZE. I would have fixed this sooner had I adopted the additional test in test_iter.py sooner. Index: listobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v retrieving revision 2.92.6.7 retrieving revision 2.92.6.8 diff -C2 -r2.92.6.7 -r2.92.6.8 *** listobject.c 2001/06/06 17:34:14 2.92.6.7 --- listobject.c 2001/06/11 19:06:44 2.92.6.8 *************** *** 1541,1544 **** --- 1541,1546 ---- if (result->ob_item == NULL) goto error; + for (i = 0; i < n; i++) + result->ob_item[i] = NULL; result->ob_size = n; From gvanrossum@users.sourceforge.net Mon Jun 11 20:09:48 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 11 Jun 2001 12:09:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects abstract.c,2.60.2.3,2.60.2.4 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv21434 Modified Files: Tag: descr-branch abstract.c Log Message: PyIter_Next(): adopt Tim's improvement, which clears the exception if it was a StopIteration. This is needed by list_fill() in listobject.c. (I have no test to prove it, but it's clear from the code of list_fill() that it makes the assumption that any exception is an error.) Index: abstract.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v retrieving revision 2.60.2.3 retrieving revision 2.60.2.4 diff -C2 -r2.60.2.3 -r2.60.2.4 *** abstract.c 2001/06/06 17:59:41 2.60.2.3 --- abstract.c 2001/06/11 19:09:46 2.60.2.4 *************** *** 1742,1748 **** --- 1742,1756 ---- } + /* Return next item. + * If an error occurs, return NULL. PyErr_Occurred() will be true. + * If the iteration terminates normally, return NULL and clear the + * PyExc_StopIteration exception (if it was set). PyErr_Occurred() + * will be false. + * Else return the next object. PyErr_Occurred() will be false. + */ PyObject * PyIter_Next(PyObject *iter) { + PyObject *result; if (!PyIter_Check(iter)) { PyErr_Format(PyExc_TypeError, *************** *** 1751,1754 **** return NULL; } ! return (*iter->ob_type->tp_iternext)(iter); } --- 1759,1767 ---- return NULL; } ! result = (*iter->ob_type->tp_iternext)(iter); ! if (result == NULL && ! PyErr_Occurred() && ! PyErr_ExceptionMatches(PyExc_StopIteration)) ! PyErr_Clear(); ! return result; } From gvanrossum@users.sourceforge.net Mon Jun 11 21:07:40 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 11 Jun 2001 13:07:40 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0259.txt,NONE,1.1 pep-0000.txt,1.95,1.96 pep-0253.txt,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv1958 Modified Files: pep-0000.txt pep-0253.txt Added Files: pep-0259.txt Log Message: PEP 259: Omit printing newline after newline --- NEW FILE: pep-0259.txt --- PEP: 259 Title: Omit printing newline after newline Version: $Revision: 1.1 $ Author: guido@python.org (Guido van Rossum) Status: Draft Type: Standards Track Python-Version: 2.2 Created: 11-Jun-2001 Post-History: 11-Jun-2001 Abstract Currently, the print statement always appends a newline, unless a trailing comma is used. This means that if we want to print data that already ends in a newline, we get two newlines, unless special precautions are taken. I propose to skip printing the newline when it follows a newline that came from data. In order to avoid having to add yet another magic variable to file objects, I propose to give the existing 'softspace' variable an extra meaning: a negative value will mean "the last data written ended in a newline so no space *or* newline is required." Problem When printing data that resembles the lines read from a file using a simple loop, double-spacing occurs unless special care is taken: >>> for line in open("/etc/passwd").readlines(): ... print line ... root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin: daemon:x:2:2:daemon:/sbin: (etc.) >>> While there are easy work-arounds, this is often noticed only during testing and requires an extra edit-test roundtrip; the fixed code is uglier and harder to maintain. Proposed Solution In the PRINT_ITEM opcode in ceval.c, when a string object is printed, a check is already made that looks at the last character of that string. Currently, if that last character is a whitespace character other than space, the softspace flag is reset to zero; this suppresses the space between two items if the first item is a string ending in newline, tab, etc. (but not when it ends in a space). Otherwise the softspace flag is set to one. The proposal changes this test slightly so that softspace is set to: -1 -- if the last object written is a string ending in a newline 0 -- if the last object written is a string ending in a whitespace character that's neither space nor newline 1 -- in all other cases (including the case when the last object written is an empty string or not a string) Then, the PRINT_NEWLINE opcode, printing of the newline is suppressed if the value of softspace is negative; in any case the softspace flag is reset to zero. Scope This only affects printing of 8-bit strings. It doesn't affect Unicode, although that could be considered a bug in the Unicode implementation. It doesn't affect other objects whose string representation happens to end in a newline character. Risks This change breaks some existing code. For example: print "Subject: PEP 259\n" print message_body In current Python, this produces a blank line separating the subject from the message body; with the proposed change, the body begins immediately below the subject. This is not very robust code anyway; it is better written as print "Subject: PEP 259" print print message_body In the test suite, only test_StringIO (which explicitly tests for this feature) breaks. Implementation A patch relative to current CVS is here: http://sourceforge.net/tracker/index.php?func=detail&aid=432183&group_id=5470&atid=305470 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.95 retrieving revision 1.96 diff -C2 -r1.95 -r1.96 *** pep-0000.txt 2001/06/06 05:56:34 1.95 --- pep-0000.txt 2001/06/11 20:07:37 1.96 *************** *** 61,64 **** --- 61,65 ---- S 257 pep-0257.txt Docstring Conventions Goodger S 258 pep-0258.txt DPS Generic Implementation Details Goodger + S 259 pep-0259.txt Omit printing newline after newline van Rossum Py-in-the-sky PEPs (not ready; may become active yet) *************** *** 185,188 **** --- 186,190 ---- S 257 pep-0257.txt Docstring Conventions Goodger S 258 pep-0258.txt DPS Generic Implementation Details Goodger + S 259 pep-0259.txt Omit printing newline after newline van Rossum Index: pep-0253.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0253.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** pep-0253.txt 2001/05/15 01:36:46 1.2 --- pep-0253.txt 2001/06/11 20:07:37 1.3 *************** *** 35,51 **** Python types in C. ! This PEP will introduce the following optional features to types: ! - create an instance of a type by calling it ! - create a subtype in C by specifying a base type pointer ! - create a subtype in Python using a class statement ! - multiple inheritance ! This PEP builds on PEP 252, which adds standard introspection to types; in particular, types are assumed to have e.g. a __hash__ ! method when the type object defines the tp_hash slot. PEP 252 also adds a dictionary to type objects which contains all methods. At the Python level, this dictionary is read-only; at the C level, it --- 35,56 ---- Python types in C. ! This PEP will introduce the following features: ! - a type, like a class, can be a factory for its instances ! - types can be subtyped in C by specifying a base type pointer ! - types can be subtyped in Python using the class statement ! - multiple inheritance from types (insofar as practical) ! - the standard coercions (int, tuple, str etc.) will be the ! corresponding type objects ! ! - a standard type hierarchy ! ! This PEP builds on pep-0252, which adds standard introspection to types; in particular, types are assumed to have e.g. a __hash__ ! method when the type object defines the tp_hash slot. pep-0252 also adds a dictionary to type objects which contains all methods. At the Python level, this dictionary is read-only; at the C level, it *************** *** 77,86 **** instances (which are regular types) can be subclassed (really subtyped) using a Python class statement. We will use this rule ! to support subtyping of built-in types, and in the process we will ! introduce some additional metatypes, and a "metametatype". (The ! metametatype is nothing unusual; Python's type system allows any ! number of metalevels.) ! Note that Python uses the concept of metatypes or metaclasses in a different way than Smalltalk. In Smalltalk-80, there is a hierarchy of metaclasses that mirrors the hierarchy of regular --- 82,92 ---- instances (which are regular types) can be subclassed (really subtyped) using a Python class statement. We 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 way than Smalltalk. In Smalltalk-80, there is a hierarchy of metaclasses that mirrors the hierarchy of regular *************** *** 105,109 **** Traditionally, for each type there is at least one C function that ! creates instances of the type. This function has to take care of both allocating memory for the object and initializing that memory. As of Python 2.0, it also has to interface with the --- 111,116 ---- Traditionally, for each type there is at least one C function that ! creates instances of the type (e.g. PyInt_FromLong(), ! PyTuple_New() and so on). This function has to take care of both allocating memory for the object and initializing that memory. As of Python 2.0, it also has to interface with the *************** *** 128,149 **** which makes all types "callable" in a trivial sense. But obviously the metatype's tp_call implementation doesn't know how ! to initialize individual types. So the type defines a new slot, ! tp_construct, which is invoked by the metatype's tp_call slot. If ! the tp_construct slot is NULL, the metatype's tp_call issues a ! nice error message: the type isn't callable. ! ! We already know that tp_construct is responsible for initializing ! the object (this will be important for subtyping too). Who should ! be responsible for allocation of the new object? Either the ! metatype's tp_call can allocate the object, or the type's ! tp_construct can allocate it. The solution is copied from typical ! C++ implementations: if the metatype's tp_call allocates storage ! for the object it passes the storage as a pointer to the type's ! tp_construct; if the metatype's tp_call does not allocate storage, ! it passes a NULL pointer to the type's tp_call in which case the ! type allocates the storage itself. This moves the policy decision ! to the metatype, and different metatypes may have different ! policies. The mechanisms are fixed though: either the metatype's ! tp_call allocates storage, or the type's tp_construct allocates. The deallocation mechanism chosen should match the allocation --- 135,149 ---- which makes all types "callable" in a trivial sense. But obviously the metatype's tp_call implementation doesn't know how ! to initialize the instances of individual types. So the type ! defines a new slot, tp_new, which is invoked by the metatype's ! tp_call slot. If the tp_new slot is NULL, the metatype's tp_call ! issues a nice error message: the type isn't callable. ! ! This mechanism gives the maximum freedom to the type: a type's ! tp_new doesn't necessarily have to return a new object, or even an ! object that is an instance of the type (although the latter should ! be rare). ! ! HIRO The deallocation mechanism chosen should match the allocation *************** *** 280,284 **** subtype with the value of the corresponding base type slots. It also fills in tp_dict, the type's dictionary; this is more a ! matter of PEP 252. The subtype's tp_dealloc slot deserves special attention. It must --- 280,284 ---- subtype with the value of the corresponding base type slots. It also fills in tp_dict, the type's dictionary; this is more a ! matter of pep-0252. The subtype's tp_dealloc slot deserves special attention. It must *************** *** 330,334 **** 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 --- 330,334 ---- 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-0252). 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 *************** *** 372,375 **** --- 372,398 ---- tp_dict slot is updated with the contents of the namespace dictionary (the third argument to the call to M). + + + 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-0252, pep-0253, and + pep-254. + + + References + + [1] "Putting Metaclasses to Work", by Ira R. Forman and Scott + H. Danforth, Addison-Wesley 1999. + (http://www.aw.com/product/0,2627,0201433052,00.html) From gvanrossum@users.sourceforge.net Mon Jun 11 22:06:05 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 11 Jun 2001 14:06:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects intobject.c,2.56.6.3,2.56.6.4 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv14124/Objects Modified Files: Tag: descr-branch intobject.c Log Message: Another one bites the dust: built-in 'int' is now the integer type. (Still not subtypable though.) Index: intobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v retrieving revision 2.56.6.3 retrieving revision 2.56.6.4 diff -C2 -r2.56.6.3 -r2.56.6.4 *** intobject.c 2001/06/06 14:27:54 2.56.6.3 --- intobject.c 2001/06/11 21:06:03 2.56.6.4 *************** *** 751,754 **** --- 751,788 ---- } + static PyObject * + int_new(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + PyObject *x = NULL; + int base = -909; + static char *kwlist[] = {"x", "base", 0}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist, + &x, &base)) + return NULL; + if (x == NULL) + return PyInt_FromLong(0L); + if (base == -909) + return PyNumber_Int(x); + if (PyString_Check(x)) + return PyInt_FromString(PyString_AS_STRING(x), NULL, base); + if (PyUnicode_Check(x)) + return PyInt_FromUnicode(PyUnicode_AS_UNICODE(x), + PyUnicode_GET_SIZE(x), + base); + PyErr_SetString(PyExc_TypeError, + "int() can't convert non-string with explicit base"); + return NULL; + } + + static char int_doc[] = + "int(x[, base]) -> integer\n\ + \n\ + Convert a string or number to an integer, if possible. A floating point\n\ + argument will be truncated towards zero (this does not include a string\n\ + representation of a floating point number!) When converting a string, use\n\ + the optional base. It is an error to supply a base when converting a\n\ + non-string."; + static PyNumberMethods int_as_number = { (binaryfunc)int_add, /*nb_add*/ *************** *** 809,813 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES /* tp_flags */ }; --- 843,865 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */ ! int_doc, /* 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 */ ! 0, /* tp_descr_get */ ! 0, /* tp_descr_set */ ! 0, /* tp_dictoffset */ ! 0, /* tp_init */ ! 0, /* tp_alloc */ ! int_new, /* tp_new */ }; From gvanrossum@users.sourceforge.net Mon Jun 11 22:06:05 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 11 Jun 2001 14:06:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.198.2.1,2.198.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv14124/Python Modified Files: Tag: descr-branch bltinmodule.c Log Message: Another one bites the dust: built-in 'int' is now the integer type. (Still not subtypable though.) Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.198.2.1 retrieving revision 2.198.2.2 diff -C2 -r2.198.2.1 -r2.198.2.2 *** bltinmodule.c 2001/06/06 17:43:42 2.198.2.1 --- bltinmodule.c 2001/06/11 21:06:03 2.198.2.2 *************** *** 1228,1264 **** static PyObject * - builtin_int(PyObject *self, PyObject *args) - { - PyObject *v; - int base = -909; /* unlikely! */ - - if (!PyArg_ParseTuple(args, "O|i:int", &v, &base)) - return NULL; - if (base == -909) - return PyNumber_Int(v); - else if (PyString_Check(v)) - return PyInt_FromString(PyString_AS_STRING(v), NULL, base); - else if (PyUnicode_Check(v)) - return PyInt_FromUnicode(PyUnicode_AS_UNICODE(v), - PyUnicode_GET_SIZE(v), - base); - else { - PyErr_SetString(PyExc_TypeError, - "int() can't convert non-string with explicit base"); - return NULL; - } - } - - static char int_doc[] = - "int(x[, base]) -> integer\n\ - \n\ - Convert a string or number to an integer, if possible. A floating point\n\ - argument will be truncated towards zero (this does not include a string\n\ - representation of a floating point number!) When converting a string, use\n\ - the optional base. It is an error to supply a base when converting a\n\ - non-string."; - - - static PyObject * builtin_long(PyObject *self, PyObject *args) { --- 1228,1231 ---- *************** *** 2138,2142 **** {"input", builtin_input, 1, input_doc}, {"intern", builtin_intern, 1, intern_doc}, - {"int", builtin_int, 1, int_doc}, {"isinstance", builtin_isinstance, 1, isinstance_doc}, {"issubclass", builtin_issubclass, 1, issubclass_doc}, --- 2105,2108 ---- *************** *** 2196,2199 **** --- 2162,2167 ---- return NULL; if (PyDict_SetItemString(dict, "list", (PyObject *) &PyList_Type) < 0) + return NULL; + if (PyDict_SetItemString(dict, "int", (PyObject *) &PyInt_Type) < 0) return NULL; if (PyDict_SetItemString(dict, "object", From tim_one@users.sourceforge.net Mon Jun 11 22:24:00 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 11 Jun 2001 14:24:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include longobject.h,2.19,2.20 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv17866/python/dist/src/Include Modified Files: longobject.h Log Message: Two new private longobject API functions, _PyLong_FromByteArray _PyLong_AsByteArray Untested and probably buggy -- they compile OK, but nothing calls them yet. Will soon be called by the struct module, to implement x-platform 'q' and 'Q'. If other people have uses for them, we could move them into the public API. See longobject.h for usage details. Index: longobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/longobject.h,v retrieving revision 2.19 retrieving revision 2.20 diff -C2 -r2.19 -r2.20 *** longobject.h 2000/09/26 05:45:59 2.19 --- longobject.h 2001/06/11 21:23:58 2.20 *************** *** 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 } From tim_one@users.sourceforge.net Mon Jun 11 22:24:00 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 11 Jun 2001 14:24:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.71,1.72 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv17866/python/dist/src/Objects Modified Files: longobject.c Log Message: Two new private longobject API functions, _PyLong_FromByteArray _PyLong_AsByteArray Untested and probably buggy -- they compile OK, but nothing calls them yet. Will soon be called by the struct module, to implement x-platform 'q' and 'Q'. If other people have uses for them, we could move them into the public API. See longobject.h for usage details. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.71 retrieving revision 1.72 diff -C2 -r1.71 -r1.72 *** longobject.c 2001/01/17 15:33:18 1.71 --- longobject.c 2001/06/11 21:23:58 1.72 *************** *** 212,215 **** --- 212,428 ---- } + 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; + unsigned int 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) { + unsigned int 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. */ + 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; + /* Store as many bytes as possible. */ + assert(accumbits >= 8); + do { + if (j >= n) + goto Overflow; + ++j; + *p = (unsigned char)(accum & 0xff); + p += pincr; + accumbits -= 8; + accum >>= 8; + } while (accumbits >= 8); + } + + /* Store the straggler (if any). */ + assert(accumbits < 8); + assert(carry == 0); /* else do_twos_comp and *every* digit was 0 */ + if (accum) { + 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; + } + + /* Fill remaining bytes with copies of the sign bit. */ + for ( ; j < n; ++j, p += pincr) + *p = (unsigned char)(do_twos_comp ? 0xff : 0); + + /* Check for delicate overflow (not enough room for the sign bit). */ + if (j > 0 && is_signed) { + unsigned char msb = *(p - pincr); + int sign_bit_set = (msb & 0x80) != 0; + if (sign_bit_set != do_twos_comp) + goto Overflow; + } + return 0; + + Overflow: + PyErr_SetString(PyExc_OverflowError, "long too big to convert"); + return -1; + + } + /* Get a C double from a long int object. */ From gvanrossum@users.sourceforge.net Tue Jun 12 01:30:36 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 11 Jun 2001 17:30:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/idle keydefs.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/idle In directory usw-pr-cvs1:/tmp/cvs-serv1944 Modified Files: keydefs.py Log Message: Make copy, cut and paste events case insensitive. Reported by Patrick K. O'Brien on idle-dev. (Should other bindings follow suit?) Index: keydefs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/idle/keydefs.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** keydefs.py 1999/01/04 16:35:02 1.2 --- keydefs.py 2001/06/12 00:30:33 1.3 *************** *** 1,6 **** windows_keydefs = \ ! {'<>': [''], ! '<>': [''], ! '<>': [''], '<>': ['', ''], '<>': [''], --- 1,6 ---- windows_keydefs = \ ! {'<>': ['', ''], ! '<>': ['', ''], ! '<>': ['', ''], '<>': ['', ''], '<>': [''], From tim_one@users.sourceforge.net Tue Jun 12 02:22:23 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 11 Jun 2001 18:22:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libstruct.tex,1.27,1.28 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv15300/python/dist/src/Doc/lib Modified Files: libstruct.tex Log Message: Added q/Q standard (x-platform 8-byte ints) mode in struct module. This completes the q/Q project. longobject.c _PyLong_AsByteArray: The original code had a gross bug: the most-significant Python digit doesn't necessarily have SHIFT significant bits, and you really need to count how many copies of the sign bit it has else spurious overflow errors result. test_struct.py: This now does exhaustive std q/Q testing at, and on both sides of, all relevant power-of-2 boundaries, both positive and negative. NEWS: Added brief dict news while I was at it. Index: libstruct.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstruct.tex,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -r1.27 -r1.28 *** libstruct.tex 2001/06/10 23:40:19 1.27 --- libstruct.tex 2001/06/12 01:22:21 1.28 *************** *** 73,77 **** The \character{q} and \character{Q} conversion codes are available in native mode only if the platform C compiler supports C \ctype{long long}, ! or, on Windows, \ctype{__int64}. \end{description} --- 73,78 ---- The \character{q} and \character{Q} conversion codes are available in native mode only if the platform C compiler supports C \ctype{long long}, ! or, on Windows, \ctype{__int64}. They're always available in standard ! modes. \end{description} *************** *** 101,106 **** that exactly enough bytes are used to satisfy the count. ! For the \character{I} and \character{L} format characters, the return ! value is a Python long integer. For the \character{P} format character, the return value is a Python --- 102,107 ---- that exactly enough bytes are used to satisfy the count. ! For the \character{I}, \character{L}, \character{q} and \character{Q} ! format characters, the return value is a Python long integer. For the \character{P} format character, the return value is a Python *************** *** 140,147 **** Standard size and alignment are as follows: no alignment is required ! for any type (so you have to use pad bytes); \ctype{short} is 2 bytes; ! \ctype{int} and \ctype{long} are 4 bytes. \ctype{float} and ! \ctype{double} are 32-bit and 64-bit IEEE floating point numbers, ! respectively. Note the difference between \character{@} and \character{=}: both use --- 141,150 ---- Standard size and alignment are as follows: no alignment is required ! for any type (so you have to use pad bytes); ! \ctype{short} is 2 bytes; ! \ctype{int} and \ctype{long} are 4 bytes; ! \ctype{long long} (\ctype{__int64} on Windows) is 8 bytes; ! \ctype{float} and \ctype{double} are 32-bit and 64-bit ! IEEE floating point numbers, respectively. Note the difference between \character{@} and \character{=}: both use From tim_one@users.sourceforge.net Tue Jun 12 02:22:24 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 11 Jun 2001 18:22:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.182,1.183 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv15300/python/dist/src/Misc Modified Files: NEWS Log Message: Added q/Q standard (x-platform 8-byte ints) mode in struct module. This completes the q/Q project. longobject.c _PyLong_AsByteArray: The original code had a gross bug: the most-significant Python digit doesn't necessarily have SHIFT significant bits, and you really need to count how many copies of the sign bit it has else spurious overflow errors result. test_struct.py: This now does exhaustive std q/Q testing at, and on both sides of, all relevant power-of-2 boundaries, both positive and negative. NEWS: Added brief dict news while I was at it. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.182 retrieving revision 1.183 diff -C2 -r1.182 -r1.183 *** NEWS 2001/06/10 23:40:19 1.182 --- NEWS 2001/06/12 01:22:21 1.183 *************** *** 85,88 **** --- 85,91 ---- order. + - Many other small changes to dicts were made, resulting in faster + operation along the most common code paths. + - Dictionary objects now support the "in" operator: "x in dict" means the same as dict.has_key(x). *************** *** 120,124 **** - Collisions in dicts are resolved via a new approach, which can help dramatically in bad cases. For example, looking up every key in a dict ! d with d.keys() = [i << 16 for i in range(20000)] is approximately 500x faster now. Thanks to Christian Tismer for pointing out the cause and the nature of an effective cure (last December! better late than never). --- 123,127 ---- - Collisions in dicts are resolved via a new approach, which can help dramatically in bad cases. For example, looking up every key in a dict ! d with d.keys() == [i << 16 for i in range(20000)] is approximately 500x faster now. Thanks to Christian Tismer for pointing out the cause and the nature of an effective cure (last December! better late than never). *************** *** 146,151 **** these types (when HAVE_LONG_LONG is #define'd by the Python config process), and then they inherit the sizes and alignments of the C types. ! XXX TODO In standard mode, 'q' and 'Q' are supported on all platforms, and ! XXX TODO are 8-byte integral types. Tests --- 149,154 ---- these types (when HAVE_LONG_LONG is #define'd by the Python config process), and then they inherit the sizes and alignments of the C types. ! In standard mode, 'q' and 'Q' are supported on all platforms, and are ! 8-byte integral types. Tests From tim_one@users.sourceforge.net Tue Jun 12 02:22:24 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 11 Jun 2001 18:22:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules structmodule.c,2.46,2.47 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv15300/python/dist/src/Modules Modified Files: structmodule.c Log Message: Added q/Q standard (x-platform 8-byte ints) mode in struct module. This completes the q/Q project. longobject.c _PyLong_AsByteArray: The original code had a gross bug: the most-significant Python digit doesn't necessarily have SHIFT significant bits, and you really need to count how many copies of the sign bit it has else spurious overflow errors result. test_struct.py: This now does exhaustive std q/Q testing at, and on both sides of, all relevant power-of-2 boundaries, both positive and negative. NEWS: Added brief dict news while I was at it. Index: structmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/structmodule.c,v retrieving revision 2.46 retrieving revision 2.47 diff -C2 -r2.46 -r2.47 *** structmodule.c 2001/06/11 16:57:33 2.46 --- structmodule.c 2001/06/12 01:22:21 2.47 *************** *** 81,84 **** --- 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 */ *************** *** 124,154 **** { LONG_LONG x; - int v_needs_decref = 0; ! if (PyInt_Check(v)) { ! x = (LONG_LONG)PyInt_AS_LONG(v); ! *p = x; ! return 0; ! } ! if (!PyLong_Check(v)) { ! PyNumberMethods *m = v->ob_type->tp_as_number; ! if (m != NULL && m->nb_long != NULL) { ! v = m->nb_long(v); ! if (v == NULL) ! return -1; ! v_needs_decref = 1; ! } ! if (!PyLong_Check(v)) { ! PyErr_SetString(StructError, ! "cannot convert argument to long"); ! if (v_needs_decref) ! Py_DECREF(v); ! return -1; ! } ! } assert(PyLong_Check(v)); x = PyLong_AsLongLong(v); ! if (v_needs_decref) ! Py_DECREF(v); if (x == (LONG_LONG)-1 && PyErr_Occurred()) return -1; --- 152,162 ---- { 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; *************** *** 163,199 **** { unsigned LONG_LONG x; - int v_needs_decref = 0; ! if (PyInt_Check(v)) { ! long i = PyInt_AS_LONG(v); ! if (i < 0) { ! PyErr_SetString(StructError, "can't convert negative " ! "int to unsigned"); ! return -1; ! } ! x = (unsigned LONG_LONG)i; ! *p = x; ! return 0; ! } ! if (!PyLong_Check(v)) { ! PyNumberMethods *m = v->ob_type->tp_as_number; ! if (m != NULL && m->nb_long != NULL) { ! v = m->nb_long(v); ! if (v == NULL) ! return -1; ! v_needs_decref = 1; ! } ! if (!PyLong_Check(v)) { ! PyErr_SetString(StructError, ! "cannot convert argument to long"); ! if (v_needs_decref) ! Py_DECREF(v); ! return -1; ! } ! } assert(PyLong_Check(v)); x = PyLong_AsUnsignedLongLong(v); ! if (v_needs_decref) ! Py_DECREF(v); if (x == (unsigned LONG_LONG)-1 && PyErr_Occurred()) return -1; --- 171,181 ---- { 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; *************** *** 501,505 **** */ ! /* Native mode routines. */ static PyObject * --- 483,487 ---- */ ! /* Native mode routines. ****************************************************/ static PyObject * *************** *** 798,801 **** --- 780,785 ---- }; + /* Big-endian routines. *****************************************************/ + static PyObject * bu_int(const char *p, const formatdef *f) *************** *** 827,830 **** --- 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) { *************** *** 869,872 **** --- 871,902 ---- static int + bp_longlong(char *p, PyObject *v, const formatdef *f) + { + int res; + v = get_pylong(v); + 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); + 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) { *************** *** 905,908 **** --- 935,940 ---- {'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}, *************** *** 910,913 **** --- 942,947 ---- }; + /* Little-endian routines. *****************************************************/ + static PyObject * lu_int(const char *p, const formatdef *f) *************** *** 939,942 **** --- 973,994 ---- 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) { *************** *** 981,984 **** --- 1033,1064 ---- static int + lp_longlong(char *p, PyObject *v, const formatdef *f) + { + int res; + v = get_pylong(v); + 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); + 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) { *************** *** 1017,1020 **** --- 1097,1102 ---- {'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}, From tim_one@users.sourceforge.net Tue Jun 12 02:22:24 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 11 Jun 2001 18:22:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.72,1.73 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv15300/python/dist/src/Objects Modified Files: longobject.c Log Message: Added q/Q standard (x-platform 8-byte ints) mode in struct module. This completes the q/Q project. longobject.c _PyLong_AsByteArray: The original code had a gross bug: the most-significant Python digit doesn't necessarily have SHIFT significant bits, and you really need to count how many copies of the sign bit it has else spurious overflow errors result. test_struct.py: This now does exhaustive std q/Q testing at, and on both sides of, all relevant power-of-2 boundaries, both positive and negative. NEWS: Added brief dict news while I was at it. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.72 retrieving revision 1.73 diff -C2 -r1.72 -r1.73 *** longobject.c 2001/06/11 21:23:58 1.72 --- longobject.c 2001/06/12 01:22:22 1.73 *************** *** 365,368 **** --- 365,369 ---- carry = do_twos_comp ? 1 : 0; for (i = 0; i < ndigits; ++i) { + unsigned int oldaccumbits = accumbits; twodigits thisdigit = v->ob_digit[i]; if (do_twos_comp) { *************** *** 371,382 **** 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; /* Store as many bytes as possible. */ ! assert(accumbits >= 8); ! do { if (j >= n) goto Overflow; --- 372,395 ---- thisdigit &= MASK; } + if (i < ndigits - 1) + accumbits += SHIFT; + else { + /* The most-significant digit may be partly empty. */ + twodigits bitmask = 1 << (SHIFT - 1); + twodigits signbit = do_twos_comp << (SHIFT - 1); + unsigned int nsignbits = 0; + while ((thisdigit & bitmask) == signbit && bitmask) { + ++nsignbits; + bitmask >>= 1; + signbit >>= 1; + } + accumbits += SHIFT - nsignbits; + } /* 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 << oldaccumbits; /* Store as many bytes as possible. */ ! while (accumbits >= 8) { if (j >= n) goto Overflow; *************** *** 386,390 **** accumbits -= 8; accum >>= 8; ! } while (accumbits >= 8); } --- 399,403 ---- accumbits -= 8; accum >>= 8; ! } } *************** *** 392,396 **** assert(accumbits < 8); assert(carry == 0); /* else do_twos_comp and *every* digit was 0 */ ! if (accum) { if (j >= n) goto Overflow; --- 405,409 ---- assert(accumbits < 8); assert(carry == 0); /* else do_twos_comp and *every* digit was 0 */ ! if (accumbits > 0) { if (j >= n) goto Overflow; From tim_one@users.sourceforge.net Tue Jun 12 02:22:23 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 11 Jun 2001 18:22:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_struct.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv15300/python/dist/src/Lib/test Modified Files: test_struct.py Log Message: Added q/Q standard (x-platform 8-byte ints) mode in struct module. This completes the q/Q project. longobject.c _PyLong_AsByteArray: The original code had a gross bug: the most-significant Python digit doesn't necessarily have SHIFT significant bits, and you really need to count how many copies of the sign bit it has else spurious overflow errors result. test_struct.py: This now does exhaustive std q/Q testing at, and on both sides of, all relevant power-of-2 boundaries, both positive and negative. NEWS: Added brief dict news while I was at it. Index: test_struct.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_struct.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -r1.9 -r1.10 *** test_struct.py 2001/06/10 23:52:59 1.9 --- test_struct.py 2001/06/12 01:22:21 1.10 *************** *** 13,16 **** --- 13,26 ---- ## 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') *************** *** 114,118 **** `fmt`, `res`, `rev`, `arg`) ! # Some q/Q sanity checks. has_native_qQ = 1 --- 124,129 ---- `fmt`, `res`, `rev`, `arg`) ! ########################################################################### ! # q/Q tests. has_native_qQ = 1 *************** *** 125,140 **** print "Platform has native q/Q?", has_native_qQ and "Yes." or "No." ! simple_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 bigendian_to_native(value): if isbigendian: return value ! chars = list(value) ! chars.reverse() ! return "".join(chars) ! if has_native_qQ: bytes = struct.calcsize('q') # The expected values here are in big-endian format, primarily because --- 136,155 ---- 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 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 test_native_qQ(): bytes = struct.calcsize('q') # The expected values here are in big-endian format, primarily because *************** *** 157,158 **** --- 172,317 ---- "%r-unpack of %r gave %r, not %r" % (format, got, retrieved, input)) + + if has_native_qQ: + test_native_qQ() + + # Standard q/Q (8 bytes; should work on all platforms). + + MIN_Q, MAX_Q = 0, 2L**64 - 1 + MIN_q, MAX_q = -(2L**63), 2L**63 - 1 + + import binascii + def test_one_qQ(x, pack=struct.pack, + unpack=struct.unpack, + unhexlify=binascii.unhexlify): + if verbose: + print "trying std q/Q on", x, "==", hex(x) + + # Try 'q'. + if MIN_q <= x <= MAX_q: + # Try '>q'. + expected = long(x) + if x < 0: + expected += 1L << 64 + 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" * (8 - len(expected)) + expected + + # >q pack work? + got = pack(">q", x) + verify(got == expected, + "'>q'-pack of %r gave %r, not %r" % + (x, got, expected)) + + # >q unpack work? + retrieved = unpack(">q", got)[0] + verify(x == retrieved, + "'>q'-unpack of %r gave %r, not %r" % + (got, retrieved, x)) + + # Adding any byte should cause a "too big" error. + any_err(unpack, ">q", '\x01' + got) + + # Try 'q', x) + any_err(pack, 'Q'. + 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" * (8 - len(expected)) + expected + + # >Q pack work? + got = pack(">Q", x) + verify(got == expected, + "'>Q'-pack of %r gave %r, not %r" % + (x, got, expected)) + + # >Q unpack work? + retrieved = unpack(">Q", got)[0] + verify(x == retrieved, + "'>Q'-unpack of %r gave %r, not %r" % + (got, retrieved, x)) + + # Adding any byte should cause a "too big" error. + any_err(unpack, ">Q", '\x01' + got) + + # Try 'Q', x) + any_err(pack, ' Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv3692/lib Modified Files: libstdtypes.tex Log Message: Fixed reference to table notes for {}.keys() and {}.items() -- these references did not get updated when the notes were renumbered in a previous update. This fixes SF bug #432208. Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.59 retrieving revision 1.60 diff -C2 -r1.59 -r1.60 *** libstdtypes.tex 2001/05/25 04:24:37 1.59 --- libstdtypes.tex 2001/06/12 03:31:56 1.60 *************** *** 931,939 **** {a copy of \var{a}'s list of (\var{key}, \var{value}) pairs} {(3)} ! \lineiii{\var{a}.keys()}{a copy of \var{a}'s list of keys}{(2)} \lineiii{\var{a}.update(\var{b})} {\code{for k in \var{b}.keys(): \var{a}[k] = \var{b}[k]}} {(4)} ! \lineiii{\var{a}.values()}{a copy of \var{a}'s list of values}{(2)} \lineiii{\var{a}.get(\var{k}\optional{, \var{x}})} {\code{\var{a}[\var{k}]} if \code{\var{k} in \var{a}}, --- 931,939 ---- {a copy of \var{a}'s list of (\var{key}, \var{value}) pairs} {(3)} ! \lineiii{\var{a}.keys()}{a copy of \var{a}'s list of keys}{(3)} \lineiii{\var{a}.update(\var{b})} {\code{for k in \var{b}.keys(): \var{a}[k] = \var{b}[k]}} {(4)} ! \lineiii{\var{a}.values()}{a copy of \var{a}'s list of values}{(3)} \lineiii{\var{a}.get(\var{k}\optional{, \var{x}})} {\code{\var{a}[\var{k}]} if \code{\var{k} in \var{a}}, *************** *** 970,975 **** modifications to the dictionary, the two lists will directly correspond. This allows the creation of \code{(\var{value}, ! \var{key})} pairs using \function{map()}: \samp{pairs = map(None, ! \var{a}.values(), \var{a}.keys())}. \item[(4)] \var{b} must be of the same type as \var{a}. --- 970,975 ---- modifications to the dictionary, the two lists will directly correspond. This allows the creation of \code{(\var{value}, ! \var{key})} pairs using \function{zip()}: \samp{pairs = ! zip(\var{a}.values(), \var{a}.keys())}. \item[(4)] \var{b} must be of the same type as \var{a}. From mal@lemburg.com Tue Jun 12 08:13:26 2001 From: mal@lemburg.com (M.-A. Lemburg) Date: Tue, 12 Jun 2001 09:13:26 +0200 Subject: [Python-checkins] CVS: python/dist/src/Include longobject.h,2.19,2.20 References: Message-ID: <3B25C116.3E65A32D@lemburg.com> Tim, I have tried to compile longobject.c/h on a HP-UX box and am getting warnings about MIN/MAX being redefined. Perhaps you should add an #undef for these before the #define ?! -- Marc-Andre Lemburg CEO eGenix.com Software GmbH ______________________________________________________________________ Company & Consulting: http://www.egenix.com/ Python Software: http://www.lemburg.com/python/ From lemburg@users.sourceforge.net Tue Jun 12 14:14:12 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Tue, 12 Jun 2001 06:14:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects stringobject.c,2.117,2.118 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv20984 Modified Files: stringobject.c Log Message: Fix for bug #432384: Recursion in PyString_AsEncodedString? Index: stringobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v retrieving revision 2.117 retrieving revision 2.118 diff -C2 -r2.117 -r2.118 *** stringobject.c 2001/05/24 16:56:35 2.117 --- stringobject.c 2001/06/12 13:14:10 2.118 *************** *** 266,270 **** PyObject *v; ! v = PyString_AsEncodedString(str, encoding, errors); if (v == NULL) goto onError; --- 266,270 ---- PyObject *v; ! v = PyString_AsEncodedObject(str, encoding, errors); if (v == NULL) goto onError; From fdrake@users.sourceforge.net Tue Jun 12 14:31:39 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 12 Jun 2001 06:31:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools push-docs.sh,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools In directory usw-pr-cvs1:/tmp/cvs-serv25316/tools Modified Files: push-docs.sh Log Message: Make the option processing more robust. Add a -F option similar to "cvs commit -F ". Add a -t option to allow specifying the prefix to the directory into which the docs should be unpacked (useful when I start trying out new styles for the presentation). Index: push-docs.sh =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/push-docs.sh,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** push-docs.sh 2001/05/09 16:33:34 1.8 --- push-docs.sh 2001/06/12 13:31:37 1.9 *************** *** 20,29 **** EXPLANATION='' ! if [ "$1" = '-m' ] ; then ! EXPLANATION="$2" ! shift 2 ! elif [ "$1" ] ; then ! EXPLANATION="`cat $1`" ! shift 1 fi --- 20,53 ---- EXPLANATION='' ! while [ "$#" -gt 0 ] ; do ! case "$1" in ! -m) ! EXPLANATION="$2" ! shift 2 ! ;; ! -t) ! DOCTYPE="$2" ! shift 2 ! ;; ! -F) ! EXPLANATION="`cat $2`" ! shift 2 ! ;; ! -*) ! echo "Unknown option: $1" >&2 ! exit 2 ! ;; ! *) ! break ! ;; ! esac ! done ! if [ "$1" ] ; then ! if [ "$EXPLANATION" ] ; then ! echo "Explanation may only be given once!" >&2 ! exit 2 ! fi ! EXPLANATION="$1" ! shift fi *************** *** 46,50 **** The development version of the documentation has been updated: ! http://python.sourceforge.net/$DOCTYPE-docs/ $EXPLANATION --- 70,74 ---- The development version of the documentation has been updated: ! http://python.sourceforge.net/$DOCTYPE-docs/ $EXPLANATION From lemburg@users.sourceforge.net Tue Jun 12 17:13:54 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Tue, 12 Jun 2001 09:13:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules main.c,1.52,1.53 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv4171 Modified Files: main.c Log Message: Removed the Python version from the PYTHONHOMEHELP string. It was still set to python2.0 ... Index: main.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/main.c,v retrieving revision 1.52 retrieving revision 1.53 diff -C2 -r1.52 -r1.53 *** main.c 2001/04/10 22:07:07 1.52 --- main.c 2001/06/12 16:13:51 1.53 *************** *** 15,19 **** #define PYTHONHOMEHELP "\\lib" #else ! #define PYTHONHOMEHELP "/python2.0" #endif --- 15,19 ---- #define PYTHONHOMEHELP "\\lib" #else ! #define PYTHONHOMEHELP "/pythonX.X" #endif From gvanrossum@users.sourceforge.net Tue Jun 12 17:29:14 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 12 Jun 2001 09:29:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules main.c,1.52,1.52.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv8396 Modified Files: Tag: release21-maint main.c Log Message: Incorporating MAL's bugfix into the 2.1.1 branch: revision 1.53 date: 2001/06/12 16:13:51; author: lemburg; state: Exp; lines: +1 -1 Removed the Python version from the PYTHONHOMEHELP string. It was still set to python2.0 ... Index: main.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/main.c,v retrieving revision 1.52 retrieving revision 1.52.2.1 diff -C2 -r1.52 -r1.52.2.1 *** main.c 2001/04/10 22:07:07 1.52 --- main.c 2001/06/12 16:29:12 1.52.2.1 *************** *** 15,19 **** #define PYTHONHOMEHELP "\\lib" #else ! #define PYTHONHOMEHELP "/python2.0" #endif --- 15,19 ---- #define PYTHONHOMEHELP "\\lib" #else ! #define PYTHONHOMEHELP "/pythonX.X" #endif From gvanrossum@users.sourceforge.net Tue Jun 12 17:48:54 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 12 Jun 2001 09:48:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib site.py,1.26,1.27 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv12111/Lib Modified Files: site.py Log Message: Add new built-in 'help' which invokes pydoc.help (with a twist). Index: site.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/site.py,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -r1.26 -r1.27 *** site.py 2001/03/23 17:53:49 1.26 --- site.py 2001/06/12 16:48:52 1.27 *************** *** 237,240 **** --- 237,254 ---- + # Define new built-in 'help'. + # This is a wrapper around pydoc.help (with a twist). + + class _Helper: + def __repr__(self): + return "Type help() for interactive help, " \ + "or help(object) for help about object." + def __call__(self, *args, **kwds): + import pydoc + return pydoc.help(*args, **kwds) + + __builtin__.help = _Helper() + + # Set the string encoding used by the Unicode implementation. The # default is 'ascii', but if you're willing to experiment, you can From gvanrossum@users.sourceforge.net Tue Jun 12 17:48:54 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 12 Jun 2001 09:48:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.183,1.184 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv12111/Misc Modified Files: NEWS Log Message: Add new built-in 'help' which invokes pydoc.help (with a twist). Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.183 retrieving revision 1.184 diff -C2 -r1.183 -r1.184 *** NEWS 2001/06/12 01:22:21 1.183 --- NEWS 2001/06/12 16:48:52 1.184 *************** *** 152,155 **** --- 152,160 ---- 8-byte integral types. + - The site module installs a new built-in function 'help' that invokes + pydoc.help. It must be invoked as 'help()'; when invoked as 'help', + it displays a message reminding the user to use 'help()' or + 'help(object)'. + Tests From tim_one@users.sourceforge.net Tue Jun 12 20:17:05 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 12 Jun 2001 12:17:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.73,1.74 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv12556/python/dist/src/Objects Modified Files: longobject.c Log Message: _PyLong_{As,From}ByteArray: Minor code rearrangement aimed at improving clarity. Should have no effect visible to callers. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.73 retrieving revision 1.74 diff -C2 -r1.73 -r1.74 *** longobject.c 2001/06/12 01:22:22 1.73 --- longobject.c 2001/06/12 19:17:03 1.74 *************** *** 285,289 **** for (i = 0; i < numsignificantbytes; ++i, p += incr) { ! unsigned int thisbyte = *p; /* Compute correction for 2's comp, if needed. */ if (is_signed) { --- 285,289 ---- for (i = 0; i < numsignificantbytes; ++i, p += incr) { ! twodigits thisbyte = *p; /* Compute correction for 2's comp, if needed. */ if (is_signed) { *************** *** 365,369 **** carry = do_twos_comp ? 1 : 0; for (i = 0; i < ndigits; ++i) { ! unsigned int oldaccumbits = accumbits; twodigits thisdigit = v->ob_digit[i]; if (do_twos_comp) { --- 365,369 ---- carry = do_twos_comp ? 1 : 0; for (i = 0; i < ndigits; ++i) { ! unsigned int numnewbits = SHIFT; twodigits thisdigit = v->ob_digit[i]; if (do_twos_comp) { *************** *** 372,379 **** thisdigit &= MASK; } ! if (i < ndigits - 1) ! accumbits += SHIFT; ! else { ! /* The most-significant digit may be partly empty. */ twodigits bitmask = 1 << (SHIFT - 1); twodigits signbit = do_twos_comp << (SHIFT - 1); --- 372,383 ---- 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; ! ! /* How many new bits did we add? The most-significant digit ! may be (probably is) at least partly empty. */ ! if (i == ndigits - 1) { twodigits bitmask = 1 << (SHIFT - 1); twodigits signbit = do_twos_comp << (SHIFT - 1); *************** *** 384,393 **** signbit >>= 1; } ! accumbits += SHIFT - nsignbits; } ! /* 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 << oldaccumbits; /* Store as many bytes as possible. */ while (accumbits >= 8) { --- 388,396 ---- signbit >>= 1; } ! assert(nsignbits <= SHIFT); ! numnewbits -= nsignbits; } ! accumbits += numnewbits; ! /* Store as many bytes as possible. */ while (accumbits >= 8) { From tim_one@users.sourceforge.net Tue Jun 12 21:10:04 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 12 Jun 2001 13:10:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _testcapimodule.c,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv21117/python/dist/src/Modules Modified Files: _testcapimodule.c Log Message: The merest start of a test for the PyLong_{As,From}{Unsigned,}LongLong() functions. I intend to replace their guts with calls to the new _PyLong_{As,From}ByteArray() functions, but AFAICT there's no tests for them at all now; I also suspect PyLong_AsLongLong() isn't catching all overflow cases, but without a std test to demonstrate that why should you believe me . Also added a raiseTestError() utility function. Index: _testcapimodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_testcapimodule.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** _testcapimodule.c 2001/04/13 17:08:15 1.3 --- _testcapimodule.c 2001/06/12 20:10:01 1.4 *************** *** 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). *************** *** 146,150 **** if (!PyArg_ParseTuple(args, ":test_dict_iteration")) return NULL; ! for (i = 0; i < 200; i++) { if (test_dict_inner(i) < 0) { --- 162,166 ---- 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 */ }; --- 173,217 ---- } + #ifdef HAVE_LONG_LONG + + /* Basic sanity checks for PyLong_{As, From}{Unsigned,}LongLong(). */ + + static PyObject * + test_longlong_api(PyObject* self, PyObject* args) + { + /* unsigned LONG_LONG uinput, uoutput; */ + LONG_LONG input, output; + PyObject *pyresult; + + if (!PyArg_ParseTuple(args, ":test_longlong_api")) + return NULL; + + input = 0; + pyresult = PyLong_FromLongLong(input); + if (pyresult == NULL) + return raiseTestError("test_longlong_api", + "unexpected null result"); + output = PyLong_AsLongLong(pyresult); + if (output == (LONG_LONG)-1 && PyErr_Occurred()) + return raiseTestError("test_longlong_api", + "unexpected -1 result"); + if (output != input) + return raiseTestError("test_longlong_api", + "output != input"); + Py_DECREF(pyresult); + + Py_INCREF(Py_None); + return Py_None; + } + + #endif + 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}, ! #ifdef HAVE_LONG_LONG ! {"test_longlong_api", test_longlong_api, METH_VARARGS}, ! #endif {NULL, NULL} /* sentinel */ }; From tim_one@users.sourceforge.net Wed Jun 13 01:36:00 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 12 Jun 2001 17:36:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _testcapimodule.c,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv10010/python/dist/src/Modules Modified Files: _testcapimodule.c Log Message: longobject.c: Replaced PyLong_{As,From}{Unsigned,}LongLong guts with calls to _PyLong_{As,From}ByteArray. _testcapimodule.c: Added strong tests of PyLong_{As,From}{Unsigned,}LongLong. Fixes SF bug #432552 PyLong_AsLongLong() problems. Possible bugfix candidate, but the fix relies on code added to longobject to support the new q/Q structmodule format codes. Index: _testcapimodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_testcapimodule.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** _testcapimodule.c 2001/06/12 20:10:01 1.4 --- _testcapimodule.c 2001/06/13 00:35:57 1.5 *************** *** 178,203 **** static PyObject * test_longlong_api(PyObject* self, PyObject* args) { ! /* unsigned LONG_LONG uinput, uoutput; */ ! LONG_LONG input, output; PyObject *pyresult; if (!PyArg_ParseTuple(args, ":test_longlong_api")) return NULL; ! input = 0; ! pyresult = PyLong_FromLongLong(input); ! if (pyresult == NULL) ! return raiseTestError("test_longlong_api", ! "unexpected null result"); ! output = PyLong_AsLongLong(pyresult); ! if (output == (LONG_LONG)-1 && PyErr_Occurred()) ! return raiseTestError("test_longlong_api", ! "unexpected -1 result"); ! if (output != input) ! return raiseTestError("test_longlong_api", ! "output != input"); ! Py_DECREF(pyresult); Py_INCREF(Py_None); --- 178,346 ---- static PyObject * + raise_test_longlong_error(const char* msg) + { + return raiseTestError("test_longlong_api", msg); + } + + #define UNBIND(X) Py_DECREF(X); (X) = NULL + + static PyObject * test_longlong_api(PyObject* self, PyObject* args) { ! const int NBITS = SIZEOF_LONG_LONG * 8; ! unsigned LONG_LONG base; PyObject *pyresult; + int i; if (!PyArg_ParseTuple(args, ":test_longlong_api")) return NULL; + + + /* 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) { + LONG_LONG in, out; + unsigned LONG_LONG uin, uout; + + /* For 0, 1, 2 use base; for 3, 4, 5 use -base */ + uin = j < 3 ? base + : (unsigned LONG_LONG)(-(LONG_LONG)base); + + /* For 0 & 3, subtract 1. + * For 1 & 4, leave alone. + * For 2 & 5, add 1. + */ + uin += (unsigned LONG_LONG)(LONG_LONG)(j % 3 - 1); + + pyresult = PyLong_FromUnsignedLongLong(uin); + if (pyresult == NULL) + return raise_test_longlong_error( + "unsigned unexpected null result"); + + uout = PyLong_AsUnsignedLongLong(pyresult); + if (uout == (unsigned LONG_LONG)-1 && PyErr_Occurred()) + return raise_test_longlong_error( + "unsigned unexpected -1 result"); + if (uout != uin) + return raise_test_longlong_error( + "unsigned output != input"); + UNBIND(pyresult); + + in = (LONG_LONG)uin; + pyresult = PyLong_FromLongLong(in); + if (pyresult == NULL) + return raise_test_longlong_error( + "signed unexpected null result"); + + out = PyLong_AsLongLong(pyresult); + if (out == (LONG_LONG)-1 && PyErr_Occurred()) + return raise_test_longlong_error( + "signed unexpected -1 result"); + if (out != in) + return raise_test_longlong_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; + LONG_LONG out; + unsigned LONG_LONG uout; + + one = PyLong_FromLong(1); + if (one == NULL) + return raise_test_longlong_error( + "unexpected NULL from PyLong_FromLong"); + + /* Unsigned complains about -1? */ + x = PyNumber_Negative(one); + if (x == NULL) + return raise_test_longlong_error( + "unexpected NULL from PyNumber_Negative"); + + uout = PyLong_AsUnsignedLongLong(x); + if (uout != (unsigned LONG_LONG)-1 || !PyErr_Occurred()) + return raise_test_longlong_error( + "PyLong_AsUnsignedLongLong(-1) didn't " + "complain"); + PyErr_Clear(); + UNBIND(x); + + /* Unsigned complains about 2**NBITS? */ + y = PyLong_FromLong((long)NBITS); + if (y == NULL) + return raise_test_longlong_error( + "unexpected NULL from PyLong_FromLong"); + + x = PyNumber_Lshift(one, y); /* 1L << NBITS, == 2**NBITS */ + UNBIND(y); + if (x == NULL) + return raise_test_longlong_error( + "unexpected NULL from PyNumber_Lshift"); + + uout = PyLong_AsUnsignedLongLong(x); + if (uout != (unsigned LONG_LONG)-1 || !PyErr_Occurred()) + return raise_test_longlong_error( + "PyLong_AsUnsignedLongLong(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 raise_test_longlong_error( + "unexpected NULL from PyNumber_Rshift"); + + out = PyLong_AsLongLong(y); + if (out != (LONG_LONG)-1 || !PyErr_Occurred()) + return raise_test_longlong_error( + "PyLong_AsLongLong(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 raise_test_longlong_error( + "unexpected NULL from PyNumber_Negative"); + + y = PyNumber_Subtract(x, one); /* -(2**(NBITS-1))-1 */ + UNBIND(x); + if (y == NULL) + return raise_test_longlong_error( + "unexpected NULL from PyNumber_Subtract"); + + out = PyLong_AsLongLong(y); + if (out != (LONG_LONG)-1 || !PyErr_Occurred()) + return raise_test_longlong_error( + "PyLong_AsLongLong(-2**(NBITS-1)-1) didn't " + "complain"); + PyErr_Clear(); + UNBIND(y); ! Py_XDECREF(x); ! Py_XDECREF(y); ! Py_DECREF(one); ! } Py_INCREF(Py_None); From tim_one@users.sourceforge.net Wed Jun 13 01:36:00 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 12 Jun 2001 17:36:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.74,1.75 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv10010/python/dist/src/Objects Modified Files: longobject.c Log Message: longobject.c: Replaced PyLong_{As,From}{Unsigned,}LongLong guts with calls to _PyLong_{As,From}ByteArray. _testcapimodule.c: Added strong tests of PyLong_{As,From}{Unsigned,}LongLong. Fixes SF bug #432552 PyLong_AsLongLong() problems. Possible bugfix candidate, but the fix relies on code added to longobject to support the new q/Q structmodule format codes. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.74 retrieving revision 1.75 diff -C2 -r1.74 -r1.75 *** longobject.c 2001/06/12 19:17:03 1.74 --- longobject.c 2001/06/13 00:35:57 1.75 *************** *** 523,688 **** #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(); return -1; } - - 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 */ --- 523,603 ---- #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 *(char*)&one != '\0' ! /* 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(); return -1; } ! res = _PyLong_AsByteArray( ! (PyLongObject *)vv, (unsigned char *)&bytes, ! SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1); ! return (LONG_LONG)(res < 0 ? 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 (unsigned LONG_LONG)(res < 0 ? res : bytes); } + + #undef IS_LITTLE_ENDIAN + #endif /* HAVE_LONG_LONG */ From tim_one@users.sourceforge.net Wed Jun 13 02:26:37 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 12 Jun 2001 18:26:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules structmodule.c,2.47,2.48 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv17987/python/dist/src/Modules Modified Files: structmodule.c Log Message: The new {b,l}p_{u,}longlong() didn't check get_pylong()'s return for NULL. Repaired that, and added appropriate tests for it to test_struct.py. Index: structmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/structmodule.c,v retrieving revision 2.47 retrieving revision 2.48 diff -C2 -r2.47 -r2.48 *** structmodule.c 2001/06/12 01:22:21 2.47 --- structmodule.c 2001/06/13 01:26:35 2.48 *************** *** 875,878 **** --- 875,880 ---- int res; v = get_pylong(v); + if (v == NULL) + return -1; res = _PyLong_AsByteArray((PyLongObject *)v, (unsigned char *)p, *************** *** 889,892 **** --- 891,896 ---- int res; v = get_pylong(v); + if (v == NULL) + return -1; res = _PyLong_AsByteArray((PyLongObject *)v, (unsigned char *)p, *************** *** 1037,1040 **** --- 1041,1046 ---- int res; v = get_pylong(v); + if (v == NULL) + return -1; res = _PyLong_AsByteArray((PyLongObject*)v, (unsigned char *)p, *************** *** 1051,1054 **** --- 1057,1062 ---- int res; v = get_pylong(v); + if (v == NULL) + return -1; res = _PyLong_AsByteArray((PyLongObject*)v, (unsigned char *)p, From tim_one@users.sourceforge.net Wed Jun 13 02:26:37 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 12 Jun 2001 18:26:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_struct.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv17987/python/dist/src/Lib/test Modified Files: test_struct.py Log Message: The new {b,l}p_{u,}longlong() didn't check get_pylong()'s return for NULL. Repaired that, and added appropriate tests for it to test_struct.py. Index: test_struct.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_struct.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -r1.10 -r1.11 *** test_struct.py 2001/06/12 01:22:21 1.10 --- test_struct.py 2001/06/13 01:26:35 1.11 *************** *** 315,317 **** --- 315,323 ---- test_one_qQ(x) + # Some error cases. + for direction in "<>": + for letter in "qQ": + for badobject in "a string", 3+42j, randrange: + any_err(struct.pack, direction + letter, badobject) + test_std_qQ() From jackjansen@users.sourceforge.net Wed Jun 13 13:38:49 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 13 Jun 2001 05:38:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/qd Qdmodule.c,1.39,1.40 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/qd In directory usw-pr-cvs1:/tmp/cvs-serv27006/python/Mac/Modules/qd Modified Files: Qdmodule.c Log Message: Fixed an error in the signature of the QdRGB converter routines. Index: Qdmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/qd/Qdmodule.c,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -r1.39 -r1.40 *** Qdmodule.c 2001/05/22 21:53:41 1.39 --- Qdmodule.c 2001/06/13 12:38:47 1.40 *************** *** 21,25 **** extern int _BMObj_Convert(PyObject *, BitMapPtr *); extern PyObject *_QdRGB_New(RGBColorPtr); ! extern int _QdRGB_Convert(PyObject *, RGBColorPtr *); #define GrafObj_New _GrafObj_New --- 21,25 ---- extern int _BMObj_Convert(PyObject *, BitMapPtr *); extern PyObject *_QdRGB_New(RGBColorPtr); ! extern int _QdRGB_Convert(PyObject *, RGBColorPtr); #define GrafObj_New _GrafObj_New *************** *** 5651,5655 **** PyMac_INIT_TOOLBOX_OBJECT_CONVERT(GrafPtr, GrafObj_Convert); PyMac_INIT_TOOLBOX_OBJECT_NEW(RGBColorPtr, QdRGB_New); ! PyMac_INIT_TOOLBOX_OBJECT_CONVERT(RGBColorPtr, QdRGB_Convert); --- 5651,5655 ---- PyMac_INIT_TOOLBOX_OBJECT_CONVERT(GrafPtr, GrafObj_Convert); PyMac_INIT_TOOLBOX_OBJECT_NEW(RGBColorPtr, QdRGB_New); ! PyMac_INIT_TOOLBOX_OBJECT_CONVERT(RGBColor, QdRGB_Convert); From jackjansen@users.sourceforge.net Wed Jun 13 13:39:05 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 13 Jun 2001 05:39:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/qd qdsupport.py,1.31,1.32 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/qd In directory usw-pr-cvs1:/tmp/cvs-serv27084/python/Mac/Modules/qd Modified Files: qdsupport.py Log Message: Fixed an error in the signature of the QdRGB converter routines. Index: qdsupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/qd/qdsupport.py,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -r1.31 -r1.32 *** qdsupport.py 2001/05/22 21:54:12 1.31 --- qdsupport.py 2001/06/13 12:39:02 1.32 *************** *** 74,78 **** extern int _BMObj_Convert(PyObject *, BitMapPtr *); extern PyObject *_QdRGB_New(RGBColorPtr); ! extern int _QdRGB_Convert(PyObject *, RGBColorPtr *); #define GrafObj_New _GrafObj_New --- 74,78 ---- extern int _BMObj_Convert(PyObject *, BitMapPtr *); extern PyObject *_QdRGB_New(RGBColorPtr); ! extern int _QdRGB_Convert(PyObject *, RGBColorPtr); #define GrafObj_New _GrafObj_New *************** *** 223,227 **** PyMac_INIT_TOOLBOX_OBJECT_CONVERT(GrafPtr, GrafObj_Convert); PyMac_INIT_TOOLBOX_OBJECT_NEW(RGBColorPtr, QdRGB_New); ! PyMac_INIT_TOOLBOX_OBJECT_CONVERT(RGBColorPtr, QdRGB_Convert); """ --- 223,227 ---- PyMac_INIT_TOOLBOX_OBJECT_CONVERT(GrafPtr, GrafObj_Convert); PyMac_INIT_TOOLBOX_OBJECT_NEW(RGBColorPtr, QdRGB_New); ! PyMac_INIT_TOOLBOX_OBJECT_CONVERT(RGBColor, QdRGB_Convert); """ From jackjansen@users.sourceforge.net Wed Jun 13 13:41:27 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 13 Jun 2001 05:41:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Build PythonCore.mcp,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Build In directory usw-pr-cvs1:/tmp/cvs-serv27500/python/Mac/Build Modified Files: PythonCore.mcp Log Message: Got rid of mactoolboxglue.c Index: PythonCore.mcp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonCore.mcp,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -r1.21 -r1.22 Binary files /tmp/cvs6vXXwK and /tmp/cvsKa5Ovm differ From gvanrossum@users.sourceforge.net Wed Jun 13 16:15:04 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 13 Jun 2001 08:15:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.81.2.41,1.81.2.42 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv31452/Misc Modified Files: Tag: release20-maint NEWS Log Message: Bring SRE up do date with Python 2.1 Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.81.2.41 retrieving revision 1.81.2.42 diff -C2 -r1.81.2.41 -r1.81.2.42 *** NEWS 2001/04/13 15:52:40 1.81.2.41 --- NEWS 2001/06/13 15:15:02 1.81.2.42 *************** *** 14,17 **** --- 14,19 ---- http://sourceforge.net/tracker/index.php?func=detail&aid=&group_id=5470&atid=105470 + - Brought SRE up to date with Python 2.1 + - #117278, #117167: _tkinter From gvanrossum@users.sourceforge.net Wed Jun 13 16:15:04 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 13 Jun 2001 08:15:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib sre.py,1.25,1.25.2.1 sre_compile.py,1.31,1.31.2.1 sre_constants.py,1.21,1.21.2.1 sre_parse.py,1.37,1.37.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv31452/Lib Modified Files: Tag: release20-maint sre.py sre_compile.py sre_constants.py sre_parse.py Log Message: Bring SRE up do date with Python 2.1 Index: sre.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre.py,v retrieving revision 1.25 retrieving revision 1.25.2.1 diff -C2 -r1.25 -r1.25.2.1 *** sre.py 2000/09/21 17:03:24 1.25 --- sre.py 2001/06/13 15:15:02 1.25.2.1 *************** *** 4,8 **** # re-compatible interface for the sre matching engine # ! # Copyright (c) 1998-2000 by Secret Labs AB. All rights reserved. # # This version of the SRE library can be redistributed under CNRI's --- 4,8 ---- # re-compatible interface for the sre matching engine # ! # Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved. # # This version of the SRE library can be redistributed under CNRI's *************** *** 15,35 **** # - # FIXME: change all FIXME's to XXX ;-) - import sre_compile import sre_parse import string # flags ! I = IGNORECASE = sre_compile.SRE_FLAG_IGNORECASE ! L = LOCALE = sre_compile.SRE_FLAG_LOCALE ! M = MULTILINE = sre_compile.SRE_FLAG_MULTILINE ! S = DOTALL = sre_compile.SRE_FLAG_DOTALL ! X = VERBOSE = sre_compile.SRE_FLAG_VERBOSE ! ! # sre extensions (may or may not be in 1.6/2.0 final) ! T = TEMPLATE = sre_compile.SRE_FLAG_TEMPLATE ! U = UNICODE = sre_compile.SRE_FLAG_UNICODE # sre exception --- 15,43 ---- # import sre_compile import sre_parse + # public symbols + __all__ = [ "match", "search", "sub", "subn", "split", "findall", + "compile", "purge", "template", "escape", "I", "L", "M", "S", "X", + "U", "IGNORECASE", "LOCALE", "MULTILINE", "DOTALL", "VERBOSE", + "UNICODE", "error" ] + + __version__ = "2.1b2" + + # this module works under 1.5.2 and later. don't use string methods import string # flags ! I = IGNORECASE = sre_compile.SRE_FLAG_IGNORECASE # ignore case ! L = LOCALE = sre_compile.SRE_FLAG_LOCALE # assume current 8-bit locale ! U = UNICODE = sre_compile.SRE_FLAG_UNICODE # assume unicode locale ! M = MULTILINE = sre_compile.SRE_FLAG_MULTILINE # make anchors look for newline ! S = DOTALL = sre_compile.SRE_FLAG_DOTALL # make dot match newline ! X = VERBOSE = sre_compile.SRE_FLAG_VERBOSE # ignore whitespace and comments ! ! # sre extensions (experimental, don't rely on these) ! T = TEMPLATE = sre_compile.SRE_FLAG_TEMPLATE # disable backtracking ! DEBUG = sre_compile.SRE_FLAG_DEBUG # dump pattern after compilation # sre exception *************** *** 39,72 **** # public interface - # FIXME: add docstrings - def match(pattern, string, flags=0): return _compile(pattern, flags).match(string) def search(pattern, string, flags=0): return _compile(pattern, flags).search(string) def sub(pattern, repl, string, count=0): return _compile(pattern, 0).sub(repl, string, count) def subn(pattern, repl, string, count=0): return _compile(pattern, 0).subn(repl, string, count) def split(pattern, string, maxsplit=0): return _compile(pattern, 0).split(string, maxsplit) def findall(pattern, string, maxsplit=0): return _compile(pattern, 0).findall(string, maxsplit) def compile(pattern, flags=0): return _compile(pattern, flags) def purge(): _cache.clear() def template(pattern, flags=0): return _compile(pattern, flags|T) def escape(pattern): s = list(pattern) for i in range(len(pattern)): --- 47,104 ---- # public interface def match(pattern, string, flags=0): + """Try to apply the pattern at the start of the string, returning + a match object, or None if no match was found.""" return _compile(pattern, flags).match(string) def search(pattern, string, flags=0): + """Scan through string looking for a match to the pattern, returning + a match object, or None if no match was found.""" return _compile(pattern, flags).search(string) def sub(pattern, repl, string, count=0): + """Return the string obtained by replacing the leftmost + non-overlapping occurrences of the pattern in string by the + replacement repl""" return _compile(pattern, 0).sub(repl, string, count) def subn(pattern, repl, string, count=0): + """Return a 2-tuple containing (new_string, number). + new_string is the string obtained by replacing the leftmost + non-overlapping occurrences of the pattern in the source + string by the replacement repl. number is the number of + substitutions that were made.""" return _compile(pattern, 0).subn(repl, string, count) def split(pattern, string, maxsplit=0): + """Split the source string by the occurrences of the pattern, + returning a list containing the resulting substrings.""" return _compile(pattern, 0).split(string, maxsplit) def findall(pattern, string, maxsplit=0): + """Return a list of all non-overlapping matches in the string. + + If one or more groups are present in the pattern, return a + list of groups; this will be a list of tuples if the pattern + has more than one group. + + Empty matches are included in the result.""" return _compile(pattern, 0).findall(string, maxsplit) def compile(pattern, flags=0): + "Compile a regular expression pattern, returning a pattern object." return _compile(pattern, flags) def purge(): + "Clear the regular expression cache" _cache.clear() + _cache_repl.clear() def template(pattern, flags=0): + "Compile a template pattern, returning a pattern object" return _compile(pattern, flags|T) def escape(pattern): + "Escape all non-alphanumeric characters in pattern." s = list(pattern) for i in range(len(pattern)): *************** *** 83,86 **** --- 115,120 ---- _cache = {} + _cache_repl = {} + _MAXCACHE = 100 *************** *** 106,109 **** --- 140,158 ---- return p + def _compile_repl(*key): + # internal: compile replacement pattern + p = _cache_repl.get(key) + if p is not None: + return p + repl, pattern = key + try: + p = sre_parse.parse_template(repl, pattern) + except error, v: + raise error, v # invalid expression + if len(_cache_repl) >= _MAXCACHE: + _cache_repl.clear() + _cache_repl[key] = p + return p + def _expand(pattern, match, template): # internal: match.expand implementation hook *************** *** 120,124 **** filter = template else: ! template = sre_parse.parse_template(template, pattern) def filter(match, template=template): return sre_parse.expand_template(template, match) --- 169,173 ---- filter = template else: ! template = _compile_repl(template, pattern) def filter(match, template=template): return sre_parse.expand_template(template, match) *************** *** 159,163 **** append(string[i:b]) if g and b != e: ! extend(m.groups()) i = e n = n + 1 --- 208,212 ---- append(string[i:b]) if g and b != e: ! extend(list(m.groups())) i = e n = n + 1 *************** *** 205,209 **** action = self.lexicon[m.lastindex][1] if callable(action): ! self.match = match action = action(self, m.group()) if action is not None: --- 254,258 ---- action = self.lexicon[m.lastindex][1] if callable(action): ! self.match = m action = action(self, m.group()) if action is not None: Index: sre_compile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre_compile.py,v retrieving revision 1.31 retrieving revision 1.31.2.1 diff -C2 -r1.31 -r1.31.2.1 *** sre_compile.py 2000/10/07 17:38:22 1.31 --- sre_compile.py 2001/06/13 15:15:02 1.31.2.1 *************** *** 4,8 **** # convert template to internal format # ! # Copyright (c) 1997-2000 by Secret Labs AB. All rights reserved. # # See the sre.py file for information on usage and redistribution. --- 4,8 ---- # convert template to internal format # ! # Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. # # See the sre.py file for information on usage and redistribution. *************** *** 13,16 **** --- 13,18 ---- from sre_constants import * + assert _sre.MAGIC == MAGIC, "SRE module mismatch" + MAXCODE = 65535 *************** *** 22,28 **** if flags & SRE_FLAG_IGNORECASE: emit(OPCODES[OP_IGNORE[op]]) else: emit(OPCODES[op]) ! emit(av) elif op is IN: if flags & SRE_FLAG_IGNORECASE: --- 24,31 ---- if flags & SRE_FLAG_IGNORECASE: emit(OPCODES[OP_IGNORE[op]]) + emit(_sre.getlower(av, flags)) else: emit(OPCODES[op]) ! emit(av) elif op is IN: if flags & SRE_FLAG_IGNORECASE: *************** *** 103,109 **** emit(OPCODES[op]) if flags & SRE_FLAG_MULTILINE: ! emit(ATCODES[AT_MULTILINE.get(av, av)]) ! else: ! emit(ATCODES[av]) elif op is BRANCH: emit(OPCODES[op]) --- 106,115 ---- emit(OPCODES[op]) if flags & SRE_FLAG_MULTILINE: ! av = AT_MULTILINE.get(av, av) ! if flags & SRE_FLAG_LOCALE: ! av = AT_LOCALE.get(av, av) ! elif flags & SRE_FLAG_UNICODE: ! av = AT_UNICODE.get(av, av) ! emit(ATCODES[av]) elif op is BRANCH: emit(OPCODES[op]) *************** *** 122,130 **** emit(OPCODES[op]) if flags & SRE_FLAG_LOCALE: ! emit(CHCODES[CH_LOCALE[av]]) elif flags & SRE_FLAG_UNICODE: ! emit(CHCODES[CH_UNICODE[av]]) ! else: ! emit(CHCODES[av]) elif op is GROUPREF: if flags & SRE_FLAG_IGNORECASE: --- 128,135 ---- emit(OPCODES[op]) if flags & SRE_FLAG_LOCALE: ! av = CH_LOCALE[av] elif flags & SRE_FLAG_UNICODE: ! av = CH_UNICODE[av] ! emit(CHCODES[av]) elif op is GROUPREF: if flags & SRE_FLAG_IGNORECASE: *************** *** 177,181 **** charmap[i] = 1 elif op is CATEGORY: ! # FIXME: could append to charmap tail return charset # cannot compress except IndexError: --- 182,186 ---- charmap[i] = 1 elif op is CATEGORY: ! # XXX: could append to charmap tail return charset # cannot compress except IndexError: *************** *** 365,369 **** # print code ! # FIXME: get rid of this limitation! assert p.pattern.groups <= 100,\ "sorry, but this version only supports 100 named groups" --- 370,374 ---- # print code ! # XXX: get rid of this limitation! assert p.pattern.groups <= 100,\ "sorry, but this version only supports 100 named groups" Index: sre_constants.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre_constants.py,v retrieving revision 1.21 retrieving revision 1.21.2.1 diff -C2 -r1.21 -r1.21.2.1 *** sre_constants.py 2000/10/07 17:38:22 1.21 --- sre_constants.py 2001/06/13 15:15:02 1.21.2.1 *************** *** 5,15 **** # run this script to update the _sre include files! # ! # Copyright (c) 1998-2000 by Secret Labs AB. All rights reserved. # # See the sre.py file for information on usage and redistribution. # MAXREPEAT = 65535 # should this really be here? --- 5,22 ---- # run this script to update the _sre include files! # ! # Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved. # # See the sre.py file for information on usage and redistribution. # + # update when constants are added or removed + + MAGIC = 20010320 + + # max code word in this release + MAXREPEAT = 65535 + # SRE standard exception (access as sre.error) # should this really be here? *************** *** 55,62 **** --- 62,75 ---- AT_BEGINNING = "at_beginning" AT_BEGINNING_LINE = "at_beginning_line" + AT_BEGINNING_STRING = "at_beginning_string" AT_BOUNDARY = "at_boundary" AT_NON_BOUNDARY = "at_non_boundary" AT_END = "at_end" AT_END_LINE = "at_end_line" + AT_END_STRING = "at_end_string" + AT_LOC_BOUNDARY = "at_loc_boundary" + AT_LOC_NON_BOUNDARY = "at_loc_non_boundary" + AT_UNI_BOUNDARY = "at_uni_boundary" + AT_UNI_NON_BOUNDARY = "at_uni_non_boundary" # categories *************** *** 110,115 **** ATCODES = [ ! AT_BEGINNING, AT_BEGINNING_LINE, AT_BOUNDARY, ! AT_NON_BOUNDARY, AT_END, AT_END_LINE ] --- 123,130 ---- ATCODES = [ ! AT_BEGINNING, AT_BEGINNING_LINE, AT_BEGINNING_STRING, AT_BOUNDARY, ! AT_NON_BOUNDARY, AT_END, AT_END_LINE, AT_END_STRING, ! AT_LOC_BOUNDARY, AT_LOC_NON_BOUNDARY, AT_UNI_BOUNDARY, ! AT_UNI_NON_BOUNDARY ] *************** *** 149,152 **** --- 164,177 ---- } + AT_LOCALE = { + AT_BOUNDARY: AT_LOC_BOUNDARY, + AT_NON_BOUNDARY: AT_LOC_NON_BOUNDARY + } + + AT_UNICODE = { + AT_BOUNDARY: AT_UNI_BOUNDARY, + AT_NON_BOUNDARY: AT_UNI_NON_BOUNDARY + } + CH_LOCALE = { CATEGORY_DIGIT: CATEGORY_DIGIT, *************** *** 179,182 **** --- 204,208 ---- SRE_FLAG_UNICODE = 32 # use unicode locale SRE_FLAG_VERBOSE = 64 # ignore whitespace and comments + SRE_FLAG_DEBUG = 128 # debugging # flags for INFO primitive *************** *** 202,206 **** * to change anything in here, edit sre_constants.py and run it. * ! * Copyright (c) 1997-2000 by Secret Labs AB. All rights reserved. * * See the _sre.c file for information on usage and redistribution. --- 228,232 ---- * to change anything in here, edit sre_constants.py and run it. * ! * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. * * See the _sre.c file for information on usage and redistribution. *************** *** 208,211 **** --- 234,239 ---- """) + + f.write("#define SRE_MAGIC %d\n" % MAGIC) dump(f, OPCODES, "SRE_OP") Index: sre_parse.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre_parse.py,v retrieving revision 1.37 retrieving revision 1.37.2.1 diff -C2 -r1.37 -r1.37.2.1 *** sre_parse.py 2000/10/07 17:38:22 1.37 --- sre_parse.py 2001/06/13 15:15:02 1.37.2.1 *************** *** 4,12 **** # convert re-style regular expression to sre pattern # ! # Copyright (c) 1998-2000 by Secret Labs AB. All rights reserved. # # See the sre.py file for information on usage and redistribution. # import string, sys --- 4,15 ---- # convert re-style regular expression to sre pattern # ! # Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved. # # See the sre.py file for information on usage and redistribution. # + # XXX: show string offset and offending character for all errors + + # this module works under 1.5.2 and later. don't use string methods import string, sys *************** *** 24,39 **** ESCAPES = { ! r"\a": (LITERAL, 7), ! r"\b": (LITERAL, 8), ! r"\f": (LITERAL, 12), ! r"\n": (LITERAL, 10), ! r"\r": (LITERAL, 13), ! r"\t": (LITERAL, 9), ! r"\v": (LITERAL, 11), r"\\": (LITERAL, ord("\\")) } CATEGORIES = { ! r"\A": (AT, AT_BEGINNING), # start of string r"\b": (AT, AT_BOUNDARY), r"\B": (AT, AT_NON_BOUNDARY), --- 27,42 ---- ESCAPES = { ! r"\a": (LITERAL, ord("\a")), ! r"\b": (LITERAL, ord("\b")), ! r"\f": (LITERAL, ord("\f")), ! r"\n": (LITERAL, ord("\n")), ! r"\r": (LITERAL, ord("\r")), ! r"\t": (LITERAL, ord("\t")), ! r"\v": (LITERAL, ord("\v")), r"\\": (LITERAL, ord("\\")) } CATEGORIES = { ! r"\A": (AT, AT_BEGINNING_STRING), # start of string r"\b": (AT, AT_BOUNDARY), r"\B": (AT, AT_NON_BOUNDARY), *************** *** 44,48 **** r"\w": (IN, [(CATEGORY, CATEGORY_WORD)]), r"\W": (IN, [(CATEGORY, CATEGORY_NOT_WORD)]), ! r"\Z": (AT, AT_END), # end of string } --- 47,51 ---- r"\w": (IN, [(CATEGORY, CATEGORY_WORD)]), r"\W": (IN, [(CATEGORY, CATEGORY_NOT_WORD)]), ! r"\Z": (AT, AT_END_STRING), # end of string } *************** *** 59,74 **** } class Pattern: # master pattern object. keeps track of global attributes def __init__(self): self.flags = 0 self.groups = 1 self.groupdict = {} ! def getgroup(self, name=None): gid = self.groups self.groups = gid + 1 if name: self.groupdict[name] = gid return gid class SubPattern: --- 62,90 ---- } + # figure out best way to convert hex/octal numbers to integers + try: + int("10", 8) + atoi = int # 2.0 and later + except TypeError: + atoi = string.atoi # 1.5.2 + class Pattern: # master pattern object. keeps track of global attributes def __init__(self): self.flags = 0 + self.open = [] self.groups = 1 self.groupdict = {} ! def opengroup(self, name=None): gid = self.groups self.groups = gid + 1 if name: self.groupdict[name] = gid + self.open.append(gid) return gid + def closegroup(self, gid): + self.open.remove(gid) + def checkgroup(self, gid): + return gid < self.groups and gid not in self.open class SubPattern: *************** *** 209,213 **** # check if the escape string represents a valid group try: ! gid = int(escape[1:]) if gid and gid < groups: return gid --- 225,229 ---- # check if the escape string represents a valid group try: ! gid = atoi(escape[1:]) if gid and gid < groups: return gid *************** *** 232,236 **** if len(escape) != 2: raise error, "bogus escape: %s" % repr("\\" + escape) ! return LITERAL, int(escape, 16) & 0xff elif str(escape[1:2]) in OCTDIGITS: # octal escape (up to three digits) --- 248,252 ---- if len(escape) != 2: raise error, "bogus escape: %s" % repr("\\" + escape) ! return LITERAL, atoi(escape, 16) & 0xff elif str(escape[1:2]) in OCTDIGITS: # octal escape (up to three digits) *************** *** 238,242 **** escape = escape + source.get() escape = escape[1:] ! return LITERAL, int(escape, 8) & 0xff if len(escape) == 2: return LITERAL, ord(escape[1]) --- 254,258 ---- escape = escape + source.get() escape = escape[1:] ! return LITERAL, atoi(escape, 8) & 0xff if len(escape) == 2: return LITERAL, ord(escape[1]) *************** *** 260,269 **** if len(escape) != 4: raise ValueError ! return LITERAL, int(escape[2:], 16) & 0xff elif escape[1:2] == "0": # octal escape while source.next in OCTDIGITS and len(escape) < 4: escape = escape + source.get() ! return LITERAL, int(escape[1:], 8) & 0xff elif escape[1:2] in DIGITS: # octal escape *or* decimal group reference (sigh) --- 276,285 ---- if len(escape) != 4: raise ValueError ! return LITERAL, atoi(escape[2:], 16) & 0xff elif escape[1:2] == "0": # octal escape while source.next in OCTDIGITS and len(escape) < 4: escape = escape + source.get() ! return LITERAL, atoi(escape[1:], 8) & 0xff elif escape[1:2] in DIGITS: # octal escape *or* decimal group reference (sigh) *************** *** 275,282 **** # got three octal digits; this is an octal escape escape = escape + source.get() ! return LITERAL, int(escape[1:], 8) & 0xff # got at least one decimal digit; this is a group reference group = _group(escape, state.groups) if group: return GROUPREF, group raise ValueError --- 291,300 ---- # got three octal digits; this is an octal escape escape = escape + source.get() ! return LITERAL, atoi(escape[1:], 8) & 0xff # got at least one decimal digit; this is a group reference group = _group(escape, state.groups) if group: + if not state.checkgroup(group): + raise error, "cannot refer to open group" return GROUPREF, group raise ValueError *************** *** 403,411 **** code2 = LITERAL, ord(this) if code1[0] != LITERAL or code2[0] != LITERAL: ! raise error, "illegal range" lo = code1[1] hi = code2[1] if hi < lo: ! raise error, "illegal range" set.append((RANGE, (lo, hi))) else: --- 421,429 ---- code2 = LITERAL, ord(this) if code1[0] != LITERAL or code2[0] != LITERAL: ! raise error, "bad character range" lo = code1[1] hi = code2[1] if hi < lo: ! raise error, "bad character range" set.append((RANGE, (lo, hi))) else: *************** *** 414,418 **** set.append(code1) ! # FIXME: move set optimization to compiler! if len(set)==1 and set[0][0] is LITERAL: subpattern.append(set[0]) # optimization --- 432,436 ---- set.append(code1) ! # XXX: should move set optimization to compiler! if len(set)==1 and set[0][0] is LITERAL: subpattern.append(set[0]) # optimization *************** *** 420,424 **** subpattern.append((NOT_LITERAL, set[1][1])) # optimization else: ! # FIXME: add charmap optimization subpattern.append((IN, set)) --- 438,442 ---- subpattern.append((NOT_LITERAL, set[1][1])) # optimization else: ! # XXX: should add charmap optimization here subpattern.append((IN, set)) *************** *** 429,432 **** --- 447,451 ---- elif this == "*": min, max = 0, MAXREPEAT + elif this == "+": min, max = 1, MAXREPEAT *************** *** 447,454 **** continue if lo: ! min = int(lo) if hi: ! max = int(hi) ! # FIXME: check that hi >= lo! else: raise error, "not supported" --- 466,474 ---- continue if lo: ! min = atoi(lo) if hi: ! max = atoi(hi) ! if max < min: ! raise error, "bad repeat interval" else: raise error, "not supported" *************** *** 457,461 **** --- 477,485 ---- item = subpattern[-1:] else: + item = None + if not item or (len(item) == 1 and item[0][0] == AT): raise error, "nothing to repeat" + if item[0][0] in (MIN_REPEAT, MAX_REPEAT): + raise error, "multiple repeat" if source.match("?"): subpattern[-1] = (MIN_REPEAT, (min, max, item)) *************** *** 486,490 **** group = 1 if not isname(name): ! raise error, "illegal character in group name" elif source.match("="): # named backreference --- 510,514 ---- group = 1 if not isname(name): ! raise error, "bad character in group name" elif source.match("="): # named backreference *************** *** 498,502 **** name = name + char if not isname(name): ! raise error, "illegal character in group name" gid = state.groupdict.get(name) if gid is None: --- 522,526 ---- name = name + char if not isname(name): ! raise error, "bad character in group name" gid = state.groupdict.get(name) if gid is None: *************** *** 540,543 **** --- 564,569 ---- else: # flags + if not FLAGS.has_key(source.next): + raise error, "unexpected end of pattern" while FLAGS.has_key(source.next): state.flags = state.flags | FLAGS[source.get()] *************** *** 548,560 **** group = None else: ! group = state.getgroup(name) p = _parse_sub(source, state) if not source.match(")"): raise error, "unbalanced parenthesis" subpattern.append((SUBPATTERN, (group, p))) else: while 1: char = source.get() ! if char is None or char == ")": break raise error, "unknown extension" --- 574,590 ---- group = None else: ! group = state.opengroup(name) p = _parse_sub(source, state) if not source.match(")"): raise error, "unbalanced parenthesis" + if group is not None: + state.closegroup(group) subpattern.append((SUBPATTERN, (group, p))) else: while 1: char = source.get() ! if char is None: ! raise error, "unexpected end of pattern" ! if char == ")": break raise error, "unknown extension" *************** *** 583,586 **** --- 613,617 ---- pattern = Pattern() pattern.flags = flags + pattern.str = str p = _parse_sub(source, pattern, 0) *************** *** 592,596 **** raise error, "bogus characters at end of regular expression" ! # p.dump() if not (flags & SRE_FLAG_VERBOSE) and p.pattern.flags & SRE_FLAG_VERBOSE: --- 623,628 ---- raise error, "bogus characters at end of regular expression" ! if flags & SRE_FLAG_DEBUG: ! p.dump() if not (flags & SRE_FLAG_VERBOSE) and p.pattern.flags & SRE_FLAG_VERBOSE: *************** *** 607,610 **** --- 639,652 ---- p = [] a = p.append + def literal(literal, p=p): + if p and p[-1][0] is LITERAL: + p[-1] = LITERAL, p[-1][1] + literal + else: + p.append((LITERAL, literal)) + sep = source[:0] + if type(sep) is type(""): + char = chr + else: + char = unichr while 1: this = s.get() *************** *** 626,633 **** raise error, "bad group name" try: ! index = int(name) except ValueError: if not isname(name): ! raise error, "illegal character in group name" try: index = pattern.groupindex[name] --- 668,675 ---- raise error, "bad group name" try: ! index = atoi(name) except ValueError: if not isname(name): ! raise error, "bad character in group name" try: index = pattern.groupindex[name] *************** *** 642,646 **** if (s.next not in DIGITS or not _group(this + s.next, pattern.groups+1)): ! code = MARK, int(group) break elif s.next in OCTDIGITS: --- 684,688 ---- if (s.next not in DIGITS or not _group(this + s.next, pattern.groups+1)): ! code = MARK, group break elif s.next in OCTDIGITS: *************** *** 650,682 **** if not code: this = this[1:] ! code = LITERAL, int(this[-6:], 8) & 0xff ! a(code) else: try: ! a(ESCAPES[this]) except KeyError: ! for c in this: ! a((LITERAL, ord(c))) else: ! a((LITERAL, ord(this))) ! return p def expand_template(template, match): ! # FIXME: this is sooooo slow. drop in the slicelist ! # code instead ! p = [] ! a = p.append sep = match.string[:0] ! if type(sep) is type(""): ! char = chr ! else: ! char = unichr ! for c, s in template: ! if c is LITERAL: ! a(char(s)) ! elif c is MARK: ! s = match.group(s) if s is None: ! raise error, "empty group" ! a(s) ! return string.join(p, sep) --- 692,732 ---- if not code: this = this[1:] ! code = LITERAL, char(atoi(this[-6:], 8) & 0xff) ! if code[0] is LITERAL: ! literal(code[1]) ! else: ! a(code) else: try: ! this = char(ESCAPES[this][1]) except KeyError: ! pass ! literal(this) else: ! literal(this) ! # convert template to groups and literals lists ! i = 0 ! groups = [] ! literals = [] ! for c, s in p: ! if c is MARK: ! groups.append((i, s)) ! literals.append(None) ! else: ! literals.append(s) ! i = i + 1 ! return groups, literals def expand_template(template, match): ! g = match.group sep = match.string[:0] ! groups, literals = template ! literals = literals[:] ! try: ! for index, group in groups: ! literals[index] = s = g(group) if s is None: ! raise IndexError ! except IndexError: ! raise error, "empty group" ! return string.join(literals, sep) From gvanrossum@users.sourceforge.net Wed Jun 13 16:15:05 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 13 Jun 2001 08:15:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _sre.c,2.45,2.45.2.1 sre_constants.h,2.9,2.9.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv31452/Modules Modified Files: Tag: release20-maint _sre.c sre_constants.h Log Message: Bring SRE up do date with Python 2.1 Index: _sre.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_sre.c,v retrieving revision 2.45 retrieving revision 2.45.2.1 diff -C2 -r2.45 -r2.45.2.1 *** _sre.c 2000/10/03 20:43:34 2.45 --- _sre.c 2001/06/13 15:15:02 2.45.2.1 *************** *** 6,17 **** * partial history: * 1999-10-24 fl created (based on existing template matcher code) ! * 2000-03-06 fl first alpha, sort of (0.5) ! * 2000-06-30 fl added fast search optimization (0.9.3) ! * 2000-06-30 fl added assert (lookahead) primitives, etc (0.9.4) ! * 2000-07-02 fl added charset optimizations, etc (0.9.5) * 2000-07-03 fl store code in pattern object, lookbehind, etc * 2000-07-08 fl added regs attribute ! * 2000-07-21 fl reset lastindex in scanner methods (0.9.6) ! * 2000-08-01 fl fixes for 1.6b1 (0.9.8) * 2000-08-03 fl added recursion limit * 2000-08-07 fl use PyOS_CheckStack() if available --- 6,17 ---- * partial history: * 1999-10-24 fl created (based on existing template matcher code) ! * 2000-03-06 fl first alpha, sort of ! * 2000-06-30 fl added fast search optimization ! * 2000-06-30 fl added assert (lookahead) primitives, etc ! * 2000-07-02 fl added charset optimizations, etc * 2000-07-03 fl store code in pattern object, lookbehind, etc * 2000-07-08 fl added regs attribute ! * 2000-07-21 fl reset lastindex in scanner methods ! * 2000-08-01 fl fixes for 1.6b1 * 2000-08-03 fl added recursion limit * 2000-08-07 fl use PyOS_CheckStack() if available *************** *** 22,27 **** * 2000-09-21 fl don't use the buffer interface for unicode strings * 2000-10-03 fl fixed assert_not primitive; support keyword arguments * ! * Copyright (c) 1997-2000 by Secret Labs AB. All rights reserved. * * This version of the SRE library can be redistributed under CNRI's --- 22,34 ---- * 2000-09-21 fl don't use the buffer interface for unicode strings * 2000-10-03 fl fixed assert_not primitive; support keyword arguments + * 2000-10-24 fl really fixed assert_not; reset groups in findall + * 2000-12-21 fl fixed memory leak in groupdict + * 2001-01-02 fl properly reset pointer after failed assertion in MIN_UNTIL + * 2001-01-15 fl avoid recursion for MIN_UNTIL; fixed uppercase literal bug + * 2001-01-16 fl fixed memory leak in pattern destructor + * 2001-03-20 fl lots of fixes for 2.1b2 + * 2001-04-15 fl export copyright as Python attribute, not global * ! * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. * * This version of the SRE library can be redistributed under CNRI's *************** *** 36,40 **** #ifndef SRE_RECURSIVE ! char copyright[] = " SRE 0.9.8 Copyright (c) 1997-2000 by Secret Labs AB "; #include "Python.h" --- 43,48 ---- #ifndef SRE_RECURSIVE ! static char copyright[] = ! " SRE 2.1b2 Copyright (c) 1997-2001 by Secret Labs AB "; #include "Python.h" *************** *** 45,49 **** /* name of this module, minus the leading underscore */ ! #define MODULE "sre" /* defining this one enables tracing */ --- 53,59 ---- /* name of this module, minus the leading underscore */ ! #if !defined(SRE_MODULE) ! #define SRE_MODULE "sre" ! #endif /* defining this one enables tracing */ *************** *** 77,80 **** --- 87,94 ---- #undef USE_INLINE + #if PY_VERSION_HEX < 0x01060000 + #define PyObject_DEL(op) PyMem_DEL((op)) + #endif + /* -------------------------------------------------------------------- */ *************** *** 131,139 **** 120, 121, 122, 123, 124, 125, 126, 127 }; - static unsigned int sre_lower(unsigned int ch) - { - return ((ch) < 128 ? sre_char_lower[ch] : ch); - } - #define SRE_IS_DIGIT(ch)\ ((ch) < 128 ? (sre_char_info[(ch)] & SRE_DIGIT_MASK) : 0) --- 145,148 ---- *************** *** 147,156 **** ((ch) < 128 ? (sre_char_info[(ch)] & SRE_WORD_MASK) : 0) ! /* locale-specific character predicates */ ! ! static unsigned int sre_lower_locale(unsigned int ch) { ! return ((ch) < 256 ? tolower((ch)) : ch); } #define SRE_LOC_IS_DIGIT(ch) ((ch) < 256 ? isdigit((ch)) : 0) #define SRE_LOC_IS_SPACE(ch) ((ch) < 256 ? isspace((ch)) : 0) --- 156,166 ---- ((ch) < 128 ? (sre_char_info[(ch)] & SRE_WORD_MASK) : 0) ! static unsigned int sre_lower(unsigned int ch) { ! return ((ch) < 128 ? sre_char_lower[ch] : ch); } + + /* locale-specific character predicates */ + #define SRE_LOC_IS_DIGIT(ch) ((ch) < 256 ? isdigit((ch)) : 0) #define SRE_LOC_IS_SPACE(ch) ((ch) < 256 ? isspace((ch)) : 0) *************** *** 159,169 **** #define SRE_LOC_IS_WORD(ch) (SRE_LOC_IS_ALNUM((ch)) || (ch) == '_') /* unicode-specific character predicates */ #if defined(HAVE_UNICODE) ! static unsigned int sre_lower_unicode(unsigned int ch) ! { ! return (unsigned int) Py_UNICODE_TOLOWER((Py_UNICODE)(ch)); ! } #define SRE_UNI_IS_DIGIT(ch) Py_UNICODE_ISDIGIT((Py_UNICODE)(ch)) #define SRE_UNI_IS_SPACE(ch) Py_UNICODE_ISSPACE((Py_UNICODE)(ch)) --- 169,181 ---- #define SRE_LOC_IS_WORD(ch) (SRE_LOC_IS_ALNUM((ch)) || (ch) == '_') + static unsigned int sre_lower_locale(unsigned int ch) + { + return ((ch) < 256 ? tolower((ch)) : ch); + } + /* unicode-specific character predicates */ #if defined(HAVE_UNICODE) ! #define SRE_UNI_IS_DIGIT(ch) Py_UNICODE_ISDIGIT((Py_UNICODE)(ch)) #define SRE_UNI_IS_SPACE(ch) Py_UNICODE_ISSPACE((Py_UNICODE)(ch)) *************** *** 171,174 **** --- 183,192 ---- #define SRE_UNI_IS_ALNUM(ch) Py_UNICODE_ISALNUM((Py_UNICODE)(ch)) #define SRE_UNI_IS_WORD(ch) (SRE_UNI_IS_ALNUM((ch)) || (ch) == '_') + + static unsigned int sre_lower_unicode(unsigned int ch) + { + return (unsigned int) Py_UNICODE_TOLOWER((Py_UNICODE)(ch)); + } + #endif *************** *** 217,220 **** --- 235,255 ---- case SRE_CATEGORY_UNI_NOT_LINEBREAK: return !SRE_UNI_IS_LINEBREAK(ch); + #else + case SRE_CATEGORY_UNI_DIGIT: + return SRE_IS_DIGIT(ch); + case SRE_CATEGORY_UNI_NOT_DIGIT: + return !SRE_IS_DIGIT(ch); + case SRE_CATEGORY_UNI_SPACE: + return SRE_IS_SPACE(ch); + case SRE_CATEGORY_UNI_NOT_SPACE: + return !SRE_IS_SPACE(ch); + case SRE_CATEGORY_UNI_WORD: + return SRE_LOC_IS_WORD(ch); + case SRE_CATEGORY_UNI_NOT_WORD: + return !SRE_LOC_IS_WORD(ch); + case SRE_CATEGORY_UNI_LINEBREAK: + return SRE_IS_LINEBREAK(ch); + case SRE_CATEGORY_UNI_NOT_LINEBREAK: + return !SRE_IS_LINEBREAK(ch); #endif } *************** *** 355,358 **** --- 390,394 ---- case SRE_AT_BEGINNING: + case SRE_AT_BEGINNING_STRING: return ((void*) ptr == state->beginning); *************** *** 370,373 **** --- 406,412 ---- SRE_IS_LINEBREAK((int) ptr[0])); + case SRE_AT_END_STRING: + return ((void*) ptr == state->end); + case SRE_AT_BOUNDARY: if (state->beginning == state->end) *************** *** 387,390 **** --- 426,465 ---- SRE_IS_WORD((int) ptr[0]) : 0; return this == that; + + case SRE_AT_LOC_BOUNDARY: + if (state->beginning == state->end) + return 0; + that = ((void*) ptr > state->beginning) ? + SRE_LOC_IS_WORD((int) ptr[-1]) : 0; + this = ((void*) ptr < state->end) ? + SRE_LOC_IS_WORD((int) ptr[0]) : 0; + return this != that; + + case SRE_AT_LOC_NON_BOUNDARY: + if (state->beginning == state->end) + return 0; + that = ((void*) ptr > state->beginning) ? + SRE_LOC_IS_WORD((int) ptr[-1]) : 0; + this = ((void*) ptr < state->end) ? + SRE_LOC_IS_WORD((int) ptr[0]) : 0; + return this == that; + + case SRE_AT_UNI_BOUNDARY: + if (state->beginning == state->end) + return 0; + that = ((void*) ptr > state->beginning) ? + SRE_UNI_IS_WORD((int) ptr[-1]) : 0; + this = ((void*) ptr < state->end) ? + SRE_UNI_IS_WORD((int) ptr[0]) : 0; + return this != that; + + case SRE_AT_UNI_NON_BOUNDARY: + if (state->beginning == state->end) + return 0; + that = ((void*) ptr > state->beginning) ? + SRE_UNI_IS_WORD((int) ptr[-1]) : 0; + this = ((void*) ptr < state->end) ? + SRE_UNI_IS_WORD((int) ptr[0]) : 0; + return this == that; } *************** *** 784,794 **** TRACE(("|%p|%p|ASSERT_NOT %d\n", pattern, ptr, pattern[1])); state->ptr = ptr - pattern[1]; ! if (state->ptr < state->beginning) ! return 0; ! i = SRE_MATCH(state, pattern + 2, level + 1); ! if (i < 0) ! return i; ! if (i) ! return 0; pattern += pattern[0]; break; --- 859,869 ---- TRACE(("|%p|%p|ASSERT_NOT %d\n", pattern, ptr, pattern[1])); state->ptr = ptr - pattern[1]; ! if (state->ptr >= state->beginning) { ! i = SRE_MATCH(state, pattern + 2, level + 1); ! if (i < 0) ! return i; ! if (i) ! return 0; ! } pattern += pattern[0]; break; *************** *** 826,830 **** exactly one character wide, and we're not already collecting backtracking points. for other cases, ! use the MAX_REPEAT operator instead */ /* <1=min> <2=max> item tail */ --- 901,905 ---- exactly one character wide, and we're not already collecting backtracking points. for other cases, ! use the MAX_REPEAT operator */ /* <1=min> <2=max> item tail */ *************** *** 900,904 **** case SRE_OP_REPEAT: /* create repeat context. all the hard work is done ! by the UNTIL operator */ /* <1=min> <2=max> item tail */ TRACE(("|%p|%p|REPEAT %d %d\n", pattern, ptr, --- 975,979 ---- case SRE_OP_REPEAT: /* create repeat context. all the hard work is done ! by the UNTIL operator (MAX_UNTIL, MIN_UNTIL) */ /* <1=min> <2=max> item tail */ TRACE(("|%p|%p|REPEAT %d %d\n", pattern, ptr, *************** *** 974,977 **** --- 1049,1053 ---- return i; state->repeat = rp; + state->ptr = ptr; return 0; *************** *** 986,990 **** count = rp->count + 1; ! TRACE(("|%p|%p|MIN_UNTIL %d\n", pattern, ptr, count)); state->ptr = ptr; --- 1062,1067 ---- count = rp->count + 1; ! TRACE(("|%p|%p|MIN_UNTIL %d %p\n", pattern, ptr, count, ! rp->pattern)); state->ptr = ptr; *************** *** 1004,1012 **** /* see if the tail matches */ state->repeat = rp->prev; ! i = SRE_MATCH(state, pattern, level + 1); if (i) { /* free(rp); */ return i; } state->repeat = rp; --- 1081,1101 ---- /* see if the tail matches */ state->repeat = rp->prev; ! /* FIXME: the following fix doesn't always work (#133283) */ ! if (0 && rp->pattern[2] == 65535) { ! /* unbounded repeat */ ! for (;;) { ! i = SRE_MATCH(state, pattern, level + 1); ! if (i || ptr >= end) ! break; ! state->ptr = ++ptr; ! } ! } else ! i = SRE_MATCH(state, pattern, level + 1); if (i) { /* free(rp); */ return i; } + + state->ptr = ptr; state->repeat = rp; *************** *** 1020,1023 **** --- 1109,1113 ---- return i; rp->count = count - 1; + state->ptr = ptr; return 0; *************** *** 1186,1218 **** PyObject* groupindex = NULL; PyObject* indexgroup = NULL; ! if (!PyArg_ParseTuple(args, "OiO|iOO", &pattern, &flags, &code, ! &groups, &groupindex, &indexgroup)) ! return NULL; ! ! code = PySequence_Fast(code, "code argument must be a sequence"); ! if (!code) return NULL; ! #if PY_VERSION_HEX >= 0x01060000 ! n = PySequence_Size(code); ! #else ! n = PySequence_Length(code); ! #endif ! self = PyObject_NEW_VAR(PatternObject, &Pattern_Type, 100*n); ! if (!self) { ! Py_DECREF(code); return NULL; - } for (i = 0; i < n; i++) { ! PyObject *o = PySequence_Fast_GET_ITEM(code, i); self->code[i] = (SRE_CODE) PyInt_AsLong(o); } - - Py_DECREF(code); ! if (PyErr_Occurred()) return NULL; Py_INCREF(pattern); --- 1276,1299 ---- PyObject* groupindex = NULL; PyObject* indexgroup = NULL; ! if (!PyArg_ParseTuple(args, "OiO!|iOO", &pattern, &flags, ! &PyList_Type, &code, &groups, ! &groupindex, &indexgroup)) return NULL; ! n = PyList_GET_SIZE(code); ! self = PyObject_NEW_VAR(PatternObject, &Pattern_Type, n); ! if (!self) return NULL; for (i = 0; i < n; i++) { ! PyObject *o = PyList_GET_ITEM(code, i); self->code[i] = (SRE_CODE) PyInt_AsLong(o); } ! if (PyErr_Occurred()) { ! PyObject_DEL(self); return NULL; + } Py_INCREF(pattern); *************** *** 1246,1252 **** if (flags & SRE_FLAG_LOCALE) return Py_BuildValue("i", sre_lower_locale(character)); - #if defined(HAVE_UNICODE) if (flags & SRE_FLAG_UNICODE) return Py_BuildValue("i", sre_lower_unicode(character)); #endif return Py_BuildValue("i", sre_lower(character)); --- 1327,1335 ---- if (flags & SRE_FLAG_LOCALE) return Py_BuildValue("i", sre_lower_locale(character)); if (flags & SRE_FLAG_UNICODE) + #if defined(HAVE_UNICODE) return Py_BuildValue("i", sre_lower_unicode(character)); + #else + return Py_BuildValue("i", sre_lower_locale(character)); #endif return Py_BuildValue("i", sre_lower(character)); *************** *** 1356,1362 **** if (pattern->flags & SRE_FLAG_LOCALE) state->lower = sre_lower_locale; - #if defined(HAVE_UNICODE) else if (pattern->flags & SRE_FLAG_UNICODE) state->lower = sre_lower_unicode; #endif else --- 1439,1447 ---- if (pattern->flags & SRE_FLAG_LOCALE) state->lower = sre_lower_locale; else if (pattern->flags & SRE_FLAG_UNICODE) + #if defined(HAVE_UNICODE) state->lower = sre_lower_unicode; + #else + state->lower = sre_lower_locale; #endif else *************** *** 1496,1500 **** string = state_init(&self->state, pattern, string, start, end); if (!string) { ! PyObject_Del(self); return NULL; } --- 1581,1585 ---- string = state_init(&self->state, pattern, string, start, end); if (!string) { ! PyObject_DEL(self); return NULL; } *************** *** 1511,1514 **** --- 1596,1600 ---- Py_XDECREF(self->pattern); Py_XDECREF(self->groupindex); + Py_XDECREF(self->indexgroup); PyObject_DEL(self); } *************** *** 1594,1598 **** PyObject* result; ! name = PyString_FromString(MODULE); if (!name) return NULL; --- 1680,1684 ---- PyObject* result; ! name = PyString_FromString(SRE_MODULE); if (!name) return NULL; *************** *** 1681,1684 **** --- 1767,1772 ---- PyObject* item; + state_reset(&state); + state.ptr = state.start; *************** *** 1963,1967 **** PyObject* def = Py_None; static char* kwlist[] = { "default", NULL }; ! if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:groups", kwlist, &def)) return NULL; --- 2051,2055 ---- PyObject* def = Py_None; static char* kwlist[] = { "default", NULL }; ! if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:groupdict", kwlist, &def)) return NULL; *************** *** 1971,1997 **** keys = PyMapping_Keys(self->pattern->groupindex); ! if (!keys) { ! Py_DECREF(result); ! return NULL; ! } for (index = 0; index < PyList_GET_SIZE(keys); index++) { PyObject* key; ! PyObject* item; key = PyList_GET_ITEM(keys, index); ! if (!key) { ! Py_DECREF(keys); ! Py_DECREF(result); ! return NULL; ! } ! item = match_getslice(self, key, def); ! if (!item) { Py_DECREF(key); ! Py_DECREF(keys); ! Py_DECREF(result); ! return NULL; } ! /* FIXME: this can fail, right? */ ! PyDict_SetItem(result, key, item); } --- 2059,2081 ---- keys = PyMapping_Keys(self->pattern->groupindex); ! if (!keys) ! goto failed; for (index = 0; index < PyList_GET_SIZE(keys); index++) { + int status; PyObject* key; ! PyObject* value; key = PyList_GET_ITEM(keys, index); ! if (!key) ! goto failed; ! value = match_getslice(self, key, def); ! if (!value) { Py_DECREF(key); ! goto failed; } ! status = PyDict_SetItem(result, key, value); ! Py_DECREF(value); ! if (status < 0) ! goto failed; } *************** *** 1999,2002 **** --- 2083,2091 ---- return result; + + failed: + Py_DECREF(keys); + Py_DECREF(result); + return NULL; } *************** *** 2325,2339 **** }; ! void ! #if defined(WIN32) ! __declspec(dllexport) ! #endif init_sre(void) { /* Patch object types */ Pattern_Type.ob_type = Match_Type.ob_type = Scanner_Type.ob_type = &PyType_Type; - Py_InitModule("_" MODULE, _functions); } --- 2414,2438 ---- }; ! DL_EXPORT(void) init_sre(void) { + PyObject* m; + PyObject* d; + /* Patch object types */ Pattern_Type.ob_type = Match_Type.ob_type = Scanner_Type.ob_type = &PyType_Type; + + m = Py_InitModule("_" SRE_MODULE, _functions); + d = PyModule_GetDict(m); + + PyDict_SetItemString( + d, "MAGIC", (PyObject*) PyInt_FromLong(SRE_MAGIC) + ); + + PyDict_SetItemString( + d, "copyright", (PyObject*) PyString_FromString(copyright) + ); } Index: sre_constants.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/sre_constants.h,v retrieving revision 2.9 retrieving revision 2.9.4.1 diff -C2 -r2.9 -r2.9.4.1 *** sre_constants.h 2000/08/01 22:47:49 2.9 --- sre_constants.h 2001/06/13 15:15:02 2.9.4.1 *************** *** 7,15 **** * to change anything in here, edit sre_constants.py and run it. * ! * Copyright (c) 1997-2000 by Secret Labs AB. All rights reserved. * * See the _sre.c file for information on usage and redistribution. */ #define SRE_OP_FAILURE 0 #define SRE_OP_SUCCESS 1 --- 7,16 ---- * to change anything in here, edit sre_constants.py and run it. * ! * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. * * See the _sre.c file for information on usage and redistribution. */ + #define SRE_MAGIC 20010320 #define SRE_OP_FAILURE 0 #define SRE_OP_SUCCESS 1 *************** *** 43,50 **** #define SRE_AT_BEGINNING 0 #define SRE_AT_BEGINNING_LINE 1 ! #define SRE_AT_BOUNDARY 2 ! #define SRE_AT_NON_BOUNDARY 3 ! #define SRE_AT_END 4 ! #define SRE_AT_END_LINE 5 #define SRE_CATEGORY_DIGIT 0 #define SRE_CATEGORY_NOT_DIGIT 1 --- 44,57 ---- #define SRE_AT_BEGINNING 0 #define SRE_AT_BEGINNING_LINE 1 ! #define SRE_AT_BEGINNING_STRING 2 ! #define SRE_AT_BOUNDARY 3 ! #define SRE_AT_NON_BOUNDARY 4 ! #define SRE_AT_END 5 ! #define SRE_AT_END_LINE 6 ! #define SRE_AT_END_STRING 7 ! #define SRE_AT_LOC_BOUNDARY 8 ! #define SRE_AT_LOC_NON_BOUNDARY 9 ! #define SRE_AT_UNI_BOUNDARY 10 ! #define SRE_AT_UNI_NON_BOUNDARY 11 #define SRE_CATEGORY_DIGIT 0 #define SRE_CATEGORY_NOT_DIGIT 1 From gvanrossum@users.sourceforge.net Wed Jun 13 17:02:11 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 13 Jun 2001 09:02:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include patchlevel.h,2.42.2.1,2.42.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv10985 Modified Files: Tag: release20-maint patchlevel.h Log Message: Change the version to 2.0.1c1 -- release candidate 1, that is. Index: patchlevel.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/patchlevel.h,v retrieving revision 2.42.2.1 retrieving revision 2.42.2.2 diff -C2 -r2.42.2.1 -r2.42.2.2 *** patchlevel.h 2001/05/08 19:02:27 2.42.2.1 --- patchlevel.h 2001/06/13 16:02:09 2.42.2.2 *************** *** 23,34 **** #define PY_MINOR_VERSION 0 #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.0.1a1" /* Historic */ ! #define PATCHLEVEL "2.0.1a1" /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. --- 23,34 ---- #define PY_MINOR_VERSION 0 #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.0.1c1" /* Historic */ ! #define PATCHLEVEL "2.0.1c1" /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. From fdrake@users.sourceforge.net Wed Jun 13 17:07:28 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 13 Jun 2001 09:07:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc Makefile,1.203,1.203.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv11943 Modified Files: Tag: release20-maint Makefile Log Message: Update version number for patch release candidate. Index: Makefile =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile,v retrieving revision 1.203 retrieving revision 1.203.2.1 diff -C2 -r1.203 -r1.203.2.1 *** Makefile 2000/10/13 15:35:26 1.203 --- Makefile 2001/06/13 16:07:26 1.203.2.1 *************** *** 65,69 **** # This is the *documentation* release, and is used to construct the file # names of the downloadable tarballs. ! RELEASE=2.0 --- 65,69 ---- # This is the *documentation* release, and is used to construct the file # names of the downloadable tarballs. ! RELEASE=2.0.1c1 From fdrake@users.sourceforge.net Wed Jun 13 17:08:16 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 13 Jun 2001 09:08:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/texinputs boilerplate.tex,1.50,1.50.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory usw-pr-cvs1:/tmp/cvs-serv12172/texinputs Modified Files: Tag: release20-maint boilerplate.tex Log Message: Update version number and date for patch release candidate. Index: boilerplate.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/boilerplate.tex,v retrieving revision 1.50 retrieving revision 1.50.2.1 diff -C2 -r1.50 -r1.50.2.1 *** boilerplate.tex 2000/10/13 15:35:27 1.50 --- boilerplate.tex 2001/06/13 16:08:13 1.50.2.1 *************** *** 2,10 **** Fred L. Drake, Jr., editor} \authoraddress{ ! BeOpen PythonLabs\\ E-mail: \email{python-docs@python.org} } ! \date{October 16, 2000} % XXX update before release! ! \release{2.0} % software release, not documentation \setshortversion{2.0} % major.minor only for software --- 2,10 ---- Fred L. Drake, Jr., editor} \authoraddress{ ! PythonLabs\\ E-mail: \email{python-docs@python.org} } ! \date{June 15, 2001} % XXX update before release! ! \release{2.0.1c1} % software release, not documentation \setshortversion{2.0} % major.minor only for software From gvanrossum@users.sourceforge.net Wed Jun 13 17:22:07 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 13 Jun 2001 09:22:07 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0000.txt,1.96,1.97 pep-0259.txt,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv15984 Modified Files: pep-0000.txt pep-0259.txt Log Message: PEP 259 rejected by user community with record unanimity. Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.96 retrieving revision 1.97 diff -C2 -r1.96 -r1.97 *** pep-0000.txt 2001/06/11 20:07:37 1.96 --- pep-0000.txt 2001/06/13 16:22:05 1.97 *************** *** 61,65 **** S 257 pep-0257.txt Docstring Conventions Goodger S 258 pep-0258.txt DPS Generic Implementation Details Goodger - S 259 pep-0259.txt Omit printing newline after newline van Rossum Py-in-the-sky PEPs (not ready; may become active yet) --- 61,64 ---- *************** *** 109,113 **** SR 224 pep-0224.txt Attribute Docstrings Lemburg SR 231 pep-0231.txt __findattr__() Warsaw ! S 233 pep-0233.txt Python Online Help Prescod --- 108,113 ---- SR 224 pep-0224.txt Attribute Docstrings Lemburg SR 231 pep-0231.txt __findattr__() Warsaw ! SD 233 pep-0233.txt Python Online Help Prescod ! SR 259 pep-0259.txt Omit printing newline after newline van Rossum *************** *** 160,164 **** SR 231 pep-0231.txt __findattr__() Warsaw SF 232 pep-0232.txt Function Attributes Warsaw ! S 233 pep-0233.txt Python Online Help Prescod S 234 pep-0234.txt Iterators Yee, van Rossum SF 235 pep-0235.txt Import on Case-Insensitive Platforms Peters --- 160,164 ---- SR 231 pep-0231.txt __findattr__() Warsaw SF 232 pep-0232.txt Function Attributes Warsaw ! SD 233 pep-0233.txt Python Online Help Prescod S 234 pep-0234.txt Iterators Yee, van Rossum SF 235 pep-0235.txt Import on Case-Insensitive Platforms Peters *************** *** 186,190 **** S 257 pep-0257.txt Docstring Conventions Goodger S 258 pep-0258.txt DPS Generic Implementation Details Goodger ! S 259 pep-0259.txt Omit printing newline after newline van Rossum --- 186,190 ---- S 257 pep-0257.txt Docstring Conventions Goodger S 258 pep-0258.txt DPS Generic Implementation Details Goodger ! SR 259 pep-0259.txt Omit printing newline after newline van Rossum Index: pep-0259.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0259.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** pep-0259.txt 2001/06/11 20:07:37 1.1 --- pep-0259.txt 2001/06/13 16:22:05 1.2 *************** *** 3,7 **** Version: $Revision$ Author: guido@python.org (Guido van Rossum) ! Status: Draft Type: Standards Track Python-Version: 2.2 --- 3,7 ---- Version: $Revision$ Author: guido@python.org (Guido van Rossum) ! Status: Rejected Type: Standards Track Python-Version: 2.2 *************** *** 108,111 **** --- 108,123 ---- http://sourceforge.net/tracker/index.php?func=detail&aid=432183&group_id=5470&atid=305470 + + + Rejected + + The user community unanimously rejected this, so I won't pursue + this idea any further. Frequently heard arguments against + included: + + - It it likely to break thousands of CGI scripts. + + - Enough magic already (also: no more tinkering with 'print' + please). From lemburg@users.sourceforge.net Wed Jun 13 18:18:08 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Wed, 13 Jun 2001 10:18:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python pythonrun.c,2.133,2.134 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv28226 Modified Files: pythonrun.c Log Message: Temporarily disable the message to stderr. Jeremy will know what to do about this... Index: pythonrun.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.133 retrieving revision 2.134 diff -C2 -r2.133 -r2.134 *** pythonrun.c 2001/03/26 19:53:38 2.133 --- pythonrun.c 2001/06/13 17:18:06 2.134 *************** *** 1077,1082 **** 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); --- 1077,1084 ---- 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); From tim_one@users.sourceforge.net Wed Jun 13 20:11:26 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 13 Jun 2001 12:11:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild python20.wse,1.21,1.21.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv23548/python/dist/src/PCbuild Modified Files: Tag: release20-maint python20.wse Log Message: Change installer dialog titles to say Python 2.0.1c1. Index: python20.wse =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/python20.wse,v retrieving revision 1.21 retrieving revision 1.21.2.1 diff -C2 -r1.21 -r1.21.2.1 *** python20.wse 2000/10/14 07:35:15 1.21 --- python20.wse 2001/06/13 19:11:24 1.21.2.1 *************** *** 2,6 **** item: Global Version=5.0 ! Title=Python 2.0 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.0.1c1 Flags=00010100 Languages=65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 *************** *** 65,69 **** item: Set Variable Variable=APPTITLE ! Value=Python 2.0 end item: Set Variable --- 65,69 ---- item: Set Variable Variable=APPTITLE ! Value=Python 2.0.1c1 end item: Set Variable From tim_one@users.sourceforge.net Wed Jun 13 20:17:34 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 13 Jun 2001 12:17:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild BUILDno.txt,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv25186 Modified Files: BUILDno.txt Log Message: Record Windows buildno for 2.0.1c1. Index: BUILDno.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/BUILDno.txt,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -r1.12 -r1.13 *** BUILDno.txt 2001/04/18 21:12:25 1.12 --- BUILDno.txt 2001/06/13 19:17:32 1.13 *************** *** 34,37 **** --- 34,39 ---- Windows Python BUILD numbers ---------------------------- + 17 2.0.1c1 + 13-Jun-2001 16 CVS development 18-Apr-2001 From tim_one@users.sourceforge.net Wed Jun 13 20:19:54 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 13 Jun 2001 12:19:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild python20.dsp,1.14,1.14.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv25640/python/dist/src/PCbuild Modified Files: Tag: release20-maint python20.dsp Log Message: Set Windows buildno to 17 for 2.0.1c1. Index: python20.dsp =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/Attic/python20.dsp,v retrieving revision 1.14 retrieving revision 1.14.2.1 diff -C2 -r1.14 -r1.14.2.1 *** python20.dsp 2000/10/14 07:35:15 1.14 --- python20.dsp 2001/06/13 19:19:52 1.14.2.1 *************** *** 695,703 **** !IF "$(CFG)" == "python20 - Win32 Release" ! # ADD CPP /D BUILD=8 !ELSEIF "$(CFG)" == "python20 - Win32 Debug" ! # ADD CPP /D BUILD=8 !ELSEIF "$(CFG)" == "python20 - Win32 Alpha Debug" --- 695,703 ---- !IF "$(CFG)" == "python20 - Win32 Release" ! # ADD CPP /D BUILD=17 !ELSEIF "$(CFG)" == "python20 - Win32 Debug" ! # ADD CPP /D BUILD=17 !ELSEIF "$(CFG)" == "python20 - Win32 Alpha Debug" From tim_one@users.sourceforge.net Wed Jun 13 20:26:02 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 13 Jun 2001 12:26:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild BUILDno.txt,1.4,1.4.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv27123/python/dist/src/PCbuild Modified Files: Tag: release20-maint BUILDno.txt Log Message: Also record the 2.0.1c1 Windows buildno in the branch, although the 9-number gap looks odd here. Index: BUILDno.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/BUILDno.txt,v retrieving revision 1.4 retrieving revision 1.4.2.1 diff -C2 -r1.4 -r1.4.2.1 *** BUILDno.txt 2000/10/14 07:35:14 1.4 --- BUILDno.txt 2001/06/13 19:26:00 1.4.2.1 *************** *** 34,37 **** --- 34,39 ---- Windows Python BUILD numbers ---------------------------- + 17 2.0.1c1 + 13-Jun-2001 8 2.0 (final) 14-Oct-2000 From tim_one@users.sourceforge.net Wed Jun 13 21:45:19 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 13 Jun 2001 13:45:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.75,1.76 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv15184/python/dist/src/Objects Modified Files: longobject.c Log Message: PyLong_As{Unsigned,}LongLong: fiddled final result casting. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.75 retrieving revision 1.76 diff -C2 -r1.75 -r1.76 *** longobject.c 2001/06/13 00:35:57 1.75 --- longobject.c 2001/06/13 20:45:17 1.76 *************** *** 573,577 **** SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1); ! return (LONG_LONG)(res < 0 ? res : bytes); } --- 573,577 ---- SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1); ! return res < 0 ? (LONG_LONG)res : bytes; } *************** *** 595,599 **** SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0); ! return (unsigned LONG_LONG)(res < 0 ? res : bytes); } --- 595,599 ---- SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0); ! return res < 0 ? (unsigned LONG_LONG)res : bytes; } From tim_one@users.sourceforge.net Wed Jun 13 21:50:10 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 13 Jun 2001 13:50:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.76,1.77 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv16247/python/dist/src/Objects Modified Files: longobject.c Log Message: _PyLong_AsByteArray: added assert that the input is normalized. This is outside the function's control, but is crucial to correct operation. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.76 retrieving revision 1.77 diff -C2 -r1.76 -r1.77 *** longobject.c 2001/06/13 20:45:17 1.76 --- longobject.c 2001/06/13 20:50:08 1.77 *************** *** 359,363 **** } ! /* Copy over all the Python digits. */ j = 0; accum = 0; --- 359,367 ---- } ! /* 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; From tim_one@users.sourceforge.net Wed Jun 13 22:01:29 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 13 Jun 2001 14:01:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.77,1.78 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv19167/python/dist/src/Objects Modified Files: longobject.c Log Message: _PyLong_AsByteArray: Don't do the "delicate overflow" check unless it's truly needed; usually saves a little time, but no change in semantics. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.77 retrieving revision 1.78 diff -C2 -r1.77 -r1.78 *** longobject.c 2001/06/13 20:50:08 1.77 --- longobject.c 2001/06/13 21:01:27 1.78 *************** *** 425,440 **** p += pincr; } ! ! /* Fill remaining bytes with copies of the sign bit. */ ! for ( ; j < n; ++j, p += pincr) ! *p = (unsigned char)(do_twos_comp ? 0xff : 0); ! ! /* Check for delicate overflow (not enough room for the sign bit). */ ! if (j > 0 && is_signed) { unsigned char msb = *(p - pincr); ! int sign_bit_set = (msb & 0x80) != 0; ! if (sign_bit_set != do_twos_comp) goto Overflow; } return 0; --- 425,449 ---- 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; From tim_one@users.sourceforge.net Wed Jun 13 22:09:17 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 13 Jun 2001 14:09:17 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.78,1.79 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv20769/python/dist/src/Objects Modified Files: longobject.c Log Message: _PyLong_FromByteArray: changed decl of "carry" to match "thisbyte". No semantic change, but a bit clearer and may help a really stupid compiler avoid pointless runtime length conversions. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.78 retrieving revision 1.79 diff -C2 -r1.78 -r1.79 *** longobject.c 2001/06/13 21:01:27 1.78 --- longobject.c 2001/06/13 21:09:15 1.79 *************** *** 279,283 **** { size_t i; ! unsigned int carry = 1; /* for 2's-comp calculation */ twodigits accum = 0; /* sliding register */ unsigned int accumbits = 0; /* number of bits in accum */ --- 279,283 ---- { 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 */ From gvanrossum@users.sourceforge.net Wed Jun 13 22:48:33 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 13 Jun 2001 14:48:33 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0253.txt,1.3,1.4 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv30297 Modified Files: pep-0253.txt Log Message: Another intermediate update. I've rewritten the requirements for a base type to be subtypable. Needs way more work! Index: pep-0253.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0253.txt,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** pep-0253.txt 2001/06/11 20:07:37 1.3 --- pep-0253.txt 2001/06/13 21:48:31 1.4 *************** *** 11,22 **** Abstract ! This PEP proposes ways for creating subtypes of existing built-in ! types, either in C or in Python. The text is currently long and ! rambling; I'll go over it again later to make it shorter. 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 object that are relevant to the Python interpreter. A few fields contain dimensional information (e.g. the basic allocation size of instances), others contain --- 11,24 ---- Abstract ! This PEP proposes additions to the type object API that will allow ! the creation of subtypes of built-in types, in C and in Python. + + Introduction + 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 (e.g. the basic allocation size of instances), others contain *************** *** 27,34 **** exception when the behavior is invoked. Some collections of functions pointers that are usually defined together are obtained ! indirectly via a pointer to an additional structure containing. While the details of initializing a PyTypeObject structure haven't ! been documented as such, they are easily glanced from the examples in the source code, and I am assuming that the reader is sufficiently familiar with the traditional way of creating new --- 29,37 ---- exception when the behavior is invoked. Some collections of functions pointers that are usually defined together are obtained ! indirectly via a pointer to an additional structure containing ! more function pointers. While the details of initializing a PyTypeObject structure haven't ! been documented as such, they are easily gleaned from the examples in the source code, and I am assuming that the reader is sufficiently familiar with the traditional way of creating new *************** *** 36,63 **** This PEP will introduce the following features: ! - a type, like a class, can be a factory for its instances ! - types can be subtyped in C by specifying a base type pointer ! - types can be subtyped in Python using the class statement ! - multiple inheritance from types (insofar as practical) ! - the standard coercions (int, tuple, str etc.) will be the ! corresponding type objects ! - a standard type hierarchy This PEP builds on pep-0252, which adds standard introspection to ! types; in particular, types are assumed to have e.g. a __hash__ ! method when the type object defines the tp_hash slot. pep-0252 also ! adds a dictionary to type objects which contains all methods. At ! the Python level, this dictionary is read-only; at the C level, it ! is accessible directly (but modifying it is not recommended except ! as part of initialization). ! Metatypes Inevitably the following discussion will come to mention metatypes --- 39,83 ---- 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-0252, 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-0252 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 ! 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 ! checking of this flag bit. This should be fixed before the final ! release.) ! About metatypes Inevitably the following discussion will come to mention metatypes *************** *** 76,99 **** In this example, type(a) is a "regular" type, and type(type(a)) is a metatype. While as distributed all types have the same metatype ! (which is also its own metatype), this is not a requirement, and ! in fact a useful 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. We 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 way than Smalltalk. In Smalltalk-80, there is a ! hierarchy of metaclasses that mirrors the hierarchy of regular ! classes, metaclasses map 1-1 to classes (except for some funny ! business at the root of the hierarchy), and each class statement ! creates both a regular class and its metaclass, putting class ! methods in the metaclass and instance methods in the regular ! class. Nice though this may be in the context of Smalltalk, it's not --- 96,120 ---- In this example, type(a) is a "regular" type, and type(type(a)) is a metatype. While as distributed all types have the same metatype ! (PyType_Type, which is also its own metatype), this is not a ! 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 ! way than Smalltalk. In Smalltalk-80, there is a hierarchy of ! metaclasses that mirrors the hierarchy of regular classes, ! metaclasses map 1-1 to classes (except for some funny business at ! the root of the hierarchy), and each class statement creates both ! a regular class and its metaclass, putting class methods in the ! metaclass and instance methods in the regular class. Nice though this may be in the context of Smalltalk, it's not *************** *** 107,118 **** initialize it at will.) - Instantiation by calling the type object ! Traditionally, for each type there is at least one C function that ! creates instances of the type (e.g. PyInt_FromLong(), ! PyTuple_New() and so on). This function has to take care of both allocating memory for the object and initializing that ! memory. As of Python 2.0, it also has to interface with the garbage collection subsystem, if the type chooses to participate in garbage collection (which is optional, but strongly recommended --- 128,154 ---- 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 + method resolution order is, how instance attributes are looked + up, and so on. + + I'll argue that left-to-right depth-first is not the best + solution when you want to get the most use from multiple + inheritance. + + I'll argue that with multiple inheritance, the metatype of the + subtype must be a descendant of the metatypes of all base types. + + I'll come back to metatypes later. ! Making a type a factory for its instances ! ! Traditionally, for each type there is at least one C factory ! function that creates instances of the type (PyTuple_New(), ! PyInt_FromLong() and so on). These factory functions take care of both allocating memory for the object and initializing that ! memory. As of Python 2.0, they also have to interface with the garbage collection subsystem, if the type chooses to participate in garbage collection (which is optional, but strongly recommended *************** *** 120,202 **** references to other objects, and hence may participate in reference cycles). - - If we're going to implement subtyping, we must separate allocation - and initialization: typically, the most derived subtype is in - charge of allocation (and hence deallocation!), but in most cases - each base type's initializer (constructor) must still be called, - from the "most base" type to the most derived type. - - But let's first get the interface for instantiation right. If we - call an object, the tp_call slot if its type gets invoked. Thus, - if we call a type, this invokes the tp_call slot of the type's - type: in other words, the tp_call slot of the metatype. - Traditionally this has been a NULL pointer, meaning that types - can't be called. Now we're adding a tp_call slot to the metatype, - which makes all types "callable" in a trivial sense. But - obviously the metatype's tp_call implementation doesn't know how - to initialize the instances of individual types. So the type - defines a new slot, tp_new, which is invoked by the metatype's - tp_call slot. If the tp_new slot is NULL, the metatype's tp_call - issues a nice error message: the type isn't callable. - - This mechanism gives the maximum freedom to the type: a type's - tp_new doesn't necessarily have to return a new object, or even an - object that is an instance of the type (although the latter should - be rare). - - HIRO - - 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 ! (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. ! ! 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. ! Subtyping 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 the various problems, and it's acceptable for C code that doesn't ! follow the rules to dump core; while for Python subtyping we would ! need to catch all errors before they become core dumps. The idea behind subtyping is very similar to that of single --- 156,200 ---- references to other objects, and hence may participate in reference cycles). ! In this proposal, type objects can be factory functions for their ! instances, making the types directly callable from Python. This ! mimics the way classes are instantiated. Of course, the C APIs ! for creating instances of various built-in types will remain valid ! and probably the most common; and not all types will become their ! own factory functions. ! ! The type object has a new slot, tp_new, which can act as a factory ! for instances of the type. Types are made callable by providing a ! tp_call slot in PyType_Type (the metatype); the slot ! implementation function looks for the tp_new slot of the type that ! is being called. ! ! If the type's tp_new slot is NULL, an exception is raised. ! Otherwise, the tp_new slot is called. The signature for the ! tp_new slot is ! ! PyObject *tp_new(PyTypeObject *type, ! PyObject *args, ! PyObject *kwds) ! ! where 'type' is the type whose tp_new slot is called, and 'args' ! and 'kwds' are the sequential and keyword arguments to the call, ! passed unchanged from tp_call. (The 'type' argument is used in ! combination with inheritance, see below.) ! ! There are no constraints on the object type that is returned, ! although by convention it should be an instance of the given ! type. It is not necessary that a new object is returned; a ! reference to an existing object is fine too. The return value ! should always be a new reference, owned by the caller. ! 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 *************** *** 207,236 **** the type object, leaving others the same. ! Not every type can serve as a base type. The base type must ! support separation of allocation and initialization by having a ! tp_construct slot that can be called with a preallocated object, ! and it must support uninitialization without deallocation by ! having a tp_clear slot as described above. The derived 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 the base type must also be exported. If the base type has a type-checking macro (e.g. PyDict_Check()), ! this macro may 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. There are ! arguments for and against changing the type-checking macro in this ! way. The argument for the change should be clear: it allows ! subtypes to be used in places where the base type is required, ! which is often the prime attraction of subtyping (as opposed to ! sharing implementation). 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 ! (hard to believe); or one could fear that a subtype might break an ! invariant assumed by the support functions of the base type. ! Sometimes it would be wise to change the base type to remove this ! reliance; other times, it would be better to require that derived ! types (implemented in C) maintain the invariants. The derived type begins by declaring a type structure which contains the base type's structure. For example, here's the type --- 205,372 ---- 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 (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. + + 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) + + 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 is required to initialize + ob_refcnt to 1 and ob_type to its type argument. To be safe, it + should probably 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 + 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) ! 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 + The derived type begins by declaring a type structure which contains the base type's structure. For example, here's the type *************** *** 400,403 **** --- 536,586 ---- 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 + (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. + + 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. From tim_one@users.sourceforge.net Wed Jun 13 23:45:29 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 13 Jun 2001 15:45:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_struct.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv12079/python/dist/src/Lib/test Modified Files: test_struct.py Log Message: Generalize the new qQ std-mode tests to all int codes (bBhHiIlLqQ). Unfortunately, the std-mode bBhHIL codes don't do any range-checking; if and when some of those get fixed, remove their letters from the IntTester.BUGGY_RANGE_CHECK string. In the meantime, a msg saying that range-tests are getting skipped is printed to stdout whenever one is skipped. Index: test_struct.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_struct.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -r1.11 -r1.12 *** test_struct.py 2001/06/13 01:26:35 1.11 --- test_struct.py 2001/06/13 22:45:27 1.12 *************** *** 3,6 **** --- 3,23 ---- ## 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: *************** *** 23,26 **** --- 40,44 ---- ## pdb.set_trace() + simple_err(struct.calcsize, 'Z') *************** *** 104,114 **** ] - isbigendian = struct.pack('=i', 1)[0] == chr(0) - 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: *************** *** 125,129 **** ########################################################################### ! # q/Q tests. has_native_qQ = 1 --- 141,145 ---- ########################################################################### ! # Simple native q/Q tests. has_native_qQ = 1 *************** *** 140,154 **** simple_err(struct.pack, "Q", "a") # ditto, but 'Q' - 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 test_native_qQ(): bytes = struct.calcsize('q') --- 156,159 ---- *************** *** 176,323 **** test_native_qQ() ! # Standard q/Q (8 bytes; should work on all platforms). ! ! MIN_Q, MAX_Q = 0, 2L**64 - 1 ! MIN_q, MAX_q = -(2L**63), 2L**63 - 1 import binascii - def test_one_qQ(x, pack=struct.pack, - unpack=struct.unpack, - unhexlify=binascii.unhexlify): - if verbose: - print "trying std q/Q on", x, "==", hex(x) ! # Try 'q'. ! if MIN_q <= x <= MAX_q: ! # Try '>q'. ! expected = long(x) ! if x < 0: ! expected += 1L << 64 ! 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" * (8 - len(expected)) + expected ! ! # >q pack work? ! got = pack(">q", x) ! verify(got == expected, ! "'>q'-pack of %r gave %r, not %r" % ! (x, got, expected)) ! ! # >q unpack work? ! retrieved = unpack(">q", got)[0] ! verify(x == retrieved, ! "'>q'-unpack of %r gave %r, not %r" % ! (got, retrieved, x)) ! ! # Adding any byte should cause a "too big" error. ! any_err(unpack, ">q", '\x01' + got) ! ! # Try 'q', x) ! any_err(pack, 'Q'. ! 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" * (8 - len(expected)) + expected ! ! # >Q pack work? ! got = pack(">Q", x) ! verify(got == expected, ! "'>Q'-pack of %r gave %r, not %r" % ! (x, got, expected)) ! ! # >Q unpack work? ! retrieved = unpack(">Q", got)[0] ! verify(x == retrieved, ! "'>Q'-unpack of %r gave %r, not %r" % ! (got, retrieved, x)) ! ! # Adding any byte should cause a "too big" error. ! any_err(unpack, ">Q", '\x01' + got) ! ! # Try 'Q', x) ! any_err(pack, '": ! for letter in "qQ": ! for badobject in "a string", 3+42j, randrange: ! any_err(struct.pack, direction + letter, badobject) ! ! test_std_qQ() --- 181,367 ---- test_native_qQ() ! ########################################################################### ! # Standard integer tests (bBhHiIlLqQ). import binascii ! class IntTester: ! # XXX Most std integer modes fail to test for out-of-range. ! BUGGY_RANGE_CHECK = "bBhHIL" ! 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() From gvanrossum@users.sourceforge.net Thu Jun 14 01:53:36 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 13 Jun 2001 17:53:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects intobject.c,2.56.6.4,2.56.6.5 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv10258 Modified Files: Tag: descr-branch intobject.c Log Message: In int_new(), assert that the type argument is &PyInt_Type. Index: intobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v retrieving revision 2.56.6.4 retrieving revision 2.56.6.5 diff -C2 -r2.56.6.4 -r2.56.6.5 *** intobject.c 2001/06/11 21:06:03 2.56.6.4 --- intobject.c 2001/06/14 00:53:34 2.56.6.5 *************** *** 758,761 **** --- 758,762 ---- static char *kwlist[] = {"x", "base", 0}; + assert(type == &PyInt_Type); if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist, &x, &base)) From gvanrossum@users.sourceforge.net Thu Jun 14 01:54:08 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 13 Jun 2001 17:54:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.38,2.16.8.39 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv10353 Modified Files: Tag: descr-branch typeobject.c Log Message: Don't inherit tp_doc -- it would be misleading. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.38 retrieving revision 2.16.8.39 diff -C2 -r2.16.8.38 -r2.16.8.39 *** typeobject.c 2001/06/11 18:45:10 2.16.8.38 --- typeobject.c 2001/06/14 00:54:06 2.16.8.39 *************** *** 945,949 **** COPYSLOT(tp_as_buffer); COPYSLOT(tp_flags); - COPYSLOT(tp_doc); if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_RICHCOMPARE) { if (type->tp_compare == NULL && type->tp_richcompare == NULL) { --- 945,948 ---- From gvanrossum@users.sourceforge.net Thu Jun 14 01:54:30 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 13 Jun 2001 17:54:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.80.2.10,2.80.2.11 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv10482 Modified Files: Tag: descr-branch dictobject.c Log Message: Ad a minimal doc string. Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.80.2.10 retrieving revision 2.80.2.11 diff -C2 -r2.80.2.10 -r2.80.2.11 *** dictobject.c 2001/06/07 11:50:05 2.80.2.10 --- dictobject.c 2001/06/14 00:54:28 2.80.2.11 *************** *** 1477,1481 **** 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ ! 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ --- 1477,1481 ---- 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ ! "dictionary type", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ From tim_one@users.sourceforge.net Thu Jun 14 01:55:43 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 13 Jun 2001 17:55:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules testcapi_long.h,NONE,1.1 _testcapimodule.c,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv9814/python/dist/src/Modules Modified Files: _testcapimodule.c Added Files: testcapi_long.h Log Message: Add tests of PyLong_{As,From}{Unsigned,}Long. These are very much like the new PyLong_{As,From}{Unsigned,}LongLong tests, so the bulk of the code is in the new #include file testcapi_long.h, which generates different code depending on how macros are set. This sucks, but I couldn't think of anything that sucked less. UNIX headache? If we still maintain dependencies by hand, someone who knows what they're doing should teach whatever needs it that _testcapimodule.c includes testcapi_long.h. --- 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* -> TypeError F_ERROR error-report function; char* -> PyObject* (returns NULL) */ static PyObject * TESTNAME() { 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 F_ERROR( "unsigned unexpected null result"); uout = F_PY_TO_U(pyresult); if (uout == (unsigned TYPENAME)-1 && PyErr_Occurred()) return F_ERROR( "unsigned unexpected -1 result"); if (uout != uin) return F_ERROR( "unsigned output != input"); UNBIND(pyresult); in = (TYPENAME)uin; pyresult = F_S_TO_PY(in); if (pyresult == NULL) return F_ERROR( "signed unexpected null result"); out = F_PY_TO_S(pyresult); if (out == (TYPENAME)-1 && PyErr_Occurred()) return F_ERROR( "signed unexpected -1 result"); if (out != in) return F_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 F_ERROR( "unexpected NULL from PyLong_FromLong"); /* Unsigned complains about -1? */ x = PyNumber_Negative(one); if (x == NULL) return F_ERROR( "unexpected NULL from PyNumber_Negative"); uout = F_PY_TO_U(x); if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred()) return F_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 F_ERROR( "unexpected NULL from PyLong_FromLong"); x = PyNumber_Lshift(one, y); /* 1L << NBITS, == 2**NBITS */ UNBIND(y); if (x == NULL) return F_ERROR( "unexpected NULL from PyNumber_Lshift"); uout = F_PY_TO_U(x); if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred()) return F_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 F_ERROR( "unexpected NULL from PyNumber_Rshift"); out = F_PY_TO_S(y); if (out != (TYPENAME)-1 || !PyErr_Occurred()) return F_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 F_ERROR( "unexpected NULL from PyNumber_Negative"); y = PyNumber_Subtract(x, one); /* -(2**(NBITS-1))-1 */ UNBIND(x); if (y == NULL) return F_ERROR( "unexpected NULL from PyNumber_Subtract"); out = F_PY_TO_S(y); if (out != (TYPENAME)-1 || !PyErr_Occurred()) return F_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: _testcapimodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_testcapimodule.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** _testcapimodule.c 2001/06/13 00:35:57 1.5 --- _testcapimodule.c 2001/06/14 00:55:41 1.6 *************** *** 173,181 **** } ! #ifdef HAVE_LONG_LONG ! /* Basic sanity checks for PyLong_{As, From}{Unsigned,}LongLong(). */ static PyObject * raise_test_longlong_error(const char* msg) { --- 173,230 ---- } ! ! /* 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 + #define F_ERROR raise_test_long_error + + #include "testcapi_long.h" + + static PyObject * + test_long_api(PyObject* self, PyObject* args) + { + if (!PyArg_ParseTuple(args, ":test_long_api")) + return NULL; + + return TESTNAME(); + } + + #undef TESTNAME + #undef TYPENAME + #undef F_S_TO_PY + #undef F_PY_TO_S + #undef F_U_TO_PY + #undef F_PY_TO_U + #undef F_ERROR + + #ifdef HAVE_LONG_LONG + + static PyObject * raise_test_longlong_error(const char* msg) { *************** *** 183,352 **** } ! #define UNBIND(X) Py_DECREF(X); (X) = NULL static PyObject * test_longlong_api(PyObject* self, PyObject* args) { - const int NBITS = SIZEOF_LONG_LONG * 8; - unsigned LONG_LONG base; - PyObject *pyresult; - int i; - if (!PyArg_ParseTuple(args, ":test_longlong_api")) return NULL; ! ! /* 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) { ! LONG_LONG in, out; ! unsigned LONG_LONG uin, uout; ! ! /* For 0, 1, 2 use base; for 3, 4, 5 use -base */ ! uin = j < 3 ? base ! : (unsigned LONG_LONG)(-(LONG_LONG)base); ! ! /* For 0 & 3, subtract 1. ! * For 1 & 4, leave alone. ! * For 2 & 5, add 1. ! */ ! uin += (unsigned LONG_LONG)(LONG_LONG)(j % 3 - 1); ! ! pyresult = PyLong_FromUnsignedLongLong(uin); ! if (pyresult == NULL) ! return raise_test_longlong_error( ! "unsigned unexpected null result"); ! ! uout = PyLong_AsUnsignedLongLong(pyresult); ! if (uout == (unsigned LONG_LONG)-1 && PyErr_Occurred()) ! return raise_test_longlong_error( ! "unsigned unexpected -1 result"); ! if (uout != uin) ! return raise_test_longlong_error( ! "unsigned output != input"); ! UNBIND(pyresult); ! ! in = (LONG_LONG)uin; ! pyresult = PyLong_FromLongLong(in); ! if (pyresult == NULL) ! return raise_test_longlong_error( ! "signed unexpected null result"); ! ! out = PyLong_AsLongLong(pyresult); ! if (out == (LONG_LONG)-1 && PyErr_Occurred()) ! return raise_test_longlong_error( ! "signed unexpected -1 result"); ! if (out != in) ! return raise_test_longlong_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; ! LONG_LONG out; ! unsigned LONG_LONG uout; ! ! one = PyLong_FromLong(1); ! if (one == NULL) ! return raise_test_longlong_error( ! "unexpected NULL from PyLong_FromLong"); ! ! /* Unsigned complains about -1? */ ! x = PyNumber_Negative(one); ! if (x == NULL) ! return raise_test_longlong_error( ! "unexpected NULL from PyNumber_Negative"); ! ! uout = PyLong_AsUnsignedLongLong(x); ! if (uout != (unsigned LONG_LONG)-1 || !PyErr_Occurred()) ! return raise_test_longlong_error( ! "PyLong_AsUnsignedLongLong(-1) didn't " ! "complain"); ! PyErr_Clear(); ! UNBIND(x); ! ! /* Unsigned complains about 2**NBITS? */ ! y = PyLong_FromLong((long)NBITS); ! if (y == NULL) ! return raise_test_longlong_error( ! "unexpected NULL from PyLong_FromLong"); ! ! x = PyNumber_Lshift(one, y); /* 1L << NBITS, == 2**NBITS */ ! UNBIND(y); ! if (x == NULL) ! return raise_test_longlong_error( ! "unexpected NULL from PyNumber_Lshift"); ! ! uout = PyLong_AsUnsignedLongLong(x); ! if (uout != (unsigned LONG_LONG)-1 || !PyErr_Occurred()) ! return raise_test_longlong_error( ! "PyLong_AsUnsignedLongLong(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 raise_test_longlong_error( ! "unexpected NULL from PyNumber_Rshift"); ! ! out = PyLong_AsLongLong(y); ! if (out != (LONG_LONG)-1 || !PyErr_Occurred()) ! return raise_test_longlong_error( ! "PyLong_AsLongLong(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 raise_test_longlong_error( ! "unexpected NULL from PyNumber_Negative"); ! ! y = PyNumber_Subtract(x, one); /* -(2**(NBITS-1))-1 */ ! UNBIND(x); ! if (y == NULL) ! return raise_test_longlong_error( ! "unexpected NULL from PyNumber_Subtract"); ! ! out = PyLong_AsLongLong(y); ! if (out != (LONG_LONG)-1 || !PyErr_Occurred()) ! return raise_test_longlong_error( ! "PyLong_AsLongLong(-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; ! } - #endif static PyMethodDef TestMethods[] = { --- 232,264 ---- } ! #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 ! #define F_ERROR raise_test_longlong_error ! ! #include "testcapi_long.h" static PyObject * test_longlong_api(PyObject* self, PyObject* args) { if (!PyArg_ParseTuple(args, ":test_longlong_api")) return NULL; ! return TESTNAME(); ! } ! #undef TESTNAME ! #undef TYPENAME ! #undef F_S_TO_PY ! #undef F_PY_TO_S ! #undef F_U_TO_PY ! #undef F_PY_TO_U ! #undef F_ERROR ! #endif /* ifdef HAVE_LONG_LONG */ static PyMethodDef TestMethods[] = { *************** *** 354,357 **** --- 266,270 ---- {"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}, From gvanrossum@users.sourceforge.net Thu Jun 14 02:01:18 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 13 Jun 2001 18:01:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.71.6.2,1.71.6.3 floatobject.c,2.81.6.3,2.81.6.4 stringobject.c,2.103.2.4,2.103.2.5 tupleobject.c,2.48.6.2,2.48.6.3 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv11831/Objects Modified Files: Tag: descr-branch longobject.c floatobject.c stringobject.c tupleobject.c Log Message: Four more built-in types bite the dust: the built-ins long, float, string and tuple are now type objects. These can't be subtyped yet! Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.71.6.2 retrieving revision 1.71.6.3 diff -C2 -r1.71.6.2 -r1.71.6.3 *** longobject.c 2001/06/06 14:27:54 1.71.6.2 --- longobject.c 2001/06/14 01:01:16 1.71.6.3 *************** *** 1813,1816 **** --- 1813,1853 ---- } + static PyObject * + long_new(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + PyObject *x = NULL; + int base = -909; /* unlikely! */ + static char *kwlist[] = {"x", "base", 0}; + + assert(type == &PyLong_Type); + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:long", kwlist, + &x, &base)) + return NULL; + if (x == NULL) + return PyLong_FromLong(0L); + if (base == -909) + return PyNumber_Long(x); + else if (PyString_Check(x)) + return PyLong_FromString(PyString_AS_STRING(x), NULL, base); + else if (PyUnicode_Check(x)) + return PyLong_FromUnicode(PyUnicode_AS_UNICODE(x), + PyUnicode_GET_SIZE(x), + base); + else { + PyErr_SetString(PyExc_TypeError, + "long() can't convert non-string with explicit base"); + return NULL; + } + } + + static char long_doc[] = + "long(x[, base]) -> integer\n\ + \n\ + Convert a string or number to a long integer, if possible. A floating\n\ + point argument will be truncated towards zero (this does not include a\n\ + string representation of a floating point number!) When converting a\n\ + string, use the optional base. It is an error to supply a base when\n\ + converting a non-string."; + static PyNumberMethods long_as_number = { (binaryfunc) long_add, /*nb_add*/ *************** *** 1853,1857 **** PyObject_HEAD_INIT(&PyType_Type) 0, /* ob_size */ ! "long int", /* tp_name */ sizeof(PyLongObject) - sizeof(digit), /* tp_basicsize */ sizeof(digit), /* tp_itemsize */ --- 1890,1894 ---- PyObject_HEAD_INIT(&PyType_Type) 0, /* ob_size */ ! "long", /* tp_name */ sizeof(PyLongObject) - sizeof(digit), /* tp_basicsize */ sizeof(digit), /* tp_itemsize */ *************** *** 1872,1874 **** --- 1909,1929 ---- 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */ + long_doc, /* 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 */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + long_new, /* tp_new */ }; Index: floatobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v retrieving revision 2.81.6.3 retrieving revision 2.81.6.4 diff -C2 -r2.81.6.3 -r2.81.6.4 *** floatobject.c 2001/06/06 14:27:54 2.81.6.3 --- floatobject.c 2001/06/14 01:01:16 2.81.6.4 *************** *** 625,628 **** --- 625,648 ---- + static PyObject * + float_new(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + PyObject *x; + static char *kwlist[] = {"x", 0}; + + assert(type == &PyFloat_Type); + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:float", kwlist, &x)) + return NULL; + if (PyString_Check(x)) + return PyFloat_FromString(x, NULL); + return PyNumber_Float(x); + } + + static char float_doc[] = + "float(x) -> floating point number\n\ + \n\ + Convert a string or number to a floating point number, if possible."; + + static PyNumberMethods float_as_number = { (binaryfunc)float_add, /*nb_add*/ *************** *** 683,687 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES /* tp_flags */ }; --- 703,725 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */ ! float_doc, /* 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 */ ! 0, /* tp_descr_get */ ! 0, /* tp_descr_set */ ! 0, /* tp_dictoffset */ ! 0, /* tp_init */ ! 0, /* tp_alloc */ ! float_new, /* tp_new */ }; Index: stringobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v retrieving revision 2.103.2.4 retrieving revision 2.103.2.5 diff -C2 -r2.103.2.4 -r2.103.2.5 *** stringobject.c 2001/06/06 14:27:54 2.103.2.4 --- stringobject.c 2001/06/14 01:01:16 2.103.2.5 *************** *** 2358,2362 **** --- 2358,2381 ---- }; + static PyObject * + string_new(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + PyObject *x = NULL; + static char *kwlist[] = {"object", 0}; + assert(type == &PyString_Type); + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:str", kwlist, &x)) + return NULL; + if (x == NULL) + return PyString_FromString(""); + return PyObject_Str(x); + } + + static char string_doc[] = + "str(object) -> string\n\ + \n\ + Return a nice string representation of the object.\n\ + If the argument is a string, the return value is the same object."; + PyTypeObject PyString_Type = { PyObject_HEAD_INIT(&PyType_Type) *************** *** 2381,2385 **** &string_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ ! 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ --- 2400,2404 ---- &string_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ ! string_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ *************** *** 2393,2396 **** --- 2412,2421 ---- 0, /* tp_base */ 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + string_new, /* tp_new */ }; Index: tupleobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/tupleobject.c,v retrieving revision 2.48.6.2 retrieving revision 2.48.6.3 diff -C2 -r2.48.6.2 -r2.48.6.3 *** tupleobject.c 2001/06/06 14:27:54 2.48.6.2 --- tupleobject.c 2001/06/14 01:01:16 2.48.6.3 *************** *** 444,447 **** --- 444,469 ---- } + static PyObject * + tuple_new(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + PyObject *arg = NULL; + static char *kwlist[] = {"sequence", 0}; + + assert(type == &PyTuple_Type); + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:tuple", kwlist, &arg)) + return NULL; + + if (arg == NULL) + return PyTuple_New(0); + else + return PySequence_Tuple(arg); + } + + static char tuple_doc[] = + "tuple(sequence) -> list\n\ + \n\ + Return a tuple whose items are the same as those of the argument sequence.\n\ + If the argument is a tuple, the return value is the same object."; + static PySequenceMethods tuple_as_sequence = { (inquiry)tuplelength, /* sq_length */ *************** *** 477,484 **** 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */ ! 0, /* tp_doc */ (traverseproc)tupletraverse, /* tp_traverse */ 0, /* tp_clear */ tuplerichcompare, /* tp_richcompare */ }; --- 499,520 ---- 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */ ! tuple_doc, /* tp_doc */ (traverseproc)tupletraverse, /* tp_traverse */ 0, /* tp_clear */ tuplerichcompare, /* 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 */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + tuple_new, /* tp_new */ }; From tim_one@users.sourceforge.net Thu Jun 14 02:11:05 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 13 Jun 2001 18:11:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _testcapimodule.c,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv14056/python/dist/src/Modules Modified Files: _testcapimodule.c Log Message: Fixed typo in comment. Index: _testcapimodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_testcapimodule.c,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -r1.6 -r1.7 *** _testcapimodule.c 2001/06/14 00:55:41 1.6 --- _testcapimodule.c 2001/06/14 01:11:03 1.7 *************** *** 175,179 **** /* 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. --- 175,179 ---- /* 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. From tim_one@users.sourceforge.net Thu Jun 14 05:56:21 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 13 Jun 2001 21:56:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.79,1.80 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv10246/python/dist/src/Objects Modified Files: longobject.c Log Message: PyLong_From{Unsigned,}Long: count the # of digits first, so no more space is allocated than needed (used to allocate 80 bytes of digit space no matter how small the long input). This also runs faster, at least on 32- bit boxes. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.79 retrieving revision 1.80 diff -C2 -r1.79 -r1.80 *** longobject.c 2001/06/13 21:09:15 1.79 --- longobject.c 2001/06/14 04:56:19 1.80 *************** *** 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; From tim_one@users.sourceforge.net Thu Jun 14 07:57:31 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 13 Jun 2001 23:57:31 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0255.txt,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv8864/python/nondist/peps Modified Files: pep-0255.txt Log Message: Substantial rewriting. Index: pep-0255.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0255.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** pep-0255.txt 2001/06/05 17:11:30 1.1 --- pep-0255.txt 2001/06/14 06:57:29 1.2 *************** *** 92,96 **** very simple example: ! def fib(): a, b = 0, 1 while 1: yield b --- 92,97 ---- very simple example: ! def fib(): ! a, b = 0, 1 while 1: yield b *************** *** 119,161 **** Specification ! A new statement, the "yield" statement, is introduced: ! yield_stmt: "yield" [expression_list] ! This statement may only be used inside functions. A function which ! contains a yield statement is a so-called "generator function". A ! generator function may not contain return statements of the form: ! "return" expression_list ! It may, however, contain return statements of the form: "return" ! When a generator function is called, an iterator[6] is returned. ! Each time the .next() method of this iterator is called, the code ! in the body of the generator function is executed until a yield ! statement or a return statement is encountered, or until the end ! of the body is reached. ! ! If a yield statement is encountered during this execution, the ! state of the function is frozen, and a value is returned to the ! object calling .next(). If an empty yield statement was ! encountered, None is returned; otherwise, the given expression(s) ! is (are) returned. ! ! If an empty return statement is encountered, nothing is returned; ! however, a StopIteration exception is raised, signalling that the ! iterator is exhausted. ! An example of how generators may be used is given below: ! # A binary tree class class Tree: def __init__(self, label, left=None, right=None): self.label = label self.left = left self.right = right ! def __repr__(self, level=0, indent=" "): s = level*indent + `self.label` if self.left: --- 120,183 ---- Specification ! A new statement is introduced: ! yield_stmt: "yield" expression_list ! "yield" is a new keyword, so a future statement[8] is needed to phase ! this in. [XXX spell this out] ! The yield statement may only be used inside functions. A function that ! contains a yield statement is called a generator function. ! ! When a generator function is called, the actual arguments are bound to ! function-local formal argument names in the usual way, but no code in ! the body of the function is executed. Instead a generator-iterator ! object is returned; this conforms to the iterator protocol[6], so in ! particular can be used in for-loops in a natural way. Note that when ! the intent is clear from context, the unqualified name "generator" may ! be used to refer either to a generator-function or a generator- ! iterator. ! ! Each time the .next() method of a generator-iterator is invoked, the ! code in the body of the generator-function is executed until a yield ! or return statement (see below) is encountered, or until the end of ! the body is reached. ! ! If a yield statement is encountered, the state of the function is ! frozen, and the value of expression_list is returned to .next()'s ! caller. By "frozen" we mean that all local state is retained, ! including the current bindings of local variables, the instruction ! pointer, and the internal evaluation stack: enough information is ! saved so that the next time .next() is invoked, the function can ! proceed exactly is if the yield statement were just another external ! call. ! A generator function can also contain return statements of the form: "return" ! Note that an expression_list is not allowed on return statements ! in the body of a generator (although, of course, they may appear in ! the bodies of non-generator functions nested within the generator). ! When a return statement is encountered, nothing is returned, but a ! StopIteration exception is raised, signalling that the iterator is ! exhausted. The same is true if control flows off the end of the ! function. Note that return means "I'm done, and have nothing ! interesting to return", for both generator functions and non-generator ! functions. ! ! Example ! ! # A binary tree class. class Tree: + def __init__(self, label, left=None, right=None): self.label = label self.left = left self.right = right ! ! def __repr__(self, level=0, indent=" "): s = level*indent + `self.label` if self.left: *************** *** 164,208 **** s = s + "\n" + self.right.__repr__(level+1, indent) return s def __iter__(self): return inorder(self) ! ! # A function that creates a tree from a list def tree(list): ! if not len(list): return [] ! i = len(list)/2 return Tree(list[i], tree(list[:i]), tree(list[i+1:])) ! ! # A recursive generator that generates the tree leaves in in-order def inorder(t): if t: ! for x in inorder(t.left): yield x yield t.label ! for x in inorder(t.right): yield x ! ! # Show it off: create a tree t = tree("ABCDEFGHIJKLMNOPQRSTUVWXYZ") ! # Print the nodes of the tree in in-order ! for x in t: print x, print ! # A non-recursive generator. def inorder(node): ! stack = [] ! while node: ! while node.left: ! stack.append(node) ! node = node.left ! yield node.label ! while not node.right: ! try: ! node = stack.pop() ! except IndexError: ! return ! yield node.label ! node = node.right ! ! # Exercise the non-recursive generator ! for x in t: print x, print --- 186,236 ---- s = s + "\n" + self.right.__repr__(level+1, indent) return s + def __iter__(self): return inorder(self) ! ! # Create a Tree from a list. def tree(list): ! n = len(list) ! if n == 0: return [] ! i = n / 2 return Tree(list[i], tree(list[:i]), tree(list[i+1:])) ! ! # A recursive generator that generates Tree leaves in in-order. def inorder(t): if t: ! for x in inorder(t.left): ! yield x yield t.label ! for x in inorder(t.right): ! yield x ! ! # Show it off: create a tree. t = tree("ABCDEFGHIJKLMNOPQRSTUVWXYZ") ! # Print the nodes of the tree in in-order. ! for x in t: ! print x, print ! # A non-recursive generator. def inorder(node): ! stack = [] ! while node: ! while node.left: ! stack.append(node) ! node = node.left ! yield node.label ! while not node.right: ! try: ! node = stack.pop() ! except IndexError: ! return ! yield node.label ! node = node.right ! ! # Exercise the non-recursive generator. ! for x in t: ! print x, print *************** *** 215,221 **** Footnotes and References ! [1] PEP 234, http://python.sourceforge.net/peps/pep-0234.html [2] http://www.stackless.com/ ! [3] PEP 219, http://python.sourceforge.net/peps/pep-0219.html [4] "Iteration Abstraction in Sather" Murer , Omohundro, Stoutamire and Szyperski --- 243,249 ---- Footnotes and References ! [1] PEP 234, http://python.sf.net/peps/pep-0234.html [2] http://www.stackless.com/ ! [3] PEP 219, http://python.sf.net/peps/pep-0219.html [4] "Iteration Abstraction in Sather" Murer , Omohundro, Stoutamire and Szyperski *************** *** 223,228 **** [5] http://www.cs.arizona.edu/icon/ [6] The concept of iterators is described in PEP 234 ! http://python.sourceforge.net/peps/pep-0234.html [7] http://python.ca/nas/python/generator.diff --- 251,257 ---- [5] http://www.cs.arizona.edu/icon/ [6] The concept of iterators is described in PEP 234 ! http://python.sf.net/peps/pep-0234.html [7] http://python.ca/nas/python/generator.diff + [8] http://python.sf.net/peps/pep-0236.html From tim_one@users.sourceforge.net Thu Jun 14 09:53:40 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 14 Jun 2001 01:53:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.80,1.81 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv2492/python/dist/src/Objects Modified Files: longobject.c Log Message: _PyLong_AsByteArray: simplify the logic for dealing with the most- significant digits sign bits. Again no change in semantics. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.80 retrieving revision 1.81 diff -C2 -r1.80 -r1.81 *** longobject.c 2001/06/14 04:56:19 1.80 --- longobject.c 2001/06/14 08:53:38 1.81 *************** *** 389,393 **** carry = do_twos_comp ? 1 : 0; for (i = 0; i < ndigits; ++i) { - unsigned int numnewbits = SHIFT; twodigits thisdigit = v->ob_digit[i]; if (do_twos_comp) { --- 389,392 ---- *************** *** 400,419 **** prepended to accum. */ accum |= thisdigit << accumbits; ! /* How many new bits did we add? The most-significant digit ! may be (probably is) at least partly empty. */ if (i == ndigits - 1) { ! twodigits bitmask = 1 << (SHIFT - 1); ! twodigits signbit = do_twos_comp << (SHIFT - 1); unsigned int nsignbits = 0; ! while ((thisdigit & bitmask) == signbit && bitmask) { ++nsignbits; ! bitmask >>= 1; ! signbit >>= 1; } ! assert(nsignbits <= SHIFT); ! numnewbits -= nsignbits; } - accumbits += numnewbits; /* Store as many bytes as possible. */ --- 399,421 ---- 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. */ From gvanrossum@users.sourceforge.net Thu Jun 14 12:26:47 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 14 Jun 2001 04:26:47 -0700 Subject: [Python-checkins] CVS: python/dist/src LICENSE,1.7.2.3,1.7.2.4 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv23464 Modified Files: Tag: release20-maint LICENSE Log Message: Fix two mentions of 2.1 instead of 2.0.1. Not worth fixing this in the 2.0.1c1 release (which has already been built and pushed out to SF and py.org), but will be correct in the 2.0.1 final release. Does this require a matching update in the license as quoted in the docs? Index: LICENSE =================================================================== RCS file: /cvsroot/python/python/dist/src/LICENSE,v retrieving revision 1.7.2.3 retrieving revision 1.7.2.4 diff -C2 -r1.7.2.3 -r1.7.2.4 *** LICENSE 2001/05/04 18:50:14 1.7.2.3 --- LICENSE 2001/06/14 11:26:45 1.7.2.4 *************** *** 21,25 **** Python license. Python 1.6.1 is essentially the same as Python 1.6, with a few minor bug fixes, and with a different license that enables ! later versions to be GPL-compatible. Python 2.1 is a derivative work of Python 1.6.1, as well as of Python 2.0. --- 21,25 ---- Python license. Python 1.6.1 is essentially the same as Python 1.6, with a few minor bug fixes, and with a different license that enables ! later versions to be GPL-compatible. Python 2.0.1 is a derivative work of Python 1.6.1, as well as of Python 2.0. *************** *** 83,87 **** products or services of Licensee, or any third party. ! 8. By copying, installing or otherwise using Python 2.1, Licensee agrees to be bound by the terms and conditions of this License Agreement. --- 83,87 ---- products or services of Licensee, or any third party. ! 8. By copying, installing or otherwise using Python 2.0.1, Licensee agrees to be bound by the terms and conditions of this License Agreement. From gvanrossum@users.sourceforge.net Thu Jun 14 14:37:47 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 14 Jun 2001 06:37:47 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0253.txt,1.4,1.5 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv10803 Modified Files: pep-0253.txt Log Message: Clarified the paragraph about creating a subtype in C. Index: pep-0253.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0253.txt,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** pep-0253.txt 2001/06/13 21:48:31 1.4 --- pep-0253.txt 2001/06/14 13:37:45 1.5 *************** *** 369,372 **** --- 369,377 ---- 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 + it may inherit GC-awareness from the base type (this is + automatic). The base type's allocation uses the standard heap. + The derived type begins by declaring a type structure which contains the base type's structure. For example, here's the type *************** *** 391,433 **** 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 ! instances ! - the tp_base field must be set to the address of the base type's ! type object ! - the tp_dealloc slot function must be a deallocation function for ! the subtype ! - the tp_flags field must be set to the usual Py_TPFLAGS_DEFAULT ! value ! - the tp_name field must be set (otherwise it will be inherited, ! which is wrong) 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. 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; this is more a ! matter of pep-0252. ! ! The subtype's tp_dealloc slot deserves special attention. It must ! uninitialize and deallocate the object in an orderly manner: first ! it must uninitialize the fields added by the extension type; then ! it must call the base type's tp_clear function; finally it must ! deallocate the memory of the object. Usually, the base type's ! tp_clear function has no global name; it is permissible to call it ! via the base type's tp_clear slot, e.g. PyListType.tp_clear(obj). ! Only if it is known that the base type uses the same allocation ! method as the subtype and the subtype requires no uninitialization ! (e.g. it adds no data fields or all its data fields are numbers) ! is it permissible to leave tp_dealloc set to zero in the subtype's ! type object; it will be copied from the base type. A subtype is not usable until PyType_InitDict() is called for it; --- 396,447 ---- 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 (i.e., 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, e.g., 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, 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; *************** *** 440,448 **** calls, a test for tp_dict==NULL can be made. ! If the subtype itself should be subtypable (usually desirable), it ! should follow the same rules are given above for base types: have ! a tp_construct that accepts a preallocated object and calls the ! base type's tp_construct, and have a tp_clear that calls the base ! type's tp_clear. --- 454,464 ---- 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. From fdrake@users.sourceforge.net Thu Jun 14 14:57:18 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 14 Jun 2001 06:57:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libprofile.tex,1.33,1.34 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv17442/lib Modified Files: libprofile.tex Log Message: Fix an improperly placed comma. Index: libprofile.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libprofile.tex,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -r1.33 -r1.34 *** libprofile.tex 2001/06/08 05:04:19 1.33 --- libprofile.tex 2001/06/14 13:57:16 1.34 *************** *** 617,621 **** profiler will actually run equally fast!!), but the above method is the simplest to use. I could have made the profiler ``self ! calibrating'', but it would have made the initialization of the profiler class slower, and would have required some \emph{very} fancy coding, or else the use of a variable where the constant \samp{.00053} --- 617,621 ---- profiler will actually run equally fast!!), but the above method is the simplest to use. I could have made the profiler ``self ! calibrating,'' but it would have made the initialization of the profiler class slower, and would have required some \emph{very} fancy coding, or else the use of a variable where the constant \samp{.00053} From fdrake@users.sourceforge.net Thu Jun 14 14:57:51 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 14 Jun 2001 06:57:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libprofile.tex,1.32,1.32.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv17663/lib Modified Files: Tag: release21-maint libprofile.tex Log Message: Fix an improperly placed comma. Index: libprofile.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libprofile.tex,v retrieving revision 1.32 retrieving revision 1.32.2.1 diff -C2 -r1.32 -r1.32.2.1 *** libprofile.tex 2001/04/13 14:34:58 1.32 --- libprofile.tex 2001/06/14 13:57:49 1.32.2.1 *************** *** 617,621 **** profiler will actually run equally fast!!), but the above method is the simplest to use. I could have made the profiler ``self ! calibrating'', but it would have made the initialization of the profiler class slower, and would have required some \emph{very} fancy coding, or else the use of a variable where the constant \samp{.00053} --- 617,621 ---- profiler will actually run equally fast!!), but the above method is the simplest to use. I could have made the profiler ``self ! calibrating,'' but it would have made the initialization of the profiler class slower, and would have required some \emph{very} fancy coding, or else the use of a variable where the constant \samp{.00053} From fdrake@users.sourceforge.net Thu Jun 14 14:58:46 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 14 Jun 2001 06:58:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libprofile.tex,1.30,1.30.8.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv18050/lib Modified Files: Tag: release20-maint libprofile.tex Log Message: Fix an improperly placed comma. Index: libprofile.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libprofile.tex,v retrieving revision 1.30 retrieving revision 1.30.8.1 diff -C2 -r1.30 -r1.30.8.1 *** libprofile.tex 1999/04/22 21:23:22 1.30 --- libprofile.tex 2001/06/14 13:58:44 1.30.8.1 *************** *** 612,616 **** profiler will actually run equally fast!!), but the above method is the simplest to use. I could have made the profiler ``self ! calibrating'', but it would have made the initialization of the profiler class slower, and would have required some \emph{very} fancy coding, or else the use of a variable where the constant \samp{.00053} --- 612,616 ---- profiler will actually run equally fast!!), but the above method is the simplest to use. I could have made the profiler ``self ! calibrating,'' but it would have made the initialization of the profiler class slower, and would have required some \emph{very} fancy coding, or else the use of a variable where the constant \samp{.00053} From gvanrossum@users.sourceforge.net Thu Jun 14 15:10:18 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 14 Jun 2001 07:10:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.80.2.11,2.80.2.12 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv22266 Modified Files: Tag: descr-branch dictobject.c Log Message: Oops, I added the doc string to the wrong type object. Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.80.2.11 retrieving revision 2.80.2.12 diff -C2 -r2.80.2.11 -r2.80.2.12 *** dictobject.c 2001/06/14 00:54:28 2.80.2.11 --- dictobject.c 2001/06/14 14:10:16 2.80.2.12 *************** *** 1314,1318 **** 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */ ! 0, /* tp_doc */ (traverseproc)dict_traverse, /* tp_traverse */ (inquiry)dict_tp_clear, /* tp_clear */ --- 1314,1318 ---- 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */ ! "dictionary type", /* tp_doc */ (traverseproc)dict_traverse, /* tp_traverse */ (inquiry)dict_tp_clear, /* tp_clear */ *************** *** 1477,1481 **** 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ ! "dictionary type", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ --- 1477,1481 ---- 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ ! 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ From gvanrossum@users.sourceforge.net Thu Jun 14 15:13:48 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 14 Jun 2001 07:13:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.39,2.16.8.40 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv23801 Modified Files: Tag: descr-branch typeobject.c Log Message: Don't inherit tp_name -- like tp_doc, it would be a lie. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.39 retrieving revision 2.16.8.40 diff -C2 -r2.16.8.39 -r2.16.8.40 *** typeobject.c 2001/06/14 00:54:06 2.16.8.39 --- typeobject.c 2001/06/14 14:13:46 2.16.8.40 *************** *** 904,909 **** } - COPYSLOT(tp_name); - /* Copying basicsize is connected to the GC flags */ oldsize = base->tp_basicsize; --- 904,907 ---- From gvanrossum@users.sourceforge.net Thu Jun 14 15:19:53 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 14 Jun 2001 07:19:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.198.2.2,2.198.2.3 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv27255 Modified Files: Tag: descr-branch bltinmodule.c Log Message: Builtins float, long, str and tuple are now also type objects. Still to do: complex, unicode, buffer, slice, xrange; and iter? Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.198.2.2 retrieving revision 2.198.2.3 diff -C2 -r2.198.2.2 -r2.198.2.3 *** bltinmodule.c 2001/06/11 21:06:03 2.198.2.2 --- bltinmodule.c 2001/06/14 14:19:51 2.198.2.3 *************** *** 1228,1283 **** static PyObject * - builtin_long(PyObject *self, PyObject *args) - { - PyObject *v; - int base = -909; /* unlikely! */ - - if (!PyArg_ParseTuple(args, "O|i:long", &v, &base)) - return NULL; - if (base == -909) - return PyNumber_Long(v); - else if (PyString_Check(v)) - return PyLong_FromString(PyString_AS_STRING(v), NULL, base); - else if (PyUnicode_Check(v)) - return PyLong_FromUnicode(PyUnicode_AS_UNICODE(v), - PyUnicode_GET_SIZE(v), - base); - else { - PyErr_SetString(PyExc_TypeError, - "long() can't convert non-string with explicit base"); - return NULL; - } - } - - static char long_doc[] = - "long(x) -> long integer\n\ - long(x, base) -> long integer\n\ - \n\ - Convert a string or number to a long integer, if possible. A floating\n\ - point argument will be truncated towards zero (this does not include a\n\ - string representation of a floating point number!) When converting a\n\ - string, use the given base. It is an error to supply a base when\n\ - converting a non-string."; - - - static PyObject * - builtin_float(PyObject *self, PyObject *args) - { - PyObject *v; - - if (!PyArg_ParseTuple(args, "O:float", &v)) - return NULL; - if (PyString_Check(v)) - return PyFloat_FromString(v, NULL); - return PyNumber_Float(v); - } - - static char float_doc[] = - "float(x) -> floating point number\n\ - \n\ - Convert a string or number to a floating point number, if possible."; - - - static PyObject * builtin_iter(PyObject *self, PyObject *args) { --- 1228,1231 ---- *************** *** 1909,1946 **** static PyObject * - builtin_str(PyObject *self, PyObject *args) - { - PyObject *v; - - if (!PyArg_ParseTuple(args, "O:str", &v)) - return NULL; - return PyObject_Str(v); - } - - static char str_doc[] = - "str(object) -> string\n\ - \n\ - Return a nice string representation of the object.\n\ - If the argument is a string, the return value is the same object."; - - - static PyObject * - builtin_tuple(PyObject *self, PyObject *args) - { - PyObject *v; - - if (!PyArg_ParseTuple(args, "O:tuple", &v)) - return NULL; - return PySequence_Tuple(v); - } - - static char tuple_doc[] = - "tuple(sequence) -> list\n\ - \n\ - Return a tuple whose items are the same as those of the argument sequence.\n\ - If the argument is a tuple, the return value is the same object."; - - - static PyObject * builtin_vars(PyObject *self, PyObject *args) { --- 1857,1860 ---- *************** *** 2096,2100 **** {"execfile", builtin_execfile, 1, execfile_doc}, {"filter", builtin_filter, 1, filter_doc}, - {"float", builtin_float, 1, float_doc}, {"getattr", builtin_getattr, 1, getattr_doc}, {"globals", builtin_globals, 1, globals_doc}, --- 2010,2013 ---- *************** *** 2110,2114 **** {"len", builtin_len, 1, len_doc}, {"locals", builtin_locals, 1, locals_doc}, - {"long", builtin_long, 1, long_doc}, {"map", builtin_map, 1, map_doc}, {"max", builtin_max, 1, max_doc}, --- 2023,2026 ---- *************** *** 2126,2131 **** {"setattr", builtin_setattr, 1, setattr_doc}, {"slice", builtin_slice, 1, slice_doc}, - {"str", builtin_str, 1, str_doc}, - {"tuple", builtin_tuple, 1, tuple_doc}, {"unicode", builtin_unicode, 1, unicode_doc}, {"unichr", builtin_unichr, 1, unichr_doc}, --- 2038,2041 ---- *************** *** 2161,2170 **** (PyObject *) &PyDict_Type) < 0) return NULL; ! if (PyDict_SetItemString(dict, "list", (PyObject *) &PyList_Type) < 0) return NULL; if (PyDict_SetItemString(dict, "int", (PyObject *) &PyInt_Type) < 0) return NULL; if (PyDict_SetItemString(dict, "object", (PyObject *) &PyBaseObject_Type) < 0) return NULL; if (PyDict_SetItemString(dict, "type", (PyObject *) &PyType_Type) < 0) --- 2071,2090 ---- (PyObject *) &PyDict_Type) < 0) return NULL; ! if (PyDict_SetItemString(dict, "float", ! (PyObject *) &PyFloat_Type) < 0) return NULL; if (PyDict_SetItemString(dict, "int", (PyObject *) &PyInt_Type) < 0) return NULL; + if (PyDict_SetItemString(dict, "list", (PyObject *) &PyList_Type) < 0) + return NULL; + if (PyDict_SetItemString(dict, "long", (PyObject *) &PyLong_Type) < 0) + return NULL; if (PyDict_SetItemString(dict, "object", (PyObject *) &PyBaseObject_Type) < 0) + return NULL; + if (PyDict_SetItemString(dict, "str", (PyObject *) &PyString_Type) < 0) + return NULL; + if (PyDict_SetItemString(dict, "tuple", + (PyObject *) &PyTuple_Type) < 0) return NULL; if (PyDict_SetItemString(dict, "type", (PyObject *) &PyType_Type) < 0) From tim_one@users.sourceforge.net Thu Jun 14 17:06:04 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 14 Jun 2001 09:06:04 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0255.txt,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv2239/python/nondist/peps Modified Files: pep-0255.txt Log Message: Minor changes; added "why a keyword?" Q&A; added Post-History. Index: pep-0255.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0255.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** pep-0255.txt 2001/06/14 06:57:29 1.2 --- pep-0255.txt 2001/06/14 16:06:02 1.3 *************** *** 11,15 **** Created: 18-May-2001 Python-Version: 2.2 ! Post-History: --- 11,15 ---- Created: 18-May-2001 Python-Version: 2.2 ! Post-History: 14-Jun-2001 *************** *** 75,84 **** Python instead, which supports lightweight coroutines. This has much the same programmatic benefits as the thread option, but is much more ! efficient. However, Stackless is a radical and controversial ! rethinking of the Python core, and it may not be possible for Jython to ! implement the same semantics. This PEP isn't the place to debate that, ! so suffice it to say here that generators provide a useful subset of ! Stackless functionality in a way that fits easily into the current ! Python implementation. That exhausts the current alternatives. Some other high-level --- 75,85 ---- Python instead, which supports lightweight coroutines. This has much the same programmatic benefits as the thread option, but is much more ! efficient. However, Stackless is a controversial rethinking of the ! Python core, and it may not be possible for Jython to implement the ! same semantics. This PEP isn't the place to debate that, so suffice it ! to say here that generators provide a useful subset of Stackless ! functionality in a way that fits easily into the current CPython ! implementation, and is believed to be relatively straightforward for ! other Python implementations. That exhausts the current alternatives. Some other high-level *************** *** 150,154 **** pointer, and the internal evaluation stack: enough information is saved so that the next time .next() is invoked, the function can ! proceed exactly is if the yield statement were just another external call. --- 151,155 ---- pointer, and the internal evaluation stack: enough information is saved so that the next time .next() is invoked, the function can ! proceed exactly as if the yield statement were just another external call. *************** *** 234,237 **** --- 235,249 ---- print x, print + + + Q & A + + Q. Why a new keyword? Why not a builtin function instead? + + A. Control flow is much better expressed via keyword in Python, and + yield is a control construct. It's also believed that efficient + implementation in Jython requires that the compiler be able to + determine potential suspension points at compile-time, and a new + keyword makes that easy. From gvanrossum@users.sourceforge.net Thu Jun 14 18:47:23 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 14 Jun 2001 10:47:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib types.py,1.14.10.4,1.14.10.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv31809 Modified Files: Tag: descr-branch types.py Log Message: Get rid of TurtleType -- it doesn't exist any more. Index: types.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/types.py,v retrieving revision 1.14.10.4 retrieving revision 1.14.10.5 diff -C2 -r1.14.10.4 -r1.14.10.5 *** types.py 2001/06/07 19:03:08 1.14.10.4 --- types.py 2001/06/14 17:47:21 1.14.10.5 *************** *** 71,75 **** FunctionIterType = type(iter(lambda: 0, 0)) DictProxyType = type(TypeType.__dict__) - TurtleType = type(TypeType) del sys, _f, _C, _x # Not for export --- 71,74 ---- From gvanrossum@users.sourceforge.net Thu Jun 14 18:52:05 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 14 Jun 2001 10:52:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects unicodeobject.c,2.93,2.94 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv483 Modified Files: unicodeobject.c Log Message: Fix a mis-indentation in _PyUnicode_New() that caused me to stare at some code for longer than needed. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.93 retrieving revision 2.94 diff -C2 -r2.93 -r2.94 *** unicodeobject.c 2001/06/07 12:26:56 2.93 --- unicodeobject.c 2001/06/14 17:52:02 2.94 *************** *** 184,191 **** } } ! else { unicode->str = PyMem_NEW(Py_UNICODE, length + 1); ! } ! PyObject_INIT(unicode, &PyUnicode_Type); } else { --- 184,191 ---- } } ! else { unicode->str = PyMem_NEW(Py_UNICODE, length + 1); ! } ! PyObject_INIT(unicode, &PyUnicode_Type); } else { From gvanrossum@users.sourceforge.net Thu Jun 14 19:12:04 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 14 Jun 2001 11:12:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects unicodeobject.c,2.87.2.3,2.87.2.4 complexobject.c,2.35.4.3,2.35.4.4 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv5083/Objects Modified Files: Tag: descr-branch unicodeobject.c complexobject.c Log Message: Two more bite the dust: built-ins unicode and complex are now also types. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.87.2.3 retrieving revision 2.87.2.4 diff -C2 -r2.87.2.3 -r2.87.2.4 *** unicodeobject.c 2001/06/06 14:27:54 2.87.2.3 --- unicodeobject.c 2001/06/14 18:12:02 2.87.2.4 *************** *** 184,191 **** } } ! else { unicode->str = PyMem_NEW(Py_UNICODE, length + 1); ! } ! PyObject_INIT(unicode, &PyUnicode_Type); } else { --- 184,191 ---- } } ! else { unicode->str = PyMem_NEW(Py_UNICODE, length + 1); ! } ! PyObject_INIT(unicode, &PyUnicode_Type); } else { *************** *** 5220,5223 **** --- 5220,5247 ---- }; + static PyObject * + unicode_new(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + PyObject *x = NULL; + static char *kwlist[] = {"string", "encoding", "errors", 0}; + char *encoding = NULL; + char *errors = NULL; + + assert(type == &PyUnicode_Type); + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:unicode", + kwlist, &x, &encoding, &errors)) + return NULL; + if (x == NULL) + return (PyObject *)_PyUnicode_New(0); + return PyUnicode_FromEncodedObject(x, encoding, errors); + } + + static char unicode_doc[] = + "unicode(string [, encoding[, errors]]) -> object\n\ + \n\ + Create a new Unicode object from the given encoded string.\n\ + encoding defaults to the current default string encoding and \n\ + errors, defining the error handling, to 'strict'."; + PyTypeObject PyUnicode_Type = { PyObject_HEAD_INIT(&PyType_Type) *************** *** 5243,5247 **** &unicode_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ ! 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ --- 5267,5271 ---- &unicode_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ ! unicode_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ *************** *** 5255,5258 **** --- 5279,5288 ---- 0, /* tp_base */ 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + unicode_new, /* tp_new */ }; Index: complexobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/complexobject.c,v retrieving revision 2.35.4.3 retrieving revision 2.35.4.4 diff -C2 -r2.35.4.3 -r2.35.4.4 *** complexobject.c 2001/06/06 14:27:54 2.35.4.3 --- complexobject.c 2001/06/14 18:12:02 2.35.4.4 *************** *** 567,570 **** --- 567,820 ---- }; + static PyObject * + complex_from_string(PyObject *v) + { + extern double strtod(const char *, char **); + const char *s, *start; + char *end; + double x=0.0, y=0.0, z; + int got_re=0, got_im=0, done=0; + int digit_or_dot; + int sw_error=0; + int sign; + char buffer[256]; /* For errors */ + char s_buffer[256]; + int len; + + if (PyString_Check(v)) { + s = PyString_AS_STRING(v); + len = PyString_GET_SIZE(v); + } + else if (PyUnicode_Check(v)) { + if (PyUnicode_GET_SIZE(v) >= sizeof(s_buffer)) { + PyErr_SetString(PyExc_ValueError, + "complex() literal too large to convert"); + return NULL; + } + if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v), + PyUnicode_GET_SIZE(v), + s_buffer, + NULL)) + return NULL; + s = s_buffer; + len = (int)strlen(s); + } + else if (PyObject_AsCharBuffer(v, &s, &len)) { + PyErr_SetString(PyExc_TypeError, + "complex() arg is not a string"); + return NULL; + } + + /* position on first nonblank */ + start = s; + while (*s && isspace(Py_CHARMASK(*s))) + s++; + if (s[0] == '\0') { + PyErr_SetString(PyExc_ValueError, + "complex() arg is an empty string"); + return NULL; + } + + z = -1.0; + sign = 1; + do { + + switch (*s) { + + case '\0': + if (s-start != len) { + PyErr_SetString( + PyExc_ValueError, + "complex() arg contains a null byte"); + return NULL; + } + if(!done) sw_error=1; + break; + + case '-': + sign = -1; + /* Fallthrough */ + case '+': + if (done) sw_error=1; + s++; + if ( *s=='\0'||*s=='+'||*s=='-' || + isspace(Py_CHARMASK(*s)) ) sw_error=1; + break; + + case 'J': + case 'j': + if (got_im || done) { + sw_error = 1; + break; + } + if (z<0.0) { + y=sign; + } + else{ + y=sign*z; + } + got_im=1; + s++; + if (*s!='+' && *s!='-' ) + done=1; + break; + + default: + if (isspace(Py_CHARMASK(*s))) { + while (*s && isspace(Py_CHARMASK(*s))) + s++; + if (s[0] != '\0') + sw_error=1; + else + done = 1; + break; + } + digit_or_dot = + (*s=='.' || isdigit(Py_CHARMASK(*s))); + if (done||!digit_or_dot) { + sw_error=1; + break; + } + errno = 0; + PyFPE_START_PROTECT("strtod", return 0) + z = strtod(s, &end) ; + PyFPE_END_PROTECT(z) + if (errno != 0) { + sprintf(buffer, + "float() out of range: %.150s", s); + PyErr_SetString( + PyExc_ValueError, + buffer); + return NULL; + } + s=end; + if (*s=='J' || *s=='j') { + + break; + } + if (got_re) { + sw_error=1; + break; + } + + /* accept a real part */ + x=sign*z; + got_re=1; + if (got_im) done=1; + z = -1.0; + sign = 1; + break; + + } /* end of switch */ + + } while (*s!='\0' && !sw_error); + + if (sw_error) { + PyErr_SetString(PyExc_ValueError, + "complex() arg is a malformed string"); + return NULL; + } + + return PyComplex_FromDoubles(x,y); + } + + static PyObject * + complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + PyObject *r, *i, *tmp; + PyNumberMethods *nbr, *nbi = NULL; + Py_complex cr, ci; + int own_r = 0; + static char *kwlist[] = {"real", "imag", 0}; + + assert(type == &PyComplex_Type); + r = Py_False; + i = NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:complex", kwlist, + &r, &i)) + return NULL; + if (PyString_Check(r) || PyUnicode_Check(r)) + return complex_from_string(r); + if ((nbr = r->ob_type->tp_as_number) == NULL || + nbr->nb_float == NULL || + (i != NULL && + ((nbi = i->ob_type->tp_as_number) == NULL || + nbi->nb_float == NULL))) { + PyErr_SetString(PyExc_TypeError, + "complex() arg can't be converted to complex"); + return NULL; + } + /* XXX Hack to support classes with __complex__ method */ + if (PyInstance_Check(r)) { + static PyObject *complexstr; + PyObject *f; + if (complexstr == NULL) { + complexstr = PyString_InternFromString("__complex__"); + if (complexstr == NULL) + return NULL; + } + f = PyObject_GetAttr(r, complexstr); + if (f == NULL) + PyErr_Clear(); + else { + PyObject *args = Py_BuildValue("()"); + if (args == NULL) + return NULL; + r = PyEval_CallObject(f, args); + Py_DECREF(args); + Py_DECREF(f); + if (r == NULL) + return NULL; + own_r = 1; + } + } + if (PyComplex_Check(r)) { + cr = ((PyComplexObject*)r)->cval; + if (own_r) { + Py_DECREF(r); + } + } + else { + tmp = PyNumber_Float(r); + if (own_r) { + Py_DECREF(r); + } + if (tmp == NULL) + return NULL; + if (!PyFloat_Check(tmp)) { + PyErr_SetString(PyExc_TypeError, + "float(r) didn't return a float"); + Py_DECREF(tmp); + return NULL; + } + cr.real = PyFloat_AsDouble(tmp); + Py_DECREF(tmp); + cr.imag = 0.0; + } + if (i == NULL) { + ci.real = 0.0; + ci.imag = 0.0; + } + else if (PyComplex_Check(i)) + ci = ((PyComplexObject*)i)->cval; + else { + tmp = (*nbi->nb_float)(i); + if (tmp == NULL) + return NULL; + ci.real = PyFloat_AsDouble(tmp); + Py_DECREF(tmp); + ci.imag = 0.; + } + cr.real -= ci.imag; + cr.imag += ci.real; + return PyComplex_FromCComplex(cr); + } + + static char complex_doc[] = + "complex(real[, imag]) -> complex number\n\ + \n\ + Create a complex number from a real part and an optional imaginary part.\n\ + This is equivalent to (real + imag*1j) where imag defaults to 0."; + static PyNumberMethods complex_as_number = { (binaryfunc)complex_add, /* nb_add */ *************** *** 615,619 **** 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ ! 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ --- 865,869 ---- 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ ! complex_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ *************** *** 627,630 **** --- 877,886 ---- 0, /* tp_base */ 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + complex_new, /* tp_new */ }; From gvanrossum@users.sourceforge.net Thu Jun 14 19:12:04 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 14 Jun 2001 11:12:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.198.2.3,2.198.2.4 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv5083/Python Modified Files: Tag: descr-branch bltinmodule.c Log Message: Two more bite the dust: built-ins unicode and complex are now also types. Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.198.2.3 retrieving revision 2.198.2.4 diff -C2 -r2.198.2.3 -r2.198.2.4 *** bltinmodule.c 2001/06/14 14:19:51 2.198.2.3 --- bltinmodule.c 2001/06/14 18:12:02 2.198.2.4 *************** *** 124,147 **** static PyObject * - builtin_unicode(PyObject *self, PyObject *args) - { - PyObject *v; - char *encoding = NULL; - char *errors = NULL; - - if ( !PyArg_ParseTuple(args, "O|ss:unicode", &v, &encoding, &errors) ) - return NULL; - return PyUnicode_FromEncodedObject(v, encoding, errors); - } - - static char unicode_doc[] = - "unicode(string [, encoding[, errors]]) -> object\n\ - \n\ - Create a new Unicode object from the given encoded string.\n\ - encoding defaults to the current default string encoding and \n\ - errors, defining the error handling, to 'strict'."; - - - static PyObject * builtin_callable(PyObject *self, PyObject *args) { --- 124,127 ---- *************** *** 392,647 **** - #ifndef WITHOUT_COMPLEX - static PyObject * - complex_from_string(PyObject *v) - { - extern double strtod(const char *, char **); - const char *s, *start; - char *end; - double x=0.0, y=0.0, z; - int got_re=0, got_im=0, done=0; - int digit_or_dot; - int sw_error=0; - int sign; - char buffer[256]; /* For errors */ - char s_buffer[256]; - int len; - - if (PyString_Check(v)) { - s = PyString_AS_STRING(v); - len = PyString_GET_SIZE(v); - } - else if (PyUnicode_Check(v)) { - if (PyUnicode_GET_SIZE(v) >= sizeof(s_buffer)) { - PyErr_SetString(PyExc_ValueError, - "complex() literal too large to convert"); - return NULL; - } - if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v), - PyUnicode_GET_SIZE(v), - s_buffer, - NULL)) - return NULL; - s = s_buffer; - len = (int)strlen(s); - } - else if (PyObject_AsCharBuffer(v, &s, &len)) { - PyErr_SetString(PyExc_TypeError, - "complex() arg is not a string"); - return NULL; - } - - /* position on first nonblank */ - start = s; - while (*s && isspace(Py_CHARMASK(*s))) - s++; - if (s[0] == '\0') { - PyErr_SetString(PyExc_ValueError, - "complex() arg is an empty string"); - return NULL; - } - - z = -1.0; - sign = 1; - do { - - switch (*s) { - - case '\0': - if (s-start != len) { - PyErr_SetString( - PyExc_ValueError, - "complex() arg contains a null byte"); - return NULL; - } - if(!done) sw_error=1; - break; - - case '-': - sign = -1; - /* Fallthrough */ - case '+': - if (done) sw_error=1; - s++; - if ( *s=='\0'||*s=='+'||*s=='-' || - isspace(Py_CHARMASK(*s)) ) sw_error=1; - break; - - case 'J': - case 'j': - if (got_im || done) { - sw_error = 1; - break; - } - if (z<0.0) { - y=sign; - } - else{ - y=sign*z; - } - got_im=1; - s++; - if (*s!='+' && *s!='-' ) - done=1; - break; - - default: - if (isspace(Py_CHARMASK(*s))) { - while (*s && isspace(Py_CHARMASK(*s))) - s++; - if (s[0] != '\0') - sw_error=1; - else - done = 1; - break; - } - digit_or_dot = - (*s=='.' || isdigit(Py_CHARMASK(*s))); - if (done||!digit_or_dot) { - sw_error=1; - break; - } - errno = 0; - PyFPE_START_PROTECT("strtod", return 0) - z = strtod(s, &end) ; - PyFPE_END_PROTECT(z) - if (errno != 0) { - sprintf(buffer, - "float() out of range: %.150s", s); - PyErr_SetString( - PyExc_ValueError, - buffer); - return NULL; - } - s=end; - if (*s=='J' || *s=='j') { - - break; - } - if (got_re) { - sw_error=1; - break; - } - - /* accept a real part */ - x=sign*z; - got_re=1; - if (got_im) done=1; - z = -1.0; - sign = 1; - break; - - } /* end of switch */ - - } while (*s!='\0' && !sw_error); - - if (sw_error) { - PyErr_SetString(PyExc_ValueError, - "complex() arg is a malformed string"); - return NULL; - } - - return PyComplex_FromDoubles(x,y); - } - - static PyObject * - builtin_complex(PyObject *self, PyObject *args) - { - PyObject *r, *i, *tmp; - PyNumberMethods *nbr, *nbi = NULL; - Py_complex cr, ci; - int own_r = 0; - - i = NULL; - if (!PyArg_ParseTuple(args, "O|O:complex", &r, &i)) - return NULL; - if (PyString_Check(r) || PyUnicode_Check(r)) - return complex_from_string(r); - if ((nbr = r->ob_type->tp_as_number) == NULL || - nbr->nb_float == NULL || - (i != NULL && - ((nbi = i->ob_type->tp_as_number) == NULL || - nbi->nb_float == NULL))) { - PyErr_SetString(PyExc_TypeError, - "complex() arg can't be converted to complex"); - return NULL; - } - /* XXX Hack to support classes with __complex__ method */ - if (PyInstance_Check(r)) { - static PyObject *complexstr; - PyObject *f; - if (complexstr == NULL) { - complexstr = PyString_InternFromString("__complex__"); - if (complexstr == NULL) - return NULL; - } - f = PyObject_GetAttr(r, complexstr); - if (f == NULL) - PyErr_Clear(); - else { - PyObject *args = Py_BuildValue("()"); - if (args == NULL) - return NULL; - r = PyEval_CallObject(f, args); - Py_DECREF(args); - Py_DECREF(f); - if (r == NULL) - return NULL; - own_r = 1; - } - } - if (PyComplex_Check(r)) { - cr = ((PyComplexObject*)r)->cval; - if (own_r) { - Py_DECREF(r); - } - } - else { - tmp = PyNumber_Float(r); - if (own_r) { - Py_DECREF(r); - } - if (tmp == NULL) - return NULL; - if (!PyFloat_Check(tmp)) { - PyErr_SetString(PyExc_TypeError, - "float(r) didn't return a float"); - Py_DECREF(tmp); - return NULL; - } - cr.real = PyFloat_AsDouble(tmp); - Py_DECREF(tmp); - cr.imag = 0.0; - } - if (i == NULL) { - ci.real = 0.0; - ci.imag = 0.0; - } - else if (PyComplex_Check(i)) - ci = ((PyComplexObject*)i)->cval; - else { - tmp = (*nbi->nb_float)(i); - if (tmp == NULL) - return NULL; - ci.real = PyFloat_AsDouble(tmp); - Py_DECREF(tmp); - ci.imag = 0.; - } - cr.real -= ci.imag; - cr.imag += ci.real; - return PyComplex_FromCComplex(cr); - } - - static char complex_doc[] = - "complex(real[, imag]) -> complex number\n\ - \n\ - Create a complex number from a real part and an optional imaginary part.\n\ - This is equivalent to (real + imag*1j) where imag defaults to 0."; - - - #endif - - static PyObject * builtin_dir(PyObject *self, PyObject *args) { --- 372,376 ---- *************** *** 2001,2007 **** {"coerce", builtin_coerce, 1, coerce_doc}, {"compile", builtin_compile, 1, compile_doc}, - #ifndef WITHOUT_COMPLEX - {"complex", builtin_complex, 1, complex_doc}, - #endif {"delattr", builtin_delattr, 1, delattr_doc}, {"dir", builtin_dir, 1, dir_doc}, --- 1730,1733 ---- *************** *** 2038,2042 **** {"setattr", builtin_setattr, 1, setattr_doc}, {"slice", builtin_slice, 1, slice_doc}, - {"unicode", builtin_unicode, 1, unicode_doc}, {"unichr", builtin_unichr, 1, unichr_doc}, {"vars", builtin_vars, 1, vars_doc}, --- 1764,1767 ---- *************** *** 2068,2071 **** --- 1793,1801 ---- Py_NotImplemented) < 0) return NULL; + #ifndef WITHOUT_COMPLEX + if (PyDict_SetItemString(dict, "complex", + (PyObject *) &PyComplex_Type) < 0) + return NULL; + #endif if (PyDict_SetItemString(dict, "dictionary", (PyObject *) &PyDict_Type) < 0) *************** *** 2089,2092 **** --- 1819,1825 ---- return NULL; if (PyDict_SetItemString(dict, "type", (PyObject *) &PyType_Type) < 0) + return NULL; + if (PyDict_SetItemString(dict, "unicode", + (PyObject *) &PyUnicode_Type) < 0) return NULL; debug = PyInt_FromLong(Py_OptimizeFlag == 0); From tim_one@users.sourceforge.net Thu Jun 14 19:42:52 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 14 Jun 2001 11:42:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.81,1.82 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv12185/python/dist/src/Objects Modified Files: longobject.c Log Message: Change IS_LITTLE_ENDIAN macro -- a little faster now. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.81 retrieving revision 1.82 diff -C2 -r1.81 -r1.82 *** longobject.c 2001/06/14 08:53:38 1.81 --- longobject.c 2001/06/14 18:42:50 1.82 *************** *** 563,567 **** */ ! #define IS_LITTLE_ENDIAN *(char*)&one != '\0' /* Create a new long int object from a C LONG_LONG int. */ --- 563,567 ---- */ ! #define IS_LITTLE_ENDIAN (int)*(unsigned char*)&one /* Create a new long int object from a C LONG_LONG int. */ From gvanrossum@users.sourceforge.net Thu Jun 14 20:37:01 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 14 Jun 2001 12:37:01 -0700 Subject: [Python-checkins] CVS: python/dist/src LICENSE,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv24930 Modified Files: LICENSE Log Message: Note that 2.0.1 is also a PSF release. (Gregor Hoffleit, SF #433223.) Index: LICENSE =================================================================== RCS file: /cvsroot/python/python/dist/src/LICENSE,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -r1.16 -r1.17 *** LICENSE 2001/05/04 18:49:06 1.16 --- LICENSE 2001/06/14 19:36:59 1.17 *************** *** 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 From gvanrossum@users.sourceforge.net Thu Jun 14 21:48:45 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 14 Jun 2001 13:48:45 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0253.txt,1.5,1.6 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv8108 Modified Files: pep-0253.txt Log Message: More good stuff. Consider this just a checkpoint. Index: pep-0253.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0253.txt,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** pep-0253.txt 2001/06/14 13:37:45 1.5 --- pep-0253.txt 2001/06/14 20:48:43 1.6 *************** *** 78,82 **** --- 78,97 ---- release.) + In current Python, a distinction is made between types and + classes. This PEP together with pep-0254 will remove that + distinction. However, for backwards compatibility there will + probably remain a bit of a distinction for years to come, and + without pep-0254, 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 + distinction is necessary, user-defined classes can be referred to + as "classic" classes. + About metatypes *************** *** 259,262 **** --- 274,280 ---- 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 *************** *** 271,277 **** Because tp_init is in a sense optional, tp_alloc is required to do ! *some* initialization of the object. It is required to initialize ! ob_refcnt to 1 and ob_type to its type argument. To be safe, it ! should probably zero out the rest of the object. The constructor arguments are passed to tp_alloc so that for --- 289,295 ---- 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 *************** *** 489,506 **** 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": , ! ...}). ! According to the Don Beaudry hook, the following call is made: ! C = M("C", (B,), dict) (where dict is the dictionary resulting from execution of the ! 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. Note that calling M requires that M itself has a type: the --- 507,568 ---- 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": , ...}). ! I propose to rig the class statement to make the following call: ! C = M("C", (B,), dict) (where dict is the dictionary resulting from execution of the ! 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 ! inventor; it is an exceptional case that is only invoked when a ! base class is not a regular class. For a regular base class (or ! 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 ! metatype. This is called a metaclass conflict [1]. Some ! metaclass conflicts can be resolved by searching through the set ! of bases for a metatype that derives from all other given ! metatypes. If such a metatype cannot be found, an exception is ! raised and the class statement fails. ! ! 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 From twouters@users.sourceforge.net Fri Jun 15 12:58:51 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Fri, 15 Jun 2001 04:58:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules termios.c,2.24.2.3,2.24.2.4 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv18439 Modified Files: Tag: release21-maint termios.c Log Message: Protect several more uses of constants with #ifdefs; these are necessary on (at least) SCO OpenServer 5. Fixes a non-SF-submitted bugreport by Michael Kent. Index: termios.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/termios.c,v retrieving revision 2.24.2.3 retrieving revision 2.24.2.4 diff -C2 -r2.24.2.3 -r2.24.2.4 *** termios.c 2001/06/11 15:21:43 2.24.2.3 --- termios.c 2001/06/15 11:58:49 2.24.2.4 *************** *** 380,384 **** --- 380,386 ---- {"IXANY", IXANY}, {"IXOFF", IXOFF}, + #ifdef IMAXBEL {"IMAXBEL", IMAXBEL}, + #endif /* struct termios.c_oflag constants */ *************** *** 506,515 **** --- 508,523 ---- {"ECHOK", ECHOK}, {"ECHONL", ECHONL}, + #ifdef ECHOCTL {"ECHOCTL", ECHOCTL}, + #endif #ifdef ECHOPRT {"ECHOPRT", ECHOPRT}, #endif + #ifdef ECHOKE {"ECHOKE", ECHOKE}, + #endif + #endif FLUSHO {"FLUSHO", FLUSHO}, + #endif {"NOFLSH", NOFLSH}, {"TOSTOP", TOSTOP}, *************** *** 546,550 **** --- 554,560 ---- {"VWERASE", VWERASE}, #endif + #ifdef VLNEXT {"VLNEXT", VLNEXT}, + #endif {"VEOL2", VEOL2}, From twouters@users.sourceforge.net Fri Jun 15 13:05:46 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Fri, 15 Jun 2001 05:05:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules termios.c,2.30,2.31 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv19567 Modified Files: termios.c Log Message: Forward-port revision 2.24.2.4 from the release21-maint branch: Protect several more uses of constants with #ifdefs; these are necessary on (at least) SCO OpenServer 5. Fixes a non-SF-submitted bugreport by Michael Kent. Index: termios.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/termios.c,v retrieving revision 2.30 retrieving revision 2.31 diff -C2 -r2.30 -r2.31 *** termios.c 2001/06/11 15:25:16 2.30 --- termios.c 2001/06/15 12:05:44 2.31 *************** *** 380,384 **** --- 380,386 ---- {"IXANY", IXANY}, {"IXOFF", IXOFF}, + #ifdef IMAXBEL {"IMAXBEL", IMAXBEL}, + #endif /* struct termios.c_oflag constants */ *************** *** 506,515 **** --- 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}, *************** *** 546,550 **** --- 554,560 ---- {"VWERASE", VWERASE}, #endif + #ifdef VLNEXT {"VLNEXT", VLNEXT}, + #endif {"VEOL2", VEOL2}, From fdrake@users.sourceforge.net Fri Jun 15 15:13:09 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 15 Jun 2001 07:13:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libstruct.tex,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv11214/lib Modified Files: libstruct.tex Log Message: Add a version annotation for the Q and q format codes. Index: libstruct.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstruct.tex,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -r1.28 -r1.29 *** libstruct.tex 2001/06/12 01:22:21 1.28 --- libstruct.tex 2001/06/15 14:13:07 1.29 *************** *** 73,78 **** The \character{q} and \character{Q} conversion codes are available in native mode only if the platform C compiler supports C \ctype{long long}, ! or, on Windows, \ctype{__int64}. They're always available in standard modes. \end{description} --- 73,79 ---- The \character{q} and \character{Q} conversion codes are available in native mode only if the platform C compiler supports C \ctype{long long}, ! or, on Windows, \ctype{__int64}. They are always available in standard modes. + \versionadded{2.2} \end{description} From gvanrossum@users.sourceforge.net Fri Jun 15 17:43:56 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 15 Jun 2001 09:43:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib statcache.py,1.7.4.1,1.7.4.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv11217 Modified Files: Tag: release20-maint statcache.py Log Message: Fix SF #433233: syntax error. Index: statcache.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/statcache.py,v retrieving revision 1.7.4.1 retrieving revision 1.7.4.2 diff -C2 -r1.7.4.1 -r1.7.4.2 *** statcache.py 2001/03/31 13:46:33 1.7.4.1 --- statcache.py 2001/06/15 16:43:54 1.7.4.2 *************** *** 50,55 **** forget(prefix) for path in cache.keys(): ! if path.startswith(prefix) and os.path.dirname(path) == prefix: ! forget(path) def forget_except_prefix(prefix): --- 50,55 ---- forget(prefix) for path in cache.keys(): ! if path.startswith(prefix) and os.path.dirname(path) == prefix: ! forget(path) def forget_except_prefix(prefix): From gvanrossum@users.sourceforge.net Fri Jun 15 19:38:15 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 15 Jun 2001 11:38:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Grammar Grammar,1.42,1.43 Message-ID: Update of /cvsroot/python/python/dist/src/Grammar In directory usw-pr-cvs1:/tmp/cvs-serv2419 Modified Files: Grammar Log Message: Neil's generator patch, in the gen-branch. Index: Grammar =================================================================== RCS file: /cvsroot/python/python/dist/src/Grammar/Grammar,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -r1.42 -r1.43 *** Grammar 2001/02/27 18:36:14 1.42 --- Grammar 2001/06/15 18:38:13 1.43 *************** *** 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 gvanrossum@users.sourceforge.net Fri Jun 15 19:48:48 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 15 Jun 2001 11:48:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Grammar Grammar,1.42,1.42.8.1 Message-ID: Update of /cvsroot/python/python/dist/src/Grammar In directory usw-pr-cvs1:/tmp/cvs-serv4170 Modified Files: Tag: gen-branch Grammar Log Message: Neil's generator patch, in the gen-branch. Index: Grammar =================================================================== RCS file: /cvsroot/python/python/dist/src/Grammar/Grammar,v retrieving revision 1.42 retrieving revision 1.42.8.1 diff -C2 -r1.42 -r1.42.8.1 *** Grammar 2001/02/27 18:36:14 1.42 --- Grammar 2001/06/15 18:48:46 1.42.8.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 gvanrossum@users.sourceforge.net Fri Jun 15 19:56:46 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 15 Jun 2001 11:56:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects frameobject.c,2.50,2.50.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv5899/Objects Modified Files: Tag: gen-branch frameobject.c Log Message: Neil's generator patch, in the gen-branch. Index: frameobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/frameobject.c,v retrieving revision 2.50 retrieving revision 2.50.2.1 diff -C2 -r2.50 -r2.50.2.1 *** frameobject.c 2001/05/08 04:08:20 2.50 --- frameobject.c 2001/06/15 18:56:44 2.50.2.1 *************** *** 68,71 **** --- 68,72 ---- int i, slots; PyObject **fastlocals; + PyObject **p; Py_TRASHCAN_SAFE_BEGIN(f) *************** *** 77,80 **** --- 78,85 ---- } + /* Free stack */ + for (p = f->f_valuestack; p < f->f_stackbottom; p++) { + Py_XDECREF(*p); + } Py_XDECREF(f->f_back); Py_XDECREF(f->f_code); *************** *** 222,225 **** --- 227,231 ---- f->f_valuestack = f->f_localsplus + (f->f_nlocals + ncells + nfrees); + f->f_stackbottom = f->f_valuestack; return f; From gvanrossum@users.sourceforge.net Fri Jun 15 19:56:46 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 15 Jun 2001 11:56:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include compile.h,2.29,2.29.6.1 frameobject.h,2.31,2.31.6.1 graminit.h,2.16,2.16.10.1 opcode.h,2.35,2.35.4.1 symtable.h,2.7,2.7.6.1 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv5899/Include Modified Files: Tag: gen-branch compile.h frameobject.h graminit.h opcode.h symtable.h Log Message: Neil's generator patch, in the gen-branch. Index: compile.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/compile.h,v retrieving revision 2.29 retrieving revision 2.29.6.1 diff -C2 -r2.29 -r2.29.6.1 *** compile.h 2001/03/22 02:32:48 2.29 --- compile.h 2001/06/15 18:56:44 2.29.6.1 *************** *** 34,37 **** --- 34,38 ---- #define CO_VARKEYWORDS 0x0008 #define CO_NESTED 0x0010 + #define CO_GENERATOR 0x0020 extern DL_IMPORT(PyTypeObject) PyCode_Type; Index: frameobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/frameobject.h,v retrieving revision 2.31 retrieving revision 2.31.6.1 diff -C2 -r2.31 -r2.31.6.1 *** frameobject.h 2001/03/13 01:58:21 2.31 --- frameobject.h 2001/06/15 18:56:44 2.31.6.1 *************** *** 22,25 **** --- 22,27 ---- PyObject *f_locals; /* local symbol table (PyDictObject) */ PyObject **f_valuestack; /* points after the last local */ + PyObject **f_stackbottom; /* points to the last item on the stack if + frame has yielded. */ 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.10.1 diff -C2 -r2.16 -r2.16.10.1 *** graminit.h 2000/08/24 20:09:45 2.16 --- graminit.h 2001/06/15 18:56:44 2.16.10.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: opcode.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/opcode.h,v retrieving revision 2.35 retrieving revision 2.35.4.1 diff -C2 -r2.35 -r2.35.4.1 *** opcode.h 2001/04/20 19:13:01 2.35 --- opcode.h 2001/06/15 18:56:44 2.35.4.1 *************** *** 72,75 **** --- 72,76 ---- #define IMPORT_STAR 84 #define EXEC_STMT 85 + #define YIELD_VALUE 86 #define POP_BLOCK 87 Index: symtable.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/symtable.h,v retrieving revision 2.7 retrieving revision 2.7.6.1 diff -C2 -r2.7 -r2.7.6.1 *** symtable.h 2001/03/22 03:57:58 2.7 --- symtable.h 2001/06/15 18:56:44 2.7.6.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; From gvanrossum@users.sourceforge.net Fri Jun 15 19:56:46 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 15 Jun 2001 11:56:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib dis.py,1.34,1.34.4.1 inspect.py,1.16,1.16.6.1 tabnanny.py,1.13,1.13.6.1 tokenize.py,1.22,1.22.6.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv5899/Lib Modified Files: Tag: gen-branch dis.py inspect.py tabnanny.py tokenize.py Log Message: Neil's generator patch, in the gen-branch. Index: dis.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/dis.py,v retrieving revision 1.34 retrieving revision 1.34.4.1 diff -C2 -r1.34 -r1.34.4.1 *** dis.py 2001/04/20 19:13:01 1.34 --- dis.py 2001/06/15 18:56:44 1.34.4.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: inspect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/inspect.py,v retrieving revision 1.16 retrieving revision 1.16.6.1 diff -C2 -r1.16 -r1.16.6.1 *** inspect.py 2001/04/13 14:04:02 1.16 --- inspect.py 2001/06/15 18:56:44 1.16.6.1 *************** *** 350,379 **** else: return '' ! class EndOfBlock(Exception): pass ! class BlockFinder: ! """Provide a tokeneater() method to detect the end of a code block.""" ! def __init__(self): ! self.indent = 0 ! self.started = 0 ! self.last = 0 ! def tokeneater(self, type, token, (srow, scol), (erow, ecol), line): ! if not self.started: ! if type == tokenize.NAME: self.started = 1 elif type == tokenize.NEWLINE: ! self.last = srow elif type == tokenize.INDENT: ! self.indent = self.indent + 1 elif type == tokenize.DEDENT: ! self.indent = self.indent - 1 ! if self.indent == 0: raise EndOfBlock, self.last ! ! def getblock(lines): ! """Extract the block of code at the top of the given list of lines.""" ! try: ! tokenize.tokenize(ListReader(lines).readline, BlockFinder().tokeneater) ! except EndOfBlock, eob: ! return lines[:eob.args[0]] def getsourcelines(object): --- 350,375 ---- else: return '' ! def getblock(lines): ! """Extract the block of code at the top of the given list of lines.""" ! indent = 0 ! started = 0 ! last = 0 ! tokens = tokenize.generate_tokens(ListReader(lines).readline) ! for (type, token, (srow, scol), (erow, ecol), line) in tokens: ! if not started: ! if type == tokenize.NAME: ! started = 1 elif type == tokenize.NEWLINE: ! last = srow elif type == tokenize.INDENT: ! indent = indent + 1 elif type == tokenize.DEDENT: ! indent = indent - 1 ! if self.indent == 0: ! return lines[:last] ! else: ! raise ValueError, "unable to find block" def getsourcelines(object): Index: tabnanny.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/tabnanny.py,v retrieving revision 1.13 retrieving revision 1.13.6.1 diff -C2 -r1.13 -r1.13.6.1 *** tabnanny.py 2001/04/08 00:38:42 1.13 --- tabnanny.py 2001/06/15 18:56:44 1.13.6.1 *************** *** 78,84 **** print "checking", `file`, "..." - reset_globals() try: ! tokenize.tokenize(f.readline, tokeneater) except tokenize.TokenError, msg: --- 78,83 ---- print "checking", `file`, "..." try: ! process_tokens(tokenize.generate_tokens(f.readline)) except tokenize.TokenError, msg: *************** *** 245,270 **** return prefix + " " + string.join(firsts, ', ') ! # The collection of globals, the reset_globals() function, and the ! # tokeneater() function, depend on which version of tokenize is ! # in use. ! if hasattr(tokenize, 'NL'): ! # take advantage of Guido's patch! ! ! indents = [] ! check_equal = 0 ! ! def reset_globals(): ! global indents, check_equal ! check_equal = 0 ! indents = [Whitespace("")] ! ! def tokeneater(type, token, start, end, line, INDENT=tokenize.INDENT, DEDENT=tokenize.DEDENT, NEWLINE=tokenize.NEWLINE, ! JUNK=(tokenize.COMMENT, tokenize.NL) ): ! global indents, check_equal if type == NEWLINE: # a program statement, or ENDMARKER, will eventually follow, --- 244,260 ---- return prefix + " " + string.join(firsts, ', ') ! # Need Guido's enhancement ! assert hasattr(tokenize, 'NL'), "tokenize module too old" ! def process_tokens(tokens, INDENT=tokenize.INDENT, DEDENT=tokenize.DEDENT, NEWLINE=tokenize.NEWLINE, ! JUNK=(tokenize.COMMENT, tokenize.NL)): + indents = [Whitespace("")] + check_equal = 0 + + for (type, token, start, end, line) in tokens: if type == NEWLINE: # a program statement, or ENDMARKER, will eventually follow, *************** *** 312,371 **** raise NannyNag(start[0], msg, line) - else: - # unpatched version of tokenize - - nesting_level = 0 - indents = [] - check_equal = 0 - - def reset_globals(): - global nesting_level, indents, check_equal - nesting_level = check_equal = 0 - indents = [Whitespace("")] - - def tokeneater(type, token, start, end, line, - INDENT=tokenize.INDENT, - DEDENT=tokenize.DEDENT, - NEWLINE=tokenize.NEWLINE, - COMMENT=tokenize.COMMENT, - OP=tokenize.OP): - global nesting_level, indents, check_equal - - if type == INDENT: - check_equal = 0 - thisguy = Whitespace(token) - if not indents[-1].less(thisguy): - witness = indents[-1].not_less_witness(thisguy) - msg = "indent not greater e.g. " + format_witnesses(witness) - raise NannyNag(start[0], msg, line) - indents.append(thisguy) - - elif type == DEDENT: - del indents[-1] - - elif type == NEWLINE: - if nesting_level == 0: - check_equal = 1 - - elif type == COMMENT: - pass - - elif check_equal: - check_equal = 0 - thisguy = Whitespace(line) - if not indents[-1].equal(thisguy): - witness = indents[-1].not_equal_witness(thisguy) - msg = "indent not equal e.g. " + format_witnesses(witness) - raise NannyNag(start[0], msg, line) - - if type == OP and token in ('{', '[', '('): - nesting_level = nesting_level + 1 - - elif type == OP and token in ('}', ']', ')'): - if nesting_level == 0: - raise NannyNag(start[0], - "unbalanced bracket '" + token + "'", - line) - nesting_level = nesting_level - 1 if __name__ == '__main__': --- 302,305 ---- Index: tokenize.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/tokenize.py,v retrieving revision 1.22 retrieving revision 1.22.6.1 diff -C2 -r1.22 -r1.22.6.1 *** tokenize.py 2001/03/23 05:22:49 1.22 --- tokenize.py 2001/06/15 18:56:44 1.22.6.1 *************** *** 112,116 **** --- 112,121 ---- pass + # backwards compatible interface, probably not used def tokenize_loop(readline, tokeneater): + for token_info in generate_tokens(readline): + apply(tokeneater, token_info) + + def generate_tokens(readline): lnum = parenlev = continued = 0 namechars, numchars = string.letters + '_', string.digits *************** *** 130,139 **** if endmatch: pos = end = endmatch.end(0) ! tokeneater(STRING, contstr + line[:end], strstart, (lnum, end), contline + line) contstr, needcont = '', 0 contline = None elif needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n': ! tokeneater(ERRORTOKEN, contstr + line, strstart, (lnum, len(line)), contline) contstr = '' --- 135,144 ---- if endmatch: pos = end = endmatch.end(0) ! yield (STRING, contstr + line[:end], strstart, (lnum, end), contline + line) contstr, needcont = '', 0 contline = None elif needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n': ! yield (ERRORTOKEN, contstr + line, strstart, (lnum, len(line)), contline) contstr = '' *************** *** 157,161 **** if line[pos] in '#\r\n': # skip comments or blank lines ! tokeneater((NL, COMMENT)[line[pos] == '#'], line[pos:], (lnum, pos), (lnum, len(line)), line) continue --- 162,166 ---- if line[pos] in '#\r\n': # skip comments or blank lines ! yield ((NL, COMMENT)[line[pos] == '#'], line[pos:], (lnum, pos), (lnum, len(line)), line) continue *************** *** 163,170 **** if column > indents[-1]: # count indents or dedents indents.append(column) ! tokeneater(INDENT, line[:pos], (lnum, 0), (lnum, pos), line) while column < indents[-1]: indents = indents[:-1] ! tokeneater(DEDENT, '', (lnum, pos), (lnum, pos), line) else: # continued statement --- 168,175 ---- if column > indents[-1]: # count indents or dedents indents.append(column) ! yield (INDENT, line[:pos], (lnum, 0), (lnum, pos), line) while column < indents[-1]: indents = indents[:-1] ! yield (DEDENT, '', (lnum, pos), (lnum, pos), line) else: # continued statement *************** *** 182,191 **** if initial in numchars or \ (initial == '.' and token != '.'): # ordinary number ! tokeneater(NUMBER, token, spos, epos, line) elif initial in '\r\n': ! tokeneater(parenlev > 0 and NL or NEWLINE, token, spos, epos, line) elif initial == '#': ! tokeneater(COMMENT, token, spos, epos, line) elif token in ("'''", '"""', # triple-quoted "r'''", 'r"""', "R'''", 'R"""', --- 187,196 ---- if initial in numchars or \ (initial == '.' and token != '.'): # ordinary number ! yield (NUMBER, token, spos, epos, line) elif initial in '\r\n': ! yield (parenlev > 0 and NL or NEWLINE, token, spos, epos, line) elif initial == '#': ! yield (COMMENT, token, spos, epos, line) elif token in ("'''", '"""', # triple-quoted "r'''", 'r"""', "R'''", 'R"""', *************** *** 198,202 **** pos = endmatch.end(0) token = line[start:pos] ! tokeneater(STRING, token, spos, (lnum, pos), line) else: strstart = (lnum, start) # multiple lines --- 203,207 ---- pos = endmatch.end(0) token = line[start:pos] ! yield (STRING, token, spos, (lnum, pos), line) else: strstart = (lnum, start) # multiple lines *************** *** 217,223 **** break else: # ordinary string ! tokeneater(STRING, token, spos, epos, line) elif initial in namechars: # ordinary name ! tokeneater(NAME, token, spos, epos, line) elif initial == '\\': # continued stmt continued = 1 --- 222,228 ---- break else: # ordinary string ! yield (STRING, token, spos, epos, line) elif initial in namechars: # ordinary name ! yield (NAME, token, spos, epos, line) elif initial == '\\': # continued stmt continued = 1 *************** *** 225,237 **** if initial in '([{': parenlev = parenlev + 1 elif initial in ')]}': parenlev = parenlev - 1 ! tokeneater(OP, token, spos, epos, line) else: ! tokeneater(ERRORTOKEN, line[pos], (lnum, pos), (lnum, pos+1), line) pos = pos + 1 for indent in indents[1:]: # pop remaining indent levels ! tokeneater(DEDENT, '', (lnum, 0), (lnum, 0), '') ! tokeneater(ENDMARKER, '', (lnum, 0), (lnum, 0), '') if __name__ == '__main__': # testing --- 230,242 ---- if initial in '([{': parenlev = parenlev + 1 elif initial in ')]}': parenlev = parenlev - 1 ! yield (OP, token, spos, epos, line) else: ! yield (ERRORTOKEN, line[pos], (lnum, pos), (lnum, pos+1), line) pos = pos + 1 for indent in indents[1:]: # pop remaining indent levels ! yield (DEDENT, '', (lnum, 0), (lnum, 0), '') ! yield (ENDMARKER, '', (lnum, 0), (lnum, 0), '') if __name__ == '__main__': # testing From gvanrossum@users.sourceforge.net Fri Jun 15 19:56:47 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 15 Jun 2001 11:56:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.246,2.246.2.1 compile.c,2.201,2.201.2.1 graminit.c,2.28,2.28.10.1 marshal.c,1.63,1.63.2.1 symtable.c,2.4,2.4.8.1 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv5899/Python Modified Files: Tag: gen-branch ceval.c compile.c graminit.c marshal.c symtable.c Log Message: Neil's generator patch, in the gen-branch. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.246 retrieving revision 2.246.2.1 diff -C2 -r2.246 -r2.246.2.1 *** ceval.c 2001/06/08 04:33:09 2.246 --- ceval.c 2001/06/15 18:56:44 2.246.2.1 *************** *** 41,44 **** --- 41,45 ---- PyObject *); + static PyObject *eval_frame(PyFrameObject *); static char *get_func_name(PyObject *); static char *get_func_desc(PyObject *); *************** *** 107,110 **** --- 108,229 ---- + staticforward PyTypeObject gentype; + + typedef struct { + PyObject_HEAD + PyFrameObject *frame; + int running; /* true if generator is being executed */ + } genobject; + + static PyObject * + gen_new(PyFrameObject *f) + { + genobject *gen = PyObject_New(genobject, &gentype); + if (gen == NULL) { + Py_DECREF(f); + return NULL; + } + gen->frame = f; + gen->running = 0; + return (PyObject *)gen; + } + + static void + gen_dealloc(genobject *gen) + { + Py_DECREF(gen->frame); + PyObject_DEL(gen); + } + + static PyObject * + gen_iternext(genobject *gen) + { + PyFrameObject *f = gen->frame; + PyObject *result; + + if (gen->running) { + PyErr_SetString(PyExc_ValueError, + "generator already executing"); + return NULL; + } + if (f->f_stackbottom == NULL) { + return NULL; + } + gen->running = 1; + result = eval_frame(f); + gen->running = 0; + return result; + } + + static PyObject * + gen_next(genobject *gen, PyObject *args) + { + PyObject *result; + + if (!PyArg_ParseTuple(args, ":next")) + return NULL; + + result = gen_iternext(gen); + + if (result == NULL && !PyErr_Occurred()) { + PyErr_SetObject(PyExc_StopIteration, Py_None); + return NULL; + } + + return result; + } + + static PyObject * + gen_getiter(PyObject *gen) + { + Py_INCREF(gen); + return gen; + } + + static struct PyMethodDef gen_methods[] = { + {"next", (PyCFunction)gen_next, METH_VARARGS, + "next() -- get the next value, or raise StopIteration"}, + {NULL, NULL} /* Sentinel */ + }; + + static PyObject * + gen_getattr(genobject *gen, char *name) + { + return Py_FindMethod(gen_methods, (PyObject *)gen, name); + } + + 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 */ + 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, /* 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 */ + }; + + #ifdef WITH_THREAD *************** *** 338,342 **** WHY_RETURN, /* 'return' statement */ WHY_BREAK, /* 'break' statement */ ! WHY_CONTINUE /* 'continue' statement */ }; --- 457,462 ---- WHY_RETURN, /* 'return' statement */ WHY_BREAK, /* 'break' statement */ ! WHY_CONTINUE, /* 'continue' statement */ ! WHY_YIELD, /* 'yield' operator */ }; *************** *** 359,366 **** /* Interpreter main loop */ ! static PyObject * ! eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, ! PyObject **args, int argcount, PyObject **kws, int kwcount, ! PyObject **defs, int defcount, PyObject *closure) { #ifdef DXPAIRS --- 479,484 ---- /* Interpreter main loop */ ! PyObject * ! eval_frame(PyFrameObject *f) { #ifdef DXPAIRS *************** *** 379,386 **** register PyObject *t; register PyObject *stream = NULL; /* for PRINT opcodes */ - register PyFrameObject *f; /* Current frame */ register PyObject **fastlocals, **freevars; PyObject *retval = NULL; /* Return value */ PyThreadState *tstate = PyThreadState_GET(); unsigned char *first_instr; #ifdef LLTRACE --- 497,504 ---- register PyObject *t; register PyObject *stream = NULL; /* for PRINT opcodes */ register PyObject **fastlocals, **freevars; PyObject *retval = NULL; /* Return value */ PyThreadState *tstate = PyThreadState_GET(); + PyCodeObject *co; unsigned char *first_instr; #ifdef LLTRACE *************** *** 389,393 **** #if defined(Py_DEBUG) || defined(LLTRACE) /* Make it easier to find out where we are with a debugger */ ! char *filename = PyString_AsString(co->co_filename); #endif --- 507,511 ---- #if defined(Py_DEBUG) || defined(LLTRACE) /* Make it easier to find out where we are with a debugger */ ! char *filename; #endif *************** *** 427,430 **** --- 545,551 ---- /* Start of code */ + if (f == NULL) + return NULL; + #ifdef USE_STACKCHECK if (tstate->recursion_depth%10 == 0 && PyOS_CheckStack()) { *************** *** 433,675 **** } #endif - - if (globals == NULL) { - PyErr_SetString(PyExc_SystemError, "eval_code2: NULL globals"); - return NULL; - } - - #ifdef LLTRACE - lltrace = PyDict_GetItemString(globals, "__lltrace__") != NULL; - #endif - - f = PyFrame_New(tstate, /*back*/ - co, /*code*/ - globals, locals); - if (f == NULL) - return NULL; - - tstate->frame = f; - fastlocals = f->f_localsplus; - freevars = f->f_localsplus + f->f_nlocals; - - if (co->co_argcount > 0 || - co->co_flags & (CO_VARARGS | CO_VARKEYWORDS)) { - int i; - int n = argcount; - PyObject *kwdict = NULL; - if (co->co_flags & CO_VARKEYWORDS) { - kwdict = PyDict_New(); - if (kwdict == NULL) - goto fail; - i = co->co_argcount; - if (co->co_flags & CO_VARARGS) - i++; - SETLOCAL(i, kwdict); - } - if (argcount > co->co_argcount) { - if (!(co->co_flags & CO_VARARGS)) { - PyErr_Format(PyExc_TypeError, - "%.200s() takes %s %d " - "%sargument%s (%d given)", - PyString_AsString(co->co_name), - defcount ? "at most" : "exactly", - co->co_argcount, - kwcount ? "non-keyword " : "", - co->co_argcount == 1 ? "" : "s", - argcount); - goto fail; - } - n = co->co_argcount; - } - for (i = 0; i < n; i++) { - x = args[i]; - Py_INCREF(x); - SETLOCAL(i, x); - } - if (co->co_flags & CO_VARARGS) { - u = PyTuple_New(argcount - n); - if (u == NULL) - goto fail; - SETLOCAL(co->co_argcount, u); - for (i = n; i < argcount; i++) { - x = args[i]; - Py_INCREF(x); - PyTuple_SET_ITEM(u, i-n, x); - } - } - for (i = 0; i < kwcount; i++) { - PyObject *keyword = kws[2*i]; - PyObject *value = kws[2*i + 1]; - int j; - if (keyword == NULL || !PyString_Check(keyword)) { - PyErr_Format(PyExc_TypeError, - "%.200s() keywords must be strings", - PyString_AsString(co->co_name)); - goto fail; - } - /* XXX slow -- speed up using dictionary? */ - for (j = 0; j < co->co_argcount; j++) { - PyObject *nm = PyTuple_GET_ITEM( - co->co_varnames, j); - int cmp = PyObject_RichCompareBool( - keyword, nm, Py_EQ); - if (cmp > 0) - break; - else if (cmp < 0) - goto fail; - } - /* Check errors from Compare */ - if (PyErr_Occurred()) - goto fail; - if (j >= co->co_argcount) { - if (kwdict == NULL) { - PyErr_Format(PyExc_TypeError, - "%.200s() got an unexpected " - "keyword argument '%.400s'", - PyString_AsString(co->co_name), - PyString_AsString(keyword)); - goto fail; - } - PyDict_SetItem(kwdict, keyword, value); - } - else { - if (GETLOCAL(j) != NULL) { - PyErr_Format(PyExc_TypeError, - "%.200s() got multiple " - "values for keyword " - "argument '%.400s'", - PyString_AsString(co->co_name), - PyString_AsString(keyword)); - goto fail; - } - Py_INCREF(value); - SETLOCAL(j, value); - } - } - if (argcount < co->co_argcount) { - int m = co->co_argcount - defcount; - for (i = argcount; i < m; i++) { - if (GETLOCAL(i) == NULL) { - PyErr_Format(PyExc_TypeError, - "%.200s() takes %s %d " - "%sargument%s (%d given)", - PyString_AsString(co->co_name), - ((co->co_flags & CO_VARARGS) || - defcount) ? "at least" - : "exactly", - m, kwcount ? "non-keyword " : "", - m == 1 ? "" : "s", i); - goto fail; - } - } - if (n > m) - i = n - m; - else - i = 0; - for (; i < defcount; i++) { - if (GETLOCAL(m+i) == NULL) { - PyObject *def = defs[i]; - Py_INCREF(def); - SETLOCAL(m+i, def); - } - } - } - } - else { - if (argcount > 0 || kwcount > 0) { - PyErr_Format(PyExc_TypeError, - "%.200s() takes no arguments (%d given)", - PyString_AsString(co->co_name), - argcount + kwcount); - goto fail; - } - } - /* Allocate and initialize storage for cell vars, and copy free - vars into frame. This isn't too efficient right now. */ - if (f->f_ncells) { - int i = 0, j = 0, nargs, found; - char *cellname, *argname; - PyObject *c; - - nargs = co->co_argcount; - if (co->co_flags & CO_VARARGS) - nargs++; - if (co->co_flags & CO_VARKEYWORDS) - nargs++; ! /* Check for cells that shadow args */ ! for (i = 0; i < f->f_ncells && j < nargs; ++i) { ! cellname = PyString_AS_STRING( ! PyTuple_GET_ITEM(co->co_cellvars, i)); ! found = 0; ! while (j < nargs) { ! argname = PyString_AS_STRING( ! PyTuple_GET_ITEM(co->co_varnames, j)); ! if (strcmp(cellname, argname) == 0) { ! c = PyCell_New(GETLOCAL(j)); ! if (c == NULL) ! goto fail; ! GETLOCAL(f->f_nlocals + i) = c; ! found = 1; ! break; ! } ! j++; ! } ! if (found == 0) { ! c = PyCell_New(NULL); ! if (c == NULL) ! goto fail; ! SETLOCAL(f->f_nlocals + i, c); ! } ! } ! /* Initialize any that are left */ ! while (i < f->f_ncells) { ! c = PyCell_New(NULL); ! if (c == NULL) ! goto fail; ! SETLOCAL(f->f_nlocals + i, c); ! i++; ! } ! } ! if (f->f_nfreevars) { ! int i; ! for (i = 0; i < f->f_nfreevars; ++i) { ! PyObject *o = PyTuple_GET_ITEM(closure, i); ! Py_INCREF(o); ! freevars[f->f_ncells + i] = o; ! } ! } ! ! if (tstate->sys_tracefunc != NULL) { ! /* 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->sys_tracefunc, ! &f->f_trace, f, "call", &str_call, ! Py_None/*XXX how to compute arguments now?*/)) { ! /* Trace function raised an error */ ! goto fail; ! } ! } ! ! if (tstate->sys_profilefunc != NULL) { ! /* Similar for sys_profilefunc, except it needn't return ! itself and isn't called for "line" events */ ! if (call_trace(&tstate->sys_profilefunc, ! (PyObject**)0, f, "call", &str_call, ! Py_None/*XXX*/)) { ! goto fail; ! } ! } ! if (++tstate->recursion_depth > recursion_limit) { --tstate->recursion_depth; --- 554,559 ---- } #endif ! /* push frame */ if (++tstate->recursion_depth > recursion_limit) { --tstate->recursion_depth; *************** *** 677,687 **** "maximum recursion depth exceeded"); tstate->frame = f->f_back; - Py_DECREF(f); return NULL; } _PyCode_GETCODEPTR(co, &first_instr); ! next_instr = first_instr; ! stack_pointer = f->f_valuestack; why = WHY_NOT; --- 561,584 ---- "maximum recursion depth exceeded"); tstate->frame = f->f_back; return NULL; } + f->f_back = tstate->frame; + tstate->frame = f; + + co = f->f_code; + fastlocals = f->f_localsplus; + freevars = f->f_localsplus + f->f_nlocals; _PyCode_GETCODEPTR(co, &first_instr); ! next_instr = first_instr + f->f_lasti; ! stack_pointer = f->f_stackbottom; ! f->f_stackbottom = NULL; ! ! #ifdef LLTRACE ! lltrace = PyDict_GetItemString(f->f_globals,"__lltrace__") != NULL; ! #endif ! #if defined(Py_DEBUG) || defined(LLTRACE) ! filename = PyString_AsString(co->co_filename); ! #endif why = WHY_NOT; *************** *** 1460,1463 **** --- 1357,1368 ---- break; + case YIELD_VALUE: + retval = POP(); + f->f_stackbottom = stack_pointer; + f->f_lasti = INSTR_OFFSET(); + why = WHY_YIELD; + break; + + case EXEC_STMT: w = POP(); *************** *** 1485,1488 **** --- 1390,1394 ---- why = (enum why_code) PyInt_AsLong(v); if (why == WHY_RETURN || + why == WHY_YIELD || why == CONTINUE_LOOP) retval = POP(); *************** *** 2226,2230 **** /* Unwind stacks if a (pseudo) exception occurred */ ! while (why != WHY_NOT && f->f_iblock > 0) { PyTryBlock *b = PyFrame_BlockPop(f); --- 2132,2136 ---- /* Unwind stacks if a (pseudo) exception occurred */ ! while (why != WHY_NOT && why != WHY_YIELD && f->f_iblock > 0) { PyTryBlock *b = PyFrame_BlockPop(f); *************** *** 2296,2309 **** /* Pop remaining stack entries */ while (!EMPTY()) { v = POP(); Py_XDECREF(v); } ! if (why != WHY_RETURN) retval = NULL; if (f->f_trace) { ! if (why == WHY_RETURN) { if (call_trace(&f->f_trace, &f->f_trace, f, "return", &str_return, retval)) { --- 2202,2217 ---- /* Pop remaining stack entries */ + /* while (!EMPTY()) { v = POP(); Py_XDECREF(v); } + */ ! if (why != WHY_RETURN && why != WHY_YIELD) retval = NULL; if (f->f_trace) { ! if (why == WHY_RETURN || why == WHY_YIELD) { if (call_trace(&f->f_trace, &f->f_trace, f, "return", &str_return, retval)) { *************** *** 2315,2319 **** } ! if (tstate->sys_profilefunc && why == WHY_RETURN) { if (call_trace(&tstate->sys_profilefunc, (PyObject**)0, f, "return", &str_return, retval)) { --- 2223,2228 ---- } ! if (tstate->sys_profilefunc && ! (why == WHY_RETURN || why == WHY_YIELD)) { if (call_trace(&tstate->sys_profilefunc, (PyObject**)0, f, "return", &str_return, retval)) { *************** *** 2326,2340 **** reset_exc_info(tstate); --tstate->recursion_depth; ! fail: /* Jump here from prelude on failure */ ! /* Restore previous frame and release the current one */ ! tstate->frame = f->f_back; ! Py_DECREF(f); return retval; } static void --- 2235,2503 ---- reset_exc_info(tstate); + /* pop frame */ --tstate->recursion_depth; + tstate->frame = f->f_back; ! return retval; ! } ! ! static PyObject * ! eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, ! PyObject **args, int argcount, PyObject **kws, int kwcount, ! PyObject **defs, int defcount, PyObject *closure) ! { ! register PyFrameObject *f; ! register PyObject *retval = NULL; ! register PyObject **fastlocals, **freevars; ! PyThreadState *tstate = PyThreadState_GET(); ! PyObject *x, *u; ! if (globals == NULL) { ! PyErr_SetString(PyExc_SystemError, "eval_code2: NULL globals"); ! return NULL; ! } ! f = PyFrame_New(tstate, /*back*/ ! co, /*code*/ ! globals, locals); ! if (f == NULL) ! return NULL; ! ! fastlocals = f->f_localsplus; ! freevars = f->f_localsplus + f->f_nlocals; ! ! if (co->co_argcount > 0 || ! co->co_flags & (CO_VARARGS | CO_VARKEYWORDS)) { ! int i; ! int n = argcount; ! PyObject *kwdict = NULL; ! if (co->co_flags & CO_VARKEYWORDS) { ! kwdict = PyDict_New(); ! if (kwdict == NULL) ! goto fail; ! i = co->co_argcount; ! if (co->co_flags & CO_VARARGS) ! i++; ! SETLOCAL(i, kwdict); ! } ! if (argcount > co->co_argcount) { ! if (!(co->co_flags & CO_VARARGS)) { ! PyErr_Format(PyExc_TypeError, ! "%.200s() takes %s %d " ! "%sargument%s (%d given)", ! PyString_AsString(co->co_name), ! defcount ? "at most" : "exactly", ! co->co_argcount, ! kwcount ? "non-keyword " : "", ! co->co_argcount == 1 ? "" : "s", ! argcount); ! goto fail; ! } ! n = co->co_argcount; ! } ! for (i = 0; i < n; i++) { ! x = args[i]; ! Py_INCREF(x); ! SETLOCAL(i, x); ! } ! if (co->co_flags & CO_VARARGS) { ! u = PyTuple_New(argcount - n); ! if (u == NULL) ! goto fail; ! SETLOCAL(co->co_argcount, u); ! for (i = n; i < argcount; i++) { ! x = args[i]; ! Py_INCREF(x); ! PyTuple_SET_ITEM(u, i-n, x); ! } ! } ! for (i = 0; i < kwcount; i++) { ! PyObject *keyword = kws[2*i]; ! PyObject *value = kws[2*i + 1]; ! int j; ! if (keyword == NULL || !PyString_Check(keyword)) { ! PyErr_Format(PyExc_TypeError, ! "%.200s() keywords must be strings", ! PyString_AsString(co->co_name)); ! goto fail; ! } ! /* XXX slow -- speed up using dictionary? */ ! for (j = 0; j < co->co_argcount; j++) { ! PyObject *nm = PyTuple_GET_ITEM( ! co->co_varnames, j); ! int cmp = PyObject_RichCompareBool( ! keyword, nm, Py_EQ); ! if (cmp > 0) ! break; ! else if (cmp < 0) ! goto fail; ! } ! /* Check errors from Compare */ ! if (PyErr_Occurred()) ! goto fail; ! if (j >= co->co_argcount) { ! if (kwdict == NULL) { ! PyErr_Format(PyExc_TypeError, ! "%.200s() got an unexpected " ! "keyword argument '%.400s'", ! PyString_AsString(co->co_name), ! PyString_AsString(keyword)); ! goto fail; ! } ! PyDict_SetItem(kwdict, keyword, value); ! } ! else { ! if (GETLOCAL(j) != NULL) { ! PyErr_Format(PyExc_TypeError, ! "%.200s() got multiple " ! "values for keyword " ! "argument '%.400s'", ! PyString_AsString(co->co_name), ! PyString_AsString(keyword)); ! goto fail; ! } ! Py_INCREF(value); ! SETLOCAL(j, value); ! } ! } ! if (argcount < co->co_argcount) { ! int m = co->co_argcount - defcount; ! for (i = argcount; i < m; i++) { ! if (GETLOCAL(i) == NULL) { ! PyErr_Format(PyExc_TypeError, ! "%.200s() takes %s %d " ! "%sargument%s (%d given)", ! PyString_AsString(co->co_name), ! ((co->co_flags & CO_VARARGS) || ! defcount) ? "at least" ! : "exactly", ! m, kwcount ? "non-keyword " : "", ! m == 1 ? "" : "s", i); ! goto fail; ! } ! } ! if (n > m) ! i = n - m; ! else ! i = 0; ! for (; i < defcount; i++) { ! if (GETLOCAL(m+i) == NULL) { ! PyObject *def = defs[i]; ! Py_INCREF(def); ! SETLOCAL(m+i, def); ! } ! } ! } ! } ! else { ! if (argcount > 0 || kwcount > 0) { ! PyErr_Format(PyExc_TypeError, ! "%.200s() takes no arguments (%d given)", ! PyString_AsString(co->co_name), ! argcount + kwcount); ! goto fail; ! } ! } ! /* Allocate and initialize storage for cell vars, and copy free ! vars into frame. This isn't too efficient right now. */ ! if (f->f_ncells) { ! int i = 0, j = 0, nargs, found; ! char *cellname, *argname; ! PyObject *c; ! ! nargs = co->co_argcount; ! if (co->co_flags & CO_VARARGS) ! nargs++; ! if (co->co_flags & CO_VARKEYWORDS) ! nargs++; ! ! /* Check for cells that shadow args */ ! for (i = 0; i < f->f_ncells && j < nargs; ++i) { ! cellname = PyString_AS_STRING( ! PyTuple_GET_ITEM(co->co_cellvars, i)); ! found = 0; ! while (j < nargs) { ! argname = PyString_AS_STRING( ! PyTuple_GET_ITEM(co->co_varnames, j)); ! if (strcmp(cellname, argname) == 0) { ! c = PyCell_New(GETLOCAL(j)); ! if (c == NULL) ! goto fail; ! GETLOCAL(f->f_nlocals + i) = c; ! found = 1; ! break; ! } ! j++; ! } ! if (found == 0) { ! c = PyCell_New(NULL); ! if (c == NULL) ! goto fail; ! SETLOCAL(f->f_nlocals + i, c); ! } ! } ! /* Initialize any that are left */ ! while (i < f->f_ncells) { ! c = PyCell_New(NULL); ! if (c == NULL) ! goto fail; ! SETLOCAL(f->f_nlocals + i, c); ! i++; ! } ! } ! if (f->f_nfreevars) { ! int i; ! for (i = 0; i < f->f_nfreevars; ++i) { ! PyObject *o = PyTuple_GET_ITEM(closure, i); ! Py_INCREF(o); ! freevars[f->f_ncells + i] = o; ! } ! } ! ! if (tstate->sys_tracefunc != NULL) { ! /* 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->sys_tracefunc, ! &f->f_trace, f, "call", &str_call, ! Py_None/*XXX how to compute arguments now?*/)) { ! /* Trace function raised an error */ ! goto fail; ! } ! } + if (tstate->sys_profilefunc != NULL) { + /* Similar for sys_profilefunc, except it needn't return + itself and isn't called for "line" events */ + if (call_trace(&tstate->sys_profilefunc, + (PyObject**)0, f, "call", &str_call, + Py_None/*XXX*/)) { + goto fail; + } + } + + if (co->co_flags & CO_GENERATOR) { + /* create a new generator that owns the ready to run frame + * and return that as the value */ + return gen_new(f); + } + + retval = eval_frame(f); + + fail: /* Jump here from prelude on failure */ + + Py_DECREF(f); return retval; } + static void Index: compile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v retrieving revision 2.201 retrieving revision 2.201.2.1 diff -C2 -r2.201 -r2.201.2.1 *** compile.c 2001/06/09 09:26:21 2.201 --- compile.c 2001/06/15 18:56:44 2.201.2.1 *************** *** 2635,2649 **** com_error(c, PyExc_SyntaxError, "'return' outside function"); } ! if (NCH(n) < 2) { ! com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None)); com_push(c, 1); } ! else ! com_node(c, CHILD(n, 1)); ! com_addbyte(c, RETURN_VALUE); com_pop(c, 1); } static void com_raise_stmt(struct compiling *c, node *n) { --- 2635,2673 ---- 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"); ! } ! com_addoparg(c, LOAD_CONST, ! com_addconst(c, PyExc_StopIteration)); com_push(c, 1); + com_addoparg(c, RAISE_VARARGS, 1); } ! else { ! if (NCH(n) < 2) { ! com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None)); ! com_push(c, 1); ! } ! else ! com_node(c, CHILD(n, 1)); ! com_addbyte(c, RETURN_VALUE); ! } com_pop(c, 1); } static void + com_yield_stmt(struct compiling *c, node *n) + { + REQ(n, yield_stmt); /* 'yield' testlist */ + if (!c->c_infunction) { + com_error(c, PyExc_SyntaxError, "'yield' outside function"); + } + 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) { *************** *** 3456,3459 **** --- 3480,3486 ---- com_return_stmt(c, n); break; + case yield_stmt: + com_yield_stmt(c, n); + break; case raise_stmt: com_raise_stmt(c, n); *************** *** 3675,3682 **** com_node(c, CHILD(n, 4)); c->c_infunction = 0; ! com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None)); ! com_push(c, 1); ! com_addbyte(c, RETURN_VALUE); ! com_pop(c, 1); } --- 3702,3718 ---- com_node(c, CHILD(n, 4)); c->c_infunction = 0; ! if (c->c_flags & CO_GENERATOR) { ! com_addoparg(c, LOAD_CONST, ! com_addconst(c, PyExc_StopIteration)); ! com_push(c, 1); ! com_addoparg(c, RAISE_VARARGS, 1); ! com_pop(c, 1); ! } ! else { ! com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None)); ! com_push(c, 1); ! com_addbyte(c, RETURN_VALUE); ! com_pop(c, 1); ! } } *************** *** 4343,4346 **** --- 4379,4384 ---- 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; *************** *** 4901,4904 **** --- 4939,4946 ---- 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: graminit.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/graminit.c,v retrieving revision 2.28 retrieving revision 2.28.10.1 diff -C2 -r2.28 -r2.28.10.1 *** graminit.c 2000/08/24 20:11:32 2.28 --- graminit.c 2001/06/15 18:56:44 2.28.10.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: marshal.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/marshal.c,v retrieving revision 1.63 retrieving revision 1.63.2.1 diff -C2 -r1.63 -r1.63.2.1 *** marshal.c 2001/05/08 15:19:57 1.63 --- marshal.c 2001/06/15 18:56:45 1.63.2.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); *************** *** 376,379 **** --- 380,387 ---- Py_INCREF(Py_None); return Py_None; + + case TYPE_STOPITER: + Py_INCREF(PyExc_StopIteration); + return PyExc_StopIteration; case TYPE_ELLIPSIS: Index: symtable.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/symtable.c,v retrieving revision 2.4 retrieving revision 2.4.8.1 diff -C2 -r2.4 -r2.4.8.1 *** symtable.c 2001/02/27 19:07:02 2.4 --- symtable.c 2001/06/15 18:56:45 2.4.8.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) From tim_one@users.sourceforge.net Fri Jun 15 21:50:44 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 15 Jun 2001 13:50:44 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0255.txt,1.3,1.4 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv29269/python/nondist/peps Modified Files: pep-0255.txt Log Message: Added pointer to the gen-branch of the CVS tree. Index: pep-0255.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0255.txt,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** pep-0255.txt 2001/06/14 16:06:02 1.3 --- pep-0255.txt 2001/06/15 20:50:42 1.4 *************** *** 250,256 **** Reference Implementation ! A preliminary patch against the CVS Python source is available[7]. Footnotes and References --- 250,260 ---- Reference Implementation ! A preliminary implementation is available as the gen-branch of the ! Python CVS tree on SourceForge[9]. Using this requires that you ! build Python from source. + This was derived from an earlier patch by Neil Schemenauer[7]. + Footnotes and References *************** *** 266,269 **** --- 270,275 ---- [7] http://python.ca/nas/python/generator.diff [8] http://python.sf.net/peps/pep-0236.html + [9] The reference implementation is on the gen-branch of Python CVS: + http://sf.net/cvs/?group_id=5470 From fdrake@users.sourceforge.net Fri Jun 15 22:32:00 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 15 Jun 2001 14:32:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/perl python.perl,1.101,1.102 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/perl In directory usw-pr-cvs1:/tmp/cvs-serv5388/perl Modified Files: python.perl Log Message: Implement the \verbatiminput LaTeX macro; this contains more magic than it should, but only enough that LaTeX2HTML doesn't bite us. Index: python.perl =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/perl/python.perl,v retrieving revision 1.101 retrieving revision 1.102 diff -C2 -r1.101 -r1.102 *** python.perl 2001/05/11 01:00:30 1.101 --- python.perl 2001/06/15 21:31:57 1.102 *************** *** 1661,1664 **** --- 1661,1710 ---- } + sub do_cmd_verbatiminput{ + local($_) = @_; + my $fname = next_argument(); + my $file; + my $found = 0; + my $texpath; + # Search TEXINPUTS for the input file, the way we're supposed to: + foreach $texpath (split /$envkey/, $TEXINPUTS) { + $file = "$texpath$dd$fname"; + last if ($found = (-f $file)); + } + my $text; + if ($found) { + open(MYFILE, "<$file") || die "\n$!\n"; + read(MYFILE, $text, 1024*1024); + close(MYFILE); + # + # These rewrites convert the raw text to something that will + # be properly visible as HTML and also will pass through the + # vagaries of conversion through LaTeX2HTML. The order in + # which the specific rewrites are performed is significant. + # + $text =~ s/\&/\&/g; + # These need to happen before the normal < and > re-writes, + # since we need to avoid LaTeX2HTML's attempt to perform + # ligature processing without regard to context (since it + # doesn't have font information). + $text =~ s/--/-&\#45;/g; + $text =~ s/<>/\>\&\#62;/g; + # Just normal re-writes... + $text =~ s//\>/g; + # These last isn't needed for the HTML, but is needed to get + # past LaTeX2HTML processing TeX macros. We use \ instead + # of / since many browsers don't support that. + $text =~ s/\\/\&\#92;/g; + } + else { + $text = 'Could not locate requested file $fname!\n'; + } + return ($alltt_start + . $text + . $alltt_end + . $_); + } 1; # This must be the last line From tim_one@users.sourceforge.net Fri Jun 15 22:37:17 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 15 Jun 2001 14:37:17 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0255.txt,1.4,1.5 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv6331/python/nondist/peps Modified Files: pep-0255.txt Log Message: Add branch-retrieval instructions, adapted from PEP 253. Index: pep-0255.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0255.txt,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** pep-0255.txt 2001/06/15 20:50:42 1.4 --- pep-0255.txt 2001/06/15 21:37:15 1.5 *************** *** 270,275 **** [7] http://python.ca/nas/python/generator.diff [8] http://python.sf.net/peps/pep-0236.html ! [9] The reference implementation is on the gen-branch of Python CVS: ! http://sf.net/cvs/?group_id=5470 --- 270,279 ---- [7] http://python.ca/nas/python/generator.diff [8] http://python.sf.net/peps/pep-0236.html ! [9] To experiment with this implementation, proceed to check out ! Python from CVS according to the instructions at ! http://sf.net/cvs/?group_id=5470 ! but add the arguments "-r gen-branch" to the cvs checkout command. ! You can also start with an existing checkout and do ! cvs update -r gen-branch From tim_one@users.sourceforge.net Sat Jun 16 01:09:30 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 15 Jun 2001 17:09:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.246,2.247 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv32542/python/dist/src/Python Modified Files: ceval.c Log Message: SF bug 433228: repr(list) woes when len(list) big call_object: If the object isn't callable, display its type in the error msg rather than its repr. Bugfix candidate. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.246 retrieving revision 2.247 diff -C2 -r2.246 -r2.247 *** ceval.c 2001/06/08 04:33:09 2.246 --- ceval.c 2001/06/16 00:09:28 2.247 *************** *** 2863,2868 **** result = (*call)(func, arg, kw); else { ! PyErr_Format(PyExc_TypeError, "object is not callable: %s", ! PyString_AS_STRING(PyObject_Repr(func))); return NULL; } --- 2863,2869 ---- result = (*call)(func, arg, kw); else { ! PyErr_Format(PyExc_TypeError, ! "object of type '%.100s' is not callable", ! func->ob_type->tp_name); return NULL; } From tim_one@users.sourceforge.net Sat Jun 16 06:11:19 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 15 Jun 2001 22:11:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include stringobject.h,2.27,2.28 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv12913/python/dist/src/Include Modified Files: stringobject.h Log Message: SF bug 433228: repr(list) woes when len(list) big. Gave Python linear-time repr() implementations for dicts, lists, strings. This means, e.g., that repr(range(50000)) is no longer 50x slower than pprint.pprint() in 2.2 . I don't consider this a bugfix candidate, as it's a performance boost. Added _PyString_Join() to the internal string API. If we want that in the public API, fine, but then it requires runtime error checks instead of asserts. Index: stringobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/stringobject.h,v retrieving revision 2.27 retrieving revision 2.28 diff -C2 -r2.27 -r2.28 *** stringobject.h 2001/05/24 16:56:35 2.27 --- stringobject.h 2001/06/16 05:11:17 2.28 *************** *** 78,81 **** --- 78,85 ---- #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 ----------------------------------------------------- */ From tim_one@users.sourceforge.net Sat Jun 16 06:11:20 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 15 Jun 2001 22:11:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.103,2.104 listobject.c,2.95,2.96 stringobject.c,2.118,2.119 tupleobject.c,2.52,2.53 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv12913/python/dist/src/Objects Modified Files: dictobject.c listobject.c stringobject.c tupleobject.c Log Message: SF bug 433228: repr(list) woes when len(list) big. Gave Python linear-time repr() implementations for dicts, lists, strings. This means, e.g., that repr(range(50000)) is no longer 50x slower than pprint.pprint() in 2.2 . I don't consider this a bugfix candidate, as it's a performance boost. Added _PyString_Join() to the internal string API. If we want that in the public API, fine, but then it requires runtime error checks instead of asserts. Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.103 retrieving revision 2.104 diff -C2 -r2.103 -r2.104 *** dictobject.c 2001/06/04 21:00:21 2.103 --- dictobject.c 2001/06/16 05:11:17 2.104 *************** *** 810,849 **** dict_repr(dictobject *mp) { ! auto PyObject *v; ! PyObject *sepa, *colon; ! register int i; ! register int any; ! i = Py_ReprEnter((PyObject*)mp); if (i != 0) { ! if (i > 0) ! return PyString_FromString("{...}"); ! return NULL; } ! v = PyString_FromString("{"); ! sepa = PyString_FromString(", "); colon = PyString_FromString(": "); ! any = 0; ! for (i = 0; i <= mp->ma_mask && v; i++) { ! dictentry *ep = mp->ma_table + i; ! PyObject *pvalue = ep->me_value; ! if (pvalue != NULL) { ! /* Prevent PyObject_Repr from deleting value during ! key format */ ! Py_INCREF(pvalue); ! if (any++) ! PyString_Concat(&v, sepa); ! PyString_ConcatAndDel(&v, PyObject_Repr(ep->me_key)); ! PyString_Concat(&v, colon); ! PyString_ConcatAndDel(&v, PyObject_Repr(pvalue)); ! Py_DECREF(pvalue); ! } } ! PyString_ConcatAndDel(&v, PyString_FromString("}")); ! Py_ReprLeave((PyObject*)mp); ! Py_XDECREF(sepa); Py_XDECREF(colon); ! return v; } --- 810,887 ---- dict_repr(dictobject *mp) { ! int i, pos; ! PyObject *s, *temp, *colon = NULL; ! PyObject *pieces = NULL, *result = NULL; ! PyObject *key, *value; ! i = Py_ReprEnter((PyObject *)mp); if (i != 0) { ! return i > 0 ? PyString_FromString("{...}") : NULL; } ! if (mp->ma_used == 0) { ! result = PyString_FromString("{}"); ! goto Done; ! } ! ! pieces = PyList_New(0); ! if (pieces == NULL) ! goto Done; ! colon = PyString_FromString(": "); ! if (colon == NULL) ! goto Done; ! ! /* Do repr() on each key+value pair, and insert ": " between them. ! Note that repr may mutate the dict. */ ! pos = 0; ! while (PyDict_Next((PyObject *)mp, &pos, &key, &value)) { ! int status; ! /* Prevent repr from deleting value during key format. */ ! Py_INCREF(value); ! s = PyObject_Repr(key); ! PyString_Concat(&s, colon); ! PyString_ConcatAndDel(&s, PyObject_Repr(value)); ! Py_DECREF(value); ! 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_XDECREF(colon); ! Py_ReprLeave((PyObject *)mp); ! return result; } Index: listobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v retrieving revision 2.95 retrieving revision 2.96 diff -C2 -r2.95 -r2.96 *** listobject.c 2001/05/26 19:37:54 2.95 --- listobject.c 2001/06/16 05:11:17 2.96 *************** *** 247,270 **** 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; } Index: stringobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v retrieving revision 2.118 retrieving revision 2.119 diff -C2 -r2.118 -r2.119 *** stringobject.c 2001/06/12 13:14:10 2.118 --- stringobject.c 2001/06/16 05:11:17 2.119 *************** *** 1032,1035 **** --- 1032,1052 ---- } + 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) Index: tupleobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/tupleobject.c,v retrieving revision 2.52 retrieving revision 2.53 diff -C2 -r2.52 -r2.53 *** tupleobject.c 2001/05/29 07:58:45 2.52 --- tupleobject.c 2001/06/16 05:11:17 2.53 *************** *** 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; } From tim_one@users.sourceforge.net Sat Jun 16 06:42:59 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 15 Jun 2001 22:42:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.184,1.185 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv19395/python/dist/src/Misc Modified Files: NEWS Log Message: Reformat decl of new _PyString_Join. Add NEWS blurb about repr() speedup. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.184 retrieving revision 1.185 diff -C2 -r1.184 -r1.185 *** NEWS 2001/06/12 16:48:52 1.184 --- NEWS 2001/06/16 05:42:57 1.185 *************** *** 127,130 **** --- 127,133 ---- the nature of an effective cure (last December! better late than never). + - repr() is much faster for large containers (dict, list, tuple). + + Library From tim_one@users.sourceforge.net Sat Jun 16 06:42:59 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 15 Jun 2001 22:42:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects stringobject.c,2.119,2.120 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv19395/python/dist/src/Objects Modified Files: stringobject.c Log Message: Reformat decl of new _PyString_Join. Add NEWS blurb about repr() speedup. Index: stringobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v retrieving revision 2.119 retrieving revision 2.120 diff -C2 -r2.119 -r2.120 *** stringobject.c 2001/06/16 05:11:17 2.119 --- stringobject.c 2001/06/16 05:42:57 2.120 *************** *** 1032,1036 **** } ! PyObject *_PyString_Join(PyObject *sep, PyObject *x) { PyObject* args; --- 1032,1037 ---- } ! PyObject * ! _PyString_Join(PyObject *sep, PyObject *x) { PyObject* args; From tim_one@users.sourceforge.net Sat Jun 16 08:52:55 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 16 Jun 2001 00:52:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.104,2.105 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv9907/python/dist/src/Objects Modified Files: dictobject.c Log Message: dict_repr: Reuse one of the int vars (minor code simplification). Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.104 retrieving revision 2.105 diff -C2 -r2.104 -r2.105 *** dictobject.c 2001/06/16 05:11:17 2.104 --- dictobject.c 2001/06/16 07:52:53 2.105 *************** *** 810,814 **** dict_repr(dictobject *mp) { ! int i, pos; PyObject *s, *temp, *colon = NULL; PyObject *pieces = NULL, *result = NULL; --- 810,814 ---- dict_repr(dictobject *mp) { ! int i; PyObject *s, *temp, *colon = NULL; PyObject *pieces = NULL, *result = NULL; *************** *** 835,840 **** /* Do repr() on each key+value pair, and insert ": " between them. Note that repr may mutate the dict. */ ! pos = 0; ! while (PyDict_Next((PyObject *)mp, &pos, &key, &value)) { int status; /* Prevent repr from deleting value during key format. */ --- 835,840 ---- /* Do repr() on each key+value pair, and insert ": " between them. Note that repr may mutate the dict. */ ! i = 0; ! while (PyDict_Next((PyObject *)mp, &i, &key, &value)) { int status; /* Prevent repr from deleting value during key format. */ From tim_one@users.sourceforge.net Sat Jun 16 09:10:15 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 16 Jun 2001 01:10:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _testcapimodule.c,1.7,1.8 testcapi_long.h,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv12541/python/dist/src/Modules Modified Files: _testcapimodule.c testcapi_long.h Log Message: Fix error in comment, and in test_long_api and test_longlong_api remove the need for the F_ERROR macro. Index: _testcapimodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_testcapimodule.c,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** _testcapimodule.c 2001/06/14 01:11:03 1.7 --- _testcapimodule.c 2001/06/16 08:10:13 1.8 *************** *** 203,207 **** #define F_U_TO_PY PyLong_FromUnsignedLong #define F_PY_TO_U PyLong_AsUnsignedLong - #define F_ERROR raise_test_long_error #include "testcapi_long.h" --- 203,206 ---- *************** *** 213,217 **** return NULL; ! return TESTNAME(); } --- 212,216 ---- return NULL; ! return TESTNAME(raise_test_long_error); } *************** *** 222,226 **** #undef F_U_TO_PY #undef F_PY_TO_U - #undef F_ERROR #ifdef HAVE_LONG_LONG --- 221,224 ---- *************** *** 238,242 **** #define F_U_TO_PY PyLong_FromUnsignedLongLong #define F_PY_TO_U PyLong_AsUnsignedLongLong - #define F_ERROR raise_test_longlong_error #include "testcapi_long.h" --- 236,239 ---- *************** *** 248,252 **** return NULL; ! return TESTNAME(); } --- 245,249 ---- return NULL; ! return TESTNAME(raise_test_longlong_error); } *************** *** 257,261 **** #undef F_U_TO_PY #undef F_PY_TO_U - #undef F_ERROR #endif /* ifdef HAVE_LONG_LONG */ --- 254,257 ---- Index: testcapi_long.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/testcapi_long.h,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** testcapi_long.h 2001/06/14 00:55:41 1.1 --- testcapi_long.h 2001/06/16 08:10:13 1.2 *************** *** 5,14 **** 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* -> TypeError ! F_ERROR error-report function; char* -> PyObject* (returns NULL) */ static PyObject * ! TESTNAME() { const int NBITS = sizeof(TYPENAME) * 8; --- 5,13 ---- 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; *************** *** 46,58 **** pyresult = F_U_TO_PY(uin); if (pyresult == NULL) ! return F_ERROR( "unsigned unexpected null result"); uout = F_PY_TO_U(pyresult); if (uout == (unsigned TYPENAME)-1 && PyErr_Occurred()) ! return F_ERROR( "unsigned unexpected -1 result"); if (uout != uin) ! return F_ERROR( "unsigned output != input"); UNBIND(pyresult); --- 45,57 ---- 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); *************** *** 61,73 **** pyresult = F_S_TO_PY(in); if (pyresult == NULL) ! return F_ERROR( "signed unexpected null result"); out = F_PY_TO_S(pyresult); if (out == (TYPENAME)-1 && PyErr_Occurred()) ! return F_ERROR( "signed unexpected -1 result"); if (out != in) ! return F_ERROR( "signed output != input"); UNBIND(pyresult); --- 60,72 ---- 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); *************** *** 86,90 **** one = PyLong_FromLong(1); if (one == NULL) ! return F_ERROR( "unexpected NULL from PyLong_FromLong"); --- 85,89 ---- one = PyLong_FromLong(1); if (one == NULL) ! return error( "unexpected NULL from PyLong_FromLong"); *************** *** 92,101 **** x = PyNumber_Negative(one); if (x == NULL) ! return F_ERROR( "unexpected NULL from PyNumber_Negative"); uout = F_PY_TO_U(x); if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred()) ! return F_ERROR( "PyLong_AsUnsignedXXX(-1) didn't complain"); PyErr_Clear(); --- 91,100 ---- 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(); *************** *** 105,109 **** y = PyLong_FromLong((long)NBITS); if (y == NULL) ! return F_ERROR( "unexpected NULL from PyLong_FromLong"); --- 104,108 ---- y = PyLong_FromLong((long)NBITS); if (y == NULL) ! return error( "unexpected NULL from PyLong_FromLong"); *************** *** 111,120 **** UNBIND(y); if (x == NULL) ! return F_ERROR( "unexpected NULL from PyNumber_Lshift"); uout = F_PY_TO_U(x); if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred()) ! return F_ERROR( "PyLong_AsUnsignedXXX(2**NBITS) didn't " "complain"); --- 110,119 ---- 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"); *************** *** 126,135 **** UNBIND(x); if (y == NULL) ! return F_ERROR( "unexpected NULL from PyNumber_Rshift"); out = F_PY_TO_S(y); if (out != (TYPENAME)-1 || !PyErr_Occurred()) ! return F_ERROR( "PyLong_AsXXX(2**(NBITS-1)) didn't " "complain"); --- 125,134 ---- 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"); *************** *** 141,145 **** UNBIND(y); if (x == NULL) ! return F_ERROR( "unexpected NULL from PyNumber_Negative"); --- 140,144 ---- UNBIND(y); if (x == NULL) ! return error( "unexpected NULL from PyNumber_Negative"); *************** *** 147,156 **** UNBIND(x); if (y == NULL) ! return F_ERROR( "unexpected NULL from PyNumber_Subtract"); out = F_PY_TO_S(y); if (out != (TYPENAME)-1 || !PyErr_Occurred()) ! return F_ERROR( "PyLong_AsXXX(-2**(NBITS-1)-1) didn't " "complain"); --- 146,155 ---- 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"); From loewis@users.sourceforge.net Sat Jun 16 09:14:06 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sat, 16 Jun 2001 01:14:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libfnmatch.tex,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv13074 Modified Files: libfnmatch.tex Log Message: Document that filter is added in 2.2. Index: libfnmatch.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfnmatch.tex,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -r1.18 -r1.19 *** libfnmatch.tex 2001/06/07 19:01:24 1.18 --- libfnmatch.tex 2001/06/16 08:14:04 1.19 *************** *** 48,51 **** --- 48,52 ---- It is the same as \code{[n for n in names if fnmatch(n, pattern)]}, but implemented more efficiently. + \versionadded{2.2} \end{funcdesc} From tim_one@users.sourceforge.net Sat Jun 16 09:48:42 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 16 Jun 2001 01:48:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.82,1.83 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv17494/python/dist/src/Objects Modified Files: longobject.c Log Message: PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with #if/#error constructs. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.82 retrieving revision 1.83 diff -C2 -r1.82 -r1.83 *** longobject.c 2001/06/14 18:42:50 1.82 --- longobject.c 2001/06/16 08:48:40 1.83 *************** *** 509,524 **** 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 */ } *************** *** 532,554 **** 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()) --- 536,562 ---- 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()) From gvanrossum@users.sourceforge.net Sat Jun 16 14:59:50 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 16 Jun 2001 06:59:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include object.h,2.79.2.13,2.79.2.14 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv30033/Include Modified Files: Tag: descr-branch object.h Log Message: Rename the *other* tp_alloc to tp_allocs. Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.79.2.13 retrieving revision 2.79.2.14 diff -C2 -r2.79.2.13 -r2.79.2.14 *** object.h 2001/06/07 18:31:55 2.79.2.13 --- object.h 2001/06/16 13:59:48 2.79.2.14 *************** *** 278,282 **** #ifdef COUNT_ALLOCS /* these must be last and never explicitly initialized */ ! int tp_alloc; int tp_free; int tp_maxalloc; --- 278,282 ---- #ifdef COUNT_ALLOCS /* these must be last and never explicitly initialized */ ! int tp_allocs; int tp_free; int tp_maxalloc; From gvanrossum@users.sourceforge.net Sat Jun 16 14:59:50 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 16 Jun 2001 06:59:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects classobject.c,2.127.2.4,2.127.2.5 object.c,2.124.4.13,2.124.4.14 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv30033/Objects Modified Files: Tag: descr-branch classobject.c object.c Log Message: Rename the *other* tp_alloc to tp_allocs. Index: classobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v retrieving revision 2.127.2.4 retrieving revision 2.127.2.5 diff -C2 -r2.127.2.4 -r2.127.2.5 *** classobject.c 2001/06/05 12:45:46 2.127.2.4 --- classobject.c 2001/06/16 13:59:48 2.127.2.5 *************** *** 560,564 **** * _Py_RefTotal was also boosted; we'll knock that down later. */ ! inst->ob_type->tp_alloc--; #endif #else /* !Py_TRACE_REFS */ --- 560,564 ---- * _Py_RefTotal was also boosted; we'll knock that down later. */ ! inst->ob_type->tp_allocs--; #endif #else /* !Py_TRACE_REFS */ Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.124.4.13 retrieving revision 2.124.4.14 diff -C2 -r2.124.4.13 -r2.124.4.14 *** object.c 2001/06/07 18:31:55 2.124.4.13 --- object.c 2001/06/16 13:59:48 2.124.4.14 *************** *** 33,37 **** for (tp = type_list; tp; tp = tp->tp_next) fprintf(stderr, "%s alloc'd: %d, freed: %d, max in use: %d\n", ! tp->tp_name, tp->tp_alloc, tp->tp_free, tp->tp_maxalloc); fprintf(stderr, "fast tuple allocs: %d, empty: %d\n", --- 33,37 ---- for (tp = type_list; tp; tp = tp->tp_next) fprintf(stderr, "%s alloc'd: %d, freed: %d, max in use: %d\n", ! tp->tp_name, tp->tp_allocs, tp->tp_free, tp->tp_maxalloc); fprintf(stderr, "fast tuple allocs: %d, empty: %d\n", *************** *** 54,58 **** return NULL; for (tp = type_list; tp; tp = tp->tp_next) { ! v = Py_BuildValue("(siii)", tp->tp_name, tp->tp_alloc, tp->tp_free, tp->tp_maxalloc); if (v == NULL) { --- 54,58 ---- return NULL; for (tp = type_list; tp; tp = tp->tp_next) { ! v = Py_BuildValue("(siii)", tp->tp_name, tp->tp_allocs, tp->tp_free, tp->tp_maxalloc); if (v == NULL) { *************** *** 73,77 **** inc_count(PyTypeObject *tp) { ! if (tp->tp_alloc == 0) { /* first time; insert in linked list */ if (tp->tp_next != NULL) /* sanity check */ --- 73,77 ---- inc_count(PyTypeObject *tp) { ! if (tp->tp_allocs == 0) { /* first time; insert in linked list */ if (tp->tp_next != NULL) /* sanity check */ *************** *** 80,86 **** type_list = tp; } ! tp->tp_alloc++; ! if (tp->tp_alloc - tp->tp_free > tp->tp_maxalloc) ! tp->tp_maxalloc = tp->tp_alloc - tp->tp_free; } #endif --- 80,86 ---- type_list = tp; } ! tp->tp_allocs++; ! if (tp->tp_allocs - tp->tp_free > tp->tp_maxalloc) ! tp->tp_maxalloc = tp->tp_allocs - tp->tp_free; } #endif From gvanrossum@users.sourceforge.net Sat Jun 16 15:34:15 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 16 Jun 2001 07:34:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules cPickle.c,2.59,2.59.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv8861 Modified Files: Tag: descr-branch cPickle.c Log Message: Make type objects picklable. They are pickled as globals. This isn't always right, but works for the important cases. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.59 retrieving revision 2.59.4.1 diff -C2 -r2.59 -r2.59.4.1 *** cPickle.c 2001/04/10 04:35:28 2.59 --- cPickle.c 2001/06/16 14:34:13 2.59.4.1 *************** *** 1872,1875 **** --- 1872,1879 ---- goto finally; } + if (type == &PyType_Type) { + res = save_global(self, args, NULL); + goto finally; + } break; From gvanrossum@users.sourceforge.net Sat Jun 16 15:34:34 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 16 Jun 2001 07:34:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib pickle.py,1.48,1.48.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv9095 Modified Files: Tag: descr-branch pickle.py Log Message: Make type objects picklable. They are pickled as globals. This isn't always right, but works for the important cases. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.48 retrieving revision 1.48.4.1 diff -C2 -r1.48 -r1.48.4.1 *** pickle.py 2001/04/10 05:02:52 1.48 --- pickle.py 2001/06/16 14:34:32 1.48.4.1 *************** *** 505,508 **** --- 505,509 ---- dispatch[FunctionType] = save_global dispatch[BuiltinFunctionType] = save_global + dispatch[TypeType] = save_global From gvanrossum@users.sourceforge.net Sat Jun 16 15:38:39 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 16 Jun 2001 07:38:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects stringobject.c,2.103.2.5,2.103.2.6 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv10364 Modified Files: Tag: descr-branch stringobject.c Log Message: Change the name of the string type from string to str, so that it doesn't lie (since it's __builtin__.str now). This breaks my heart, and maybe I'll think of a better solution later, but for now, this is the best I can think of to make built-in types picklable. Types should be smarter about when to return __builtin__ as their module name, but that's a separate story. Index: stringobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v retrieving revision 2.103.2.5 retrieving revision 2.103.2.6 diff -C2 -r2.103.2.5 -r2.103.2.6 *** stringobject.c 2001/06/14 01:01:16 2.103.2.5 --- stringobject.c 2001/06/16 14:38:37 2.103.2.6 *************** *** 2381,2385 **** PyObject_HEAD_INIT(&PyType_Type) 0, ! "string", sizeof(PyStringObject), sizeof(char), --- 2381,2385 ---- PyObject_HEAD_INIT(&PyType_Type) 0, ! "str", sizeof(PyStringObject), sizeof(char), From gvanrossum@users.sourceforge.net Sat Jun 16 15:41:42 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 16 Jun 2001 07:41:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include object.h,2.79.2.14,2.79.2.15 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv11001/Include Modified Files: Tag: descr-branch object.h Log Message: I think I've got the right solution for tp_alloc: it's a lower-level function that really should only allocate the memory and initialize the type and refcount. The new signature gets the number of items (in case it's a VarObject). The smarts have to be put in tp_new(). Thies does away wih my fear that tp_alloc() and tp_new() would have to be merged -- they are both needed. Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.79.2.14 retrieving revision 2.79.2.15 diff -C2 -r2.79.2.14 -r2.79.2.15 *** object.h 2001/06/16 13:59:48 2.79.2.14 --- object.h 2001/06/16 14:41:40 2.79.2.15 *************** *** 206,210 **** typedef int (*descrsetfunc) (PyObject *, PyObject *, PyObject *); typedef int (*initproc)(PyObject *, PyObject *, PyObject *); ! typedef PyObject *(*allocfunc)(struct _typeobject *, PyObject *, PyObject *); typedef struct _typeobject { --- 206,211 ---- typedef int (*descrsetfunc) (PyObject *, PyObject *, PyObject *); typedef int (*initproc)(PyObject *, PyObject *, PyObject *); ! typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *); ! typedef PyObject *(*allocfunc)(struct _typeobject *, int); typedef struct _typeobject { *************** *** 271,275 **** initproc tp_init; allocfunc tp_alloc; ! allocfunc tp_new; PyObject *tp_bases; PyObject *tp_mro; /* method resolution order */ --- 272,276 ---- initproc tp_init; allocfunc tp_alloc; ! newfunc tp_new; PyObject *tp_bases; PyObject *tp_mro; /* method resolution order */ *************** *** 297,302 **** extern DL_IMPORT(int) PyType_InitDict(PyTypeObject *); ! extern DL_IMPORT(PyObject *) PyType_GenericAlloc(PyTypeObject *, ! PyObject *, PyObject *); extern DL_IMPORT(PyObject *) PyType_GenericNew(PyTypeObject *, PyObject *, PyObject *); --- 298,302 ---- extern DL_IMPORT(int) PyType_InitDict(PyTypeObject *); ! extern DL_IMPORT(PyObject *) PyType_GenericAlloc(PyTypeObject *, int); extern DL_IMPORT(PyObject *) PyType_GenericNew(PyTypeObject *, PyObject *, PyObject *); From gvanrossum@users.sourceforge.net Sat Jun 16 15:41:42 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 16 Jun 2001 07:41:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.40,2.16.8.41 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv11001/Objects Modified Files: Tag: descr-branch typeobject.c Log Message: I think I've got the right solution for tp_alloc: it's a lower-level function that really should only allocate the memory and initialize the type and refcount. The new signature gets the number of items (in case it's a VarObject). The smarts have to be put in tp_new(). Thies does away wih my fear that tp_alloc() and tp_new() would have to be merged -- they are both needed. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.40 retrieving revision 2.16.8.41 diff -C2 -r2.16.8.40 -r2.16.8.41 *** typeobject.c 2001/06/14 14:13:46 2.16.8.40 --- typeobject.c 2001/06/16 14:41:40 2.16.8.41 *************** *** 78,82 **** PyObject * ! PyType_GenericAlloc(PyTypeObject *type, PyObject *args, PyObject *kwds) { int size; --- 78,82 ---- PyObject * ! PyType_GenericAlloc(PyTypeObject *type, int nitems) { int size; *************** *** 85,89 **** /* Inline PyObject_New() so we can zero the memory */ ! size = _PyObject_SIZE(type); mem = PyObject_MALLOC(size); if (mem == NULL) --- 85,89 ---- /* Inline PyObject_New() so we can zero the memory */ ! size = _PyObject_VAR_SIZE(type, nitems); mem = PyObject_MALLOC(size); if (mem == NULL) *************** *** 96,100 **** if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) Py_INCREF(type); ! PyObject_INIT(obj, type); if (PyType_IS_GC(type)) PyObject_GC_Init(obj); --- 96,103 ---- if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) Py_INCREF(type); ! if (type->tp_itemsize == 0) ! PyObject_INIT(obj, type); ! else ! (void) PyObject_INIT_VAR((PyVarObject *)obj, type, nitems); if (PyType_IS_GC(type)) PyObject_GC_Init(obj); *************** *** 107,111 **** PyObject *self; ! self = type->tp_alloc(type, args, kwds); if (self == NULL) return NULL; --- 110,114 ---- PyObject *self; ! self = type->tp_alloc(type, 0); if (self == NULL) return NULL; *************** *** 527,541 **** static PyObject * ! type_alloc(PyTypeObject *metatype, PyObject *args, PyObject *kwds) { PyTypeObject *type; - PyObject *name, *bases, *dict; - static char *kwlist[] = {"name", "bases", "dict", 0}; ! /* Check arguments (again?!?! yes, alas -- we need the dict!) */ ! if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO:type", kwlist, ! &name, &bases, &dict)) ! return NULL; ! type = (PyTypeObject *)PyType_GenericAlloc(metatype, args, kwds); if (type != NULL) type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE; --- 530,538 ---- static PyObject * ! type_alloc(PyTypeObject *metatype, int nitems) { PyTypeObject *type; ! type = (PyTypeObject *)PyType_GenericAlloc(metatype, nitems); if (type != NULL) type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE; From fdrake@users.sourceforge.net Sat Jun 16 21:46:12 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Sat, 16 Jun 2001 13:46:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules termios.c,2.24.2.4,2.24.2.5 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv16654/Modules Modified Files: Tag: release21-maint termios.c Log Message: Spell "#ifdef" as "#ifdef", not "#endif". Index: termios.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/termios.c,v retrieving revision 2.24.2.4 retrieving revision 2.24.2.5 diff -C2 -r2.24.2.4 -r2.24.2.5 *** termios.c 2001/06/15 11:58:49 2.24.2.4 --- termios.c 2001/06/16 20:46:10 2.24.2.5 *************** *** 517,521 **** {"ECHOKE", ECHOKE}, #endif ! #endif FLUSHO {"FLUSHO", FLUSHO}, #endif --- 517,521 ---- {"ECHOKE", ECHOKE}, #endif ! #ifndef FLUSHO {"FLUSHO", FLUSHO}, #endif From fdrake@users.sourceforge.net Sat Jun 16 22:02:33 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Sat, 16 Jun 2001 14:02:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.247,2.248 sysmodule.c,2.85,2.86 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv19114 Modified Files: ceval.c sysmodule.c Log Message: Instead of initializing & interning the strings passed to the profile and trace functions lazily, which incurs extra argument pushing and checks in the C overhead for profiling/tracing, create the strings semi-lazily when the Python code first registers a profile or trace function. This simplifies the trampoline into the profile/trace functions. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.247 retrieving revision 2.248 diff -C2 -r2.247 -r2.248 *** ceval.c 2001/06/16 00:09:28 2.247 --- ceval.c 2001/06/16 21:02:31 2.248 *************** *** 63,67 **** static void call_exc_trace(PyObject **, PyObject**, PyFrameObject *); static int call_trace(PyObject **, PyObject **, ! PyFrameObject *, char *, PyObject **, PyObject *); static PyObject *loop_subscript(PyObject *, PyObject *); static PyObject *apply_slice(PyObject *, PyObject *, PyObject *); --- 63,67 ---- static void call_exc_trace(PyObject **, PyObject**, PyFrameObject *); static int call_trace(PyObject **, PyObject **, ! PyFrameObject *, PyObject *, PyObject *); static PyObject *loop_subscript(PyObject *, PyObject *); static PyObject *apply_slice(PyObject *, PyObject *, PyObject *); *************** *** 655,659 **** is detected. */ if (call_trace(&tstate->sys_tracefunc, ! &f->f_trace, f, "call", &str_call, Py_None/*XXX how to compute arguments now?*/)) { /* Trace function raised an error */ --- 655,659 ---- is detected. */ if (call_trace(&tstate->sys_tracefunc, ! &f->f_trace, f, str_call, Py_None/*XXX how to compute arguments now?*/)) { /* Trace function raised an error */ *************** *** 666,670 **** itself and isn't called for "line" events */ if (call_trace(&tstate->sys_profilefunc, ! (PyObject**)0, f, "call", &str_call, Py_None/*XXX*/)) { goto fail; --- 666,670 ---- itself and isn't called for "line" events */ if (call_trace(&tstate->sys_profilefunc, ! (PyObject**)0, f, str_call, Py_None/*XXX*/)) { goto fail; *************** *** 1962,1966 **** f->f_lasti = INSTR_OFFSET(); err = call_trace(&f->f_trace, &f->f_trace, ! f, "line", &str_line, Py_None); break; --- 1962,1966 ---- f->f_lasti = INSTR_OFFSET(); err = call_trace(&f->f_trace, &f->f_trace, ! f, str_line, Py_None); break; *************** *** 2307,2311 **** if (why == WHY_RETURN) { if (call_trace(&f->f_trace, &f->f_trace, f, ! "return", &str_return, retval)) { Py_XDECREF(retval); retval = NULL; --- 2307,2311 ---- if (why == WHY_RETURN) { if (call_trace(&f->f_trace, &f->f_trace, f, ! str_return, retval)) { Py_XDECREF(retval); retval = NULL; *************** *** 2317,2321 **** if (tstate->sys_profilefunc && why == WHY_RETURN) { if (call_trace(&tstate->sys_profilefunc, (PyObject**)0, ! f, "return", &str_return, retval)) { Py_XDECREF(retval); retval = NULL; --- 2317,2321 ---- if (tstate->sys_profilefunc && why == WHY_RETURN) { if (call_trace(&tstate->sys_profilefunc, (PyObject**)0, ! f, str_return, retval)) { Py_XDECREF(retval); retval = NULL; *************** *** 2585,2590 **** return; } ! err = call_trace(p_trace, p_newtrace, f, ! "exception", &str_exception, arg); Py_DECREF(arg); if (err == 0) --- 2585,2589 ---- return; } ! err = call_trace(p_trace, p_newtrace, f, str_exception, arg); Py_DECREF(arg); if (err == 0) *************** *** 2602,2617 **** may point to NULL variable; may be same variable as p_newtrace ! PyObject **p_omsg: in/out; may not be NULL; ! if non-null & *p_omsg == NULL, will be ! initialized with an interned string ! corresponding to msg. */ static int call_trace(PyObject **p_trace, PyObject **p_newtrace, PyFrameObject *f, ! char *msg, PyObject **p_omsg, PyObject *arg) { PyThreadState *tstate = f->f_tstate; ! PyObject *args, *what; PyObject *res = NULL; --- 2601,2613 ---- may point to NULL variable; may be same variable as p_newtrace ! PyObject *msg: in; must not be NULL */ static int call_trace(PyObject **p_trace, PyObject **p_newtrace, PyFrameObject *f, ! PyObject *msg, PyObject *arg) { PyThreadState *tstate = f->f_tstate; ! PyObject *args; PyObject *res = NULL; *************** *** 2628,2645 **** if (args == NULL) goto cleanup; ! if (*p_omsg != NULL) { ! what = *p_omsg; ! Py_INCREF(what); ! } ! else { ! what = PyString_InternFromString(msg); ! if (what == NULL) ! goto cleanup; ! *p_omsg = what; ! Py_INCREF(what); ! } Py_INCREF(f); PyTuple_SET_ITEM(args, 0, (PyObject *)f); ! PyTuple_SET_ITEM(args, 1, what); if (arg == NULL) arg = Py_None; --- 2624,2631 ---- if (args == NULL) goto cleanup; ! Py_INCREF(msg); Py_INCREF(f); PyTuple_SET_ITEM(args, 0, (PyObject *)f); ! PyTuple_SET_ITEM(args, 1, msg); if (arg == NULL) arg = Py_None; *************** *** 2686,2689 **** --- 2672,2705 ---- } } + + /* Initialize the strings that get passed to the profile and trace functions; + * this avoids doing this while we're actually profiling/tracing. + */ + int + _PyTrace_Init(void) + { + if (str_call == NULL) { + str_call = PyString_InternFromString("call"); + if (str_call == NULL) + return -1; + } + if (str_exception == NULL) { + str_exception = PyString_InternFromString("exception"); + if (str_exception == NULL) + return -1; + } + if (str_line == NULL) { + str_line = PyString_InternFromString("line"); + if (str_line == NULL) + return -1; + } + if (str_return == NULL) { + str_return = PyString_InternFromString("return"); + if (str_return == NULL) + return -1; + } + return 0; + } + PyObject * Index: sysmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/sysmodule.c,v retrieving revision 2.85 retrieving revision 2.86 diff -C2 -r2.85 -r2.86 *** sysmodule.c 2001/04/10 22:07:43 2.85 --- sysmodule.c 2001/06/16 21:02:31 2.86 *************** *** 197,204 **** --- 197,208 ---- Set the current default string encoding used by the Unicode implementation."; + extern int _PyTrace_Init(void); + static PyObject * sys_settrace(PyObject *self, PyObject *args) { PyThreadState *tstate = PyThreadState_Get(); + if (_PyTrace_Init() == -1) + return NULL; if (args == Py_None) args = NULL; *************** *** 221,224 **** --- 225,230 ---- { PyThreadState *tstate = PyThreadState_Get(); + if (_PyTrace_Init() == -1) + return NULL; if (args == Py_None) args = NULL; From loewis@users.sourceforge.net Sun Jun 17 08:05:45 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 17 Jun 2001 00:05:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/xml/sax expatreader.py,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/xml/sax In directory usw-pr-cvs1:/tmp/cvs-serv27805 Modified Files: expatreader.py Log Message: Synchronize with 1.13 of PyXML: Allow application to set a new content handler and lex_prop handler during parsing. Closes bug #433761. Small hack to make expat be ignored in Jython. Index: expatreader.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xml/sax/expatreader.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -r1.22 -r1.23 *** expatreader.py 2001/01/27 09:01:20 1.22 --- expatreader.py 2001/06/17 07:05:43 1.23 *************** *** 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 gvanrossum@users.sourceforge.net Sun Jun 17 14:31:28 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 17 Jun 2001 06:31:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib imaplib.py,1.27,1.28 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv31273 Modified Files: imaplib.py Log Message: SF patch #433619, by Michel Pelletier: Summary: NAMESPACE support in imaplib.py Initial Comment: Support for the IMAP NAMESPACE extension defined in rfc 2342. This is almost a necessity for working with modern IMAP servers. Index: imaplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/imaplib.py,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -r1.27 -r1.28 *** imaplib.py 2001/02/22 13:24:27 1.27 --- imaplib.py 2001/06/17 13:31:25 1.28 *************** *** 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) From lemburg@users.sourceforge.net Sun Jun 17 19:32:38 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Sun, 17 Jun 2001 11:32:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _codecsmodule.c,2.6,2.7 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv17705 Modified Files: _codecsmodule.c Log Message: Fix for bug [ #433047 ] missing args to PyArg_ParseTuple Index: _codecsmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_codecsmodule.c,v retrieving revision 2.6 retrieving revision 2.7 diff -C2 -r2.6 -r2.7 *** _codecsmodule.c 2000/09/21 21:09:45 2.6 --- _codecsmodule.c 2001/06/17 18:32:36 2.7 *************** *** 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; From tim_one@users.sourceforge.net Sun Jun 17 22:57:19 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 17 Jun 2001 14:57:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tut tut.tex,1.139,1.140 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tut In directory usw-pr-cvs1:/tmp/cvs-serv17843/python/dist/src/Doc/tut Modified Files: tut.tex Log Message: Clarification in the fp appendix suggested on c.l.py by Michael Chermside. Also replaced a *star* style emphasis in the Representation Error section with an \emph{} thingie. Index: tut.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tut/tut.tex,v retrieving revision 1.139 retrieving revision 1.140 diff -C2 -r1.139 -r1.140 *** tut.tex 2001/06/08 17:09:01 1.139 --- tut.tex 2001/06/17 21:57:17 1.140 *************** *** 4181,4185 **** not a bug in Python, it is not a bug in your code either, and you'll see the same kind of thing in all languages that support your ! hardware's floating-point arithmetic. Python's builtin \function{str()} function produces only 12 --- 4181,4186 ---- not a bug in Python, it is not a bug in your code either, and you'll see the same kind of thing in all languages that support your ! hardware's floating-point arithmetic (although some languages may ! not \emph{display} the difference by default, or in all output modes). Python's builtin \function{str()} function produces only 12 *************** *** 4327,4331 **** Note that since we rounded up, this is actually a little bit larger than 1/10; if we had not rounded up, the quotient would have been a little ! bit smaller than 1/10. But in no case can it be *exactly* 1/10! So the computer never ``sees'' 1/10: what it sees is the exact --- 4328,4332 ---- Note that since we rounded up, this is actually a little bit larger than 1/10; if we had not rounded up, the quotient would have been a little ! bit smaller than 1/10. But in no case can it be \emph{exactly} 1/10! So the computer never ``sees'' 1/10: what it sees is the exact From tim_one@users.sourceforge.net Sun Jun 17 22:57:19 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 17 Jun 2001 14:57:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.97,1.98 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv17843/python/dist/src/Misc Modified Files: ACKS Log Message: Clarification in the fp appendix suggested on c.l.py by Michael Chermside. Also replaced a *star* style emphasis in the Representation Error section with an \emph{} thingie. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.97 retrieving revision 1.98 diff -C2 -r1.97 -r1.98 *** ACKS 2001/06/09 09:26:21 1.97 --- ACKS 2001/06/17 21:57:17 1.98 *************** *** 72,75 **** --- 72,76 ---- David Chaum Nicolas Chauvat + Michael Chermside Albert Chin-A-Young Tom Christiansen From gvanrossum@users.sourceforge.net Mon Jun 18 00:13:42 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 17 Jun 2001 16:13:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include object.h,2.79.2.15,2.79.2.16 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv28752 Modified Files: Tag: descr-branch object.h Log Message: Add a new flag, Py_TPFLAGS_BASETYPE, that must be set in a type that supports subtyping. This makes more sense than requiring that tp_init is set. Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.79.2.15 retrieving revision 2.79.2.16 diff -C2 -r2.79.2.15 -r2.79.2.16 *** object.h 2001/06/16 14:41:40 2.79.2.15 --- object.h 2001/06/17 23:13:39 2.79.2.16 *************** *** 401,404 **** --- 401,407 ---- #define Py_TPFLAGS_HEAPTYPE (1L<<9) + /* Set if the type allows subclassing */ + #define Py_TPFLAGS_BASETYPE (1L<<10) + #define Py_TPFLAGS_DEFAULT ( \ Py_TPFLAGS_HAVE_GETCHARBUFFER | \ From gvanrossum@users.sourceforge.net Mon Jun 18 00:18:21 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 17 Jun 2001 16:18:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects listobject.c,2.92.6.8,2.92.6.9 dictobject.c,2.80.2.12,2.80.2.13 moduleobject.c,2.31.6.4,2.31.6.5 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv29363 Modified Files: Tag: descr-branch listobject.c dictobject.c moduleobject.c Log Message: Add Py_TPFLAGS_BASETYPE to tp_flags. Index: listobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v retrieving revision 2.92.6.8 retrieving revision 2.92.6.9 diff -C2 -r2.92.6.8 -r2.92.6.9 *** listobject.c 2001/06/11 19:06:44 2.92.6.8 --- listobject.c 2001/06/17 23:18:19 2.92.6.9 *************** *** 1661,1665 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */ list_doc, /* tp_doc */ (traverseproc)list_traverse, /* tp_traverse */ --- 1661,1666 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC | ! Py_TPFLAGS_BASETYPE, /* tp_flags */ list_doc, /* tp_doc */ (traverseproc)list_traverse, /* tp_traverse */ Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.80.2.12 retrieving revision 2.80.2.13 diff -C2 -r2.80.2.12 -r2.80.2.13 *** dictobject.c 2001/06/14 14:10:16 2.80.2.12 --- dictobject.c 2001/06/17 23:18:19 2.80.2.13 *************** *** 1313,1317 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */ "dictionary type", /* tp_doc */ (traverseproc)dict_traverse, /* tp_traverse */ --- 1313,1318 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC | ! Py_TPFLAGS_BASETYPE, /* tp_flags */ "dictionary type", /* tp_doc */ (traverseproc)dict_traverse, /* tp_traverse */ Index: moduleobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/moduleobject.c,v retrieving revision 2.31.6.4 retrieving revision 2.31.6.5 diff -C2 -r2.31.6.4 -r2.31.6.5 *** moduleobject.c 2001/06/06 14:27:54 2.31.6.4 --- moduleobject.c 2001/06/17 23:18:19 2.31.6.5 *************** *** 209,213 **** PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */ 0, /* tp_doc */ (traverseproc)module_traverse, /* tp_traverse */ --- 209,214 ---- PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC | ! Py_TPFLAGS_BASETYPE, /* tp_flags */ 0, /* tp_doc */ (traverseproc)module_traverse, /* tp_traverse */ From gvanrossum@users.sourceforge.net Mon Jun 18 00:27:30 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 17 Jun 2001 16:27:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.1.2.13,1.1.2.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv30823 Modified Files: Tag: descr-branch test_descr.py Log Message: Add tests for some specific error conditions. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_descr.py,v retrieving revision 1.1.2.13 retrieving revision 1.1.2.14 diff -C2 -r1.1.2.13 -r1.1.2.14 *** test_descr.py 2001/06/07 19:17:39 1.1.2.13 --- test_descr.py 2001/06/17 23:27:27 1.1.2.14 *************** *** 413,416 **** --- 413,461 ---- verify(G.__mro__ == (G, E, D, C, B, A, object)) + def errors(): + if verbose: print "Testing errors..." + + try: + class C(list, dictionary): + pass + except TypeError: + pass + else: + print "Ouch: inheritance from both list and dict should be illegal!" + + try: + class C(object, None): + pass + except TypeError: + pass + else: + print "Ouch: inheritance from non-type should be illegal!" + class Classic: + pass + + try: + class C(object, Classic): + pass + except TypeError: + pass + else: + print "Ouch: inheritance from object and Classic should be illegal!" + + try: + class C(int): + pass + except TypeError: + pass + else: + print "Ouch: inheritance from int should be illegal!" + + try: + class C(object): + __slots__ = {} + except TypeError: + pass + else: + print "Ouch: __slots__ = {} should be illegal!" + def all(): lists() *************** *** 426,429 **** --- 471,475 ---- multi() diamond() + errors() all() From gvanrossum@users.sourceforge.net Mon Jun 18 00:28:33 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 17 Jun 2001 16:28:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.41,2.16.8.42 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv30954 Modified Files: Tag: descr-branch typeobject.c Log Message: Test for the Py_TPFLAGS_BASETYPE flag. Fold type_init() into type_new(). You can now instantiate object() again. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.41 retrieving revision 2.16.8.42 diff -C2 -r2.16.8.41 -r2.16.8.42 *** typeobject.c 2001/06/16 14:41:40 2.16.8.41 --- typeobject.c 2001/06/17 23:28:31 2.16.8.42 *************** *** 321,347 **** } ! /* TypeType's initializer; called when a type is subclassed */ staticforward void object_dealloc(PyObject *); staticforward int object_init(PyObject *, PyObject *, PyObject *); ! static int ! type_init(PyObject *self, PyObject *args, PyObject *kwds) { ! PyObject *name, *bases, *dict, *slots; ! PyTypeObject *type, *base; static char *kwlist[] = {"name", "bases", "dict", 0}; etype *et; struct memberlist *mp; ! int i, nbases, nslots, slotoffset, allocsize; ! ! assert(PyType_Check(self)); ! type = (PyTypeObject *)self; ! /* Check this is a virginal type object */ ! if (type->tp_dict != NULL) { ! PyErr_SetString(PyExc_TypeError, ! "can't re-initialize type objects"); ! return -1; } --- 321,386 ---- } ! static int ! extra_ivars(PyTypeObject *type, PyTypeObject *base) ! { ! int t_size = type->tp_basicsize; ! int b_size = base->tp_basicsize; ! ! assert((type->tp_flags & Py_TPFLAGS_GC) >= ! (base->tp_flags & Py_TPFLAGS_GC)); /* base has GC, type not! */ ! if (type->tp_flags & Py_TPFLAGS_GC) ! t_size -= PyGC_HEAD_SIZE; ! if (base->tp_flags & Py_TPFLAGS_GC) ! b_size -= PyGC_HEAD_SIZE; ! assert(t_size >= b_size); /* type smaller than base! */ ! if (type->tp_itemsize || base->tp_itemsize) { ! /* If itemsize is involved, stricter rules */ ! return t_size != b_size || ! type->tp_itemsize != base->tp_itemsize; ! } ! if (t_size == b_size) ! return 0; ! 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; ! } ! ! static PyTypeObject * ! solid_base(PyTypeObject *type) ! { ! PyTypeObject *base; + if (type->tp_base) + base = solid_base(type->tp_base); + else + base = &PyBaseObject_Type; + if (extra_ivars(type, base)) + return type; + else + return base; + } + staticforward void object_dealloc(PyObject *); staticforward int object_init(PyObject *, PyObject *, PyObject *); ! static PyObject * ! type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) { ! PyObject *name, *bases, *dict; static char *kwlist[] = {"name", "bases", "dict", 0}; + PyObject *slots; + PyTypeObject *type, *base; etype *et; struct memberlist *mp; ! int i, nbases, nslots, slotoffset; ! if (PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 && ! (kwds == NULL || (PyDict_Check(kwds) && PyDict_Size(kwds) == 0))) { ! /* type(x) -> x.__class__ */ ! PyObject *x = PyTuple_GET_ITEM(args, 0); ! Py_INCREF(x->ob_type); ! return (PyObject *) x->ob_type; } *************** *** 349,357 **** if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO:type", kwlist, &name, &bases, &dict)) ! return -1; ! if (!PyTuple_Check(bases) || !PyDict_Check(dict)) { ! PyErr_SetString(PyExc_TypeError, ! "usage: type(name, bases, dict) "); ! return -1; } --- 388,410 ---- if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO:type", kwlist, &name, &bases, &dict)) ! return NULL; ! if (PyTuple_Check(bases)) { ! int i, n; ! n = PyTuple_GET_SIZE(bases); ! for (i = 0; i < n; i++) { ! PyObject *base_i = PyTuple_GET_ITEM(bases, i); ! PyTypeObject *type_i = base_i->ob_type; ! if (issubtype(metatype, type_i)) ! continue; ! if (issubtype(type_i, metatype)) { ! metatype = type_i; ! continue; ! } ! PyErr_SetString(PyExc_TypeError, ! "metaclass conflict among bases"); ! return NULL; ! } ! if (metatype->tp_new != type_new) ! return metatype->tp_new(metatype, args, kwds); } *************** *** 361,365 **** bases = Py_BuildValue("(O)", &PyBaseObject_Type); if (bases == NULL) ! return -1; nbases = 1; } --- 414,418 ---- bases = Py_BuildValue("(O)", &PyBaseObject_Type); if (bases == NULL) ! return NULL; nbases = 1; } *************** *** 370,387 **** base = best_base(bases); if (base == NULL) ! return -1; ! if (base->tp_init == NULL && base != &PyBaseObject_Type) { ! PyErr_SetString(PyExc_TypeError, ! "base type must have a constructor slot"); ! return -1; } - /* Set tp_base and tp_bases */ - type->tp_bases = bases; - Py_INCREF(base); - type->tp_base = base; - /* Check for a __slots__ sequence variable in dict, and count it */ - /* XXX This should move to type_alloc() */ slots = PyDict_GetItemString(dict, "__slots__"); nslots = 0; --- 423,435 ---- base = best_base(bases); if (base == NULL) ! return NULL; ! if (!PyType_HasFeature(base, Py_TPFLAGS_BASETYPE)) { ! PyErr_Format(PyExc_TypeError, ! "type '%.100s' is not an acceptable base type", ! base->tp_name); ! return NULL; } /* Check for a __slots__ sequence variable in dict, and count it */ slots = PyDict_GetItemString(dict, "__slots__"); nslots = 0; *************** *** 393,397 **** slots = PySequence_Tuple(slots); if (slots == NULL) ! return -1; nslots = PyTuple_GET_SIZE(slots); for (i = 0; i < nslots; i++) { --- 441,445 ---- slots = PySequence_Tuple(slots); if (slots == NULL) ! return NULL; nslots = PyTuple_GET_SIZE(slots); for (i = 0; i < nslots; i++) { *************** *** 400,404 **** "__slots__ must be a sequence of strings"); Py_DECREF(slots); ! return -1; } } --- 448,452 ---- "__slots__ must be a sequence of strings"); Py_DECREF(slots); ! return NULL; } } *************** *** 409,427 **** nslots = 1; ! /* Check allocation size and initialize the type object */ ! allocsize = sizeof(etype) + nslots*sizeof(struct memberlist); ! if (type->ob_type->tp_basicsize < allocsize) { ! PyErr_Format( ! PyExc_SystemError, ! "insufficient allocated memory for subtype: " ! "allocated %d, needed %d", ! type->ob_type->tp_basicsize, ! allocsize); ! return -1; ! } et = (etype *)type; Py_INCREF(name); et->name = name; et->slots = slots; type->tp_as_number = &et->as_number; type->tp_as_sequence = &et->as_sequence; --- 457,474 ---- nslots = 1; ! /* Allocate the type object */ ! type = (PyTypeObject *)metatype->tp_alloc(metatype, nslots); ! if (type == NULL) ! return NULL; ! ! /* Keep name and slots alive in the extended type object */ et = (etype *)type; Py_INCREF(name); et->name = name; et->slots = slots; + + /* Initialize essential fields */ + type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE | + Py_TPFLAGS_BASETYPE; type->tp_as_number = &et->as_number; type->tp_as_sequence = &et->as_sequence; *************** *** 430,437 **** type->tp_name = PyString_AS_STRING(name); /* Initialize tp_introduced from passed-in dict */ type->tp_introduced = dict = PyDict_Copy(dict); if (dict == NULL) ! return -1; /* Add descriptors for custom slots from __slots__, or for __dict__ */ --- 477,489 ---- type->tp_name = PyString_AS_STRING(name); + /* Set tp_base and tp_bases */ + type->tp_bases = bases; + Py_INCREF(base); + type->tp_base = base; + /* Initialize tp_introduced from passed-in dict */ type->tp_introduced = dict = PyDict_Copy(dict); if (dict == NULL) ! return NULL; /* Add descriptors for custom slots from __slots__, or for __dict__ */ *************** *** 467,584 **** type->tp_setattro = PyObject_GenericSetAttr; } - if (base->tp_dealloc == NULL) - type->tp_dealloc = object_dealloc; - else - type->tp_dealloc = subtype_dealloc; if (base->tp_new == NULL) type->tp_new = PyType_GenericNew; if (base->tp_alloc == NULL) type->tp_alloc = PyType_GenericAlloc; - if (base->tp_init == NULL) - type->tp_init = object_init; /* Initialize the rest */ if (PyType_InitDict(type) < 0) ! return -1; /* Override slots that deserve it */ override_slots(type, type->tp_dict); - return 0; - } - - static int - extra_ivars(PyTypeObject *type, PyTypeObject *base) - { - int t_size = type->tp_basicsize; - int b_size = base->tp_basicsize; - - assert((type->tp_flags & Py_TPFLAGS_GC) >= - (base->tp_flags & Py_TPFLAGS_GC)); /* base has GC, type not! */ - if (type->tp_flags & Py_TPFLAGS_GC) - t_size -= PyGC_HEAD_SIZE; - if (base->tp_flags & Py_TPFLAGS_GC) - b_size -= PyGC_HEAD_SIZE; - assert(t_size >= b_size); /* type smaller than base! */ - if (type->tp_itemsize || base->tp_itemsize) { - /* If itemsize is involved, stricter rules */ - return t_size != b_size || - type->tp_itemsize != base->tp_itemsize; - } - if (t_size == b_size) - return 0; - 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; - } - - static PyTypeObject * - solid_base(PyTypeObject *type) - { - PyTypeObject *base; - - if (type->tp_base) - base = solid_base(type->tp_base); - else - base = &PyBaseObject_Type; - if (extra_ivars(type, base)) - return type; - else - return base; - } - - static PyObject * - type_alloc(PyTypeObject *metatype, int nitems) - { - PyTypeObject *type; - - type = (PyTypeObject *)PyType_GenericAlloc(metatype, nitems); - if (type != NULL) - type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE; return (PyObject *)type; } static PyObject * - type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) - { - PyObject *name, *bases, *dict; - static char *kwlist[] = {"name", "bases", "dict", 0}; - - if (PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 && - (kwds == NULL || (PyDict_Check(kwds) && PyDict_Size(kwds) == 0))) { - /* type(x) -> x.__class__ */ - PyObject *x = PyTuple_GET_ITEM(args, 0); - Py_INCREF(x->ob_type); - return (PyObject *) x->ob_type; - } - - /* Check arguments (again?!?! yes, alas -- we need the bases!) */ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO:type", kwlist, - &name, &bases, &dict)) - return NULL; - if (PyTuple_Check(bases)) { - int i, n; - n = PyTuple_GET_SIZE(bases); - for (i = 0; i < n; i++) { - PyObject *base_i = PyTuple_GET_ITEM(bases, i); - PyTypeObject *type_i = base_i->ob_type; - if (issubtype(metatype, type_i)) - continue; - if (issubtype(type_i, metatype)) { - metatype = type_i; - continue; - } - PyErr_SetString(PyExc_TypeError, - "metaclass conflict among bases"); - return NULL; - } - if (metatype->tp_new != type_new) - return metatype->tp_new(metatype, args, kwds); - } - return PyType_GenericNew(metatype, args, kwds); - } - - static PyObject * type_getattro(PyTypeObject *type, PyObject *name) { --- 519,537 ---- 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 */ if (PyType_InitDict(type) < 0) ! return NULL; /* Override slots that deserve it */ override_slots(type, type->tp_dict); return (PyObject *)type; } static PyObject * type_getattro(PyTypeObject *type, PyObject *name) { *************** *** 614,619 **** 0, /* ob_size */ "type", /* tp_name */ ! sizeof(etype) + sizeof(struct memberlist), /* tp_basicsize */ ! 0, /* tp_itemsize */ (destructor)type_dealloc, /* tp_dealloc */ 0, /* tp_print */ --- 567,572 ---- 0, /* ob_size */ "type", /* tp_name */ ! sizeof(etype), /* tp_basicsize */ ! sizeof(struct memberlist), /* tp_itemsize */ (destructor)type_dealloc, /* tp_dealloc */ 0, /* tp_print */ *************** *** 631,635 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ type_doc, /* tp_doc */ 0, /* tp_traverse */ --- 584,588 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ type_doc, /* tp_doc */ 0, /* tp_traverse */ *************** *** 647,652 **** 0, /* tp_descr_set */ offsetof(PyTypeObject, tp_dict), /* tp_dictoffset */ ! type_init, /* tp_init */ ! type_alloc, /* tp_alloc */ type_new, /* tp_new */ }; --- 600,605 ---- 0, /* tp_descr_set */ offsetof(PyTypeObject, tp_dict), /* tp_dictoffset */ ! 0, /* tp_init */ ! PyType_GenericAlloc, /* tp_alloc */ type_new, /* tp_new */ }; *************** *** 678,682 **** sizeof(PyObject), /* tp_basicsize */ 0, /* tp_itemsize */ ! 0/*(destructor)object_dealloc*/, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ --- 631,635 ---- sizeof(PyObject), /* tp_basicsize */ 0, /* tp_itemsize */ ! (destructor)object_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ *************** *** 693,697 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ "The most base type", /* tp_doc */ 0, /* tp_traverse */ --- 646,650 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ "The most base type", /* tp_doc */ 0, /* tp_traverse */ *************** *** 709,715 **** 0, /* tp_descr_set */ 0, /* tp_dictoffset */ ! 0, /* tp_init */ ! 0, /* tp_alloc */ ! 0, /* tp_new */ }; --- 662,668 ---- 0, /* tp_descr_set */ 0, /* tp_dictoffset */ ! object_init, /* tp_init */ ! PyType_GenericAlloc, /* tp_alloc */ ! PyType_GenericNew, /* tp_new */ }; From loewis@users.sourceforge.net Mon Jun 18 02:09:43 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 17 Jun 2001 18:09:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib UserDict.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv12119 Modified Files: UserDict.py Log Message: Patch #413171: Implement get, setdefault, update in terms of has_key, __getitem__, and __setitem__. Index: UserDict.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/UserDict.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -r1.13 -r1.14 *** UserDict.py 2001/05/03 04:54:41 1.13 --- UserDict.py 2001/06/18 01:09:41 1.14 *************** *** 35,45 **** 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() From gvanrossum@users.sourceforge.net Mon Jun 18 13:33:38 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 18 Jun 2001 05:33:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib rexec.py,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv27537 Modified Files: rexec.py Log Message: Fix SF bug #433904 (Alex Martelli) - all s_* methods return None only. Index: rexec.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/rexec.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -r1.28 -r1.29 *** rexec.py 2001/02/15 22:15:13 1.28 --- rexec.py 2001/06/18 12:33:36 1.29 *************** *** 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(...) From gvanrossum@users.sourceforge.net Mon Jun 18 13:34:34 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 18 Jun 2001 05:34:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib rexec.py,1.28,1.28.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv27875 Modified Files: Tag: release21-maint rexec.py Log Message: Applying this to the 2.1.1 branch: Fix SF bug #433904 (Alex Martelli) - all s_* methods return None only. Index: rexec.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/rexec.py,v retrieving revision 1.28 retrieving revision 1.28.4.1 diff -C2 -r1.28 -r1.28.4.1 *** rexec.py 2001/02/15 22:15:13 1.28 --- rexec.py 2001/06/18 12:34:31 1.28.4.1 *************** *** 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(...) From gvanrossum@users.sourceforge.net Mon Jun 18 14:38:56 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 18 Jun 2001 06:38:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.42,2.16.8.43 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv9596 Modified Files: Tag: descr-branch typeobject.c Log Message: Add generic getattr to base object type, so object().__class__ works. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.42 retrieving revision 2.16.8.43 diff -C2 -r2.16.8.42 -r2.16.8.43 *** typeobject.c 2001/06/17 23:28:31 2.16.8.42 --- typeobject.c 2001/06/18 13:38:54 2.16.8.43 *************** *** 643,647 **** 0, /* tp_call */ 0, /* tp_str */ ! 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 643,647 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ From gvanrossum@users.sourceforge.net Mon Jun 18 14:40:17 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 18 Jun 2001 06:40:17 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.1.2.14,1.1.2.15 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv9860 Modified Files: Tag: descr-branch test_descr.py Log Message: Add tests for behavior of object(). Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_descr.py,v retrieving revision 1.1.2.14 retrieving revision 1.1.2.15 diff -C2 -r1.1.2.14 -r1.1.2.15 *** test_descr.py 2001/06/17 23:27:27 1.1.2.14 --- test_descr.py 2001/06/18 13:40:15 1.1.2.15 *************** *** 413,416 **** --- 413,438 ---- verify(G.__mro__ == (G, E, D, C, B, A, object)) + def objects(): + if verbose: print "Testing 'object' class..." + # Not much to test here :-) + a = object() + verify(a.__class__ == object == type(a)) + b = object() + verify(a is not b) + + try: + object().foo + except AttributeError: + pass + else: + print "Ouch: object() should not have a foo attribute!" + + try: + object().foo = 12 + except AttributeError: + pass + else: + print "Ouch: object() should not allow setting a foo attribute!" + def errors(): if verbose: print "Testing errors..." *************** *** 471,474 **** --- 493,497 ---- multi() diamond() + objects() errors() From fdrake@users.sourceforge.net Mon Jun 18 16:00:00 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 18 Jun 2001 08:00:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/doc doc.tex,1.41,1.42 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/doc In directory usw-pr-cvs1:/tmp/cvs-serv28487/doc Modified Files: doc.tex Log Message: Add some information on the use of \verbatiminput to display sources from an external file. Index: doc.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/doc/doc.tex,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -r1.41 -r1.42 *** doc.tex 2001/05/11 01:01:12 1.41 --- doc.tex 2001/06/18 14:59:58 1.42 *************** *** 612,615 **** --- 612,630 ---- lines at the top or bottom of any \env{verbatim} display. + Longer displays of verbatim text may be included by storing the + example text in an external file containing only plain text. The + file may be included using the standard \macro{verbatiminput} + macro; this macro takes a single argument naming the file + containing the text. For example, to include the Python source + file \file{example.py}, use: + + \begin{verbatim} + \verbatiminput{example.py} + \end{verbatim} + + Use of \macro{verbatiminput} allows easier use of special editing + modes for the included file. The file should be placed in the + same directory as the \LaTeX{} files for the document. + The Python Documentation Special Interest Group has discussed a number of approaches to creating pretty-printed code displays and From gvanrossum@users.sourceforge.net Mon Jun 18 18:38:43 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 18 Jun 2001 10:38:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.43,2.16.8.44 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv736 Modified Files: Tag: descr-branch typeobject.c Log Message: Fix an older bug: while tp_dictoffset was calculated correctly, the offset in the descriptor for the __dict__ was wrong. (I've a suspicion there's still a bug in the calculation of __slots__ offsets -- will investiage these later.) Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.43 retrieving revision 2.16.8.44 diff -C2 -r2.16.8.43 -r2.16.8.44 *** typeobject.c 2001/06/18 13:38:54 2.16.8.43 --- typeobject.c 2001/06/18 17:38:41 2.16.8.44 *************** *** 503,511 **** else if (nslots) { type->tp_dictoffset = slotoffset; - slotoffset += sizeof(PyObject *); mp->name = "__dict__"; mp->type = T_OBJECT; mp->offset = slotoffset; mp->readonly = 1; } type->tp_basicsize = slotoffset; --- 503,511 ---- else if (nslots) { type->tp_dictoffset = slotoffset; mp->name = "__dict__"; mp->type = T_OBJECT; mp->offset = slotoffset; mp->readonly = 1; + slotoffset += sizeof(PyObject *); } type->tp_basicsize = slotoffset; From gvanrossum@users.sourceforge.net Mon Jun 18 19:13:09 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 18 Jun 2001 11:13:09 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0254.txt,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv8945 Added Files: pep-0254.txt Log Message: Make a dummy PEP so that PEP 0 doesn't have a broken link. --- NEW FILE: pep-0254.txt --- PEP: 254 Title: Making Classes Look More Like Types Version: $Revision: 1.1 $ Author: guido@python.org (Guido van Rossum) Status: Draft Type: Standards Track Python-Version: 2.2 Created: 18-June-2001 Post-History: Abstract This PEP has not been written yet. Watch this space! Copyright This document has been placed in the public domain. Local Variables: mode: indented-text indent-tabs-mode: nil End: From akuchling@users.sourceforge.net Mon Jun 18 20:04:06 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Mon, 18 Jun 2001 12:04:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules pcremodule.c,2.25,2.26 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv20746 Modified Files: pcremodule.c Log Message: [Bug #433047, reported by Armin Rigo] Remove extra 'i' character in PyArg_ParseTuple() call. (2.1.1 bugfix candidate.) Index: pcremodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/pcremodule.c,v retrieving revision 2.25 retrieving revision 2.26 diff -C2 -r2.25 -r2.26 *** pcremodule.c 2000/09/01 23:29:27 2.25 --- pcremodule.c 2001/06/18 19:04:04 2.26 *************** *** 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;} From gvanrossum@users.sourceforge.net Mon Jun 18 20:19:00 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 18 Jun 2001 12:19:00 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0257.txt,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv26597 Modified Files: pep-0257.txt Log Message: New version from David Goodger, where he makes me co-author (since it's mostly lifted from my style guide). I don't plan to actively contribute much -- David is the primary author. There are many miscellaneous updates here. Index: pep-0257.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0257.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** pep-0257.txt 2001/06/06 05:55:20 1.1 --- pep-0257.txt 2001/06/18 19:18:58 1.2 *************** *** 3,12 **** Version: $Revision$ Last-Modified: $Date$ ! Author: dgoodger@bigfoot.com (David Goodger) Discussions-To: doc-sig@python.org Status: Draft Type: Informational Created: 29-May-2001 ! Post-History: --- 3,13 ---- Version: $Revision$ Last-Modified: $Date$ ! Author: dgoodger@bigfoot.com (David Goodger), ! guido@digicool.com (Guido van Rossum) Discussions-To: doc-sig@python.org Status: Draft Type: Informational Created: 29-May-2001 ! Post-History: 13-Jun-2001 *************** *** 17,45 **** Specification All modules should normally have docstrings, and all functions and classes exported by a module should also have docstrings. Public methods (including the __init__ constructor) should also have ! docstrings. ! [+] A package may be documented in the module docstring of the ! [+] __init__.py file in the package directory. ! The docstring of a script (a stand-alone program) should be usable ! as its "usage" message, printed when the script is invoked with ! incorrect or missing arguments (or perhaps with a "-h" option, for ! "help"). Such a docstring should document the script's function ! and command line syntax, environment variables, and files. Usage ! messages can be fairly elaborate (several screens full) and should ! be sufficient for a new user to use the command properly, as well ! as a complete quick reference to all options and arguments for the ! sophisticated user. ! For consistency, always use """triple double quotes""" around ! docstrings. ! [+] Use r"""raw triple double quotes""" if you use any ! [+] backslashes in your docstrings. There are two forms of docstrings: one-liners and multi-line --- 18,75 ---- + Rationale + + The aim of this PEP is to standardize the high-level structure of + docstrings: what they should contain, and how to say it (without + touching on any markup syntax within docstrings). The PEP + contains conventions, not laws or syntax. + + "A universal convention supplies all of maintainability, + clarity, consistency, and a foundation for good programming + habits too. What it doesn't do is insist that you follow it + against your will. That's Python!" + + --Tim Peters on comp.lang.python, 2001-06-16 + + If you violate the conventions, the worst you'll get is some dirty + looks. But some software (such as the Docstring Processing System + [1]) will be aware of the conventions, so following them will get + you the best results. + + Specification + What is a Docstring? + -------------------- + + A docstring is a string literal that occurs as the first statement + in a module, function, class, or method definition. Such a + docstring becomes the __doc__ special attribute of that object. + All modules should normally have docstrings, and all functions and classes exported by a module should also have docstrings. Public methods (including the __init__ constructor) should also have ! docstrings. A package may be documented in the module docstring ! of the __init__.py file in the package directory. ! String literals occuring elsewhere in Python code may also act as ! documentation. They are not recognized by the Python bytecode ! compiler and are not accessible as runtime object attributes ! (i.e. not assigned to __doc__), but two types of extra docstrings ! are recognized by software tools: ! ! 1. String literals occuring immediately after a simple assignment ! at the top level of a module, class, or __init__ method ! are called "attribute docstrings". ! 2. String literals occuring immediately after another docstring ! are called "additional docstrings". ! Please see PEP 258 "DPS Generic Implementation Details" [2] for a ! detailed description of attribute and additional docstrings. ! For consistency, always use """triple double quotes""" around ! docstrings. Use r"""raw triple double quotes""" if you use any ! backslashes in your docstrings. There are two forms of docstrings: one-liners and multi-line *************** *** 50,54 **** One-liners are for really obvious cases. They should really fit ! on one line. For example: def kos_root(): --- 80,84 ---- One-liners are for really obvious cases. They should really fit ! on one line. For example:: def kos_root(): *************** *** 66,84 **** This looks better for one-liners. ! - There's no blank line either before or after the docstring. - The docstring is a phrase ending in a period. It prescribes the function's effect as a command ("Do this", "Return that"), not as a description: e.g. don't write "Returns the pathname ..." - - [+] - The one-line docstring should NOT be a "signature" reiterating - [+] the function parameters (which can be obtained by introspection). - [+] Don't do: - - [+] def function(a, b): - [+] """function(a, b) -> list""" ! [+] This type of docstring is only appropriate for C functions (such ! [+] as built-ins), where introspection is not possible. Multi-line Docstrings --- 96,114 ---- This looks better for one-liners. ! - There's no blank line either before or after the docstring. - The docstring is a phrase ending in a period. It prescribes the function's effect as a command ("Do this", "Return that"), not as a description: e.g. don't write "Returns the pathname ..." ! - The one-line docstring should NOT be a "signature" reiterating ! the function parameters (which can be obtained by ! introspection). Don't do:: ! ! def function(a, b): ! """function(a, b) -> list""" ! ! This type of docstring is only appropriate for C functions (such ! as built-ins), where introspection is not possible. Multi-line Docstrings *************** *** 109,117 **** a blank line. The docstring for a module should generally list the classes, exceptions and functions (and any other objects) that are exported by the module, with a one-line summary of each. (These summaries generally give less detail than the summary line in the object's ! docstring.) The docstring for a function or method should summarize its --- 139,159 ---- a blank line. + The docstring of a script (a stand-alone program) should be usable + as its "usage" message, printed when the script is invoked with + incorrect or missing arguments (or perhaps with a "-h" option, for + "help"). Such a docstring should document the script's function + and command line syntax, environment variables, and files. Usage + messages can be fairly elaborate (several screens full) and should + be sufficient for a new user to use the command properly, as well + as a complete quick reference to all options and arguments for the + sophisticated user. + The docstring for a module should generally list the classes, exceptions and functions (and any other objects) that are exported by the module, with a one-line summary of each. (These summaries generally give less detail than the summary line in the object's ! docstring.) The docstring for a package (i.e., the docstring of ! the package's __init__.py module) should also list the modules and ! subpackages exported by the package. The docstring for a function or method should summarize its *************** *** 142,150 **** case sensitive and the argument names can be used for keyword arguments, so the docstring should document the correct argument ! names. It is best to list each argument on a separate line, - [-] with two dashes separating the name from the description, - [-] like this: - def complex(real=0.0, imag=0.0): """Form a complex number. --- 184,190 ---- case sensitive and the argument names can be used for keyword arguments, so the docstring should document the correct argument ! names. It is best to list each argument on a separate line. For ! example:: def complex(real=0.0, imag=0.0): """Form a complex number. *************** *** 157,182 **** if imag == 0.0 and real == 0.0: return complex_zero ... - - [-] The BDFL [3] recommends inserting a blank line between the - [-] last paragraph in a multi-line docstring and its closing quotes, - [-] placing the closing quotes on a line by themselves. This way, - [-] Emacs' fill-paragraph command can be used on it. ! [+] Attribute Docstrings: see PEP 258, "DPS Generic Implementation ! [+] Details" [4] - [+] Additional Docstrings: see PEP 258, "DPS Generic Implementation - [+] Details" [4] - References and Footnotes ! [1] http://www.python.org/doc/essays/styleguide.html ! [2] http://www.python.org/sigs/doc-sig/ ! [3] Guido van Rossum, Python's Benevolent Dictator For Life. ! [4] http://python.sf.net/peps/pep-0258.html --- 197,219 ---- if imag == 0.0 and real == 0.0: return complex_zero ... ! The BDFL [3] recommends inserting a blank line between the last ! paragraph in a multi-line docstring and its closing quotes, ! placing the closing quotes on a line by themselves. This way, ! Emacs' fill-paragraph command can be used on it. References and Footnotes + + [1] http://python.sf.net/peps/pep-0256.html ! [2] http://python.sf.net/peps/pep-0258.html ! [3] Guido van Rossum, Python's creator and Benevolent Dictator For ! Life. ! [4] http://www.python.org/doc/essays/styleguide.html ! [5] http://www.python.org/sigs/doc-sig/ *************** *** 189,209 **** The "Specification" text comes mostly verbatim from the Python ! Style Guide by Guido van Rossum [1]. ! (If it's OK with him, I will add GvR as an author of this PEP. I ! am quite confident that the BDFL doesn't want to own this PEP :-). ! Apart from minor editing, proposed additions to the Style Guide ! text are marked with '[+]' to the left of each line, and proposed ! omissions are marked with '[-]'. If it is deemed that this PEP is ! unnecessary, then it can be taken as suggestions for Style Guide ! modification.) ! ! This document borrows ideas from the archives of the Python Doc-SIG ! [2]. Thanks to all members past and present. ! ! ! ! Local Variables: ! mode: indented-text ! indent-tabs-mode: nil ! End: --- 226,231 ---- The "Specification" text comes mostly verbatim from the Python ! Style Guide by Guido van Rossum [4]. ! This document borrows ideas from the archives of the Python ! Doc-SIG [5]. Thanks to all members past and present. From gvanrossum@users.sourceforge.net Mon Jun 18 20:19:53 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 18 Jun 2001 12:19:53 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0000.txt,1.97,1.98 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv26990 Modified Files: pep-0000.txt Log Message: Add van Rossum as co-author of PEP 257. Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.97 retrieving revision 1.98 diff -C2 -r1.97 -r1.98 *** pep-0000.txt 2001/06/13 16:22:05 1.97 --- pep-0000.txt 2001/06/18 19:19:51 1.98 *************** *** 59,63 **** S 255 pep-0255.txt Simple Generators Schemenauer, et al S 256 pep-0256.txt Docstring Processing System Framework Goodger ! S 257 pep-0257.txt Docstring Conventions Goodger S 258 pep-0258.txt DPS Generic Implementation Details Goodger --- 59,63 ---- S 255 pep-0255.txt Simple Generators Schemenauer, et al S 256 pep-0256.txt Docstring Processing System Framework Goodger ! S 257 pep-0257.txt Docstring Conventions Goodger, van Rossum S 258 pep-0258.txt DPS Generic Implementation Details Goodger *************** *** 184,188 **** S 255 pep-0255.txt Simple Generators Schemenauer, et al S 256 pep-0256.txt Docstring Processing System Framework Goodger ! S 257 pep-0257.txt Docstring Conventions Goodger S 258 pep-0258.txt DPS Generic Implementation Details Goodger SR 259 pep-0259.txt Omit printing newline after newline van Rossum --- 184,188 ---- S 255 pep-0255.txt Simple Generators Schemenauer, et al S 256 pep-0256.txt Docstring Processing System Framework Goodger ! S 257 pep-0257.txt Docstring Conventions Goodger, van Rossum S 258 pep-0258.txt DPS Generic Implementation Details Goodger SR 259 pep-0259.txt Omit printing newline after newline van Rossum From tim_one@users.sourceforge.net Mon Jun 18 20:21:13 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 18 Jun 2001 12:21:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_b1.py,1.34,1.35 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv27024/python/dist/src/Lib/test Modified Files: test_b1.py Log Message: SF bug 434186: 0x80000000/2 != 0x80000000>>1 i_divmod: New and simpler algorithm. Old one returned gibberish on most boxes when the numerator was -sys.maxint-1. Oddly enough, it worked in the release (not debug) build on Windows, because the compiler optimized away some tricky sign manipulations that were incorrect in this case. Makes you wonder ... Bugfix candidate. Index: test_b1.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_b1.py,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -r1.34 -r1.35 *** test_b1.py 2001/01/22 19:30:07 1.34 --- test_b1.py 2001/06/18 19:21:11 1.35 *************** *** 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: From tim_one@users.sourceforge.net Mon Jun 18 20:21:13 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 18 Jun 2001 12:21:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects intobject.c,2.56,2.57 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv27024/python/dist/src/Objects Modified Files: intobject.c Log Message: SF bug 434186: 0x80000000/2 != 0x80000000>>1 i_divmod: New and simpler algorithm. Old one returned gibberish on most boxes when the numerator was -sys.maxint-1. Oddly enough, it worked in the release (not debug) build on Windows, because the compiler optimized away some tricky sign manipulations that were incorrect in this case. Makes you wonder ... Bugfix candidate. Index: intobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v retrieving revision 2.56 retrieving revision 2.57 diff -C2 -r2.56 -r2.57 *** intobject.c 2001/03/06 12:12:02 2.56 --- intobject.c 2001/06/18 19:21:11 2.57 *************** *** 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; From gvanrossum@users.sourceforge.net Mon Jun 18 21:17:38 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 18 Jun 2001 13:17:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.44,2.16.8.45 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv13926 Modified Files: Tag: descr-branch typeobject.c Log Message: - type_new(): fix a bogus increment in the slotoffset calculation. - type_new(): DECREF(type) when raising an error. - PyBaseObject_Type: add a default setattr implementation. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.44 retrieving revision 2.16.8.45 diff -C2 -r2.16.8.44 -r2.16.8.45 *** typeobject.c 2001/06/18 17:38:41 2.16.8.44 --- typeobject.c 2001/06/18 20:17:36 2.16.8.45 *************** *** 484,489 **** /* Initialize tp_introduced from passed-in dict */ type->tp_introduced = dict = PyDict_Copy(dict); ! if (dict == NULL) return NULL; /* Add descriptors for custom slots from __slots__, or for __dict__ */ --- 484,491 ---- /* Initialize tp_introduced from passed-in dict */ type->tp_introduced = dict = PyDict_Copy(dict); ! if (dict == NULL) { ! Py_DECREF(type); return NULL; + } /* Add descriptors for custom slots from __slots__, or for __dict__ */ *************** *** 498,502 **** mp->type = T_OBJECT; mp->offset = slotoffset; ! slotoffset += i*sizeof(PyObject *); } } --- 500,504 ---- mp->type = T_OBJECT; mp->offset = slotoffset; ! slotoffset += sizeof(PyObject *); } } *************** *** 525,530 **** /* Initialize the rest */ ! if (PyType_InitDict(type) < 0) return NULL; /* Override slots that deserve it */ --- 527,534 ---- /* Initialize the rest */ ! if (PyType_InitDict(type) < 0) { ! Py_DECREF(type); return NULL; + } /* Override slots that deserve it */ *************** *** 644,648 **** 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ ! 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ --- 648,652 ---- 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ ! PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ From gvanrossum@users.sourceforge.net Mon Jun 18 21:46:15 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 18 Jun 2001 13:46:15 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0252.txt,1.8,1.9 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv19320 Modified Files: pep-0252.txt Log Message: Fix typo reported by Andrew MacKeith. Index: pep-0252.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0252.txt,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** pep-0252.txt 2001/06/08 20:50:31 1.8 --- pep-0252.txt 2001/06/18 20:46:13 1.9 *************** *** 328,332 **** - readonly: Boolean indicating whether assignment to this attribute is disallowed. This is usually true for methods. ! Example: C.meth.readonly == 1; C.ivar.kind == 0. - get(): a function of one argument that retrieves the attribute --- 328,332 ---- - 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 From gvanrossum@users.sourceforge.net Mon Jun 18 21:50:29 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 18 Jun 2001 13:50:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.1.2.15,1.1.2.16 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv20299 Modified Files: Tag: descr-branch test_descr.py Log Message: Test slots. Write tests for non-existant attributes using hasattr(). Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_descr.py,v retrieving revision 1.1.2.15 retrieving revision 1.1.2.16 diff -C2 -r1.1.2.15 -r1.1.2.16 *** test_descr.py 2001/06/18 13:40:15 1.1.2.15 --- test_descr.py 2001/06/18 20:50:27 1.1.2.16 *************** *** 414,437 **** def objects(): ! if verbose: print "Testing 'object' class..." ! # Not much to test here :-) a = object() verify(a.__class__ == object == type(a)) b = object() verify(a is not b) ! try: ! object().foo except AttributeError: pass else: ! print "Ouch: object() should not have a foo attribute!" ! try: ! object().foo = 12 ! except AttributeError: pass ! else: ! print "Ouch: object() should not allow setting a foo attribute!" def errors(): --- 414,470 ---- def objects(): ! if verbose: print "Testing object class..." a = object() verify(a.__class__ == object == type(a)) b = object() verify(a is not b) ! verify(not hasattr(a, "foo")) try: ! a.foo = 12 except AttributeError: pass else: ! print "Ouch: object() should not allow setting a foo attribute!" ! verify(not hasattr(object(), "__dict__")) ! class Cdict(object): pass ! x = Cdict() ! verify(x.__dict__ is None) ! x.foo = 1 ! verify(x.foo == 1) ! verify(x.__dict__ == {'foo': 1}) ! ! def slots(): ! if verbose: print "Testing __slots__..." ! class C0(object): ! __slots__ = [] ! x = C0() ! verify(not hasattr(x, "__dict__")) ! verify(not hasattr(x, "foo")) ! ! class C1(object): ! __slots__ = ['a'] ! x = C1() ! verify(not hasattr(x, "__dict__")) ! verify(x.a == None) ! x.a = 1 ! verify(x.a == 1) ! del x.a ! verify(x.a == None) ! ! class C3(object): ! __slots__ = ['a', 'b', 'c'] ! x = C3() ! verify(not hasattr(x, "__dict__")) ! verify(x.a is None) ! verify(x.b is None) ! verify(x.c is None) ! x.a = 1 ! x.b = 2 ! x.c = 3 ! verify(x.a == 1) ! verify(x.b == 2) ! verify(x.c == 3) def errors(): *************** *** 480,483 **** --- 513,524 ---- print "Ouch: __slots__ = {} should be illegal!" + try: + class C(object): + __slots__ = [1] + except TypeError: + pass + else: + print "Ouch: __slots__ = [1] should be illegal!" + def all(): lists() *************** *** 494,497 **** --- 535,539 ---- diamond() objects() + slots() errors() From fdrake@users.sourceforge.net Mon Jun 18 22:05:07 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 18 Jun 2001 14:05:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules termios.c,2.24.2.5,2.24.2.6 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv23740/Modules Modified Files: Tag: release21-maint termios.c Log Message: Fix my own typo: protect the FLUSHO usage with "#ifdef FLUSHO", not "#ifndef FLUSHO". Index: termios.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/termios.c,v retrieving revision 2.24.2.5 retrieving revision 2.24.2.6 diff -C2 -r2.24.2.5 -r2.24.2.6 *** termios.c 2001/06/16 20:46:10 2.24.2.5 --- termios.c 2001/06/18 21:05:04 2.24.2.6 *************** *** 517,521 **** {"ECHOKE", ECHOKE}, #endif ! #ifndef FLUSHO {"FLUSHO", FLUSHO}, #endif --- 517,521 ---- {"ECHOKE", ECHOKE}, #endif ! #ifdef FLUSHO {"FLUSHO", FLUSHO}, #endif From gvanrossum@users.sourceforge.net Mon Jun 18 22:33:19 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 18 Jun 2001 14:33:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects complexobject.c,2.35.4.4,2.35.4.5 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv29437 Modified Files: Tag: descr-branch complexobject.c Log Message: Make complex usable as a base type. Wasn't so hard. :-) Index: complexobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/complexobject.c,v retrieving revision 2.35.4.4 retrieving revision 2.35.4.5 diff -C2 -r2.35.4.4 -r2.35.4.5 *** complexobject.c 2001/06/14 18:12:02 2.35.4.4 --- complexobject.c 2001/06/18 21:33:17 2.35.4.5 *************** *** 184,187 **** --- 184,198 ---- } + static PyObject * + complex_subtype_from_c_complex(PyTypeObject *type, Py_complex cval) + { + PyObject *op; + + op = PyType_GenericAlloc(type, 0); + if (op != NULL) + ((PyComplexObject *)op)->cval = cval; + return op; + } + PyObject * PyComplex_FromCComplex(Py_complex cval) *************** *** 198,201 **** --- 209,221 ---- } + static PyObject * + complex_subtype_from_doubles(PyTypeObject *type, double real, double imag) + { + Py_complex c; + c.real = real; + c.imag = imag; + return complex_subtype_from_c_complex(type, c); + } + PyObject * PyComplex_FromDoubles(double real, double imag) *************** *** 568,572 **** static PyObject * ! complex_from_string(PyObject *v) { extern double strtod(const char *, char **); --- 588,592 ---- static PyObject * ! complex_subtype_from_string(PyTypeObject *type, PyObject *v) { extern double strtod(const char *, char **); *************** *** 716,720 **** } ! return PyComplex_FromDoubles(x,y); } --- 736,740 ---- } ! return complex_subtype_from_doubles(type, x, y); } *************** *** 728,732 **** static char *kwlist[] = {"real", "imag", 0}; - assert(type == &PyComplex_Type); r = Py_False; i = NULL; --- 748,751 ---- *************** *** 735,739 **** return NULL; if (PyString_Check(r) || PyUnicode_Check(r)) ! return complex_from_string(r); if ((nbr = r->ob_type->tp_as_number) == NULL || nbr->nb_float == NULL || --- 754,758 ---- return NULL; if (PyString_Check(r) || PyUnicode_Check(r)) ! return complex_subtype_from_string(type, r); if ((nbr = r->ob_type->tp_as_number) == NULL || nbr->nb_float == NULL || *************** *** 808,812 **** cr.real -= ci.imag; cr.imag += ci.real; ! return PyComplex_FromCComplex(cr); } --- 827,831 ---- cr.real -= ci.imag; cr.imag += ci.real; ! return complex_subtype_from_c_complex(type, cr); } *************** *** 864,868 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ complex_doc, /* tp_doc */ 0, /* tp_traverse */ --- 883,887 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ complex_doc, /* tp_doc */ 0, /* tp_traverse */ From gvanrossum@users.sourceforge.net Mon Jun 18 23:02:32 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 18 Jun 2001 15:02:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.1.2.16,1.1.2.17 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv3702 Modified Files: Tag: descr-branch test_descr.py Log Message: numops(): add optional skip argument, a list of binary op names to skip. complexes(): new function, tests complex numerical operators and tests subtyping from complex. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_descr.py,v retrieving revision 1.1.2.16 retrieving revision 1.1.2.17 diff -C2 -r1.1.2.16 -r1.1.2.17 *** test_descr.py 2001/06/18 20:50:27 1.1.2.16 --- test_descr.py 2001/06/18 22:02:29 1.1.2.17 *************** *** 171,181 **** unops[name] = expr ! def numops(a, b): dict = {'a': a, 'b': b} for name, expr in binops.items(): ! name = "__%s__" % name ! if hasattr(a, name): ! res = eval(expr, dict) ! testbinop(a, b, res, expr, name) for name, expr in unops.items(): name = "__%s__" % name --- 171,182 ---- unops[name] = expr ! def numops(a, b, skip=[]): dict = {'a': a, 'b': b} for name, expr in binops.items(): ! if name not in skip: ! name = "__%s__" % name ! if hasattr(a, name): ! res = eval(expr, dict) ! testbinop(a, b, res, expr, name) for name, expr in unops.items(): name = "__%s__" % name *************** *** 196,199 **** --- 197,217 ---- numops(100.0, 3.0) + def complexes(): + if verbose: print "Testing complex operations..." + numops(100.0j, 3.0j, skip=['lt', 'le', 'gt', 'ge']) + class Number(complex): + __slots__ = ['prec'] + def __repr__(self): + prec = self.prec or 12 + if self.imag == 0.0: + return "%.*g" % (prec, self.real) + if self.real == 0.0: + return "%.*gj" % (prec, self.imag) + return "(%.*g+%.*gj)" % (prec, self.real, prec, self.imag) + __str__ = __repr__ + a = Number(3.14) + a.prec = 12 + verify(`a` == "3.14") + def spamlists(): if verbose: print "Testing spamlist operations..." *************** *** 527,530 **** --- 545,549 ---- longs() floats() + complexes() spamlists() spamdicts() From tim_one@users.sourceforge.net Mon Jun 18 23:08:15 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 18 Jun 2001 15:08:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Grammar Grammar,1.42,1.43 Message-ID: Update of /cvsroot/python/python/dist/src/Grammar In directory usw-pr-cvs1:/tmp/cvs-serv4630/python/dist/src/Grammar Modified Files: Grammar Log Message: Merging the gen-branch into the main line, at Guido's direction. Yay! Bugfix candidate in inspect.py: it was referencing "self" outside of a method. Index: Grammar =================================================================== RCS file: /cvsroot/python/python/dist/src/Grammar/Grammar,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -r1.42 -r1.43 *** Grammar 2001/02/27 18:36:14 1.42 --- Grammar 2001/06/18 22:08:13 1.43 *************** *** 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 Mon Jun 18 23:08:15 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 18 Jun 2001 15:08:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects frameobject.c,2.50,2.51 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv4630/python/dist/src/Objects Modified Files: frameobject.c Log Message: Merging the gen-branch into the main line, at Guido's direction. Yay! Bugfix candidate in inspect.py: it was referencing "self" outside of a method. Index: frameobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/frameobject.c,v retrieving revision 2.50 retrieving revision 2.51 diff -C2 -r2.50 -r2.51 *** frameobject.c 2001/05/08 04:08:20 2.50 --- frameobject.c 2001/06/18 22:08:13 2.51 *************** *** 68,71 **** --- 68,72 ---- int i, slots; PyObject **fastlocals; + PyObject **p; Py_TRASHCAN_SAFE_BEGIN(f) *************** *** 77,80 **** --- 78,85 ---- } + /* Free stack */ + for (p = f->f_valuestack; p < f->f_stackbottom; p++) { + Py_XDECREF(*p); + } Py_XDECREF(f->f_back); Py_XDECREF(f->f_code); *************** *** 222,225 **** --- 227,231 ---- f->f_valuestack = f->f_localsplus + (f->f_nlocals + ncells + nfrees); + f->f_stackbottom = f->f_valuestack; return f; From tim_one@users.sourceforge.net Mon Jun 18 23:08:15 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 18 Jun 2001 15:08:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include compile.h,2.29,2.30 frameobject.h,2.31,2.32 graminit.h,2.16,2.17 opcode.h,2.35,2.36 symtable.h,2.7,2.8 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv4630/python/dist/src/Include Modified Files: compile.h frameobject.h graminit.h opcode.h symtable.h Log Message: Merging the gen-branch into the main line, at Guido's direction. Yay! Bugfix candidate in inspect.py: it was referencing "self" outside of a method. Index: compile.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/compile.h,v retrieving revision 2.29 retrieving revision 2.30 diff -C2 -r2.29 -r2.30 *** compile.h 2001/03/22 02:32:48 2.29 --- compile.h 2001/06/18 22:08:13 2.30 *************** *** 34,37 **** --- 34,38 ---- #define CO_VARKEYWORDS 0x0008 #define CO_NESTED 0x0010 + #define CO_GENERATOR 0x0020 extern DL_IMPORT(PyTypeObject) PyCode_Type; Index: frameobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/frameobject.h,v retrieving revision 2.31 retrieving revision 2.32 diff -C2 -r2.31 -r2.32 *** frameobject.h 2001/03/13 01:58:21 2.31 --- frameobject.h 2001/06/18 22:08:13 2.32 *************** *** 22,25 **** --- 22,27 ---- PyObject *f_locals; /* local symbol table (PyDictObject) */ PyObject **f_valuestack; /* points after the last local */ + PyObject **f_stackbottom; /* points to the last item on the stack if + frame has yielded. */ 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.17 diff -C2 -r2.16 -r2.17 *** graminit.h 2000/08/24 20:09:45 2.16 --- graminit.h 2001/06/18 22:08:13 2.17 *************** *** 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: opcode.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/opcode.h,v retrieving revision 2.35 retrieving revision 2.36 diff -C2 -r2.35 -r2.36 *** opcode.h 2001/04/20 19:13:01 2.35 --- opcode.h 2001/06/18 22:08:13 2.36 *************** *** 72,75 **** --- 72,76 ---- #define IMPORT_STAR 84 #define EXEC_STMT 85 + #define YIELD_VALUE 86 #define POP_BLOCK 87 Index: symtable.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/symtable.h,v retrieving revision 2.7 retrieving revision 2.8 diff -C2 -r2.7 -r2.8 *** symtable.h 2001/03/22 03:57:58 2.7 --- symtable.h 2001/06/18 22:08:13 2.8 *************** *** 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; From tim_one@users.sourceforge.net Mon Jun 18 23:08:15 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 18 Jun 2001 15:08:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib dis.py,1.34,1.35 inspect.py,1.16,1.17 tabnanny.py,1.13,1.14 tokenize.py,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv4630/python/dist/src/Lib Modified Files: dis.py inspect.py tabnanny.py tokenize.py Log Message: Merging the gen-branch into the main line, at Guido's direction. Yay! Bugfix candidate in inspect.py: it was referencing "self" outside of a method. Index: dis.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/dis.py,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -r1.34 -r1.35 *** dis.py 2001/04/20 19:13:01 1.34 --- dis.py 2001/06/18 22:08:13 1.35 *************** *** 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: inspect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/inspect.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -r1.16 -r1.17 *** inspect.py 2001/04/13 14:04:02 1.16 --- inspect.py 2001/06/18 22:08:13 1.17 *************** *** 350,379 **** else: return '' ! class EndOfBlock(Exception): pass ! class BlockFinder: ! """Provide a tokeneater() method to detect the end of a code block.""" ! def __init__(self): ! self.indent = 0 ! self.started = 0 ! self.last = 0 ! def tokeneater(self, type, token, (srow, scol), (erow, ecol), line): ! if not self.started: ! if type == tokenize.NAME: self.started = 1 elif type == tokenize.NEWLINE: ! self.last = srow elif type == tokenize.INDENT: ! self.indent = self.indent + 1 elif type == tokenize.DEDENT: ! self.indent = self.indent - 1 ! if self.indent == 0: raise EndOfBlock, self.last ! ! def getblock(lines): ! """Extract the block of code at the top of the given list of lines.""" ! try: ! tokenize.tokenize(ListReader(lines).readline, BlockFinder().tokeneater) ! except EndOfBlock, eob: ! return lines[:eob.args[0]] def getsourcelines(object): --- 350,375 ---- else: return '' ! def getblock(lines): ! """Extract the block of code at the top of the given list of lines.""" ! indent = 0 ! started = 0 ! last = 0 ! tokens = tokenize.generate_tokens(ListReader(lines).readline) ! for (type, token, (srow, scol), (erow, ecol), line) in tokens: ! if not started: ! if type == tokenize.NAME: ! started = 1 elif type == tokenize.NEWLINE: ! last = srow elif type == tokenize.INDENT: ! indent = indent + 1 elif type == tokenize.DEDENT: ! indent = indent - 1 ! if indent == 0: ! return lines[:last] ! else: ! raise ValueError, "unable to find block" def getsourcelines(object): Index: tabnanny.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/tabnanny.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -r1.13 -r1.14 *** tabnanny.py 2001/04/08 00:38:42 1.13 --- tabnanny.py 2001/06/18 22:08:13 1.14 *************** *** 78,84 **** print "checking", `file`, "..." - reset_globals() try: ! tokenize.tokenize(f.readline, tokeneater) except tokenize.TokenError, msg: --- 78,83 ---- print "checking", `file`, "..." try: ! process_tokens(tokenize.generate_tokens(f.readline)) except tokenize.TokenError, msg: *************** *** 245,270 **** return prefix + " " + string.join(firsts, ', ') ! # The collection of globals, the reset_globals() function, and the ! # tokeneater() function, depend on which version of tokenize is ! # in use. ! if hasattr(tokenize, 'NL'): ! # take advantage of Guido's patch! ! ! indents = [] ! check_equal = 0 ! ! def reset_globals(): ! global indents, check_equal ! check_equal = 0 ! indents = [Whitespace("")] ! ! def tokeneater(type, token, start, end, line, INDENT=tokenize.INDENT, DEDENT=tokenize.DEDENT, NEWLINE=tokenize.NEWLINE, ! JUNK=(tokenize.COMMENT, tokenize.NL) ): ! global indents, check_equal if type == NEWLINE: # a program statement, or ENDMARKER, will eventually follow, --- 244,260 ---- return prefix + " " + string.join(firsts, ', ') ! # Need Guido's enhancement ! assert hasattr(tokenize, 'NL'), "tokenize module too old" ! def process_tokens(tokens, INDENT=tokenize.INDENT, DEDENT=tokenize.DEDENT, NEWLINE=tokenize.NEWLINE, ! JUNK=(tokenize.COMMENT, tokenize.NL)): + indents = [Whitespace("")] + check_equal = 0 + + for (type, token, start, end, line) in tokens: if type == NEWLINE: # a program statement, or ENDMARKER, will eventually follow, *************** *** 312,371 **** raise NannyNag(start[0], msg, line) - else: - # unpatched version of tokenize - - nesting_level = 0 - indents = [] - check_equal = 0 - - def reset_globals(): - global nesting_level, indents, check_equal - nesting_level = check_equal = 0 - indents = [Whitespace("")] - - def tokeneater(type, token, start, end, line, - INDENT=tokenize.INDENT, - DEDENT=tokenize.DEDENT, - NEWLINE=tokenize.NEWLINE, - COMMENT=tokenize.COMMENT, - OP=tokenize.OP): - global nesting_level, indents, check_equal - - if type == INDENT: - check_equal = 0 - thisguy = Whitespace(token) - if not indents[-1].less(thisguy): - witness = indents[-1].not_less_witness(thisguy) - msg = "indent not greater e.g. " + format_witnesses(witness) - raise NannyNag(start[0], msg, line) - indents.append(thisguy) - - elif type == DEDENT: - del indents[-1] - - elif type == NEWLINE: - if nesting_level == 0: - check_equal = 1 - - elif type == COMMENT: - pass - - elif check_equal: - check_equal = 0 - thisguy = Whitespace(line) - if not indents[-1].equal(thisguy): - witness = indents[-1].not_equal_witness(thisguy) - msg = "indent not equal e.g. " + format_witnesses(witness) - raise NannyNag(start[0], msg, line) - - if type == OP and token in ('{', '[', '('): - nesting_level = nesting_level + 1 - - elif type == OP and token in ('}', ']', ')'): - if nesting_level == 0: - raise NannyNag(start[0], - "unbalanced bracket '" + token + "'", - line) - nesting_level = nesting_level - 1 if __name__ == '__main__': --- 302,305 ---- Index: tokenize.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/tokenize.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -r1.22 -r1.23 *** tokenize.py 2001/03/23 05:22:49 1.22 --- tokenize.py 2001/06/18 22:08:13 1.23 *************** *** 112,116 **** --- 112,121 ---- pass + # backwards compatible interface, probably not used def tokenize_loop(readline, tokeneater): + for token_info in generate_tokens(readline): + apply(tokeneater, token_info) + + def generate_tokens(readline): lnum = parenlev = continued = 0 namechars, numchars = string.letters + '_', string.digits *************** *** 130,139 **** if endmatch: pos = end = endmatch.end(0) ! tokeneater(STRING, contstr + line[:end], strstart, (lnum, end), contline + line) contstr, needcont = '', 0 contline = None elif needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n': ! tokeneater(ERRORTOKEN, contstr + line, strstart, (lnum, len(line)), contline) contstr = '' --- 135,144 ---- if endmatch: pos = end = endmatch.end(0) ! yield (STRING, contstr + line[:end], strstart, (lnum, end), contline + line) contstr, needcont = '', 0 contline = None elif needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n': ! yield (ERRORTOKEN, contstr + line, strstart, (lnum, len(line)), contline) contstr = '' *************** *** 157,161 **** if line[pos] in '#\r\n': # skip comments or blank lines ! tokeneater((NL, COMMENT)[line[pos] == '#'], line[pos:], (lnum, pos), (lnum, len(line)), line) continue --- 162,166 ---- if line[pos] in '#\r\n': # skip comments or blank lines ! yield ((NL, COMMENT)[line[pos] == '#'], line[pos:], (lnum, pos), (lnum, len(line)), line) continue *************** *** 163,170 **** if column > indents[-1]: # count indents or dedents indents.append(column) ! tokeneater(INDENT, line[:pos], (lnum, 0), (lnum, pos), line) while column < indents[-1]: indents = indents[:-1] ! tokeneater(DEDENT, '', (lnum, pos), (lnum, pos), line) else: # continued statement --- 168,175 ---- if column > indents[-1]: # count indents or dedents indents.append(column) ! yield (INDENT, line[:pos], (lnum, 0), (lnum, pos), line) while column < indents[-1]: indents = indents[:-1] ! yield (DEDENT, '', (lnum, pos), (lnum, pos), line) else: # continued statement *************** *** 182,191 **** if initial in numchars or \ (initial == '.' and token != '.'): # ordinary number ! tokeneater(NUMBER, token, spos, epos, line) elif initial in '\r\n': ! tokeneater(parenlev > 0 and NL or NEWLINE, token, spos, epos, line) elif initial == '#': ! tokeneater(COMMENT, token, spos, epos, line) elif token in ("'''", '"""', # triple-quoted "r'''", 'r"""', "R'''", 'R"""', --- 187,196 ---- if initial in numchars or \ (initial == '.' and token != '.'): # ordinary number ! yield (NUMBER, token, spos, epos, line) elif initial in '\r\n': ! yield (parenlev > 0 and NL or NEWLINE, token, spos, epos, line) elif initial == '#': ! yield (COMMENT, token, spos, epos, line) elif token in ("'''", '"""', # triple-quoted "r'''", 'r"""', "R'''", 'R"""', *************** *** 198,202 **** pos = endmatch.end(0) token = line[start:pos] ! tokeneater(STRING, token, spos, (lnum, pos), line) else: strstart = (lnum, start) # multiple lines --- 203,207 ---- pos = endmatch.end(0) token = line[start:pos] ! yield (STRING, token, spos, (lnum, pos), line) else: strstart = (lnum, start) # multiple lines *************** *** 217,223 **** break else: # ordinary string ! tokeneater(STRING, token, spos, epos, line) elif initial in namechars: # ordinary name ! tokeneater(NAME, token, spos, epos, line) elif initial == '\\': # continued stmt continued = 1 --- 222,228 ---- break else: # ordinary string ! yield (STRING, token, spos, epos, line) elif initial in namechars: # ordinary name ! yield (NAME, token, spos, epos, line) elif initial == '\\': # continued stmt continued = 1 *************** *** 225,237 **** if initial in '([{': parenlev = parenlev + 1 elif initial in ')]}': parenlev = parenlev - 1 ! tokeneater(OP, token, spos, epos, line) else: ! tokeneater(ERRORTOKEN, line[pos], (lnum, pos), (lnum, pos+1), line) pos = pos + 1 for indent in indents[1:]: # pop remaining indent levels ! tokeneater(DEDENT, '', (lnum, 0), (lnum, 0), '') ! tokeneater(ENDMARKER, '', (lnum, 0), (lnum, 0), '') if __name__ == '__main__': # testing --- 230,242 ---- if initial in '([{': parenlev = parenlev + 1 elif initial in ')]}': parenlev = parenlev - 1 ! yield (OP, token, spos, epos, line) else: ! yield (ERRORTOKEN, line[pos], (lnum, pos), (lnum, pos+1), line) pos = pos + 1 for indent in indents[1:]: # pop remaining indent levels ! yield (DEDENT, '', (lnum, 0), (lnum, 0), '') ! yield (ENDMARKER, '', (lnum, 0), (lnum, 0), '') if __name__ == '__main__': # testing From tim_one@users.sourceforge.net Mon Jun 18 23:08:15 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 18 Jun 2001 15:08:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.248,2.249 compile.c,2.201,2.202 graminit.c,2.28,2.29 marshal.c,1.63,1.64 symtable.c,2.4,2.5 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv4630/python/dist/src/Python Modified Files: ceval.c compile.c graminit.c marshal.c symtable.c Log Message: Merging the gen-branch into the main line, at Guido's direction. Yay! Bugfix candidate in inspect.py: it was referencing "self" outside of a method. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.248 retrieving revision 2.249 diff -C2 -r2.248 -r2.249 *** ceval.c 2001/06/16 21:02:31 2.248 --- ceval.c 2001/06/18 22:08:13 2.249 *************** *** 41,44 **** --- 41,45 ---- PyObject *); + static PyObject *eval_frame(PyFrameObject *); static char *get_func_name(PyObject *); static char *get_func_desc(PyObject *); *************** *** 107,110 **** --- 108,229 ---- + staticforward PyTypeObject gentype; + + typedef struct { + PyObject_HEAD + PyFrameObject *frame; + int running; /* true if generator is being executed */ + } genobject; + + static PyObject * + gen_new(PyFrameObject *f) + { + genobject *gen = PyObject_New(genobject, &gentype); + if (gen == NULL) { + Py_DECREF(f); + return NULL; + } + gen->frame = f; + gen->running = 0; + return (PyObject *)gen; + } + + static void + gen_dealloc(genobject *gen) + { + Py_DECREF(gen->frame); + PyObject_DEL(gen); + } + + static PyObject * + gen_iternext(genobject *gen) + { + PyFrameObject *f = gen->frame; + PyObject *result; + + if (gen->running) { + PyErr_SetString(PyExc_ValueError, + "generator already executing"); + return NULL; + } + if (f->f_stackbottom == NULL) { + return NULL; + } + gen->running = 1; + result = eval_frame(f); + gen->running = 0; + return result; + } + + static PyObject * + gen_next(genobject *gen, PyObject *args) + { + PyObject *result; + + if (!PyArg_ParseTuple(args, ":next")) + return NULL; + + result = gen_iternext(gen); + + if (result == NULL && !PyErr_Occurred()) { + PyErr_SetObject(PyExc_StopIteration, Py_None); + return NULL; + } + + return result; + } + + static PyObject * + gen_getiter(PyObject *gen) + { + Py_INCREF(gen); + return gen; + } + + static struct PyMethodDef gen_methods[] = { + {"next", (PyCFunction)gen_next, METH_VARARGS, + "next() -- get the next value, or raise StopIteration"}, + {NULL, NULL} /* Sentinel */ + }; + + static PyObject * + gen_getattr(genobject *gen, char *name) + { + return Py_FindMethod(gen_methods, (PyObject *)gen, name); + } + + 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 */ + 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, /* 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 */ + }; + + #ifdef WITH_THREAD *************** *** 338,342 **** WHY_RETURN, /* 'return' statement */ WHY_BREAK, /* 'break' statement */ ! WHY_CONTINUE /* 'continue' statement */ }; --- 457,462 ---- WHY_RETURN, /* 'return' statement */ WHY_BREAK, /* 'break' statement */ ! WHY_CONTINUE, /* 'continue' statement */ ! WHY_YIELD, /* 'yield' operator */ }; *************** *** 359,366 **** /* Interpreter main loop */ ! static PyObject * ! eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, ! PyObject **args, int argcount, PyObject **kws, int kwcount, ! PyObject **defs, int defcount, PyObject *closure) { #ifdef DXPAIRS --- 479,484 ---- /* Interpreter main loop */ ! PyObject * ! eval_frame(PyFrameObject *f) { #ifdef DXPAIRS *************** *** 379,386 **** register PyObject *t; register PyObject *stream = NULL; /* for PRINT opcodes */ - register PyFrameObject *f; /* Current frame */ register PyObject **fastlocals, **freevars; PyObject *retval = NULL; /* Return value */ PyThreadState *tstate = PyThreadState_GET(); unsigned char *first_instr; #ifdef LLTRACE --- 497,504 ---- register PyObject *t; register PyObject *stream = NULL; /* for PRINT opcodes */ register PyObject **fastlocals, **freevars; PyObject *retval = NULL; /* Return value */ PyThreadState *tstate = PyThreadState_GET(); + PyCodeObject *co; unsigned char *first_instr; #ifdef LLTRACE *************** *** 389,393 **** #if defined(Py_DEBUG) || defined(LLTRACE) /* Make it easier to find out where we are with a debugger */ ! char *filename = PyString_AsString(co->co_filename); #endif --- 507,511 ---- #if defined(Py_DEBUG) || defined(LLTRACE) /* Make it easier to find out where we are with a debugger */ ! char *filename; #endif *************** *** 427,430 **** --- 545,551 ---- /* Start of code */ + if (f == NULL) + return NULL; + #ifdef USE_STACKCHECK if (tstate->recursion_depth%10 == 0 && PyOS_CheckStack()) { *************** *** 433,675 **** } #endif - - if (globals == NULL) { - PyErr_SetString(PyExc_SystemError, "eval_code2: NULL globals"); - return NULL; - } - - #ifdef LLTRACE - lltrace = PyDict_GetItemString(globals, "__lltrace__") != NULL; - #endif - - f = PyFrame_New(tstate, /*back*/ - co, /*code*/ - globals, locals); - if (f == NULL) - return NULL; - - tstate->frame = f; - fastlocals = f->f_localsplus; - freevars = f->f_localsplus + f->f_nlocals; - - if (co->co_argcount > 0 || - co->co_flags & (CO_VARARGS | CO_VARKEYWORDS)) { - int i; - int n = argcount; - PyObject *kwdict = NULL; - if (co->co_flags & CO_VARKEYWORDS) { - kwdict = PyDict_New(); - if (kwdict == NULL) - goto fail; - i = co->co_argcount; - if (co->co_flags & CO_VARARGS) - i++; - SETLOCAL(i, kwdict); - } - if (argcount > co->co_argcount) { - if (!(co->co_flags & CO_VARARGS)) { - PyErr_Format(PyExc_TypeError, - "%.200s() takes %s %d " - "%sargument%s (%d given)", - PyString_AsString(co->co_name), - defcount ? "at most" : "exactly", - co->co_argcount, - kwcount ? "non-keyword " : "", - co->co_argcount == 1 ? "" : "s", - argcount); - goto fail; - } - n = co->co_argcount; - } - for (i = 0; i < n; i++) { - x = args[i]; - Py_INCREF(x); - SETLOCAL(i, x); - } - if (co->co_flags & CO_VARARGS) { - u = PyTuple_New(argcount - n); - if (u == NULL) - goto fail; - SETLOCAL(co->co_argcount, u); - for (i = n; i < argcount; i++) { - x = args[i]; - Py_INCREF(x); - PyTuple_SET_ITEM(u, i-n, x); - } - } - for (i = 0; i < kwcount; i++) { - PyObject *keyword = kws[2*i]; - PyObject *value = kws[2*i + 1]; - int j; - if (keyword == NULL || !PyString_Check(keyword)) { - PyErr_Format(PyExc_TypeError, - "%.200s() keywords must be strings", - PyString_AsString(co->co_name)); - goto fail; - } - /* XXX slow -- speed up using dictionary? */ - for (j = 0; j < co->co_argcount; j++) { - PyObject *nm = PyTuple_GET_ITEM( - co->co_varnames, j); - int cmp = PyObject_RichCompareBool( - keyword, nm, Py_EQ); - if (cmp > 0) - break; - else if (cmp < 0) - goto fail; - } - /* Check errors from Compare */ - if (PyErr_Occurred()) - goto fail; - if (j >= co->co_argcount) { - if (kwdict == NULL) { - PyErr_Format(PyExc_TypeError, - "%.200s() got an unexpected " - "keyword argument '%.400s'", - PyString_AsString(co->co_name), - PyString_AsString(keyword)); - goto fail; - } - PyDict_SetItem(kwdict, keyword, value); - } - else { - if (GETLOCAL(j) != NULL) { - PyErr_Format(PyExc_TypeError, - "%.200s() got multiple " - "values for keyword " - "argument '%.400s'", - PyString_AsString(co->co_name), - PyString_AsString(keyword)); - goto fail; - } - Py_INCREF(value); - SETLOCAL(j, value); - } - } - if (argcount < co->co_argcount) { - int m = co->co_argcount - defcount; - for (i = argcount; i < m; i++) { - if (GETLOCAL(i) == NULL) { - PyErr_Format(PyExc_TypeError, - "%.200s() takes %s %d " - "%sargument%s (%d given)", - PyString_AsString(co->co_name), - ((co->co_flags & CO_VARARGS) || - defcount) ? "at least" - : "exactly", - m, kwcount ? "non-keyword " : "", - m == 1 ? "" : "s", i); - goto fail; - } - } - if (n > m) - i = n - m; - else - i = 0; - for (; i < defcount; i++) { - if (GETLOCAL(m+i) == NULL) { - PyObject *def = defs[i]; - Py_INCREF(def); - SETLOCAL(m+i, def); - } - } - } - } - else { - if (argcount > 0 || kwcount > 0) { - PyErr_Format(PyExc_TypeError, - "%.200s() takes no arguments (%d given)", - PyString_AsString(co->co_name), - argcount + kwcount); - goto fail; - } - } - /* Allocate and initialize storage for cell vars, and copy free - vars into frame. This isn't too efficient right now. */ - if (f->f_ncells) { - int i = 0, j = 0, nargs, found; - char *cellname, *argname; - PyObject *c; - - nargs = co->co_argcount; - if (co->co_flags & CO_VARARGS) - nargs++; - if (co->co_flags & CO_VARKEYWORDS) - nargs++; ! /* Check for cells that shadow args */ ! for (i = 0; i < f->f_ncells && j < nargs; ++i) { ! cellname = PyString_AS_STRING( ! PyTuple_GET_ITEM(co->co_cellvars, i)); ! found = 0; ! while (j < nargs) { ! argname = PyString_AS_STRING( ! PyTuple_GET_ITEM(co->co_varnames, j)); ! if (strcmp(cellname, argname) == 0) { ! c = PyCell_New(GETLOCAL(j)); ! if (c == NULL) ! goto fail; ! GETLOCAL(f->f_nlocals + i) = c; ! found = 1; ! break; ! } ! j++; ! } ! if (found == 0) { ! c = PyCell_New(NULL); ! if (c == NULL) ! goto fail; ! SETLOCAL(f->f_nlocals + i, c); ! } ! } ! /* Initialize any that are left */ ! while (i < f->f_ncells) { ! c = PyCell_New(NULL); ! if (c == NULL) ! goto fail; ! SETLOCAL(f->f_nlocals + i, c); ! i++; ! } ! } ! if (f->f_nfreevars) { ! int i; ! for (i = 0; i < f->f_nfreevars; ++i) { ! PyObject *o = PyTuple_GET_ITEM(closure, i); ! Py_INCREF(o); ! freevars[f->f_ncells + i] = o; ! } ! } ! ! if (tstate->sys_tracefunc != NULL) { ! /* 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->sys_tracefunc, ! &f->f_trace, f, str_call, ! Py_None/*XXX how to compute arguments now?*/)) { ! /* Trace function raised an error */ ! goto fail; ! } ! } ! ! if (tstate->sys_profilefunc != NULL) { ! /* Similar for sys_profilefunc, except it needn't return ! itself and isn't called for "line" events */ ! if (call_trace(&tstate->sys_profilefunc, ! (PyObject**)0, f, str_call, ! Py_None/*XXX*/)) { ! goto fail; ! } ! } ! if (++tstate->recursion_depth > recursion_limit) { --tstate->recursion_depth; --- 554,559 ---- } #endif ! /* push frame */ if (++tstate->recursion_depth > recursion_limit) { --tstate->recursion_depth; *************** *** 677,687 **** "maximum recursion depth exceeded"); tstate->frame = f->f_back; - Py_DECREF(f); return NULL; } _PyCode_GETCODEPTR(co, &first_instr); ! next_instr = first_instr; ! stack_pointer = f->f_valuestack; why = WHY_NOT; --- 561,584 ---- "maximum recursion depth exceeded"); tstate->frame = f->f_back; return NULL; } + f->f_back = tstate->frame; + tstate->frame = f; + + co = f->f_code; + fastlocals = f->f_localsplus; + freevars = f->f_localsplus + f->f_nlocals; _PyCode_GETCODEPTR(co, &first_instr); ! next_instr = first_instr + f->f_lasti; ! stack_pointer = f->f_stackbottom; ! f->f_stackbottom = NULL; ! ! #ifdef LLTRACE ! lltrace = PyDict_GetItemString(f->f_globals,"__lltrace__") != NULL; ! #endif ! #if defined(Py_DEBUG) || defined(LLTRACE) ! filename = PyString_AsString(co->co_filename); ! #endif why = WHY_NOT; *************** *** 1460,1463 **** --- 1357,1368 ---- break; + case YIELD_VALUE: + retval = POP(); + f->f_stackbottom = stack_pointer; + f->f_lasti = INSTR_OFFSET(); + why = WHY_YIELD; + break; + + case EXEC_STMT: w = POP(); *************** *** 1485,1488 **** --- 1390,1394 ---- why = (enum why_code) PyInt_AsLong(v); if (why == WHY_RETURN || + why == WHY_YIELD || why == CONTINUE_LOOP) retval = POP(); *************** *** 2226,2230 **** /* Unwind stacks if a (pseudo) exception occurred */ ! while (why != WHY_NOT && f->f_iblock > 0) { PyTryBlock *b = PyFrame_BlockPop(f); --- 2132,2136 ---- /* Unwind stacks if a (pseudo) exception occurred */ ! while (why != WHY_NOT && why != WHY_YIELD && f->f_iblock > 0) { PyTryBlock *b = PyFrame_BlockPop(f); *************** *** 2296,2309 **** /* Pop remaining stack entries */ while (!EMPTY()) { v = POP(); Py_XDECREF(v); } ! if (why != WHY_RETURN) retval = NULL; if (f->f_trace) { ! if (why == WHY_RETURN) { if (call_trace(&f->f_trace, &f->f_trace, f, str_return, retval)) { --- 2202,2217 ---- /* Pop remaining stack entries */ + /* while (!EMPTY()) { v = POP(); Py_XDECREF(v); } + */ ! if (why != WHY_RETURN && why != WHY_YIELD) retval = NULL; if (f->f_trace) { ! if (why == WHY_RETURN || why == WHY_YIELD) { if (call_trace(&f->f_trace, &f->f_trace, f, str_return, retval)) { *************** *** 2315,2319 **** } ! if (tstate->sys_profilefunc && why == WHY_RETURN) { if (call_trace(&tstate->sys_profilefunc, (PyObject**)0, f, str_return, retval)) { --- 2223,2228 ---- } ! if (tstate->sys_profilefunc && ! (why == WHY_RETURN || why == WHY_YIELD)) { if (call_trace(&tstate->sys_profilefunc, (PyObject**)0, f, str_return, retval)) { *************** *** 2326,2341 **** reset_exc_info(tstate); --tstate->recursion_depth; ! fail: /* Jump here from prelude on failure */ ! /* Restore previous frame and release the current one */ ! tstate->frame = f->f_back; ! Py_DECREF(f); return retval; } static void set_exc_info(PyThreadState *tstate, --- 2235,2504 ---- reset_exc_info(tstate); + /* pop frame */ --tstate->recursion_depth; + tstate->frame = f->f_back; ! return retval; ! } ! ! static PyObject * ! eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, ! PyObject **args, int argcount, PyObject **kws, int kwcount, ! PyObject **defs, int defcount, PyObject *closure) ! { ! register PyFrameObject *f; ! register PyObject *retval = NULL; ! register PyObject **fastlocals, **freevars; ! PyThreadState *tstate = PyThreadState_GET(); ! PyObject *x, *u; ! if (globals == NULL) { ! PyErr_SetString(PyExc_SystemError, "eval_code2: NULL globals"); ! return NULL; ! } ! f = PyFrame_New(tstate, /*back*/ ! co, /*code*/ ! globals, locals); ! if (f == NULL) ! return NULL; ! ! fastlocals = f->f_localsplus; ! freevars = f->f_localsplus + f->f_nlocals; ! ! if (co->co_argcount > 0 || ! co->co_flags & (CO_VARARGS | CO_VARKEYWORDS)) { ! int i; ! int n = argcount; ! PyObject *kwdict = NULL; ! if (co->co_flags & CO_VARKEYWORDS) { ! kwdict = PyDict_New(); ! if (kwdict == NULL) ! goto fail; ! i = co->co_argcount; ! if (co->co_flags & CO_VARARGS) ! i++; ! SETLOCAL(i, kwdict); ! } ! if (argcount > co->co_argcount) { ! if (!(co->co_flags & CO_VARARGS)) { ! PyErr_Format(PyExc_TypeError, ! "%.200s() takes %s %d " ! "%sargument%s (%d given)", ! PyString_AsString(co->co_name), ! defcount ? "at most" : "exactly", ! co->co_argcount, ! kwcount ? "non-keyword " : "", ! co->co_argcount == 1 ? "" : "s", ! argcount); ! goto fail; ! } ! n = co->co_argcount; ! } ! for (i = 0; i < n; i++) { ! x = args[i]; ! Py_INCREF(x); ! SETLOCAL(i, x); ! } ! if (co->co_flags & CO_VARARGS) { ! u = PyTuple_New(argcount - n); ! if (u == NULL) ! goto fail; ! SETLOCAL(co->co_argcount, u); ! for (i = n; i < argcount; i++) { ! x = args[i]; ! Py_INCREF(x); ! PyTuple_SET_ITEM(u, i-n, x); ! } ! } ! for (i = 0; i < kwcount; i++) { ! PyObject *keyword = kws[2*i]; ! PyObject *value = kws[2*i + 1]; ! int j; ! if (keyword == NULL || !PyString_Check(keyword)) { ! PyErr_Format(PyExc_TypeError, ! "%.200s() keywords must be strings", ! PyString_AsString(co->co_name)); ! goto fail; ! } ! /* XXX slow -- speed up using dictionary? */ ! for (j = 0; j < co->co_argcount; j++) { ! PyObject *nm = PyTuple_GET_ITEM( ! co->co_varnames, j); ! int cmp = PyObject_RichCompareBool( ! keyword, nm, Py_EQ); ! if (cmp > 0) ! break; ! else if (cmp < 0) ! goto fail; ! } ! /* Check errors from Compare */ ! if (PyErr_Occurred()) ! goto fail; ! if (j >= co->co_argcount) { ! if (kwdict == NULL) { ! PyErr_Format(PyExc_TypeError, ! "%.200s() got an unexpected " ! "keyword argument '%.400s'", ! PyString_AsString(co->co_name), ! PyString_AsString(keyword)); ! goto fail; ! } ! PyDict_SetItem(kwdict, keyword, value); ! } ! else { ! if (GETLOCAL(j) != NULL) { ! PyErr_Format(PyExc_TypeError, ! "%.200s() got multiple " ! "values for keyword " ! "argument '%.400s'", ! PyString_AsString(co->co_name), ! PyString_AsString(keyword)); ! goto fail; ! } ! Py_INCREF(value); ! SETLOCAL(j, value); ! } ! } ! if (argcount < co->co_argcount) { ! int m = co->co_argcount - defcount; ! for (i = argcount; i < m; i++) { ! if (GETLOCAL(i) == NULL) { ! PyErr_Format(PyExc_TypeError, ! "%.200s() takes %s %d " ! "%sargument%s (%d given)", ! PyString_AsString(co->co_name), ! ((co->co_flags & CO_VARARGS) || ! defcount) ? "at least" ! : "exactly", ! m, kwcount ? "non-keyword " : "", ! m == 1 ? "" : "s", i); ! goto fail; ! } ! } ! if (n > m) ! i = n - m; ! else ! i = 0; ! for (; i < defcount; i++) { ! if (GETLOCAL(m+i) == NULL) { ! PyObject *def = defs[i]; ! Py_INCREF(def); ! SETLOCAL(m+i, def); ! } ! } ! } ! } ! else { ! if (argcount > 0 || kwcount > 0) { ! PyErr_Format(PyExc_TypeError, ! "%.200s() takes no arguments (%d given)", ! PyString_AsString(co->co_name), ! argcount + kwcount); ! goto fail; ! } ! } ! /* Allocate and initialize storage for cell vars, and copy free ! vars into frame. This isn't too efficient right now. */ ! if (f->f_ncells) { ! int i = 0, j = 0, nargs, found; ! char *cellname, *argname; ! PyObject *c; ! ! nargs = co->co_argcount; ! if (co->co_flags & CO_VARARGS) ! nargs++; ! if (co->co_flags & CO_VARKEYWORDS) ! nargs++; ! ! /* Check for cells that shadow args */ ! for (i = 0; i < f->f_ncells && j < nargs; ++i) { ! cellname = PyString_AS_STRING( ! PyTuple_GET_ITEM(co->co_cellvars, i)); ! found = 0; ! while (j < nargs) { ! argname = PyString_AS_STRING( ! PyTuple_GET_ITEM(co->co_varnames, j)); ! if (strcmp(cellname, argname) == 0) { ! c = PyCell_New(GETLOCAL(j)); ! if (c == NULL) ! goto fail; ! GETLOCAL(f->f_nlocals + i) = c; ! found = 1; ! break; ! } ! j++; ! } ! if (found == 0) { ! c = PyCell_New(NULL); ! if (c == NULL) ! goto fail; ! SETLOCAL(f->f_nlocals + i, c); ! } ! } ! /* Initialize any that are left */ ! while (i < f->f_ncells) { ! c = PyCell_New(NULL); ! if (c == NULL) ! goto fail; ! SETLOCAL(f->f_nlocals + i, c); ! i++; ! } ! } ! if (f->f_nfreevars) { ! int i; ! for (i = 0; i < f->f_nfreevars; ++i) { ! PyObject *o = PyTuple_GET_ITEM(closure, i); ! Py_INCREF(o); ! freevars[f->f_ncells + i] = o; ! } ! } ! ! if (tstate->sys_tracefunc != NULL) { ! /* 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->sys_tracefunc, ! &f->f_trace, f, str_call, ! Py_None/*XXX how to compute arguments now?*/)) { ! /* Trace function raised an error */ ! goto fail; ! } ! } ! ! if (tstate->sys_profilefunc != NULL) { ! /* Similar for sys_profilefunc, except it needn't return ! itself and isn't called for "line" events */ ! if (call_trace(&tstate->sys_profilefunc, ! (PyObject**)0, f, str_call, ! Py_None/*XXX*/)) { ! goto fail; ! } ! } ! ! if (co->co_flags & CO_GENERATOR) { ! /* create a new generator that owns the ready to run frame ! * and return that as the value */ ! return gen_new(f); ! } ! ! retval = eval_frame(f); + fail: /* Jump here from prelude on failure */ + + Py_DECREF(f); return retval; } + static void set_exc_info(PyThreadState *tstate, *************** *** 2701,2705 **** return 0; } - PyObject * --- 2864,2867 ---- Index: compile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v retrieving revision 2.201 retrieving revision 2.202 diff -C2 -r2.201 -r2.202 *** compile.c 2001/06/09 09:26:21 2.201 --- compile.c 2001/06/18 22:08:13 2.202 *************** *** 2635,2649 **** com_error(c, PyExc_SyntaxError, "'return' outside function"); } ! if (NCH(n) < 2) { ! com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None)); com_push(c, 1); } ! else ! com_node(c, CHILD(n, 1)); ! com_addbyte(c, RETURN_VALUE); com_pop(c, 1); } static void com_raise_stmt(struct compiling *c, node *n) { --- 2635,2673 ---- 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"); ! } ! com_addoparg(c, LOAD_CONST, ! com_addconst(c, PyExc_StopIteration)); com_push(c, 1); + com_addoparg(c, RAISE_VARARGS, 1); } ! else { ! if (NCH(n) < 2) { ! com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None)); ! com_push(c, 1); ! } ! else ! com_node(c, CHILD(n, 1)); ! com_addbyte(c, RETURN_VALUE); ! } com_pop(c, 1); } static void + com_yield_stmt(struct compiling *c, node *n) + { + REQ(n, yield_stmt); /* 'yield' testlist */ + if (!c->c_infunction) { + com_error(c, PyExc_SyntaxError, "'yield' outside function"); + } + 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) { *************** *** 3456,3459 **** --- 3480,3486 ---- com_return_stmt(c, n); break; + case yield_stmt: + com_yield_stmt(c, n); + break; case raise_stmt: com_raise_stmt(c, n); *************** *** 3675,3682 **** com_node(c, CHILD(n, 4)); c->c_infunction = 0; ! com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None)); ! com_push(c, 1); ! com_addbyte(c, RETURN_VALUE); ! com_pop(c, 1); } --- 3702,3718 ---- com_node(c, CHILD(n, 4)); c->c_infunction = 0; ! if (c->c_flags & CO_GENERATOR) { ! com_addoparg(c, LOAD_CONST, ! com_addconst(c, PyExc_StopIteration)); ! com_push(c, 1); ! com_addoparg(c, RAISE_VARARGS, 1); ! com_pop(c, 1); ! } ! else { ! com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None)); ! com_push(c, 1); ! com_addbyte(c, RETURN_VALUE); ! com_pop(c, 1); ! } } *************** *** 4343,4346 **** --- 4379,4384 ---- 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; *************** *** 4901,4904 **** --- 4939,4946 ---- 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: graminit.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/graminit.c,v retrieving revision 2.28 retrieving revision 2.29 diff -C2 -r2.28 -r2.29 *** graminit.c 2000/08/24 20:11:32 2.28 --- graminit.c 2001/06/18 22:08:13 2.29 *************** *** 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: marshal.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/marshal.c,v retrieving revision 1.63 retrieving revision 1.64 diff -C2 -r1.63 -r1.64 *** marshal.c 2001/05/08 15:19:57 1.63 --- marshal.c 2001/06/18 22:08:13 1.64 *************** *** 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); *************** *** 376,379 **** --- 380,387 ---- Py_INCREF(Py_None); return Py_None; + + case TYPE_STOPITER: + Py_INCREF(PyExc_StopIteration); + return PyExc_StopIteration; case TYPE_ELLIPSIS: Index: symtable.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/symtable.c,v retrieving revision 2.4 retrieving revision 2.5 diff -C2 -r2.4 -r2.5 *** symtable.c 2001/02/27 19:07:02 2.4 --- symtable.c 2001/06/18 22:08:13 2.5 *************** *** 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) From gvanrossum@users.sourceforge.net Mon Jun 18 23:21:44 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 18 Jun 2001 15:21:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.45,2.16.8.46 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv8469 Modified Files: Tag: descr-branch typeobject.c Log Message: Experimental policy change: - the call to tp_init is now made in type_call, not in type_new - tp_new is only called with sequential arguments - PyType_GenericNew is now super-simple: only calls tp_alloc This makes it easier for subclassable types to do the right thing -- no need to call tp_init in their tp_new implementation. We'll see if this works out alright. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.45 retrieving revision 2.16.8.46 diff -C2 -r2.16.8.45 -r2.16.8.46 *** typeobject.c 2001/06/18 20:17:36 2.16.8.45 --- typeobject.c 2001/06/18 22:21:42 2.16.8.46 *************** *** 67,70 **** --- 67,72 ---- type_call(PyTypeObject *type, PyObject *args, PyObject *kwds) { + PyObject *obj; + if (type->tp_new == NULL) { PyErr_Format(PyExc_TypeError, *************** *** 74,78 **** } ! return type->tp_new(type, args, kwds); } --- 76,87 ---- } ! 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; ! } ! } ! return obj; } *************** *** 108,121 **** PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds) { ! PyObject *self; ! ! self = type->tp_alloc(type, 0); ! if (self == NULL) ! return NULL; ! if (type->tp_init != NULL && type->tp_init(self, args, kwds) < 0) { ! Py_DECREF(self); ! return NULL; ! } ! return self; } --- 117,121 ---- PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds) { ! return type->tp_alloc(type, 0); } From tim_one@users.sourceforge.net Mon Jun 18 23:27:41 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 18 Jun 2001 15:27:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_struct.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv9470/python/dist/src/Lib/test Modified Files: test_struct.py Log Message: Added "i" and "l" to the list of std-mode struct codes that don't range- check correctly on pack(). While these were checking OK on my 32-bit box, Mark Favas reported failures on a 64-bit box (alas, easy to believe). Index: test_struct.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_struct.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -r1.12 -r1.13 *** test_struct.py 2001/06/13 22:45:27 1.12 --- test_struct.py 2001/06/18 22:27:39 1.13 *************** *** 189,193 **** # XXX Most std integer modes fail to test for out-of-range. ! BUGGY_RANGE_CHECK = "bBhHIL" def __init__(self, formatpair, bytesize): --- 189,196 ---- # 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): From bwarsaw@users.sourceforge.net Tue Jun 19 00:40:37 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Mon, 18 Jun 2001 16:40:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc python-mode.el,4.1,4.2 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv24639 Modified Files: python-mode.el Log Message: (py-continuation-offset): New variable which controls how much to indent continuation lines, defined as lines following those that end in backslash. (py-compute-indentation): Support for py-continuation-offset. Index: python-mode.el =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/python-mode.el,v retrieving revision 4.1 retrieving revision 4.2 diff -C2 -r4.1 -r4.2 *** python-mode.el 2001/04/11 22:27:41 4.1 --- python-mode.el 2001/06/18 23:40:35 4.2 *************** *** 9,13 **** ;; Keywords: python languages oop ! (defconst py-version "$Revision$" "`python-mode' version number.") --- 9,13 ---- ;; Keywords: python languages oop ! (defconst py-version "4.1" "`python-mode' version number.") *************** *** 124,127 **** --- 124,134 ---- :group 'python) + (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) + (defcustom py-smart-indentation t "*Should `python-mode' try to automagically set some indentation variables? *************** *** 1801,1805 **** ;; column (end-of-line) ! (setq endpos (point) searching t) (back-to-indentation) (setq startpos (point)) --- 1808,1813 ---- ;; column (end-of-line) ! (setq endpos (point) ! searching t) (back-to-indentation) (setq startpos (point)) *************** *** 1826,1830 **** (goto-char startpos) (skip-chars-forward "^ \t\n"))) ! (1+ (current-column)))))) ;; not on a continuation line --- 1834,1839 ---- (goto-char startpos) (skip-chars-forward "^ \t\n"))) ! (+ (current-column) py-continuation-offset 1) ! )))) ;; not on a continuation line From tim_one@users.sourceforge.net Tue Jun 19 00:56:39 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 18 Jun 2001 16:56:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib imaplib.py,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv27903/python/dist/src/Lib Modified Files: imaplib.py Log Message: Somebody checked this in w/ an ambiguous tab/space mix (reported by Mark Favas). Index: imaplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/imaplib.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -r1.28 -r1.29 *** imaplib.py 2001/06/17 13:31:25 1.28 --- imaplib.py 2001/06/18 23:56:36 1.29 *************** *** 574,582 **** def namespace(self): ! """ Returns IMAP namespaces ala rfc2342 ! """ ! name = 'NAMESPACE' ! typ, dat = self._simple_command(name) ! return self._untagged_response(typ, dat, name) --- 574,582 ---- def namespace(self): ! """ Returns IMAP namespaces ala rfc2342 ! """ ! name = 'NAMESPACE' ! typ, dat = self._simple_command(name) ! return self._untagged_response(typ, dat, name) From tim_one@users.sourceforge.net Tue Jun 19 01:26:27 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 18 Jun 2001 17:26:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib keyword.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv32447/python/dist/src/Lib Modified Files: keyword.py Log Message: Updated keyword.py for "yield". Index: keyword.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/keyword.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -r1.10 -r1.11 *** keyword.py 2001/02/09 09:10:35 1.10 --- keyword.py 2001/06/19 00:26:25 1.11 *************** *** 43,46 **** --- 43,47 ---- 'try', 'while', + 'yield', #--end keywords-- ] From tim_one@users.sourceforge.net Tue Jun 19 01:28:49 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 18 Jun 2001 17:28:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/idle PyParse.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/idle In directory usw-pr-cvs1:/tmp/cvs-serv32590/python/dist/src/Tools/idle Modified Files: PyParse.py Log Message: Taught IDLE's autoident parser that "yield" is a keyword that begins a stmt. Along w/ the preceding change to keyword.py, making all this work w/ a future-stmt just looks harder and harder. Index: PyParse.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/idle/PyParse.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** PyParse.py 2001/02/16 22:13:48 1.8 --- PyParse.py 2001/06/19 00:28:47 1.9 *************** *** 30,33 **** --- 30,34 ---- | raise | import + | yield ) \b From gvanrossum@users.sourceforge.net Tue Jun 19 12:43:28 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 19 Jun 2001 04:43:28 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0257.txt,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv25787 Modified Files: pep-0257.txt Log Message: Add back the Emacs stanza. Index: pep-0257.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0257.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** pep-0257.txt 2001/06/18 19:18:58 1.2 --- pep-0257.txt 2001/06/19 11:43:26 1.3 *************** *** 230,231 **** --- 230,238 ---- This document borrows ideas from the archives of the Python Doc-SIG [5]. Thanks to all members past and present. + + + + Local Variables: + mode: indented-text + indent-tabs-mode: nil + End: From gvanrossum@users.sourceforge.net Tue Jun 19 13:26:48 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 19 Jun 2001 05:26:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include object.h,2.79.2.16,2.79.2.17 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv3016 Modified Files: Tag: descr-branch object.h Log Message: - Rename the (#ifdef COUNT_ALLOCS) counter tp_free to tp_frees. - Add a new slot, tp_free, which will be a low-level "free object's memory" callback. Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.79.2.16 retrieving revision 2.79.2.17 diff -C2 -r2.79.2.16 -r2.79.2.17 *** object.h 2001/06/17 23:13:39 2.79.2.16 --- object.h 2001/06/19 12:26:46 2.79.2.17 *************** *** 273,276 **** --- 273,277 ---- allocfunc tp_alloc; newfunc tp_new; + destructor tp_free; /* Low-level free-memory routine */ PyObject *tp_bases; PyObject *tp_mro; /* method resolution order */ *************** *** 280,284 **** /* these must be last and never explicitly initialized */ int tp_allocs; ! int tp_free; int tp_maxalloc; struct _typeobject *tp_next; --- 281,285 ---- /* these must be last and never explicitly initialized */ int tp_allocs; ! int tp_frees; int tp_maxalloc; struct _typeobject *tp_next; *************** *** 460,465 **** #ifndef Py_TRACE_REFS #ifdef COUNT_ALLOCS ! #define _Py_Dealloc(op) ((op)->ob_type->tp_free++, (*(op)->ob_type->tp_dealloc)((PyObject *)(op))) ! #define _Py_ForgetReference(op) ((op)->ob_type->tp_free++) #else /* !COUNT_ALLOCS */ #define _Py_Dealloc(op) (*(op)->ob_type->tp_dealloc)((PyObject *)(op)) --- 461,466 ---- #ifndef Py_TRACE_REFS #ifdef COUNT_ALLOCS ! #define _Py_Dealloc(op) ((op)->ob_type->tp_frees++, (*(op)->ob_type->tp_dealloc)((PyObject *)(op))) ! #define _Py_ForgetReference(op) ((op)->ob_type->tp_frees++) #else /* !COUNT_ALLOCS */ #define _Py_Dealloc(op) (*(op)->ob_type->tp_dealloc)((PyObject *)(op)) From gvanrossum@users.sourceforge.net Tue Jun 19 13:27:24 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 19 Jun 2001 05:27:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects object.c,2.124.4.14,2.124.4.15 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv3175 Modified Files: Tag: descr-branch object.c Log Message: - Rename the (#ifdef COUNT_ALLOCS) counter tp_free to tp_frees. Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.124.4.14 retrieving revision 2.124.4.15 diff -C2 -r2.124.4.14 -r2.124.4.15 *** object.c 2001/06/16 13:59:48 2.124.4.14 --- object.c 2001/06/19 12:27:22 2.124.4.15 *************** *** 33,37 **** for (tp = type_list; tp; tp = tp->tp_next) fprintf(stderr, "%s alloc'd: %d, freed: %d, max in use: %d\n", ! tp->tp_name, tp->tp_allocs, tp->tp_free, tp->tp_maxalloc); fprintf(stderr, "fast tuple allocs: %d, empty: %d\n", --- 33,37 ---- for (tp = type_list; tp; tp = tp->tp_next) fprintf(stderr, "%s alloc'd: %d, freed: %d, max in use: %d\n", ! tp->tp_name, tp->tp_allocs, tp->tp_frees, tp->tp_maxalloc); fprintf(stderr, "fast tuple allocs: %d, empty: %d\n", *************** *** 55,59 **** for (tp = type_list; tp; tp = tp->tp_next) { v = Py_BuildValue("(siii)", tp->tp_name, tp->tp_allocs, ! tp->tp_free, tp->tp_maxalloc); if (v == NULL) { Py_DECREF(result); --- 55,59 ---- for (tp = type_list; tp; tp = tp->tp_next) { v = Py_BuildValue("(siii)", tp->tp_name, tp->tp_allocs, ! tp->tp_frees, tp->tp_maxalloc); if (v == NULL) { Py_DECREF(result); *************** *** 81,86 **** } tp->tp_allocs++; ! if (tp->tp_allocs - tp->tp_free > tp->tp_maxalloc) ! tp->tp_maxalloc = tp->tp_allocs - tp->tp_free; } #endif --- 81,86 ---- } tp->tp_allocs++; ! if (tp->tp_allocs - tp->tp_frees > tp->tp_maxalloc) ! tp->tp_maxalloc = tp->tp_allocs - tp->tp_frees; } #endif *************** *** 1466,1470 **** op->_ob_next = op->_ob_prev = NULL; #ifdef COUNT_ALLOCS ! op->ob_type->tp_free++; #endif } --- 1466,1470 ---- op->_ob_next = op->_ob_prev = NULL; #ifdef COUNT_ALLOCS ! op->ob_type->tp_frees++; #endif } From gvanrossum@users.sourceforge.net Tue Jun 19 15:14:02 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 19 Jun 2001 07:14:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.46,2.16.8.47 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv25807 Modified Files: Tag: descr-branch typeobject.c Log Message: Support for the tp_free slot: object_dealloc and type_dealloc now call this. Also, PyType_Type doesn't have to specify a value for tp_alloc, that's inherited from PyBaseObject_Type. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.46 retrieving revision 2.16.8.47 diff -C2 -r2.16.8.46 -r2.16.8.47 *** typeobject.c 2001/06/18 22:21:42 2.16.8.46 --- typeobject.c 2001/06/19 14:14:00 2.16.8.47 *************** *** 557,564 **** Py_XDECREF(type->tp_base); Py_XDECREF(type->tp_dict); Py_XDECREF(et->name); Py_XDECREF(et->slots); ! /* XXX more, e.g. bases, mro, introduced ... */ ! PyObject_DEL(type); } --- 557,567 ---- Py_XDECREF(type->tp_base); Py_XDECREF(type->tp_dict); + Py_XDECREF(type->tp_bases); + Py_XDECREF(type->tp_mro); + Py_XDECREF(type->tp_introduced); + /* XXX more? */ Py_XDECREF(et->name); Py_XDECREF(et->slots); ! type->ob_type->tp_free((PyObject *)type); } *************** *** 605,609 **** offsetof(PyTypeObject, tp_dict), /* tp_dictoffset */ 0, /* tp_init */ ! PyType_GenericAlloc, /* tp_alloc */ type_new, /* tp_new */ }; --- 608,612 ---- offsetof(PyTypeObject, tp_dict), /* tp_dictoffset */ 0, /* tp_init */ ! 0, /* tp_alloc */ type_new, /* tp_new */ }; *************** *** 621,624 **** --- 624,633 ---- object_dealloc(PyObject *self) { + self->ob_type->tp_free(self); + } + + static void + object_free(PyObject *self) + { PyObject_Del(self); } *************** *** 669,672 **** --- 678,682 ---- PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ + object_free, /* tp_free */ }; *************** *** 920,923 **** --- 930,934 ---- COPYSLOT(tp_alloc); COPYSLOT(tp_new); + COPYSLOT(tp_free); } From jackjansen@users.sourceforge.net Tue Jun 19 16:00:26 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 19 Jun 2001 08:00:26 -0700 Subject: [Python-checkins] CVS: python/dist/src Makefile.pre.in,1.39,1.40 configure.in,1.218,1.219 config.h.in,2.93,2.94 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv3612 Modified Files: Makefile.pre.in configure.in config.h.in Log Message: Added a MACHDEP_OBJS to the python link. Use this on MacOSX to include Mac/macglue.c into the core interpreter. This file contains the glue code that allows extension modules for Mac toolboxes to live in different shared libraries but still communicate with each other. The glue code is controlled by the USE_MAC_TOOLBOX_GLUE define. Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -r1.39 -r1.40 *** Makefile.pre.in 2001/06/06 17:51:57 1.39 --- Makefile.pre.in 2001/06/19 15:00:23 1.40 *************** *** 139,142 **** --- 139,143 ---- DLINCLDIR= @DLINCLDIR@ DYNLOADFILE= @DYNLOADFILE@ + MACHDEP_OBJS= @MACHDEP_OBJS@ PYTHON= python$(EXE) *************** *** 223,226 **** --- 224,228 ---- Python/getopt.o \ Python/$(DYNLOADFILE) \ + $(MACHDEP_OBJS) \ $(LIBOBJS) *************** *** 412,415 **** --- 414,419 ---- $(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 ############################################################################ Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.218 retrieving revision 1.219 diff -C2 -r1.218 -r1.219 *** configure.in 2001/05/11 16:10:56 1.218 --- configure.in 2001/06/19 15:00:23 1.219 *************** *** 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";; --- 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 -u _PyMac_Error -framework System -framework Foundation -framework Carbon" ;; UnixWare*) LINKFORSHARED="-dy -Bdynamic -Wl,-Bexport";; SCO_SV*) LINKFORSHARED="-Bdynamic -dy -Wl,-Bexport";; *************** *** 997,1000 **** --- 997,1016 ---- AC_DEFINE(HAVE_DYNAMIC_LOADING) 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 Index: config.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/config.h.in,v retrieving revision 2.93 retrieving revision 2.94 diff -C2 -r2.93 -r2.94 *** config.h.in 2001/05/11 16:10:56 2.93 --- config.h.in 2001/06/19 15:00:23 2.94 *************** *** 230,233 **** --- 230,236 ---- #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, From nascheme@users.sourceforge.net Tue Jun 19 16:44:17 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Tue, 19 Jun 2001 08:44:17 -0700 Subject: [Python-checkins] CVS: python/dist/src configure,1.210,1.211 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv15646 Modified Files: configure Log Message: Added a MACHDEP_OBJS to the python link. Use this on MacOSX to include Mac/macglue.c into the core interpreter. This file contains the glue code that allows extension modules for Mac toolboxes to live in different shared libraries but still communicate with each other. The glue code is controlled by the USE_MAC_TOOLBOX_GLUE define. [checked in for Jack] Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.210 retrieving revision 1.211 diff -C2 -r1.210 -r1.211 *** configure 2001/05/11 16:11:25 1.210 --- configure 2001/06/19 15:44:15 1.211 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.217 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.219 [...1624 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 --- 6243,6247 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6246: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then *************** *** 6399,6402 **** --- 6419,6423 ---- 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 From bwarsaw@users.sourceforge.net Tue Jun 19 19:24:44 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 19 Jun 2001 11:24:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc python-mode.el,4.2,4.3 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv27071 Modified Files: python-mode.el Log Message: (python-font-lock-keywords): Add "yield" as a keyword to support the new "simple generators" feature of 2.2. See PEP 255. Index: python-mode.el =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/python-mode.el,v retrieving revision 4.2 retrieving revision 4.3 diff -C2 -r4.2 -r4.3 *** python-mode.el 2001/06/18 23:40:35 4.2 --- python-mode.el 2001/06/19 18:24:42 4.3 *************** *** 9,13 **** ;; Keywords: python languages oop ! (defconst py-version "4.1" "`python-mode' version number.") --- 9,13 ---- ;; Keywords: python languages oop ! (defconst py-version "$Revision$" "`python-mode' version number.") *************** *** 311,315 **** "in" "is" "lambda" "not" "or" "pass" "print" "raise" ! "return" "while" ) "\\|")) --- 311,315 ---- "in" "is" "lambda" "not" "or" "pass" "print" "raise" ! "return" "while" "yield" ) "\\|")) From bwarsaw@users.sourceforge.net Tue Jun 19 20:07:48 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 19 Jun 2001 12:07:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib quopri.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv9005 Modified Files: quopri.py Log Message: Better support for RFC 1521 quoted-printable specification, along with addition of interface for consistency with base64 module. Namely, encodestring(), decodestring(): New functions which accept a string object and return a string object. They just wrap the string in StringIOs and pass them to the encode() and decode() methods respectively. encodestring() accepts a default argument of quotetabs, defaulting to zero, which is passed on straight through to encode(). encode(): Fix the bug where an extra newline would always be added to the output, which prevented an idempotent roundtrip through encode->decode. Now, if the source string doesn't end in a newline, then the result string won't end in a newline. Also, extend the quotetabs argument semantics to include quoting embedded strings, which is also optional according to the RFC. test() -> main() "from quopri import *" also imports encodestring() and decodestring(). Index: quopri.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/quopri.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -r1.11 -r1.12 *** quopri.py 2001/03/22 22:30:21 1.11 --- quopri.py 2001/06/19 19:07:46 1.12 *************** *** 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,95 ---- 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 ! linelen = 0 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' for c in line: if needsquoting(c, quotetabs): c = quote(c) ! # Have we hit the RFC 1521 encoded line maximum? ! if linelen + len(c) >= MAXLINESIZE: ! # Write out the previous line ! if prevline is not None: ! write(prevline) ! prevline = EMPTYSTRING.join(outline) ! linelen = 0 ! outline = [] ! outline.append(c) ! linelen += len(c) ! # Write out the current line ! if prevline is not None: ! write(prevline) ! prevline = EMPTYSTRING.join(outline) ! linelen = 0 ! outline = [] ! # 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 **** --- 126,139 ---- 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.""" *************** *** 106,111 **** bits = bits*16 + (ord(c) - i) return bits ! def test(): import sys import getopt --- 154,161 ---- bits = bits*16 + (ord(c) - i) return bits + ! ! def main(): import sys import getopt *************** *** 149,152 **** sys.exit(sts) if __name__ == '__main__': ! test() --- 199,204 ---- sys.exit(sts) + + if __name__ == '__main__': ! main() From bwarsaw@users.sourceforge.net Tue Jun 19 20:08:15 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 19 Jun 2001 12:08:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_quopri.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv9227 Added Files: test_quopri.py Log Message: A unittest-based test for the quopri module. --- 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'), # 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) From barry@digicool.com Tue Jun 19 20:19:06 2001 From: barry@digicool.com (Barry A. Warsaw) Date: Tue, 19 Jun 2001 15:19:06 -0400 Subject: [Python-checkins] CVS: python/dist/src/Lib quopri.py,1.11,1.12 References: Message-ID: <15151.42410.21715.685620@anthem.wooz.org> BW> Also, extend the quotetabs argument semantics to include BW> quoting embedded strings, which is also optional according to ----------------^^^^^^^^^^^^^^^^ Urg! I meant "embedded spaces" BW> the RFC. -Barry From jvr@users.sourceforge.net Tue Jun 19 20:44:04 2001 From: jvr@users.sourceforge.net (Just van Rossum) Date: Tue, 19 Jun 2001 12:44:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/distutils mwerkscompiler.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils In directory usw-pr-cvs1:/tmp/cvs-serv19655 Modified Files: mwerkscompiler.py Log Message: Fixed -D emulation for symbols with a value, as specified with the define_macros Extension argument. Index: mwerkscompiler.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/mwerkscompiler.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** mwerkscompiler.py 2001/05/17 12:52:01 1.2 --- mwerkscompiler.py 2001/06/19 19:44:02 1.3 *************** *** 165,169 **** fp.write('#define %s\n'%name) else: ! fp.write('#define %s "%s"\n'%(name, value)) fp.close() settings['prefixname'] = prefixname --- 165,169 ---- fp.write('#define %s\n'%name) else: ! fp.write('#define %s %s\n'%(name, value)) fp.close() settings['prefixname'] = prefixname From bwarsaw@users.sourceforge.net Tue Jun 19 20:44:44 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 19 Jun 2001 12:44:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libquopri.tex,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv20048 Modified Files: libquopri.tex Log Message: Document the new encodestring() and decodestring() functions. Also, add some description of what the quotetabs argument does for the encode*() functions. Finally, add a "see also" pointing to the base64 module. Index: libquopri.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libquopri.tex,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -r1.12 -r1.13 *** libquopri.tex 2000/04/04 20:43:50 1.12 --- libquopri.tex 2001/06/19 19:44:42 1.13 *************** *** 22,26 **** \var{input} and \var{output} must either be file objects or objects that mimic the file object interface. \var{input} will be read until ! \code{\var{input}.read()} returns an empty string. \end{funcdesc} --- 22,26 ---- \var{input} and \var{output} must either be file objects or objects that mimic the file object interface. \var{input} will be read until ! \code{\var{input}.readline()} returns an empty string. \end{funcdesc} *************** *** 30,38 **** \var{input} and \var{output} must either be file objects or objects that mimic the file object interface. \var{input} will be read until ! \code{\var{input}.read()} returns an empty string. \end{funcdesc} \begin{seealso} \seemodule{mimify}{General utilities for processing of MIME messages.} \end{seealso} --- 30,55 ---- \var{input} and \var{output} must either be file objects or objects that mimic the file object interface. \var{input} will be read until ! \code{\var{input}.readline()} returns an empty string. ! \var{quotetabs} is a flag which controls whether to encode embedded ! spaces and tabs; when true it encodes such embedded whitespace, and ! when false it leaves them unencoded. Note that spaces and tabs ! appearing at the end of lines are always encoded, as per \rfc{1521}. \end{funcdesc} + \begin{funcdesc}{decodestring}{s} + Like \function{decode()}, except that it accepts a source string and + returns the corresponding decoded string. + \end{funcdesc} + + \begin{funcdesc}{encodestring}{s\optional{, quotetabs}} + Like \function{encode()}, except that it accepts a source string and + returns the corresponding encoded string. \var{quotetabs} is optional + (defaulting to 0), and is passed straight through to + \function{encode()}. + \end{funcdesc} + \begin{seealso} \seemodule{mimify}{General utilities for processing of MIME messages.} + \seemodule{base64}{Encode and decode MIME base64 data} \end{seealso} From bwarsaw@users.sourceforge.net Tue Jun 19 20:54:21 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 19 Jun 2001 12:54:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/i18n pygettext.py,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/i18n In directory usw-pr-cvs1:/tmp/cvs-serv22737 Modified Files: pygettext.py Log Message: write(): It's been generally agreed on the i18n-sig that the docstring marker should be output as a #, flag, e.g. "#, docstring". Index: pygettext.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/i18n/pygettext.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -r1.18 -r1.19 *** pygettext.py 2001/05/24 23:06:13 1.18 --- pygettext.py 2001/06/19 19:54:19 1.19 *************** *** 343,347 **** # to skip translating some unimportant docstrings. if reduce(operator.__add__, v.values()): ! print >> fp, '#. docstring' # k is the message string, v is a dictionary-set of (filename, # lineno) tuples. We want to sort the entries in v first by --- 343,347 ---- # to skip translating some unimportant docstrings. if reduce(operator.__add__, v.values()): ! print >> fp, '#, docstring' # k is the message string, v is a dictionary-set of (filename, # lineno) tuples. We want to sort the entries in v first by From lemburg@users.sourceforge.net Tue Jun 19 21:07:53 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Tue, 19 Jun 2001 13:07:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/encodings utf_16.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/encodings In directory usw-pr-cvs1:/tmp/cvs-serv27074/Lib/encodings Modified Files: utf_16.py Log Message: This patch by Martin v. Loewis changes the UTF-16 codec to only write a BOM at the start of the stream and also to only read it as BOM at the start of a stream. Subsequent reading/writing of BOMs will read/write the BOM as ZWNBSP character. This is in sync with the Unicode specifications. Note that UTF-16 files will now *have* to start with a BOM mark in order to be readable by the codec. Index: utf_16.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/utf_16.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** utf_16.py 2000/03/10 23:17:24 1.1 --- utf_16.py 2001/06/19 20:07:51 1.2 *************** *** 7,11 **** """ ! import codecs ### Codec APIs --- 7,11 ---- """ ! import codecs, sys ### Codec APIs *************** *** 19,26 **** class StreamWriter(Codec,codecs.StreamWriter): ! pass class StreamReader(Codec,codecs.StreamReader): ! pass ### encodings module API --- 19,56 ---- class StreamWriter(Codec,codecs.StreamWriter): ! def __init__(self, stream, errors='strict'): ! self.bom_written = 0 ! codecs.StreamWriter.__init__(self, stream, errors) ! ! def write(self, data): ! result = codecs.StreamWriter.write(self, data) ! if not self.bom_written: ! self.bom_written = 1 ! if sys.byteorder == 'little': ! self.encode = codecs.utf_16_le_encode ! else: ! self.encode = codecs.utf_16_be_encode ! return result class StreamReader(Codec,codecs.StreamReader): ! def __init__(self, stream, errors='strict'): ! self.bom_read = 0 ! codecs.StreamReader.__init__(self, stream, errors) ! ! def read(self, size=-1): ! if not self.bom_read: ! signature = self.stream.read(2) ! if signature == codecs.BOM_BE: ! self.decode = codecs.utf_16_be_decode ! elif signature == codecs.BOM_LE: ! self.decode = codecs.utf_16_le_decode ! else: ! raise UnicodeError,"UTF-16 stream does not start with BOM" ! if size > 2: ! size -= 2 ! elif size >= 0: ! size = 0 ! self.bom_read = 1 ! return codecs.StreamReader.read(self, size) ### encodings module API From lemburg@users.sourceforge.net Tue Jun 19 21:09:30 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Tue, 19 Jun 2001 13:09:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_codecs.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv28211/Lib/test Added Files: test_codecs.py Log Message: Test by Martin v. Loewis for the new UTF-16 codec handling of BOM marks. --- NEW FILE: test_codecs.py --- import test_support,unittest import codecs import StringIO class UTF16Test(unittest.TestCase): spamle = '\xff\xfes\x00p\x00a\x00m\x00s\x00p\x00a\x00m\x00' spambe = '\xfe\xff\x00s\x00p\x00a\x00m\x00s\x00p\x00a\x00m' def test_only_one_bom(self): _,_,reader,writer = codecs.lookup("utf-16") # encode some stream s = StringIO.StringIO() f = writer(s) f.write(u"spam") f.write(u"spam") d = s.getvalue() # check whether there is exactly one BOM in it self.assert_(d == self.spamle or d == self.spambe) # try to read it back s = StringIO.StringIO(d) f = reader(s) self.assertEquals(f.read(), u"spamspam") test_support.run_unittest(UTF16Test) From jackjansen@users.sourceforge.net Tue Jun 19 21:11:38 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 19 Jun 2001 13:11:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib profile.py,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv28657/Python/Lib Modified Files: profile.py Log Message: An import MacOS was missing after the code-rearranging. Added. Index: profile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/profile.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -r1.28 -r1.29 *** profile.py 2001/06/08 04:25:24 1.28 --- profile.py 2001/06/19 20:11:36 1.29 *************** *** 91,94 **** --- 91,95 ---- if os.name == "mac": + import MacOS def _get_time_mac(timer=MacOS.GetTicks): return timer() / 60.0 From tim_one@users.sourceforge.net Tue Jun 19 21:11:52 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 19 Jun 2001 13:11:52 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0255.txt,1.5,1.6 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv28820/python/nondist/peps Modified Files: pep-0255.txt Log Message: Record that the generator work is part of the regular CVS tree now. Index: pep-0255.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0255.txt,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** pep-0255.txt 2001/06/15 21:37:15 1.5 --- pep-0255.txt 2001/06/19 20:11:50 1.6 *************** *** 250,256 **** Reference Implementation ! A preliminary implementation is available as the gen-branch of the ! Python CVS tree on SourceForge[9]. Using this requires that you ! build Python from source. This was derived from an earlier patch by Neil Schemenauer[7]. --- 250,256 ---- Reference Implementation ! The current implementation, in a preliminary state (no docs and no ! focused tests), is part of Python's CVS development tree[9]. ! Using this requires that you build Python from source. This was derived from an earlier patch by Neil Schemenauer[7]. *************** *** 270,279 **** [7] http://python.ca/nas/python/generator.diff [8] http://python.sf.net/peps/pep-0236.html ! [9] To experiment with this implementation, proceed to check out ! Python from CVS according to the instructions at http://sf.net/cvs/?group_id=5470 - but add the arguments "-r gen-branch" to the cvs checkout command. - You can also start with an existing checkout and do - cvs update -r gen-branch --- 270,276 ---- [7] http://python.ca/nas/python/generator.diff [8] http://python.sf.net/peps/pep-0236.html ! [9] To experiment with this implementation, check out Python from CVS ! according to the instructions at http://sf.net/cvs/?group_id=5470 From jackjansen@users.sourceforge.net Tue Jun 19 21:20:07 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 19 Jun 2001 13:20:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_mailbox.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv31019/Python/Lib/test Modified Files: test_mailbox.py Log Message: The test used int(time.time()) to get a random number, but this doesn't work on the mac (where times are bigger than ints). Changed to int(time.time()%1000000). Index: test_mailbox.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_mailbox.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** test_mailbox.py 2001/05/22 16:29:01 1.5 --- test_mailbox.py 2001/06/19 20:20:05 1.6 *************** *** 40,44 **** def createMessage(self, dir): ! t = int(time.time()) pid = self._counter self._counter += 1 --- 40,44 ---- def createMessage(self, dir): ! t = int(time.time() % 1000000) pid = self._counter self._counter += 1 From jackjansen@users.sourceforge.net Tue Jun 19 22:23:13 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 19 Jun 2001 14:23:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/distutils mwerkscompiler.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils In directory usw-pr-cvs1:/tmp/cvs-serv16825/Python/Lib/distutils Modified Files: mwerkscompiler.py Log Message: - _filename_to_abs() didn't cater for .. components in the pathname. Fixed. - compile() didn't return a (empty) list of objects. Fixed. - the various _fix_xxx_args() methods weren't called (are they new or did I overlook them?). Fixed. Index: mwerkscompiler.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/mwerkscompiler.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** mwerkscompiler.py 2001/06/19 19:44:02 1.3 --- mwerkscompiler.py 2001/06/19 21:23:11 1.4 *************** *** 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): *************** *** 201,205 **** 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, ':') From jvr@users.sourceforge.net Tue Jun 19 22:37:35 2001 From: jvr@users.sourceforge.net (Just van Rossum) Date: Tue, 19 Jun 2001 14:37:35 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Tools/IDE PyBrowser.py,1.7,1.8 PyConsole.py,1.5,1.6 PyDebugger.py,1.4,1.5 PyDocSearch.py,1.4,1.5 PyEdit.py,1.18,1.19 PythonIDE.py,1.5,1.6 PythonIDE.rsrc,1.6,1.7 PythonIDEMain.py,1.11,1.12 Splash.py,1.11,1.12 Wapplication.py,1.10,1.11 Wtext.py,1.9,1.10 Wtraceback.py,1.4,1.5 Wwindows.py,1.9,1.10 ModuleBrowser.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Tools/IDE In directory usw-pr-cvs1:/tmp/cvs-serv20894 Modified Files: PyBrowser.py PyConsole.py PyDebugger.py PyDocSearch.py PyEdit.py PythonIDE.py PythonIDE.rsrc PythonIDEMain.py Splash.py Wapplication.py Wtext.py Wtraceback.py Wwindows.py ModuleBrowser.py Log Message: Some long overdue maintainance. Made all IDE sources 7-bit-clean, to avoid any further encoding conversion troubles. Index: PyBrowser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PyBrowser.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** PyBrowser.py 2001/05/17 12:36:39 1.7 --- PyBrowser.py 2001/06/19 21:37:32 1.8 *************** *** 39,43 **** '' + value # test to see if it is a string, in case a __repr__ method is buggy except: ! value = '‚‚‚ exception in repr()' if truncvalue: return key + '\t' + value[:255] --- 39,43 ---- '' + value # test to see if it is a string, in case a __repr__ method is buggy except: ! value = '\xa5\xa5\xa5 exception in repr()' if truncvalue: return key + '\t' + value[:255] *************** *** 361,365 **** tp = type(object) if tp in SIMPLE_TYPES and tp is not types.NoneType: ! raise TypeError, 'canÕt browse simple type: %s' % tp.__name__ elif tp == types.DictionaryType: return unpack_dict(object, indent) --- 361,365 ---- tp = type(object) if tp in SIMPLE_TYPES and tp is not types.NoneType: ! raise TypeError, "can't browse simple type: %s" % tp.__name__ elif tp == types.DictionaryType: return unpack_dict(object, indent) Index: PyConsole.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PyConsole.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** PyConsole.py 2001/05/26 20:01:41 1.5 --- PyConsole.py 2001/06/19 21:37:32 1.6 *************** *** 49,53 **** def open(self): W.EditText.open(self) ! self.write('Python ' + sys.version + '\n' + sys.copyright + '\n') self.write(sys.ps1) self.flush() --- 49,53 ---- def open(self): W.EditText.open(self) ! self.write('Python ' + sys.version + '\nType "copyright", "credits" or "license" for more information.\n') self.write(sys.ps1) self.flush() *************** *** 157,162 **** W.SetCursor('watch') namespacelist = self.getnamespacelist() ! self.namespacemenu.set([("Clear window", self.clearbuffer), ("Font settingsƒ", self.dofontsettings), ! ["Namespace"] + namespacelist, ("Browse namespaceƒ", self.browsenamespace)]) currentname = self.consoletext._namespace["__name__"] for i in range(len(namespacelist)): --- 157,162 ---- W.SetCursor('watch') namespacelist = self.getnamespacelist() ! self.namespacemenu.set([("Clear window", self.clearbuffer), ("Font settings\xc9", self.dofontsettings), ! ["Namespace"] + namespacelist, ("Browse namespace\xc9", self.browsenamespace)]) currentname = self.consoletext._namespace["__name__"] for i in range(len(namespacelist)): *************** *** 265,269 **** self.w.outputtext = OutputTextWidget((-1, -1, -14, 1), inset = (6, 5), fontsettings = self.fontsettings, tabsettings = self.tabsettings, readonly = 1) ! menuitems = [("Clear window", self.clearbuffer), ("Font settingsƒ", self.dofontsettings)] self.w.popupmenu = W.PopupMenu((-15, -1, 16, 16), menuitems) --- 265,269 ---- self.w.outputtext = OutputTextWidget((-1, -1, -14, 1), inset = (6, 5), fontsettings = self.fontsettings, tabsettings = self.tabsettings, readonly = 1) ! menuitems = [("Clear window", self.clearbuffer), ("Font settings\xc9", self.dofontsettings)] self.w.popupmenu = W.PopupMenu((-15, -1, 16, 16), menuitems) Index: PyDebugger.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PyDebugger.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** PyDebugger.py 2001/05/17 12:36:30 1.4 --- PyDebugger.py 2001/06/19 21:37:33 1.5 *************** *** 73,77 **** if running: self.set_continue() ! self.reason = 'Runningƒ' self.setstate('running') else: --- 73,77 ---- if running: self.set_continue() ! self.reason = 'Running\xc9' self.setstate('running') else: *************** *** 188,192 **** options = [('Clear breakpoints', self.w.panes.bottom.src.source.clearbreakpoints), ('Clear all breakpoints', self.clear_all_breaks), ! ('Edit breakpointsƒ', self.edit_breaks), '-', (self.tracemagic and 'Disable __magic__ tracing' or 'Enable __magic__ tracing', self.togglemagic)] --- 188,192 ---- options = [('Clear breakpoints', self.w.panes.bottom.src.source.clearbreakpoints), ('Clear all breakpoints', self.clear_all_breaks), ! ('Edit breakpoints\xc9', self.edit_breaks), '-', (self.tracemagic and 'Disable __magic__ tracing' or 'Enable __magic__ tracing', self.togglemagic)] *************** *** 319,323 **** def running(self): W.SetCursor('watch') ! self.reason = 'Runningƒ' self.setstate('running') #self.w.panes.bottom.src.source.set('') --- 319,323 ---- def running(self): W.SetCursor('watch') ! self.reason = 'Running\xc9' self.setstate('running') #self.w.panes.bottom.src.source.set('') *************** *** 351,355 **** f, filename, (suff, mode, dummy) = imp.find_module(modname) except ImportError: ! self.w.panes.bottom.src.source.set('canÕt find file') else: if f: --- 351,355 ---- f, filename, (suff, mode, dummy) = imp.find_module(modname) except ImportError: ! self.w.panes.bottom.src.source.set("can't find file") else: if f: *************** *** 361,367 **** self.w.panes.bottom.src.source.set(data, filename) else: ! self.w.panes.bottom.src.source.set('canÕt find file') else: ! self.w.panes.bottom.src.source.set('canÕt find file') else: self.w.panes.bottom.src.source.set(data, filename) --- 361,367 ---- self.w.panes.bottom.src.source.set(data, filename) else: ! self.w.panes.bottom.src.source.set("can't find file") else: ! self.w.panes.bottom.src.source.set("can't find file") else: self.w.panes.bottom.src.source.set(data, filename) *************** *** 683,687 **** self.w.panes.gr = W.Group(None) self.w.panes.gr.breaks = W.List((0, 0, -130, 0), callback = self.linehit) #, flags = Lists.lOnlyOne) ! self.w.panes.gr.openbutton = W.Button((-80, 4, 0, 16), 'Viewƒ', self.openbuttonhit) self.w.panes.gr.deletebutton = W.Button((-80, 28, 0, 16), 'Delete', self.deletebuttonhit) --- 683,687 ---- self.w.panes.gr = W.Group(None) self.w.panes.gr.breaks = W.List((0, 0, -130, 0), callback = self.linehit) #, flags = Lists.lOnlyOne) ! self.w.panes.gr.openbutton = W.Button((-80, 4, 0, 16), 'View\xc9', self.openbuttonhit) self.w.panes.gr.deletebutton = W.Button((-80, 28, 0, 16), 'Delete', self.deletebuttonhit) *************** *** 881,885 **** def getdebugger(): if not __debug__: ! raise W.AlertError, "CanÕt debug in –Optimize bytecode” mode.\r(see –Default startup options” in EditPythonPreferences)" global _debugger if _debugger is None: --- 881,885 ---- def getdebugger(): if not __debug__: ! raise W.AlertError, "Can't debug in \"Optimize bytecode\" mode.\r(see \"Default startup options\" in EditPythonPreferences)" global _debugger if _debugger is None: Index: PyDocSearch.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PyDocSearch.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** PyDocSearch.py 2001/05/17 12:35:13 1.4 --- PyDocSearch.py 2001/06/19 21:37:33 1.5 *************** *** 102,106 **** def __init__(self): ! self.w = W.Dialog((440, 64), "Searchingƒ") self.w.searching = W.TextBox((4, 4, -4, 16), "DevDev:PyPyDoc 1.5.1:ext:parseTupleAndKeywords.html") self.w.hits = W.TextBox((4, 24, -4, 16), "Hits: 0") --- 102,106 ---- def __init__(self): ! self.w = W.Dialog((440, 64), "Searching\xc9") self.w.searching = W.TextBox((4, 4, -4, 16), "DevDev:PyPyDoc 1.5.1:ext:parseTupleAndKeywords.html") self.w.hits = W.TextBox((4, 24, -4, 16), "Hits: 0") Index: PyEdit.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PyEdit.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -r1.18 -r1.19 *** PyEdit.py 2001/05/23 20:03:06 1.18 --- PyEdit.py 2001/06/19 21:37:33 1.19 *************** *** 68,72 **** sourceOS = 'UNIX' searchString = '\n' ! change = EasyDialogs.AskYesNoCancel('–%s” contains %s-style line feeds. ' 'Change them to MacOS carriage returns?' % (self.title, sourceOS), 1) # bug: Cancel is treated as No --- 68,72 ---- sourceOS = 'UNIX' searchString = '\n' ! change = EasyDialogs.AskYesNoCancel('"%s" contains %s-style line feeds. ' 'Change them to MacOS carriage returns?' % (self.title, sourceOS), 1) # bug: Cancel is treated as No *************** *** 225,230 **** def makeoptionsmenu(self): ! menuitems = [('Font settingsƒ', self.domenu_fontsettings), ! ("Save optionsƒ", self.domenu_options), '-', ('\0' + chr(self.run_as_main) + 'Run as __main__', self.domenu_toggle_run_as_main), --- 225,230 ---- def makeoptionsmenu(self): ! menuitems = [('Font settings\xc9', self.domenu_fontsettings), ! ("Save options\xc9", self.domenu_options), '-', ('\0' + chr(self.run_as_main) + 'Run as __main__', self.domenu_toggle_run_as_main), *************** *** 232,236 **** #'-', ('Modularize', self.domenu_modularize), ! ('Browse namespaceƒ', self.domenu_browsenamespace), '-'] if self.profiling: --- 232,236 ---- #'-', ('Modularize', self.domenu_modularize), ! ('Browse namespace\xc9', self.domenu_browsenamespace), '-'] if self.profiling: *************** *** 241,245 **** menuitems = menuitems + [('Disable debugger', self.domenu_toggledebugger), ('Clear breakpoints', self.domenu_clearbreakpoints), ! ('Edit breakpointsƒ', self.domenu_editbreakpoints)] else: menuitems = menuitems + [('Enable debugger', self.domenu_toggledebugger)] --- 241,245 ---- menuitems = menuitems + [('Disable debugger', self.domenu_toggledebugger), ('Clear breakpoints', self.domenu_clearbreakpoints), ! ('Edit breakpoints\xc9', self.domenu_editbreakpoints)] else: menuitems = menuitems + [('Enable debugger', self.domenu_toggledebugger)] *************** *** 286,290 **** modname = _filename_as_modname(self.title) if not modname: ! raise W.AlertError, 'CanÕt modularize –%s”' % self.title run_as_main = self.run_as_main self.run_as_main = 0 --- 286,290 ---- modname = _filename_as_modname(self.title) if not modname: ! raise W.AlertError, "Can't modularize \"%s\"" % self.title run_as_main = self.run_as_main self.run_as_main = 0 *************** *** 361,365 **** 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(): --- 361,365 ---- 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(): *************** *** 417,425 **** def domenu_save_as_applet(self, *args): ! try: ! import buildtools ! except ImportError: ! # only have buildtools in Python >= 1.5.2 ! raise W.AlertError, "–Save as Applet” is only supported in\rPython 1.5.2 and up." buildtools.DEBUG = 0 # ouch. --- 417,421 ---- def domenu_save_as_applet(self, *args): ! import buildtools buildtools.DEBUG = 0 # ouch. *************** *** 505,509 **** import EasyDialogs import Qd; Qd.InitCursor() ! save = EasyDialogs.AskYesNoCancel('Save –%s” before running?' % self.title, 1) if save > 0: if self.domenu_save(): --- 501,505 ---- import EasyDialogs import Qd; Qd.InitCursor() ! save = EasyDialogs.AskYesNoCancel('Save "%s" before running?' % self.title, 1) if save > 0: if self.domenu_save(): *************** *** 561,575 **** classend = identifieRE_match(classname) if classend < 1: ! raise W.AlertError, 'CanÕt find a class.' classname = classname[:classend] break elif line and line[0] not in '\t#': ! raise W.AlertError, 'CanÕt find a class.' else: ! 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)): --- 557,571 ---- classend = identifieRE_match(classname) if classend < 1: ! raise W.AlertError, "Can't find a class." classname = classname[:classend] break elif line and line[0] not in '\t#': ! raise W.AlertError, "Can't find a class." else: ! 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)): *************** *** 577,581 **** pytext = string.join(lines, '\r') elif indent > 0: ! raise W.AlertError, 'CanÕt run indented code.' # add "newlines" to fool compile/exec: --- 573,577 ---- pytext = string.join(lines, '\r') elif indent > 0: ! raise W.AlertError, "Can't run indented code." # add "newlines" to fool compile/exec: *************** *** 840,844 **** ("Replace", "cmdr", self.replace), ("Replace all", None, self.replaceall), ! ("DonÕt find", "cmdd", self.dont), ("Cancel", "cmd.", self.cancel) ] --- 836,840 ---- ("Replace", "cmdr", self.replace), ("Replace all", None, self.replaceall), ! ("Don't find", "cmdd", self.dont), ("Cancel", "cmd.", self.cancel) ] *************** *** 849,853 **** if shortcut: self.w.bind(shortcut, self.w[title].push) ! self.w.setdefaultbutton(self.w["DonÕt find"]) self.w.find.edit.bind("", self.key) self.w.bind("", self.activate) --- 845,849 ---- if shortcut: self.w.bind(shortcut, self.w[title].push) ! self.w.setdefaultbutton(self.w["Don't find"]) self.w.find.edit.bind("", self.key) self.w.bind("", self.activate) *************** *** 882,890 **** for title, cmd, call in self.buttons[:-2]: self.w[title].enable(0) ! self.w.setdefaultbutton(self.w["DonÕt find"]) else: for title, cmd, call in self.buttons[:-2]: self.w[title].enable(0) ! self.w.setdefaultbutton(self.w["DonÕt find"]) def find(self): --- 878,886 ---- for title, cmd, call in self.buttons[:-2]: self.w[title].enable(0) ! self.w.setdefaultbutton(self.w["Don't find"]) else: for title, cmd, call in self.buttons[:-2]: self.w[title].enable(0) ! self.w.setdefaultbutton(self.w["Don't find"]) def find(self): *************** *** 1205,1209 **** self.fontsettings, self.tabsettings, self.windowsize = geteditorprefs() self.w = W.Dialog((328, 120), "Editor default settings") ! self.w.setfontbutton = W.Button((8, 8, 80, 16), "Set fontƒ", self.dofont) self.w.fonttext = W.TextBox((98, 10, -8, 14), self.template % (self.fontsettings[0], self.fontsettings[2])) --- 1201,1205 ---- self.fontsettings, self.tabsettings, self.windowsize = geteditorprefs() self.w = W.Dialog((328, 120), "Editor default settings") ! self.w.setfontbutton = W.Button((8, 8, 80, 16), "Set font\xc9", self.dofont) self.w.fonttext = W.TextBox((98, 10, -8, 14), self.template % (self.fontsettings[0], self.fontsettings[2])) Index: PythonIDE.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PythonIDE.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** PythonIDE.py 1999/10/30 11:45:16 1.5 --- PythonIDE.py 2001/06/19 21:37:33 1.6 *************** *** 1,8 **** ! # copyright 1996-1999 Just van Rossum, Letterror. just@letterror.com # keep this (__main__) as clean as possible, since we are using # it like the "normal" interpreter. ! __version__ = '1.0' --- 1,8 ---- ! # copyright 1996-2001 Just van Rossum, Letterror. just@letterror.com # keep this (__main__) as clean as possible, since we are using # it like the "normal" interpreter. ! __version__ = '1.0.1' Index: PythonIDE.rsrc =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PythonIDE.rsrc,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -r1.6 -r1.7 Binary files /tmp/cvs1wMTZk and /tmp/cvsseKfyv differ Index: PythonIDEMain.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PythonIDEMain.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -r1.11 -r1.12 *** PythonIDEMain.py 2001/05/17 12:35:09 1.11 --- PythonIDEMain.py 2001/06/19 21:37:33 1.12 *************** *** 51,61 **** m = Wapplication.Menu(self.menubar, "File") newitem = FrameWork.MenuItem(m, "New", "N", 'new') ! openitem = FrameWork.MenuItem(m, "Openƒ", "O", 'open') FrameWork.Separator(m) closeitem = FrameWork.MenuItem(m, "Close", "W", 'close') saveitem = FrameWork.MenuItem(m, "Save", "S", 'save') ! saveasitem = FrameWork.MenuItem(m, "Save asƒ", None, 'save_as') FrameWork.Separator(m) ! saveasappletitem = FrameWork.MenuItem(m, "Save as Appletƒ", None, 'save_as_applet') FrameWork.Separator(m) quititem = FrameWork.MenuItem(m, "Quit", "Q", 'quit') --- 51,61 ---- m = Wapplication.Menu(self.menubar, "File") newitem = FrameWork.MenuItem(m, "New", "N", 'new') ! openitem = FrameWork.MenuItem(m, "Open\xc9", "O", 'open') FrameWork.Separator(m) closeitem = FrameWork.MenuItem(m, "Close", "W", 'close') saveitem = FrameWork.MenuItem(m, "Save", "S", 'save') ! saveasitem = FrameWork.MenuItem(m, "Save as\xc9", None, 'save_as') FrameWork.Separator(m) ! saveasappletitem = FrameWork.MenuItem(m, "Save as Applet\xc9", None, 'save_as_applet') FrameWork.Separator(m) quititem = FrameWork.MenuItem(m, "Quit", "Q", 'quit') *************** *** 72,76 **** sellineitem = FrameWork.MenuItem(m, "Select line", "L", "selectline") FrameWork.Separator(m) ! finditem = FrameWork.MenuItem(m, "Findƒ", "F", "find") findagainitem = FrameWork.MenuItem(m, "Find again", 'G', "findnext") enterselitem = FrameWork.MenuItem(m, "Enter search string", "E", "entersearchstring") --- 72,76 ---- sellineitem = FrameWork.MenuItem(m, "Select line", "L", "selectline") FrameWork.Separator(m) ! finditem = FrameWork.MenuItem(m, "Find\xc9", "F", "find") findagainitem = FrameWork.MenuItem(m, "Find again", 'G', "findnext") enterselitem = FrameWork.MenuItem(m, "Enter search string", "E", "entersearchstring") *************** *** 85,94 **** runselitem = FrameWork.MenuItem(m, "Run selection", None, 'runselection') FrameWork.Separator(m) ! moditem = FrameWork.MenuItem(m, "Module browserƒ", "M", self.domenu_modulebrowser) FrameWork.Separator(m) mm = FrameWork.SubMenu(m, "Preferences") ! FrameWork.MenuItem(mm, "Set Scripts folderƒ", None, self.do_setscriptsfolder) ! FrameWork.MenuItem(mm, "Editor default settingsƒ", None, self.do_editorprefs) ! FrameWork.MenuItem(mm, "Set default window fontƒ", None, self.do_setwindowfont) self.openwindowsmenu = Wapplication.Menu(self.menubar, 'Windows') --- 85,94 ---- runselitem = FrameWork.MenuItem(m, "Run selection", None, 'runselection') FrameWork.Separator(m) ! moditem = FrameWork.MenuItem(m, "Module browser\xc9", "M", self.domenu_modulebrowser) FrameWork.Separator(m) mm = FrameWork.SubMenu(m, "Preferences") ! FrameWork.MenuItem(mm, "Set Scripts folder\xc9", None, self.do_setscriptsfolder) ! FrameWork.MenuItem(mm, "Editor default settings\xc9", None, self.do_editorprefs) ! FrameWork.MenuItem(mm, "Set default window font\xc9", None, self.do_setwindowfont) self.openwindowsmenu = Wapplication.Menu(self.menubar, 'Windows') *************** *** 111,115 **** if not os.path.exists(path): os.mkdir(path) ! f = open(os.path.join(path, "Place your scripts hereƒ"), "w") f.close() fss = macfs.FSSpec(path) --- 111,115 ---- if not os.path.exists(path): os.mkdir(path) ! f = open(os.path.join(path, "Place your scripts here\xc9"), "w") f.close() fss = macfs.FSSpec(path) *************** *** 157,164 **** self.openscript(path) else: ! W.Message("CanÕt open file of type '%s'." % ftype) def getabouttext(self): ! return "About Python IDEƒ" def do_about(self, id, item, window, event): --- 157,164 ---- self.openscript(path) else: ! W.Message("Can't open file of type '%s'." % ftype) def getabouttext(self): ! return "About Python IDE\xc9" def do_about(self, id, item, window, event): Index: Splash.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/Splash.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -r1.11 -r1.12 *** Splash.py 2001/05/17 12:35:05 1.11 --- Splash.py 2001/06/19 21:37:33 1.12 *************** *** 25,28 **** --- 25,31 ---- _progress = 0 + _about_width = 440 + _about_height = 340 + def importing(module): global _progress *************** *** 33,47 **** Qd.TextFont(fontID) Qd.TextSize(9) ! rect = (35, 265, 365, 281) if module: ! TE.TETextBox('Importing: ' + module, rect, 0) if not _progress: ! Qd.FrameRect((35, 281, 365, 289)) ! pos = min(36 + 330 * _progress / 44, 364) ! Qd.PaintRect((36, 282, pos, 288)) _progress = _progress + 1 else: ! Qd.EraseRect(rect) ! Qd.PaintRect((36, 282, pos, 288)) Qd.QDFlushPortBuffer(splash.GetDialogWindow().GetWindowPort(), None) --- 36,52 ---- Qd.TextFont(fontID) Qd.TextSize(9) ! labelrect = (35, _about_height - 35, _about_width - 35, _about_height - 19) ! framerect = (35, _about_height - 19, _about_width - 35, _about_height - 11) ! l, t, r, b = progrect = Qd.InsetRect(framerect, 1, 1) if module: ! TE.TETextBox('Importing: ' + module, labelrect, 0) if not _progress: ! Qd.FrameRect(framerect) ! pos = min(r, l + ((r - l) * _progress) / 44) ! Qd.PaintRect((l, t, pos, b)) _progress = _progress + 1 else: ! Qd.EraseRect(labelrect) ! Qd.PaintRect((l, t, pos, b)) Qd.QDFlushPortBuffer(splash.GetDialogWindow().GetWindowPort(), None) *************** *** 72,89 **** _keepsplashscreenopen = 0 ! abouttext1 = """The Python Integrated Development Environment for the MacintoshŽ Version: %s ! Copyright 1997-2000 Just van Rossum, Letterror. Python %s %s See: for information and documentation.""" ! flauwekul = [ 'Goodday, Bruce.', ! 'WhatÕs new?', ! 'Nudge, nudge, say no more!', ! 'No, no sir, itÕs not dead. ItÕs resting.', ! 'Albatros!', ! 'ItÕs . . .', ! 'Is your name not Bruce, then?', """But Mr F.G. Superman has a secret identity . . . when trouble strikes at any time . . . --- 77,94 ---- _keepsplashscreenopen = 0 ! abouttext1 = """The Python Integrated Development Environment for the Macintosh\xaa Version: %s ! Copyright 1997-2001 Just van Rossum, Letterror. Python %s %s See: for information and documentation.""" ! flauwekul = [ "Goodday, Bruce.", ! "What's new?", ! "Nudge, nudge, say no more!", ! "No, no sir, it's not dead. It's resting.", ! "Albatros!", ! "It's . . .", ! "Is your name not Bruce, then?", """But Mr F.G. Superman has a secret identity . . . when trouble strikes at any time . . . *************** *** 112,116 **** Qd.TextFont(fontID) Qd.TextSize(9) ! rect = (10, 115, 390, 290) if not what: import __main__ --- 117,121 ---- Qd.TextFont(fontID) Qd.TextSize(9) ! rect = (10, 115, _about_width - 10, _about_height - 30) if not what: import __main__ *************** *** 135,138 **** --- 140,144 ---- time = Evt.TickCount() whattext = 0 + drawtext(whattext) while _keepsplashscreenopen: ok, event = Evt.EventAvail(Events.highLevelEventMask) *************** *** 155,159 **** time = Evt.TickCount() del splash ! #Res.CloseResFile(splashresfile) def about(): --- 161,165 ---- time = Evt.TickCount() del splash ! def about(): Index: Wapplication.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/Wapplication.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -r1.10 -r1.11 *** Wapplication.py 2001/05/17 12:35:01 1.10 --- Wapplication.py 2001/06/19 21:37:33 1.11 *************** *** 345,352 **** f, filename, (suff, mode, dummy) = imp.find_module(modname) except ImportError: ! raise W.AlertError, "CanÕt find file for –%s”" % modname else: if not f: ! raise W.AlertError, "CanÕt find file for –%s”" % modname f.close() if suff == '.py': --- 345,352 ---- f, filename, (suff, mode, dummy) = imp.find_module(modname) except ImportError: ! raise W.AlertError, "Can't find file for \"%s\"" % modname else: if not f: ! raise W.AlertError, "Can't find file for \"%s\"" % modname f.close() if suff == '.py': *************** *** 354,360 **** return else: ! raise W.AlertError, "CanÕt find file for –%s”" % modname else: ! raise W.AlertError, "CanÕt find file •%sÕ" % filename if lineno is not None: editor.selectline(lineno, charoffset) --- 354,360 ---- return else: ! raise W.AlertError, "Can't find file for \"%s\"" % modname else: ! raise W.AlertError, "Can't find file \"%s\"" % filename if lineno is not None: editor.selectline(lineno, charoffset) Index: Wtext.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/Wtext.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -r1.9 -r1.10 *** Wtext.py 2001/05/17 12:34:56 1.9 --- Wtext.py 2001/06/19 21:37:33 1.10 *************** *** 872,876 **** if not __debug__: import W ! raise W.AlertError, "CanÕt debug in –Optimize bytecode” mode.\r(see –Default startup options” in EditPythonPreferences)" import PyDebugger self._debugger = PyDebugger.getdebugger() --- 872,876 ---- if not __debug__: import W ! raise W.AlertError, "Can't debug in \"Optimize bytecode\" mode.\r(see \"Default startup options\" in EditPythonPreferences)" import PyDebugger self._debugger = PyDebugger.getdebugger() Index: Wtraceback.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/Wtraceback.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** Wtraceback.py 2001/05/17 12:34:52 1.4 --- Wtraceback.py 2001/06/19 21:37:33 1.5 *************** *** 58,62 **** if lineno: charno = charno - 1 ! text = str(value) + '\rFile: "' + str(filename) + '", line ' + str(lineno) + '\r\r' + line[:charno] + "‚" + line[charno:-1] else: text = str(value) + '\rFile: "' + str(filename) + '"' --- 58,62 ---- if lineno: charno = charno - 1 ! text = str(value) + '\rFile: "' + str(filename) + '", line ' + str(lineno) + '\r\r' + line[:charno] + "\xa5" + line[charno:-1] else: text = str(value) + '\rFile: "' + str(filename) + '"' *************** *** 124,131 **** self.w.editbutton.enable(0) ! self.w.browselocalsbutton = W.Button((80, -30, 100, 16), "Browse localsƒ", self.browselocals) self.w.browselocalsbutton.enable(0) ! self.w.postmortembutton = W.Button((190, -30, 100, 16), "Post mortemƒ", self.postmortem) self.w.setdefaultbutton(self.w.editbutton) --- 124,131 ---- self.w.editbutton.enable(0) ! self.w.browselocalsbutton = W.Button((80, -30, 100, 16), "Browse locals\xc9", self.browselocals) self.w.browselocalsbutton.enable(0) ! self.w.postmortembutton = W.Button((190, -30, 100, 16), "Post mortem\xc9", self.postmortem) self.w.setdefaultbutton(self.w.editbutton) Index: Wwindows.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/Wwindows.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -r1.9 -r1.10 *** Wwindows.py 2001/05/17 12:34:48 1.9 --- Wwindows.py 2001/06/19 21:37:33 1.10 *************** *** 569,573 **** import EasyDialogs if EasyDialogs.AskYesNoCancel( ! "CanÕt find window or widget to insert text into; copy to clipboard instead?", 1) == 1: import Scrap --- 569,573 ---- import EasyDialogs if EasyDialogs.AskYesNoCancel( ! "Can't find window or widget to insert text into; copy to clipboard instead?", 1) == 1: import Scrap Index: ModuleBrowser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/ModuleBrowser.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** ModuleBrowser.py 2001/05/17 12:36:43 1.3 --- ModuleBrowser.py 2001/06/19 21:37:33 1.4 *************** *** 15,21 **** #self.window.bevelbox = W.BevelBox((0, 0, 0, 56)) self.window.openbutton = W.Button((10, 8, 80, 16), "Open", self.openbuttonhit) ! self.window.browsebutton = W.Button((100, 8, 80, 16), "Browseƒ", self.browsebuttonhit) self.window.reloadbutton = W.Button((10, 32, 80, 16), "Reload", self.reloadbuttonhit) ! self.window.openotherbutton = W.Button((100, 32, 80, 16), "Open otherƒ", self.openother) self.window.openbutton.enable(0) --- 15,21 ---- #self.window.bevelbox = W.BevelBox((0, 0, 0, 56)) self.window.openbutton = W.Button((10, 8, 80, 16), "Open", self.openbuttonhit) ! self.window.browsebutton = W.Button((100, 8, 80, 16), "Browse\xc9", self.browsebuttonhit) self.window.reloadbutton = W.Button((10, 32, 80, 16), "Reload", self.reloadbuttonhit) ! self.window.openotherbutton = W.Button((100, 32, 80, 16), "Open other\xc9", self.openother) self.window.openbutton.enable(0) *************** *** 82,86 **** except ImportError: W.SetCursor("arrow") ! W.Message("CanÕt find file for module –%s”." % modname) else: --- 82,86 ---- except ImportError: W.SetCursor("arrow") ! W.Message("Can't find file for module '%s'." % modname) else: *************** *** 94,98 **** W.getapplication().openscript(path[:-1], modname=modname) else: ! W.Message("CanÕt edit –%s”; it might be a shared library or a .pyc file." % modname) --- 94,98 ---- W.getapplication().openscript(path[:-1], modname=modname) else: ! W.Message("Can't edit '%s'; it might be a shared library or a .pyc file." % modname) *************** *** 107,113 **** except ImportError: if modname in sys.builtin_module_names: ! alerttext = "–%s” is a builtin module, which you canÕt edit." % modname else: ! alerttext = "No module named –%s”." % modname raise W.AlertError, alerttext self.openscript(path, modname) --- 107,113 ---- except ImportError: if modname in sys.builtin_module_names: ! alerttext = "'%s' is a builtin module, which you can't edit." % modname else: ! alerttext = "No module named '%s'." % modname raise W.AlertError, alerttext self.openscript(path, modname) From jvr@users.sourceforge.net Tue Jun 19 22:38:44 2001 From: jvr@users.sourceforge.net (Just van Rossum) Date: Tue, 19 Jun 2001 14:38:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/IDE scripts/Widget demos WidgetTest.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/IDE scripts/Widget demos In directory usw-pr-cvs1:/tmp/cvs-serv21220 Modified Files: WidgetTest.py Log Message: made 7-bit-clean. ***** Bogus filespec: scripts/Widget ***** Bogus filespec: demos Index: WidgetTest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/IDE scripts/Widget demos/WidgetTest.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** WidgetTest.py 1999/09/26 12:24:58 1.1 --- WidgetTest.py 2001/06/19 21:38:42 1.2 *************** *** 47,51 **** # a checkbox ! window.ch = W.CheckBox((10, 130, 160, 16), "Check (command §)", checkcallback) # set of radio buttons (should become easier/nicer) --- 47,51 ---- # a checkbox ! window.ch = W.CheckBox((10, 130, 160, 16), "Check (command \xa4)", checkcallback) # set of radio buttons (should become easier/nicer) *************** *** 66,70 **** # bind some keystrokes to functions ! window.bind('cmd§', window.ch.push) window.bind('cmd1', window.r1.push) window.bind('cmd2', window.r2.push) --- 66,70 ---- # bind some keystrokes to functions ! window.bind('cmd\xa4', window.ch.push) window.bind('cmd1', window.r1.push) window.bind('cmd2', window.r2.push) From bwarsaw@users.sourceforge.net Tue Jun 19 23:48:12 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 19 Jun 2001 15:48:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib quopri.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv4201 Modified Files: quopri.py Log Message: encode(): Fixed the handling of soft line breaks for lines over 76 characters in length. Remember that when calculating the soft breaks, the trailing `=' sign counts against the max length! Index: quopri.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/quopri.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -r1.12 -r1.13 *** quopri.py 2001/06/19 19:07:46 1.12 --- quopri.py 2001/06/19 22:48:10 1.13 *************** *** 49,53 **** prevline = None - linelen = 0 while 1: line = input.readline() --- 49,52 ---- *************** *** 60,82 **** line = line[:-1] stripped = '\n' for c in line: if needsquoting(c, quotetabs): c = quote(c) - # Have we hit the RFC 1521 encoded line maximum? - if linelen + len(c) >= MAXLINESIZE: - # Write out the previous line - if prevline is not None: - write(prevline) - prevline = EMPTYSTRING.join(outline) - linelen = 0 - outline = [] outline.append(c) ! linelen += len(c) ! # Write out the current line if prevline is not None: write(prevline) ! prevline = EMPTYSTRING.join(outline) ! linelen = 0 ! outline = [] # Write out the last line, without a trailing newline if prevline is not None: --- 59,80 ---- 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: From bwarsaw@users.sourceforge.net Tue Jun 19 23:48:44 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 19 Jun 2001 15:48:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_quopri.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv4279 Modified Files: test_quopri.py Log Message: Add a bunch of sample strings to test soft line breaks of varying end cases. Index: test_quopri.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_quopri.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** test_quopri.py 2001/06/19 19:08:13 1.1 --- test_quopri.py 2001/06/19 22:48:42 1.2 *************** *** 68,72 **** ('hello ', 'hello=20'), ('hello\t', 'hello=09'), ! # Now some really complex stuff (DECSAMPLE, ENCSAMPLE), ) --- 68,99 ---- ('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), ) From nascheme@users.sourceforge.net Wed Jun 20 01:39:30 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Tue, 19 Jun 2001 17:39:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.249,2.250 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv27156/Python Modified Files: ceval.c Log Message: Remove unused code. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.249 retrieving revision 2.250 diff -C2 -r2.249 -r2.250 *** ceval.c 2001/06/18 22:08:13 2.249 --- ceval.c 2001/06/20 00:39:28 2.250 *************** *** 2200,2212 **** } /* main loop */ - /* Pop remaining stack entries */ - - /* - while (!EMPTY()) { - v = POP(); - Py_XDECREF(v); - } - */ - if (why != WHY_RETURN && why != WHY_YIELD) retval = NULL; --- 2200,2203 ---- From tim_one@users.sourceforge.net Wed Jun 20 07:57:34 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 19 Jun 2001 23:57:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.250,2.251 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv31108/python/dist/src/Python Modified Files: ceval.c Log Message: gen_iternext(): repair subtle refcount problem. NeilS, please check! This came from staring at your genbug.py, but I'm not sure it plugs all possible holes. Without this, I caught a frameobject refcount going negative, and it was also the cause (in debug build) of _Py_ForgetReference's attempt to forget an object with already- NULL _ob_prev and _ob_next pointers -- although I'm still not entirely sure how! Part of the difficulty is that frameobjects are stored on a free list that gets recycled very quickly, so if there's a stray pointer to one of them it never looks like an insane frameobject (never goes trough the free() mangling MS debug forces, etc). Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.250 retrieving revision 2.251 diff -C2 -r2.250 -r2.251 *** ceval.c 2001/06/20 00:39:28 2.250 --- ceval.c 2001/06/20 06:57:32 2.251 *************** *** 153,156 **** --- 153,161 ---- result = eval_frame(f); gen->running = 0; + /* The connection between this frame and its parent is over now, so + must NULL out f_back lest it get decref'ed when gen dies (note + that eval_frame sets f->f_back without bumping its refcount: we + never had a fully legit reference to it). */ + f->f_back = NULL; return result; } From gvanrossum@users.sourceforge.net Wed Jun 20 15:56:24 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 20 Jun 2001 07:56:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.81.2.42,1.81.2.43 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv27270 Modified Files: Tag: release20-maint NEWS Log Message: News about the 2.0.1 final release (planned for Friday 6/22/01). Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.81.2.42 retrieving revision 1.81.2.43 diff -C2 -r1.81.2.42 -r1.81.2.43 *** NEWS 2001/06/13 15:15:02 1.81.2.42 --- NEWS 2001/06/20 14:56:22 1.81.2.43 *************** *** 2,5 **** --- 2,14 ---- ============================ + - A few references to Python 2.1 in the LICENSE were changed to 2.0.1. + + - Bogus indentation in Lib/statcache.py was fixed. + + - A few small nits in the documentation were fixed. + + What's Fixed in Python 2.0.1c1 + ============================== + Critical Patches (from MoinMoin) From fdrake@users.sourceforge.net Wed Jun 20 15:56:39 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 20 Jun 2001 07:56:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc Makefile,1.203.2.1,1.203.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv27354 Modified Files: Tag: release20-maint Makefile Log Message: Update version number and date for 2.0.1 final release. Index: Makefile =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile,v retrieving revision 1.203.2.1 retrieving revision 1.203.2.2 diff -C2 -r1.203.2.1 -r1.203.2.2 *** Makefile 2001/06/13 16:07:26 1.203.2.1 --- Makefile 2001/06/20 14:56:37 1.203.2.2 *************** *** 65,69 **** # This is the *documentation* release, and is used to construct the file # names of the downloadable tarballs. ! RELEASE=2.0.1c1 --- 65,69 ---- # This is the *documentation* release, and is used to construct the file # names of the downloadable tarballs. ! RELEASE=2.0.1 From fdrake@users.sourceforge.net Wed Jun 20 15:56:40 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 20 Jun 2001 07:56:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/texinputs boilerplate.tex,1.50.2.1,1.50.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory usw-pr-cvs1:/tmp/cvs-serv27354/texinputs Modified Files: Tag: release20-maint boilerplate.tex Log Message: Update version number and date for 2.0.1 final release. Index: boilerplate.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/boilerplate.tex,v retrieving revision 1.50.2.1 retrieving revision 1.50.2.2 diff -C2 -r1.50.2.1 -r1.50.2.2 *** boilerplate.tex 2001/06/13 16:08:13 1.50.2.1 --- boilerplate.tex 2001/06/20 14:56:37 1.50.2.2 *************** *** 6,10 **** } ! \date{June 15, 2001} % XXX update before release! ! \release{2.0.1c1} % software release, not documentation \setshortversion{2.0} % major.minor only for software --- 6,10 ---- } ! \date{June 22, 2001} % XXX update before release! ! \release{2.0.1} % software release, not documentation \setshortversion{2.0} % major.minor only for software From tim_one@users.sourceforge.net Wed Jun 20 20:08:23 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 20 Jun 2001 12:08:23 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0255.txt,1.6,1.7 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv31571/peps Modified Files: pep-0255.txt Log Message: Added brief section about exception propagation. Index: pep-0255.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0255.txt,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -r1.6 -r1.7 *** pep-0255.txt 2001/06/19 20:11:50 1.6 --- pep-0255.txt 2001/06/20 19:08:20 1.7 *************** *** 170,173 **** --- 170,203 ---- + Generators and Exception Propagation + + If an unhandled exception-- including, but not limited to, + StopIteration --is raised by, or passes through, a generator function, + then the exception is passed on to the caller in the usual way, and + subsequent attempts to resume the generator function raise + StopIteration. In other words, an unhandled exception terminates a + generator's useful life. + + Example (not idiomatic but to illustrate the point): + + >>> def f(): + ... return 1/0 + >>> def g(): + ... yield f() # the zero division exception propagates + ... yield 42 # and we'll never get here + >>> k = g() + >>> k.next() + Traceback (most recent call last): + File "", line 1, in ? + File "", line 2, in g + File "", line 2, in f + ZeroDivisionError: integer division or modulo by zero + >>> k.next() # and the generator function cannot be resumed + Traceback (most recent call last): + File "", line 1, in ? + StopIteration + >>> + + Example From bwarsaw@users.sourceforge.net Wed Jun 20 20:41:42 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Wed, 20 Jun 2001 12:41:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/i18n pygettext.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/i18n In directory usw-pr-cvs1:/tmp/cvs-serv8345 Modified Files: pygettext.py Log Message: write(): Karl Eichwalder points out that the #, flag comments should be outputted just before the msgid lines. Index: pygettext.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/i18n/pygettext.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -r1.19 -r1.20 *** pygettext.py 2001/06/19 19:54:19 1.19 --- pygettext.py 2001/06/20 19:41:40 1.20 *************** *** 339,347 **** rentries.sort() for k, v in rentries: # If the entry was gleaned out of a docstring, then add a # comment stating so. This is to aid translators who may wish # to skip translating some unimportant docstrings. if reduce(operator.__add__, v.values()): ! print >> fp, '#, docstring' # k is the message string, v is a dictionary-set of (filename, # lineno) tuples. We want to sort the entries in v first by --- 339,348 ---- rentries.sort() for k, v in rentries: + isdocstring = 0 # If the entry was gleaned out of a docstring, then add a # comment stating so. This is to aid translators who may wish # to skip translating some unimportant docstrings. if reduce(operator.__add__, v.values()): ! isdocstring = 1 # k is the message string, v is a dictionary-set of (filename, # lineno) tuples. We want to sort the entries in v first by *************** *** 371,374 **** --- 372,377 ---- if len(locline) > 2: print >> fp, locline + if isdocstring: + print >> fp, '#, docstring' print >> fp, 'msgid', normalize(k) print >> fp, 'msgstr ""\n' From jvr@users.sourceforge.net Wed Jun 20 20:57:57 2001 From: jvr@users.sourceforge.net (Just van Rossum) Date: Wed, 20 Jun 2001 12:57:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Tools/IDE PyDebugger.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Tools/IDE In directory usw-pr-cvs1:/tmp/cvs-serv12941 Modified Files: PyDebugger.py Log Message: Override bdb's canonic() method with a no-op: with bdb's version we couldn't edit breakpoints in file-less ("Untitled" script windows). Besides, we did't need it as we always use full path names anyway. Index: PyDebugger.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PyDebugger.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** PyDebugger.py 2001/06/19 21:37:33 1.5 --- PyDebugger.py 2001/06/20 19:57:55 1.6 *************** *** 50,53 **** --- 50,58 ---- self.laststacksel = None + def canonic(self, filename): + # override: the provided canonic() method breaks our + # file-less Untitled windows + return filename + def reset(self): self.currentframe = None From tim_one@users.sourceforge.net Wed Jun 20 21:32:59 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 20 Jun 2001 13:32:59 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0255.txt,1.7,1.8 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv20081/peps Modified Files: pep-0255.txt Log Message: Add section explaining that yield *isn't* special wrt try/except/finally. Index: pep-0255.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0255.txt,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** pep-0255.txt 2001/06/20 19:08:20 1.7 --- pep-0255.txt 2001/06/20 20:32:56 1.8 *************** *** 200,203 **** --- 200,237 ---- + Yield and Try/Except/Finally + + While "yield" is a control-flow statement, and in most respects acts + like a "return" statement from the caller's point of view, within a + generator it acts more like a callback function. In particular, it has + no special semantics with respect to try/except/finally. This is best + illustrated by a contrived example; the primary lesson to take from + this is that using yield in a finally block is a dubious idea! + + >>> def g(): + ... try: + ... yield 1 + ... 1/0 # raises exception + ... yield 2 # we never get here + ... finally: + ... yield 3 # yields, and we raise the exception *next* time + ... yield 4 # we never get here + >>> k = g() + >>> k.next() + 1 + >>> k.next() + 3 + >>> k.next() # as if "yield 3" were a callback, exception raised now + Traceback (most recent call last): + File "", line 1, in ? + File "", line 4, in g + ZeroDivisionError: integer division or modulo by zero + >>> k.next() # unhandled exception terminated the generator + Traceback (most recent call last): + File "", line 1, in ? + StopIteration + >>> + + Example From jackjansen@users.sourceforge.net Wed Jun 20 21:50:21 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 20 Jun 2001 13:50:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Python macgetargv.c,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Python In directory usw-pr-cvs1:/tmp/cvs-serv23677/MacPython/Mac/Python Modified Files: macgetargv.c Log Message: Adapted for Universal Headers 3.4: refcon type has changed (sigh) and use modern (UPP in stead of Proc) names for callback object creation. Index: macgetargv.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Python/macgetargv.c,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -r1.23 -r1.24 *** macgetargv.c 2001/05/22 22:37:05 1.23 --- macgetargv.c 2001/06/20 20:50:19 1.24 *************** *** 42,45 **** --- 42,51 ---- #include + #if UNIVERSAL_INTERFACES_VERSION >= 0x0340 + typedef long refcontype; + #else + typedef unsigned long refcontype; + #endif + #include "Python.h" #include "macglue.h" *************** *** 110,114 **** static pascal OSErr ! handle_not(const AppleEvent *theAppleEvent, AppleEvent *reply, unsigned long refCon) { #pragma unused (reply, refCon) --- 116,120 ---- static pascal OSErr ! handle_not(const AppleEvent *theAppleEvent, AppleEvent *reply, refcontype refCon) { #pragma unused (reply, refCon) *************** *** 120,124 **** static pascal OSErr ! handle_open_app(const AppleEvent *theAppleEvent, AppleEvent *reply, unsigned long refCon) { #pragma unused (reply, refCon) --- 126,130 ---- static pascal OSErr ! handle_open_app(const AppleEvent *theAppleEvent, AppleEvent *reply, refcontype refCon) { #pragma unused (reply, refCon) *************** *** 133,137 **** static pascal OSErr ! handle_open_doc(const AppleEvent *theAppleEvent, AppleEvent *reply, unsigned long refCon) { #pragma unused (reply, refCon) --- 139,143 ---- static pascal OSErr ! handle_open_doc(const AppleEvent *theAppleEvent, AppleEvent *reply, refcontype refCon) { #pragma unused (reply, refCon) *************** *** 171,177 **** set_ae_handlers() { ! open_doc_upp = NewAEEventHandlerProc(handle_open_doc); ! open_app_upp = NewAEEventHandlerProc(handle_open_app); ! not_upp = NewAEEventHandlerProc(handle_not); AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, --- 177,183 ---- set_ae_handlers() { ! open_doc_upp = NewAEEventHandlerUPP(&handle_open_doc); ! open_app_upp = NewAEEventHandlerUPP(&handle_open_app); ! not_upp = NewAEEventHandlerUPP(&handle_not); AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, From jackjansen@users.sourceforge.net Wed Jun 20 21:53:36 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 20 Jun 2001 13:53:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/ae AEmodule.c,1.26,1.27 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/ae In directory usw-pr-cvs1:/tmp/cvs-serv24625/MacPython/Mac/Modules/ae Modified Files: AEmodule.c Log Message: Adapted to Universal Headers 3.4: new refcontype and use UPP names in stead of Proc names for callback creation. Index: AEmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/ae/AEmodule.c,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -r1.26 -r1.27 *** AEmodule.c 2001/05/22 21:50:54 1.26 --- AEmodule.c 2001/06/20 20:53:33 1.27 *************** *** 1205,1211 **** static pascal OSErr ! GenericEventHandler(const AppleEvent *request, AppleEvent *reply, unsigned long refcon) { PyObject *handler = (PyObject *)refcon; --- 1205,1216 ---- + #if UNIVERSAL_INTERFACES_VERSION >= 0x0340 + typedef long refcontype; + #else + typedef unsigned long refcontype; + #endif static pascal OSErr ! GenericEventHandler(const AppleEvent *request, AppleEvent *reply, refcontype refcon) { PyObject *handler = (PyObject *)refcon; *************** *** 1245,1249 **** upp_AEIdleProc = NewAEIdleUPP(AEIdleProc); ! upp_GenericEventHandler = NewAEEventHandlerUPP(GenericEventHandler); PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_New); PyMac_INIT_TOOLBOX_OBJECT_CONVERT(AEDesc, AEDesc_Convert); --- 1250,1254 ---- upp_AEIdleProc = NewAEIdleUPP(AEIdleProc); ! upp_GenericEventHandler = NewAEEventHandlerUPP(&GenericEventHandler); PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_New); PyMac_INIT_TOOLBOX_OBJECT_CONVERT(AEDesc, AEDesc_Convert); From jackjansen@users.sourceforge.net Wed Jun 20 21:53:40 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 20 Jun 2001 13:53:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/ae aesupport.py,1.20,1.21 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/ae In directory usw-pr-cvs1:/tmp/cvs-serv24669/MacPython/Mac/Modules/ae Modified Files: aesupport.py Log Message: Adapted to Universal Headers 3.4: new refcontype and use UPP names in stead of Proc names for callback creation. Index: aesupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/ae/aesupport.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -r1.20 -r1.21 *** aesupport.py 2001/05/22 21:51:00 1.20 --- aesupport.py 2001/06/20 20:53:38 1.21 *************** *** 117,122 **** finalstuff = finalstuff + """ static pascal OSErr ! GenericEventHandler(const AppleEvent *request, AppleEvent *reply, unsigned long refcon) { PyObject *handler = (PyObject *)refcon; --- 117,128 ---- finalstuff = finalstuff + """ + #if UNIVERSAL_INTERFACES_VERSION >= 0x0340 + typedef long refcontype; + #else + typedef unsigned long refcontype; + #endif + static pascal OSErr ! GenericEventHandler(const AppleEvent *request, AppleEvent *reply, refcontype refcon) { PyObject *handler = (PyObject *)refcon; *************** *** 150,154 **** --- 156,164 ---- initstuff = initstuff + """ upp_AEIdleProc = NewAEIdleUPP(AEIdleProc); + #if UNIVERSAL_INTERFACES_VERSION >= 0x0340 + upp_GenericEventHandler = NewAEEventHandlerUPP(&GenericEventHandler); + #else upp_GenericEventHandler = NewAEEventHandlerUPP(GenericEventHandler); + #endif PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_New); PyMac_INIT_TOOLBOX_OBJECT_CONVERT(AEDesc, AEDesc_Convert); From jackjansen@users.sourceforge.net Wed Jun 20 21:55:07 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 20 Jun 2001 13:55:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/scrap Scrapmodule.c,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/scrap In directory usw-pr-cvs1:/tmp/cvs-serv25109/MacPython/Mac/Modules/scrap Modified Files: Scrapmodule.c Log Message: Removed some unused routines under Carbon. They caused compile errors with UH34. Index: Scrapmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/scrap/Scrapmodule.c,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -r1.6 -r1.7 *** Scrapmodule.c 2001/05/22 21:55:21 1.6 --- Scrapmodule.c 2001/06/20 20:55:05 1.7 *************** *** 15,18 **** --- 15,20 ---- #endif + #if !TARGET_API_MAC_CARBON + /* ** Generate ScrapInfo records *************** *** 27,30 **** --- 29,33 ---- PyMac_BuildStr255, itself->scrapName); } + #endif static PyObject *Scrap_Error; From tim_one@users.sourceforge.net Wed Jun 20 21:56:09 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 20 Jun 2001 13:56:09 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0255.txt,1.8,1.9 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv25263/peps Modified Files: pep-0255.txt Log Message: Added Q&A about "return". Index: pep-0255.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0255.txt,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** pep-0255.txt 2001/06/20 20:32:56 1.8 --- pep-0255.txt 2001/06/20 20:56:07 1.9 *************** *** 311,314 **** --- 311,332 ---- keyword makes that easy. + Q. Why allow "return" at all? Why not force termination to be spelled + "raise StopIteration"? + + A. The mechanics of StopIteration are low-level details, much like the + mechanics of IndexError in Python 2.1: the implementation needs to + do *something* well-defined under the covers, and Python exposes + these mechanisms for advanced users. That's not an argument for + forcing everyone to work at that level, though. "return" means "I'm + done" in any kind of function, and that's easy to explain and to use. + + Q. Then why not allow an expression on "return" too? + + A. Perhaps we will someday. In Icon, "return expr" means both "I'm + done", and "but I have one final useful value to return too, and + this is it". At the start, and in the absence of compelling uses + for "return expr", it's simply cleaner to use "yield" exclusively + for delivering values. + Reference Implementation From fdrake@users.sourceforge.net Wed Jun 20 22:17:11 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 20 Jun 2001 14:17:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/texinputs python.sty,1.75,1.76 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory usw-pr-cvs1:/tmp/cvs-serv31382/texinputs Modified Files: python.sty Log Message: Add a little more support for describing version information. This is not pretty, but does what is needed. Index: python.sty =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/python.sty,v retrieving revision 1.75 retrieving revision 1.76 diff -C2 -r1.75 -r1.76 *** python.sty 2001/05/11 01:00:29 1.75 --- python.sty 2001/06/20 21:17:09 1.76 *************** *** 1049,1052 **** --- 1049,1053 ---- \newcommand{\version}{} \newcommand{\shortversion}{} + \newcommand{\releaseinfo}{} \newcommand{\releasename}{Release} \newcommand{\release}[1]{% *************** *** 1055,1058 **** --- 1056,1061 ---- \newcommand{\setshortversion}[1]{% \renewcommand{\shortversion}{#1}} + \newcommand{\setreleaseinfo}[1]{% + \renewcommand{\releaseinfo}{#1}} % Allow specification of the author's address separately from the From jackjansen@users.sourceforge.net Wed Jun 20 22:20:20 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 20 Jun 2001 14:20:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/win Winmodule.c,1.35,1.36 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/win In directory usw-pr-cvs1:/tmp/cvs-serv32463/Python/Mac/Modules/win Modified Files: Winmodule.c Log Message: Reversed the order of the checks for None or a Dialog where a Window is expected so it doesn't crash under OSX/Mach-o. Index: Winmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/win/Winmodule.c,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -r1.35 -r1.36 *** Winmodule.c 2001/05/22 21:56:36 1.35 --- Winmodule.c 2001/06/20 21:20:18 1.36 *************** *** 77,81 **** WinObj_Convert(PyObject *v, WindowPtr *p_itself) { ! #if 1 { DialogRef dlg; --- 77,84 ---- WinObj_Convert(PyObject *v, WindowPtr *p_itself) { ! ! if (v == Py_None) { *p_itself = NULL; return 1; } ! if (PyInt_Check(v)) { *p_itself = (WindowPtr)PyInt_AsLong(v); return 1; } ! { DialogRef dlg; *************** *** 86,99 **** PyErr_Clear(); } - #else - if (DlgObj_Check(v)) { - *p_itself = DlgObj_ConvertToWindow(v); - return 1; - } - #endif - - if (v == Py_None) { *p_itself = NULL; return 1; } - if (PyInt_Check(v)) { *p_itself = (WindowPtr)PyInt_AsLong(v); return 1; } - if (!WinObj_Check(v)) { --- 89,92 ---- From jackjansen@users.sourceforge.net Wed Jun 20 22:20:24 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 20 Jun 2001 14:20:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/win winsupport.py,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/win In directory usw-pr-cvs1:/tmp/cvs-serv32519/Python/Mac/Modules/win Modified Files: winsupport.py Log Message: Reversed the order of the checks for None or a Dialog where a Window is expected so it doesn't crash under OSX/Mach-o. Index: winsupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/win/winsupport.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -r1.24 -r1.25 *** winsupport.py 2001/05/22 21:56:42 1.24 --- winsupport.py 2001/06/20 21:20:22 1.25 *************** *** 138,142 **** OutRbrace() def outputCheckConvertArg(self): ! Output("#if 1") OutLbrace() Output("DialogRef dlg;") --- 138,145 ---- OutRbrace() def outputCheckConvertArg(self): ! Out(""" ! if (v == Py_None) { *p_itself = NULL; return 1; } ! if (PyInt_Check(v)) { *p_itself = (WindowPtr)PyInt_AsLong(v); return 1; } ! """) OutLbrace() Output("DialogRef dlg;") *************** *** 147,160 **** Output("PyErr_Clear();") OutRbrace() - Output("#else") - OutLbrace("if (DlgObj_Check(v))") - Output("*p_itself = DlgObj_ConvertToWindow(v);") - Output("return 1;") - OutRbrace() - Output("#endif") - Out(""" - if (v == Py_None) { *p_itself = NULL; return 1; } - if (PyInt_Check(v)) { *p_itself = (WindowPtr)PyInt_AsLong(v); return 1; } - """) def outputCleanupStructMembers(self): Output("if (self->ob_freeit && self->ob_itself)") --- 150,153 ---- From jackjansen@users.sourceforge.net Wed Jun 20 22:21:04 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 20 Jun 2001 14:21:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/waste wastemodule.c,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/waste In directory usw-pr-cvs1:/tmp/cvs-serv32677/Python/Mac/Modules/waste Modified Files: wastemodule.c Log Message: Added a const to shut up a compiler warning. Index: wastemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/waste/wastemodule.c,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -r1.16 -r1.17 *** wastemodule.c 2001/05/22 21:56:20 1.16 --- wastemodule.c 2001/06/20 21:21:02 1.17 *************** *** 155,159 **** static pascal OSErr ! my_draw_handler(Rect *destRect, WEObjectReference objref) { PyObject *args=NULL, *rv=NULL; --- 155,159 ---- static pascal OSErr ! my_draw_handler(const Rect *destRect, WEObjectReference objref) { PyObject *args=NULL, *rv=NULL; From jackjansen@users.sourceforge.net Wed Jun 20 22:21:09 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 20 Jun 2001 14:21:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/waste wastesupport.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/waste In directory usw-pr-cvs1:/tmp/cvs-serv32730/Python/Mac/Modules/waste Modified Files: wastesupport.py Log Message: Added a const to shut up a compiler warning. Index: wastesupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/waste/wastesupport.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -r1.13 -r1.14 *** wastesupport.py 2000/09/08 22:06:16 1.13 --- wastesupport.py 2001/06/20 21:21:07 1.14 *************** *** 203,207 **** static pascal OSErr ! my_draw_handler(Rect *destRect, WEObjectReference objref) { PyObject *args=NULL, *rv=NULL; --- 203,207 ---- static pascal OSErr ! my_draw_handler(const Rect *destRect, WEObjectReference objref) { PyObject *args=NULL, *rv=NULL; From jackjansen@users.sourceforge.net Wed Jun 20 22:22:09 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 20 Jun 2001 14:22:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/qd Qdmodule.c,1.40,1.41 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/qd In directory usw-pr-cvs1:/tmp/cvs-serv452/Python/Mac/Modules/qd Modified Files: Qdmodule.c Log Message: ANSIfied function headers to shut up compiler warnings on OSX/Mach-o. Index: Qdmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/qd/Qdmodule.c,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -r1.40 -r1.41 *** Qdmodule.c 2001/06/13 12:38:47 1.40 --- Qdmodule.c 2001/06/20 21:22:07 1.41 *************** *** 522,526 **** } QDGlobalsAccessObject; ! static PyObject *QDGA_New() { QDGlobalsAccessObject *it; --- 522,526 ---- } QDGlobalsAccessObject; ! static PyObject *QDGA_New(void) { QDGlobalsAccessObject *it; From jackjansen@users.sourceforge.net Wed Jun 20 22:22:14 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 20 Jun 2001 14:22:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/qd qdsupport.py,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/qd In directory usw-pr-cvs1:/tmp/cvs-serv541/Python/Mac/Modules/qd Modified Files: qdsupport.py Log Message: ANSIfied function headers to shut up compiler warnings on OSX/Mach-o. Index: qdsupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/qd/qdsupport.py,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -r1.32 -r1.33 *** qdsupport.py 2001/06/13 12:39:02 1.32 --- qdsupport.py 2001/06/20 21:22:12 1.33 *************** *** 451,455 **** def outputNew(self): Output() ! Output("%sPyObject *%s_New()", self.static, self.prefix) OutLbrace() Output("%s *it;", self.objecttype) --- 451,455 ---- def outputNew(self): Output() ! Output("%sPyObject *%s_New(void)", self.static, self.prefix) OutLbrace() Output("%s *it;", self.objecttype) From jackjansen@users.sourceforge.net Wed Jun 20 22:22:21 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 20 Jun 2001 14:22:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/snd Sndmodule.c,1.25,1.26 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/snd In directory usw-pr-cvs1:/tmp/cvs-serv568/Python/Mac/Modules/snd Modified Files: Sndmodule.c Log Message: ANSIfied function headers to shut up compiler warnings on OSX/Mach-o. Index: Sndmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/snd/Sndmodule.c,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -r1.25 -r1.26 *** Sndmodule.c 2001/05/22 21:55:35 1.25 --- Sndmodule.c 2001/06/20 21:22:19 1.26 *************** *** 352,356 **** } SPBObject; ! static PyObject *SPBObj_New() { SPBObject *it; --- 352,356 ---- } SPBObject; ! static PyObject *SPBObj_New(void) { SPBObject *it; From jackjansen@users.sourceforge.net Wed Jun 20 22:22:25 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 20 Jun 2001 14:22:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/snd sndsupport.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/snd In directory usw-pr-cvs1:/tmp/cvs-serv615/Python/Mac/Modules/snd Modified Files: sndsupport.py Log Message: ANSIfied function headers to shut up compiler warnings on OSX/Mach-o. Index: sndsupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/snd/sndsupport.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -r1.15 -r1.16 *** sndsupport.py 2001/05/22 21:55:39 1.15 --- sndsupport.py 2001/06/20 21:22:23 1.16 *************** *** 245,249 **** def outputNew(self): Output() ! Output("%sPyObject *%s_New()", self.static, self.prefix) OutLbrace() Output("%s *it;", self.objecttype) --- 245,249 ---- def outputNew(self): Output() ! Output("%sPyObject *%s_New(void)", self.static, self.prefix) OutLbrace() Output("%s *it;", self.objecttype) From jackjansen@users.sourceforge.net Wed Jun 20 22:29:17 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 20 Jun 2001 14:29:17 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/fm Fmmodule.c,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/fm In directory usw-pr-cvs1:/tmp/cvs-serv1867/Python/Mac/Modules/fm Modified Files: Fmmodule.c Log Message: {Is,Set}AntiAliasedTextEnabled don't exist on MacOS 8.5.5 and earlier. For now: cop out and blacklist them. Index: Fmmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/fm/Fmmodule.c,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** Fmmodule.c 2001/05/22 21:52:22 1.8 --- Fmmodule.c 2001/06/20 21:29:15 1.9 *************** *** 282,317 **** } - static PyObject *Fm_SetAntiAliasedTextEnabled(PyObject *_self, PyObject *_args) - { - PyObject *_res = NULL; - OSStatus _err; - Boolean iEnable; - SInt16 iMinFontSize; - if (!PyArg_ParseTuple(_args, "bh", - &iEnable, - &iMinFontSize)) - return NULL; - _err = SetAntiAliasedTextEnabled(iEnable, - iMinFontSize); - if (_err != noErr) return PyMac_Error(_err); - Py_INCREF(Py_None); - _res = Py_None; - return _res; - } - - static PyObject *Fm_IsAntiAliasedTextEnabled(PyObject *_self, PyObject *_args) - { - PyObject *_res = NULL; - Boolean _rv; - SInt16 oMinFontSize; - if (!PyArg_ParseTuple(_args, "")) - return NULL; - _rv = IsAntiAliasedTextEnabled(&oMinFontSize); - _res = Py_BuildValue("bh", - _rv, - oMinFontSize); - return _res; - } - static PyMethodDef Fm_methods[] = { --- 282,285 ---- *************** *** 358,365 **** {"GetAppFont", (PyCFunction)Fm_GetAppFont, 1, "() -> (short _rv)"}, - {"SetAntiAliasedTextEnabled", (PyCFunction)Fm_SetAntiAliasedTextEnabled, 1, - "(Boolean iEnable, SInt16 iMinFontSize) -> None"}, - {"IsAntiAliasedTextEnabled", (PyCFunction)Fm_IsAntiAliasedTextEnabled, 1, - "() -> (Boolean _rv, SInt16 oMinFontSize)"}, {NULL, NULL, 0} }; --- 326,329 ---- From jackjansen@users.sourceforge.net Wed Jun 20 22:29:21 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 20 Jun 2001 14:29:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/fm fmscan.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/fm In directory usw-pr-cvs1:/tmp/cvs-serv1886/Python/Mac/Modules/fm Modified Files: fmscan.py Log Message: {Is,Set}AntiAliasedTextEnabled don't exist on MacOS 8.5.5 and earlier. For now: cop out and blacklist them. Index: fmscan.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/fm/fmscan.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** fmscan.py 2001/01/03 16:44:27 1.8 --- fmscan.py 2001/06/20 21:29:19 1.9 *************** *** 37,40 **** --- 37,45 ---- "AntiTextGetApplicationAware", "AntiTextSetApplicationAware", + # These are tricky: they're not Carbon dependent or anything, but they + # exist only on 8.6 or later (both in Carbon and Classic). + # Disabling them is the easiest path. + 'SetAntiAliasedTextEnabled', + 'IsAntiAliasedTextEnabled', ] From fdrake@users.sourceforge.net Wed Jun 20 22:29:32 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 20 Jun 2001 14:29:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/perl python.perl,1.102,1.103 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/perl In directory usw-pr-cvs1:/tmp/cvs-serv1932/perl Modified Files: python.perl Log Message: Added support for new \setreleaseinfo macro. Normalize all generated HTML so that attribute names come out as name="value" instead of name='value'. Changed the target of RFC links to point to the hypertext RFCs at www.faqs.org instead of the plain text RFCs at www.ietf.org. Index: python.perl =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/perl/python.perl,v retrieving revision 1.102 retrieving revision 1.103 diff -C2 -r1.102 -r1.103 *** python.perl 2001/06/15 21:31:57 1.102 --- python.perl 2001/06/20 21:29:30 1.103 *************** *** 42,54 **** # absolute URL; assume it points off-site my $icon = make_icon_filename($OFF_SITE_LINK_ICON); ! return (" [off-site link]"); } --- 42,54 ---- # absolute URL; assume it points off-site my $icon = make_icon_filename($OFF_SITE_LINK_ICON); ! return (" \"[off-site"); } *************** *** 105,108 **** --- 105,109 ---- $DEVELOPER_ADDRESS = ''; $SHORT_VERSION = ''; + $RELEASE_INFO = ''; $PACKAGE_VERSION = ''; *************** *** 115,118 **** --- 116,125 ---- } + sub do_cmd_setreleaseinfo{ + local($_) = @_; + $RELEASE_INFO = next_argument(); + return $_; + } + sub do_cmd_setshortversion{ local($_) = @_; *************** *** 237,241 **** $key = $module unless $key; ! return "$module" . $_; } --- 244,248 ---- $key = $module unless $key; ! return "$module" . $_; } *************** *** 245,250 **** my $newsgroup = next_argument(); my $icon = get_link_icon("news:$newsgroup"); ! my $stuff = "" ! . "$newsgroup$icon"; return $stuff . $_; } --- 252,257 ---- my $newsgroup = next_argument(); my $icon = get_link_icon("news:$newsgroup"); ! my $stuff = ("" ! . "$newsgroup$icon"); return $stuff . $_; } *************** *** 277,292 **** my $page = next_argument(); my $section = next_argument(); ! return "$page($section)" . $_; } ! $PEP_FORMAT = "http://python.sourceforge.net/peps/pep-XXXX.html"; ! $RFC_FORMAT = "http://www.ietf.org/rfc/rfcXXXX.txt"; sub get_rfc_url($$){ my($rfcnum, $format) = @_; ! $rfcnum = sprintf("%04d", $rfcnum); ! $format = "$format"; ! $format =~ s/XXXX/$rfcnum/; ! return $format; } --- 284,297 ---- my $page = next_argument(); my $section = next_argument(); ! return "$page($section)" . $_; } ! $PEP_FORMAT = "http://python.sourceforge.net/peps/pep-%04d.html"; ! #$RFC_FORMAT = "http://www.ietf.org/rfc/rfc%04d.txt"; ! $RFC_FORMAT = "http://www.faqs.org/rfcs/rfc%d.html"; sub get_rfc_url($$){ my($rfcnum, $format) = @_; ! return sprintf($format, $rfcnum); } *************** *** 324,334 **** my $repl = ''; if ($url) { ! $repl = ("$title$icon"); } else { ! $repl = "$title"; } return $repl . $_; --- 329,339 ---- my $repl = ''; if ($url) { ! $repl = ("$title$icon"); } else { ! $repl = "$title"; } return $repl . $_; *************** *** 356,360 **** $text = "$type in version $release:\n$explanation."; } ! return "\n$text\n" . $_; } --- 361,365 ---- $text = "$type in version $release:\n$explanation."; } ! return "\n$text\n" . $_; } *************** *** 373,381 **** local($_) = @_; my $platform = next_argument(); ! $ModulePlatforms{"$THIS_MODULE"} = $platform; $platform = "Macintosh" if $platform eq 'Mac'; ! return "\n

Availability: $platform.

\n" . $_; } --- 378,386 ---- local($_) = @_; my $platform = next_argument(); ! $ModulePlatforms{"$THIS_MODULE"} = $platform; $platform = "Macintosh" if $platform eq 'Mac'; ! return "\n

Availability: $platform.

\n" . $_; } *************** *** 446,450 **** my($node,$target) = @_; print INTLABELS "\$internal_labels{\"$target\"} = \"$URL/$node\";\n"; ! return ""; } --- 451,455 ---- my($node,$target) = @_; print INTLABELS "\$internal_labels{\"$target\"} = \"$URL/$node\";\n"; ! return ""; } *************** *** 459,463 **** sub new_link_info{ my $name = "l2h-" . ++$globals{'max_id'}; ! my $aname = ""; my $ahref = gen_link($CURRENT_FILE, $name); return ($name, $aname, $ahref); --- 464,468 ---- sub new_link_info{ my $name = "l2h-" . ++$globals{'max_id'}; ! my $aname = ""; my $ahref = gen_link($CURRENT_FILE, $name); return ($name, $aname, $ahref); *************** *** 579,583 **** sub idx_cmd_bifuncindex{ my $str = next_argument(); ! add_index_entry("$str() (built-in function)", @_[0]); } --- 584,588 ---- sub idx_cmd_bifuncindex{ my $str = next_argument(); ! add_index_entry("$str() (built-in function)", @_[0]); } *************** *** 621,625 **** print "[$name]"; return make_mod_index_entry( ! "$name (${word}module)", 'DEF'); } --- 626,630 ---- print "[$name]"; return make_mod_index_entry( ! "$name (${word}module)", 'DEF'); } *************** *** 639,643 **** my $str = next_argument(); $word = "$word " if $word; ! $str = "$str (${word}module)"; # can't use add_index_entry() since the 2nd arg to gen_index_id() is used; # just inline it all here --- 644,648 ---- my $str = next_argument(); $word = "$word " if $word; ! $str = "$str (${word}module)"; # can't use add_index_entry() since the 2nd arg to gen_index_id() is used; # just inline it all here *************** *** 713,717 **** my $arg_list = next_argument(); my $idx = make_str_index_entry( ! "$function_name()" . get_indexsubitem()); $idx =~ s/ \(.*\)//; $idx =~ s/\(\)//; # ???? - why both of these? --- 718,722 ---- my $arg_list = next_argument(); my $idx = make_str_index_entry( ! "$function_name()" . get_indexsubitem()); $idx =~ s/ \(.*\)//; $idx =~ s/\(\)//; # ???? - why both of these? *************** *** 742,746 **** local($_) = @_; my $name = next_argument(); ! my $idx = make_str_index_entry("$name"); return "
$idx\n
" . $_ --- 747,751 ---- local($_) = @_; my $name = next_argument(); ! my $idx = make_str_index_entry("$name"); return "
$idx\n
" . $_ *************** *** 755,760 **** unless $index_name; my($name,$aname,$ahref) = new_link_info(); ! add_index_entry("$index_name (C type)", $ahref); ! return "
$aname$type_name\n
" . $_ . '
' --- 760,765 ---- unless $index_name; my($name,$aname,$ahref) = new_link_info(); ! add_index_entry("$index_name (C type)", $ahref); ! return "
$aname$type_name\n
" . $_ . '
' *************** *** 765,769 **** my $var_type = next_argument(); my $var_name = next_argument(); ! my $idx = make_str_index_entry("$var_name" . get_indexsubitem()); $idx =~ s/ \(.*\)//; --- 770,774 ---- my $var_type = next_argument(); my $var_name = next_argument(); ! my $idx = make_str_index_entry("$var_name" . get_indexsubitem()); $idx =~ s/ \(.*\)//; *************** *** 784,788 **** my $function_name = next_argument(); my $arg_list = convert_args(next_argument()); ! my $idx = make_str_index_entry("$function_name()" . get_indexsubitem()); $idx =~ s/ \(.*\)//; --- 789,794 ---- my $function_name = next_argument(); my $arg_list = convert_args(next_argument()); ! my $idx = make_str_index_entry("$function_name()" ! . '' . get_indexsubitem()); $idx =~ s/ \(.*\)//; *************** *** 795,799 **** my $function_name = next_argument(); my $arg_list = convert_args(next_argument()); ! return "
$function_name" . "($arg_list)\n" . '
' --- 801,805 ---- my $function_name = next_argument(); my $arg_list = convert_args(next_argument()); ! return "
$function_name" . "($arg_list)\n" . '
' *************** *** 806,810 **** my $function_name = next_argument(); my $arg_list = convert_args(next_argument()); ! my $prefix = "$function_name()"; my $idx = make_str_index_entry($prefix . get_indexsubitem()); $prefix =~ s/\(\)//; --- 812,816 ---- my $function_name = next_argument(); my $arg_list = convert_args(next_argument()); ! my $prefix = "$function_name()"; my $idx = make_str_index_entry($prefix . get_indexsubitem()); $prefix =~ s/\(\)//; *************** *** 817,821 **** my $function_name = next_argument(); my $arg_list = convert_args(next_argument()); ! my $prefix = "$function_name"; return "
$prefix($arg_list)\n
" . $_; --- 823,827 ---- my $function_name = next_argument(); my $arg_list = convert_args(next_argument()); ! my $prefix = "$function_name"; return "
$prefix($arg_list)\n
" . $_; *************** *** 834,843 **** my $idx; if ($INDEX_OPCODES) { ! $idx = make_str_index_entry("$opcode_name" ! . " (byte code instruction)"); $idx =~ s/ \(byte code instruction\)//; } else { ! $idx = "$opcode_name"; } my $stuff = "
$idx"; --- 840,849 ---- my $idx; if ($INDEX_OPCODES) { ! $idx = make_str_index_entry("$opcode_name" ! . ' (byte code instruction)'); $idx =~ s/ \(byte code instruction\)//; } else { ! $idx = "$opcode_name"; } my $stuff = "
$idx"; *************** *** 884,888 **** local($_) = @_; my $excname = next_argument(); ! my $idx = make_str_index_entry("$excname"); return "
exception $idx\n
" . $_ . '
' } --- 890,894 ---- local($_) = @_; my $excname = next_argument(); ! my $idx = make_str_index_entry("$excname"); return "
exception $idx\n
" . $_ . '
' } *************** *** 896,900 **** my $arg_list = convert_args(next_argument()); $idx = make_str_index_entry( ! "$THIS_CLASS ($what in $THIS_MODULE)" ); $idx =~ s/ \(.*\)//; return ("
$what $idx($arg_list)\n
" --- 902,906 ---- my $arg_list = convert_args(next_argument()); $idx = make_str_index_entry( ! "$THIS_CLASS ($what in $THIS_MODULE)" ); $idx =~ s/ \(.*\)//; return ("
$what $idx($arg_list)\n
" *************** *** 911,915 **** $THIS_CLASS = next_argument(); $idx = make_str_index_entry( ! "$THIS_CLASS (class in $THIS_MODULE)" ); $idx =~ s/ \(.*\)//; return ("
class $idx\n
" --- 917,921 ---- $THIS_CLASS = next_argument(); $idx = make_str_index_entry( ! "$THIS_CLASS (class in $THIS_MODULE)"); $idx =~ s/ \(.*\)//; return ("
class $idx\n
" *************** *** 934,938 **** $extra = " ($class_name method)"; } ! my $idx = make_str_index_entry("$method()$extra"); $idx =~ s/ \(.*\)//; $idx =~ s/\(\)//; --- 940,945 ---- $extra = " ($class_name method)"; } ! my $idx = make_str_index_entry( ! "$method()$extra"); $idx =~ s/ \(.*\)//; $idx =~ s/\(\)//; *************** *** 952,956 **** $extra = " ($class_name method)"; } ! my $idx = make_str_index_entry("$method()$extra"); $idx =~ s/ \(.*\)//; $idx =~ s/\(\)//; --- 959,964 ---- $extra = " ($class_name method)"; } ! my $idx = make_str_index_entry( ! "$method()$extra"); $idx =~ s/ \(.*\)//; $idx =~ s/\(\)//; *************** *** 989,993 **** $extra = " ($class attribute)" if ($class ne ''); ! my $idx = make_str_index_entry("$member$extra"); $idx =~ s/ \(.*\)//; $idx =~ s/\(\)//; --- 997,1001 ---- $extra = " ($class attribute)" if ($class ne ''); ! my $idx = make_str_index_entry("$member$extra"); $idx =~ s/ \(.*\)//; $idx =~ s/\(\)//; *************** *** 1005,1009 **** $extra = " ($class attribute)" if ($class ne ''); ! my $idx = make_str_index_entry("$member$extra"); $idx =~ s/ \(.*\)//; $idx =~ s/\(\)//; --- 1013,1017 ---- $extra = " ($class attribute)" if ($class ne ''); ! my $idx = make_str_index_entry("$member$extra"); $idx =~ s/ \(.*\)//; $idx =~ s/\(\)//; *************** *** 1015,1019 **** next_optional_argument(); my $member = next_argument(); ! return "
$member\n
" . $_ . '
'; --- 1023,1027 ---- next_optional_argument(); my $member = next_argument(); ! return "
$member\n
" . $_ . '
'; *************** *** 1025,1029 **** next_optional_argument(); my $member = next_argument(); ! return "
$member
" . $_; } --- 1033,1037 ---- next_optional_argument(); my $member = next_argument(); ! return "
$member
" . $_; } *************** *** 1120,1124 **** . "\n " . "\n " ! . "\n " . $_ . "\n " --- 1128,1132 ---- . "\n " . "\n " ! . "\n " . $_ . "\n " *************** *** 1169,1173 **** . "\n " . "\n " ! . "\n " . $_ . "\n " --- 1177,1181 ---- . "\n " . "\n " ! . "\n " . $_ . "\n " *************** *** 1223,1227 **** . "\n " . "\n " ! . "\n " . $_ . "\n " --- 1231,1235 ---- . "\n " . "\n " ! . "\n " . $_ . "\n " *************** *** 1286,1294 **** my $href = translate_commands($t_authorURL); $href = make_named_href('author', $href, ! "$t_author"); $the_title .= "\n

$href

"; } else { ! $the_title .= ("\n

$t_author

"); } } --- 1294,1304 ---- my $href = translate_commands($t_authorURL); $href = make_named_href('author', $href, ! "$t_author" ! . ''); $the_title .= "\n

$href

"; } else { ! $the_title .= ("\n

$t_author" ! . '

'); } } *************** *** 1308,1312 **** $the_title .= "\n

"; if ($PACKAGE_VERSION) { ! $the_title .= "Release $PACKAGE_VERSION
\n"; } $the_title .= "$t_date

" --- 1318,1323 ---- $the_title .= "\n

"; if ($PACKAGE_VERSION) { ! $the_title .= ('Release ' ! . "$PACKAGE_VERSION$RELEASE_INFO
\n"); } $the_title .= "$t_date

" *************** *** 1485,1492 **** sub do_env_seealso{ ! return "
\n " ! . "

See Also:

\n" ! . @_[0] ! . '
'; } --- 1496,1503 ---- sub do_env_seealso{ ! return ("
\n " ! . "

See Also:

\n" ! . @_[0] ! . '
'); } *************** *** 1504,1512 **** $period = ''; } ! return '
' ! . "\n
Module " ! . "$module:" ! . "\n
$text$period\n
" ! . $_; } --- 1515,1523 ---- $period = ''; } ! return ('
' ! . "\n
Module " ! . "$module:" ! . "\n
$text$period\n
" ! . $_); } *************** *** 1587,1591 **** sub do_env_definitions{ ! return "
" . @_[0] . "
\n"; } --- 1598,1602 ---- sub do_env_definitions{ ! return "
" . @_[0] . "
\n"; } From jackjansen@users.sourceforge.net Wed Jun 20 22:31:21 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 20 Jun 2001 14:31:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/ctl Ctlmodule.c,1.44,1.45 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/ctl In directory usw-pr-cvs1:/tmp/cvs-serv2348/Python/Mac/Modules/ctl Modified Files: Ctlmodule.c Log Message: Don't use extern when we mean staticforward (OSX gcc is picky about it). Blacklist SendControlMessage: it's signature has changed between Universal Headers 3.3 and 3.4. Index: Ctlmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/ctl/Ctlmodule.c,v retrieving revision 1.44 retrieving revision 1.45 diff -C2 -r1.44 -r1.45 *** Ctlmodule.c 2001/05/22 21:51:44 1.44 --- Ctlmodule.c 2001/06/20 21:31:19 1.45 *************** *** 82,87 **** static ControlUserPaneTrackingUPP mytrackingproc_upp; ! extern int settrackfunc(PyObject *); /* forward */ ! extern void clrtrackfunc(void); /* forward */ staticforward int setcallback(PyObject *, OSType, PyObject *, UniversalProcPtr *); --- 82,87 ---- static ControlUserPaneTrackingUPP mytrackingproc_upp; ! staticforward int settrackfunc(PyObject *); /* forward */ ! staticforward void clrtrackfunc(void); /* forward */ staticforward int setcallback(PyObject *, OSType, PyObject *, UniversalProcPtr *); *************** *** 911,932 **** #endif - static PyObject *CtlObj_SendControlMessage(ControlObject *_self, PyObject *_args) - { - PyObject *_res = NULL; - SInt32 _rv; - SInt16 inMessage; - SInt32 inParam; - if (!PyArg_ParseTuple(_args, "hl", - &inMessage, - &inParam)) - return NULL; - _rv = SendControlMessage(_self->ob_itself, - inMessage, - inParam); - _res = Py_BuildValue("l", - _rv); - return _res; - } - static PyObject *CtlObj_EmbedControl(ControlObject *_self, PyObject *_args) { --- 911,914 ---- *************** *** 1896,1901 **** "(CCTabHandle newColorTable) -> None"}, #endif - {"SendControlMessage", (PyCFunction)CtlObj_SendControlMessage, 1, - "(SInt16 inMessage, SInt32 inParam) -> (SInt32 _rv)"}, {"EmbedControl", (PyCFunction)CtlObj_EmbedControl, 1, "(ControlHandle inContainer) -> None"}, --- 1878,1881 ---- From jackjansen@users.sourceforge.net Wed Jun 20 22:31:25 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 20 Jun 2001 14:31:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/ctl ctlscan.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/ctl In directory usw-pr-cvs1:/tmp/cvs-serv2391/Python/Mac/Modules/ctl Modified Files: ctlscan.py Log Message: Don't use extern when we mean staticforward (OSX gcc is picky about it). Blacklist SendControlMessage: it's signature has changed between Universal Headers 3.3 and 3.4. Index: ctlscan.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/ctl/ctlscan.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -r1.19 -r1.20 *** ctlscan.py 2001/01/09 22:08:33 1.19 --- ctlscan.py 2001/06/20 21:31:23 1.20 *************** *** 80,83 **** --- 80,84 ---- 'SetControlProperty', 'GetControlPropertySize', + 'SendControlMessage', # Parameter changed from long to void* from UH3.3 to UH3.4 ] From jackjansen@users.sourceforge.net Wed Jun 20 22:31:30 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 20 Jun 2001 14:31:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/ctl ctlsupport.py,1.39,1.40 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/ctl In directory usw-pr-cvs1:/tmp/cvs-serv2414/Python/Mac/Modules/ctl Modified Files: ctlsupport.py Log Message: Don't use extern when we mean staticforward (OSX gcc is picky about it). Blacklist SendControlMessage: it's signature has changed between Universal Headers 3.3 and 3.4. Index: ctlsupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/ctl/ctlsupport.py,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -r1.39 -r1.40 *** ctlsupport.py 2001/05/22 21:51:49 1.39 --- ctlsupport.py 2001/06/20 21:31:28 1.40 *************** *** 123,128 **** static ControlUserPaneTrackingUPP mytrackingproc_upp; ! extern int settrackfunc(PyObject *); /* forward */ ! extern void clrtrackfunc(void); /* forward */ staticforward int setcallback(PyObject *, OSType, PyObject *, UniversalProcPtr *); """ --- 123,128 ---- static ControlUserPaneTrackingUPP mytrackingproc_upp; ! staticforward int settrackfunc(PyObject *); /* forward */ ! staticforward void clrtrackfunc(void); /* forward */ staticforward int setcallback(PyObject *, OSType, PyObject *, UniversalProcPtr *); """ From fdrake@users.sourceforge.net Wed Jun 20 22:31:38 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 20 Jun 2001 14:31:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/perl l2hinit.perl,1.53,1.54 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/perl In directory usw-pr-cvs1:/tmp/cvs-serv2442/perl Modified Files: l2hinit.perl Log Message: Update to use the newly separated values $PACKAGE_VERSION and $RELEASE_INFO. Normalize all HTML attributes to be written as name="value" instead of name='value'. Index: l2hinit.perl =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/perl/l2hinit.perl,v retrieving revision 1.53 retrieving revision 1.54 diff -C2 -r1.53 -r1.54 *** l2hinit.perl 2001/01/09 22:02:10 1.53 --- l2hinit.perl 2001/06/20 21:31:36 1.54 *************** *** 182,191 **** if ($PACKAGE_VERSION ne '' && $t_date) { return ("" ! . "Release $PACKAGE_VERSION," . " documentation updated on $t_date."); } if ($PACKAGE_VERSION ne '') { return ("" ! . "Release $PACKAGE_VERSION."); } if ($t_date) { --- 182,191 ---- if ($PACKAGE_VERSION ne '' && $t_date) { return ("" ! . "Release $PACKAGE_VERSION$RELEASE_INFO," . " documentation updated on $t_date."); } if ($PACKAGE_VERSION ne '') { return ("" ! . "Release $PACKAGE_VERSION$RELEASE_INFO."); } if ($t_date) { *************** *** 326,334 **** $key =~ s/([a-zA-Z0-9._]*)<\/tt>/\1/; if ($ModulePlatforms{$key} && !$allthesame) { ! $plat = (" ($ModulePlatforms{$key}" . ')'); } print MODIDXFILE $moditem . $IDXFILE_FIELD_SEP ! . "$key$plat###\n"; } close(MODIDXFILE); --- 326,334 ---- $key =~ s/([a-zA-Z0-9._]*)<\/tt>/\1/; if ($ModulePlatforms{$key} && !$allthesame) { ! $plat = (" ($ModulePlatforms{$key}" . ')'); } print MODIDXFILE $moditem . $IDXFILE_FIELD_SEP ! . "$key$plat###\n"; } close(MODIDXFILE); *************** *** 416,420 **** $the_version = ",\n$t_date"; if ($PACKAGE_VERSION) { ! $the_version .= ", Release $PACKAGE_VERSION"; } } --- 416,420 ---- $the_version = ",\n$t_date"; if ($PACKAGE_VERSION) { ! $the_version .= ", Release $PACKAGE_VERSION$RELEASE_INFO"; } } From fdrake@users.sourceforge.net Wed Jun 20 22:33:15 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 20 Jun 2001 14:33:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/texinputs boilerplate.tex,1.59,1.60 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory usw-pr-cvs1:/tmp/cvs-serv2809/texinputs Modified Files: boilerplate.tex Log Message: Separate the version number and release status into two separate values. Index: boilerplate.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/boilerplate.tex,v retrieving revision 1.59 retrieving revision 1.60 diff -C2 -r1.59 -r1.60 *** boilerplate.tex 2001/04/18 05:02:01 1.59 --- boilerplate.tex 2001/06/20 21:33:13 1.60 *************** *** 7,10 **** \date{\today} % XXX update before release! ! \release{2.2a0} % software release, not documentation \setshortversion{2.2} % major.minor only for software --- 7,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 From fdrake@users.sourceforge.net Wed Jun 20 22:34:37 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 20 Jun 2001 14:34:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/texinputs license.tex,NONE,1.1 copyright.tex,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory usw-pr-cvs1:/tmp/cvs-serv3006 Modified Files: copyright.tex Added Files: license.tex Log Message: Separate the copyright statements and license text; include some new comments regarding the history of Python licensing from Guido. --- NEW FILE: license.tex --- \section{History of the software} Python was created in the early 1990s by Guido van Rossum at Stichting Mathematisch Centrum (CWI) in the Netherlands as a successor of a language called ABC. Guido is Python's principal author, although it includes many contributions from others. The last version released from CWI was Python 1.2. In 1995, Guido continued his work on Python at the Corporation for National Research Initiatives (CNRI) in Reston, Virginia where he released several versions of the software. Python 1.6 was the last of the versions released by CNRI. In 2000, Guido and the Python core development team moved to BeOpen.com to form the BeOpen PythonLabs team. Python 2.0 was the first and only release from BeOpen.com. Following the release of Python 1.6, and after Guido van Rossum left CNRI to work with commercial software developers, it became clear that the ability to use Python with software available under the GNU Public License (GPL) was very desirable. CNRI and the Free Software Foundation (FSF) interacted to develop enabling wording changes to the Python license. Python 1.6.1 is essentially the same as Python 1.6, with a few minor bug fixes, and with a different license that enables later versions to be GPL-compatible. Python 2.0.1 is a derivative work of Python 1.6.1, as well as of Python 2.0. 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 and its alpha and beta releases, is owned by the Python Software Foundation (PSF), a non-profit modeled after the Apache Software Foundation. See \url{http://www.python.org/psf/} for more information about the PSF. Thanks to the many outside volunteers who have worked under Guido's direction to make these releases possible. \section{Terms and conditions for accessing or otherwise using Python} \centerline{\strong{PSF LICENSE AGREEMENT}} \begin{enumerate} \item This LICENSE AGREEMENT is between the Python Software Foundation (``PSF''), and the Individual or Organization (``Licensee'') accessing and otherwise using Python \version{} software in source or binary form and its associated documentation. \item Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python \version{} alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., ``Copyright \copyright{} 2001 Python Software Foundation; All Rights Reserved'' are retained in Python \version{} alone or in any derivative version prepared by Licensee. \item In the event Licensee prepares a derivative work that is based on or incorporates Python \version{} or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python \version. \item PSF is making Python \version{} available to Licensee on an ``AS IS'' basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON \version{} WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. \item PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON \version{} FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON \version, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. \item This License Agreement will automatically terminate upon a material breach of its terms and conditions. \item 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. \item By copying, installing or otherwise using Python \version, Licensee agrees to be bound by the terms and conditions of this License Agreement. \end{enumerate} \centerline{\strong{BEOPEN.COM TERMS AND CONDITIONS FOR PYTHON 2.0}} \centerline{\strong{BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1}} \begin{enumerate} \item This LICENSE AGREEMENT is between BeOpen.com (``BeOpen''), having an office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the Individual or Organization (``Licensee'') accessing and otherwise using this software in source or binary form and its associated documentation (``the Software''). \item Subject to the terms and conditions of this BeOpen Python License Agreement, BeOpen hereby grants Licensee a non-exclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use the Software alone or in any derivative version, provided, however, that the BeOpen Python License is retained in the Software, alone or in any derivative version prepared by Licensee. \item BeOpen is making the Software available to Licensee on an ``AS IS'' basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. \item BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. \item This License Agreement will automatically terminate upon a material breach of its terms and conditions. \item This License Agreement shall be governed by and interpreted in all respects by the law of the State of California, excluding conflict of law provisions. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between BeOpen and Licensee. This License Agreement does not grant permission to use BeOpen trademarks or trade names in a trademark sense to endorse or promote products or services of Licensee, or any third party. As an exception, the ``BeOpen Python'' logos available at http://www.pythonlabs.com/logos.html may be used according to the permissions granted on that web page. \item By copying, installing or otherwise using the software, Licensee agrees to be bound by the terms and conditions of this License Agreement. \end{enumerate} \centerline{\strong{CNRI OPEN SOURCE GPL-COMPATIBLE LICENSE AGREEMENT}} \begin{enumerate} \item This LICENSE AGREEMENT is between the Corporation for National Research Initiatives, having an office at 1895 Preston White Drive, Reston, VA 20191 (``CNRI''), and the Individual or Organization (``Licensee'') accessing and otherwise using Python 1.6.1 software in source or binary form and its associated documentation. \item Subject to the terms and conditions of this License Agreement, CNRI hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python 1.6.1 alone or in any derivative version, provided, however, that CNRI's License Agreement and CNRI's notice of copyright, i.e., ``Copyright \copyright{} 1995-2001 Corporation for National Research Initiatives; All Rights Reserved'' are retained in Python 1.6.1 alone or in any derivative version prepared by Licensee. Alternately, in lieu of CNRI's License Agreement, Licensee may substitute the following text (omitting the quotes): ``Python 1.6.1 is made available subject to the terms and conditions in CNRI's License Agreement. This Agreement together with Python 1.6.1 may be located on the Internet using the following unique, persistent identifier (known as a handle): 1895.22/1013. This Agreement may also be obtained from a proxy server on the Internet using the following URL: \url{http://hdl.handle.net/1895.22/1013}.'' \item In the event Licensee prepares a derivative work that is based on or incorporates Python 1.6.1 or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python 1.6.1. \item CNRI is making Python 1.6.1 available to Licensee on an ``AS IS'' basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. \item CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. \item This License Agreement will automatically terminate upon a material breach of its terms and conditions. \item 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 1.6.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 CNRI and Licensee. This License Agreement does not grant permission to use CNRI trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party. \item By clicking on the ``ACCEPT'' button where indicated, or by copying, installing or otherwise using Python 1.6.1, Licensee agrees to be bound by the terms and conditions of this License Agreement. \end{enumerate} \centerline{ACCEPT} \centerline{\strong{CWI PERMISSIONS STATEMENT AND DISCLAIMER}} Copyright \copyright{} 1991 - 1995, 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 name 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. Index: copyright.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/copyright.tex,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -r1.11 -r1.12 *** copyright.tex 2001/04/10 05:26:29 1.11 --- copyright.tex 2001/06/20 21:34:35 1.12 *************** *** 1,3 **** - \begin{small} Copyright \copyright{} 2001 Python Software Foundation. All rights reserved. --- 1,2 ---- *************** *** 12,108 **** All rights reserved. ! %%begin{latexonly} ! \vskip 4mm ! %%end{latexonly} ! ! \centerline{\strong{BEOPEN.COM TERMS AND CONDITIONS FOR PYTHON 2.0}} ! ! \centerline{\strong{BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1}} ! ! \begin{enumerate} ! ! \item ! This LICENSE AGREEMENT is between BeOpen.com (``BeOpen''), having an ! office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the ! Individual or Organization (``Licensee'') accessing and otherwise ! using this software in source or binary form and its associated ! documentation (``the Software''). ! ! \item ! Subject to the terms and conditions of this BeOpen Python License ! Agreement, BeOpen hereby grants Licensee a non-exclusive, ! royalty-free, world-wide license to reproduce, analyze, test, perform ! and/or display publicly, prepare derivative works, distribute, and ! otherwise use the Software alone or in any derivative version, ! provided, however, that the BeOpen Python License is retained in the ! Software, alone or in any derivative version prepared by Licensee. ! ! \item ! BeOpen is making the Software available to Licensee on an ``AS IS'' ! basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR ! IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND ! DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS ! FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT ! INFRINGE ANY THIRD PARTY RIGHTS. ! ! \item ! BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE ! SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS ! AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY ! DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. ! ! \item ! This License Agreement will automatically terminate upon a material ! breach of its terms and conditions. ! ! \item ! This License Agreement shall be governed by and interpreted in all ! respects by the law of the State of California, excluding conflict of ! law provisions. Nothing in this License Agreement shall be deemed to ! create any relationship of agency, partnership, or joint venture ! between BeOpen and Licensee. This License Agreement does not grant ! permission to use BeOpen trademarks or trade names in a trademark ! sense to endorse or promote products or services of Licensee, or any ! third party. As an exception, the ``BeOpen Python'' logos available ! at http://www.pythonlabs.com/logos.html may be used according to the ! permissions granted on that web page. ! ! \item ! By copying, installing or otherwise using the software, Licensee ! agrees to be bound by the terms and conditions of this License ! Agreement. ! \end{enumerate} ! ! ! \centerline{\strong{CNRI OPEN SOURCE GPL-COMPATIBLE LICENSE AGREEMENT}} ! ! Python 1.6.1 is made available subject to the terms and conditions in ! CNRI's License Agreement. This Agreement together with Python 1.6.1 may ! be located on the Internet using the following unique, persistent ! identifier (known as a handle): 1895.22/1013. This Agreement may also ! be obtained from a proxy server on the Internet using the following ! URL: \url{http://hdl.handle.net/1895.22/1013}. ! ! ! \centerline{\strong{CWI PERMISSIONS STATEMENT AND DISCLAIMER}} ! ! Copyright \copyright{} 1991 - 1995, 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 name 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. ! \end{small} --- 11,14 ---- All rights reserved. ! See the end of this document for complete license and permissions ! information. From fdrake@users.sourceforge.net Wed Jun 20 22:37:36 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 20 Jun 2001 14:37:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/mac mac.tex,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/mac In directory usw-pr-cvs1:/tmp/cvs-serv3521/mac Modified Files: mac.tex Log Message: Update to include the license information in a less annoying place. Index: mac.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/mac/mac.tex,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** mac.tex 2001/04/13 04:49:30 1.7 --- mac.tex 2001/06/20 21:37:34 1.8 *************** *** 72,75 **** --- 72,79 ---- \input{undoc} % Undocumented Modules + \appendix + \chapter{History and License} + \input{license} + % % The ugly "%begin{latexonly}" pseudo-environments are really just to From fdrake@users.sourceforge.net Wed Jun 20 22:37:37 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 20 Jun 2001 14:37:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ref ref.tex,1.35,1.36 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory usw-pr-cvs1:/tmp/cvs-serv3521/ref Modified Files: ref.tex Log Message: Update to include the license information in a less annoying place. Index: ref.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref.tex,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -r1.35 -r1.36 *** ref.tex 2001/03/23 16:21:15 1.35 --- ref.tex 2001/06/20 21:37:34 1.36 *************** *** 62,65 **** --- 62,68 ---- \input{refa1} % Future statements and nested scopes + \chapter{History and License} + \input{license} + \input{ref.ind} From fdrake@users.sourceforge.net Wed Jun 20 22:37:36 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 20 Jun 2001 14:37:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib lib.tex,1.186,1.187 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv3521/lib Modified Files: lib.tex Log Message: Update to include the license information in a less annoying place. Index: lib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/lib.tex,v retrieving revision 1.186 retrieving revision 1.187 diff -C2 -r1.186 -r1.187 *** lib.tex 2001/05/30 04:59:50 1.186 --- lib.tex 2001/06/20 21:37:34 1.187 *************** *** 318,321 **** --- 318,324 ---- \input{reportingbugs} + \chapter{History and License} + \input{license} + % % The ugly "%begin{latexonly}" pseudo-environments are really just to From fdrake@users.sourceforge.net Wed Jun 20 22:37:37 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 20 Jun 2001 14:37:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tut tut.tex,1.140,1.141 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tut In directory usw-pr-cvs1:/tmp/cvs-serv3521/tut Modified Files: tut.tex Log Message: Update to include the license information in a less annoying place. Index: tut.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tut/tut.tex,v retrieving revision 1.140 retrieving revision 1.141 diff -C2 -r1.140 -r1.141 *** tut.tex 2001/06/17 21:57:17 1.140 --- tut.tex 2001/06/20 21:37:34 1.141 *************** *** 4353,4355 **** --- 4353,4358 ---- not!). + \chapter{History and License} + \input{license} + \end{document} From fdrake@users.sourceforge.net Wed Jun 20 22:37:36 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 20 Jun 2001 14:37:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ext ext.tex,1.96,1.97 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ext In directory usw-pr-cvs1:/tmp/cvs-serv3521/ext Modified Files: ext.tex Log Message: Update to include the license information in a less annoying place. Index: ext.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ext/ext.tex,v retrieving revision 1.96 retrieving revision 1.97 diff -C2 -r1.96 -r1.97 *** ext.tex 2001/05/02 17:16:16 1.96 --- ext.tex 2001/06/20 21:37:34 1.97 *************** *** 2591,2593 **** --- 2591,2596 ---- \input{reportingbugs} + \chapter{History and License} + \input{license} + \end{document} From fdrake@users.sourceforge.net Wed Jun 20 22:39:14 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 20 Jun 2001 14:39:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.126,1.127 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv3941/api Modified Files: api.tex Log Message: Move license information to a less annoying location in the document. Add documentation for PyErr_SetFromErrnoWithFilename(). Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.126 retrieving revision 1.127 diff -C2 -r1.126 -r1.127 *** api.tex 2001/06/03 03:12:57 1.126 --- api.tex 2001/06/20 21:39:12 1.127 *************** *** 952,955 **** --- 952,965 ---- \end{cfuncdesc} + \begin{cfuncdesc}{PyObject*}{PyErr_SetFromErrnoWithFilename}{PyObject *type, + char *filename} + Similar to \cfunction{PyErr_SetFromErrno()}, with the additional + behavior that if \var{filename} is not \NULL, it is passed to the + constructor of \var{type} as a third parameter. In the case of + exceptions such as \exception{IOError} and \exception{OSError}, this + is used to define the \member{filename} attribute of the exception + instance. + \end{cfuncdesc} + \begin{cfuncdesc}{void}{PyErr_BadInternalCall}{} This is a shorthand for \samp{PyErr_SetString(PyExc_TypeError, *************** *** 5329,5332 **** --- 5339,5345 ---- \chapter{Reporting Bugs} \input{reportingbugs} + + \chapter{History and License} + \input{license} \input{api.ind} % Index -- must be last From jackjansen@users.sourceforge.net Wed Jun 20 22:44:40 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 20 Jun 2001 14:44:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/ae aesupport.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/ae In directory usw-pr-cvs1:/tmp/cvs-serv4957/Python/Mac/Modules/ae Modified Files: aesupport.py Log Message: Got rid of a silly #if. Index: aesupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/ae/aesupport.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -r1.21 -r1.22 *** aesupport.py 2001/06/20 20:53:38 1.21 --- aesupport.py 2001/06/20 21:44:38 1.22 *************** *** 156,160 **** initstuff = initstuff + """ upp_AEIdleProc = NewAEIdleUPP(AEIdleProc); ! #if UNIVERSAL_INTERFACES_VERSION >= 0x0340 upp_GenericEventHandler = NewAEEventHandlerUPP(&GenericEventHandler); #else --- 156,160 ---- initstuff = initstuff + """ upp_AEIdleProc = NewAEIdleUPP(AEIdleProc); ! #if UNIVERSAL_INTERFACES_VERSION >= 0x03400 upp_GenericEventHandler = NewAEEventHandlerUPP(&GenericEventHandler); #else From nascheme@users.sourceforge.net Thu Jun 21 03:41:12 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Wed, 20 Jun 2001 19:41:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.251,2.252 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv2845/Python Modified Files: ceval.c Log Message: Try to avoid creating reference cycles involving generators. Only keep a reference to f_back when its really needed. Do a little whitespace normalization as well. This whole file is a big war between tabs and spaces but now is probably not the time to reindent everything. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.251 retrieving revision 2.252 diff -C2 -r2.251 -r2.252 *** ceval.c 2001/06/20 06:57:32 2.251 --- ceval.c 2001/06/21 02:41:10 2.252 *************** *** 139,142 **** --- 139,143 ---- gen_iternext(genobject *gen) { + PyThreadState *tstate = PyThreadState_GET(); PyFrameObject *f = gen->frame; PyObject *result; *************** *** 150,162 **** return NULL; } ! gen->running = 1; result = eval_frame(f); ! gen->running = 0; ! /* The connection between this frame and its parent is over now, so ! must NULL out f_back lest it get decref'ed when gen dies (note ! that eval_frame sets f->f_back without bumping its refcount: we ! never had a fully legit reference to it). */ f->f_back = NULL; ! return result; } --- 151,172 ---- return NULL; } ! ! /* Generators always return to their most recent caller, not ! * necessarily their creator. */ ! Py_INCREF(tstate->frame); ! assert(f->f_back == NULL); ! f->f_back = tstate->frame; ! ! gen->running = 1; result = eval_frame(f); ! gen->running = 0; ! ! /* Don't keep the reference to f_back any longer than necessary. It ! * may keep a chain of frames alive or it could create a reference ! * cycle. */ ! Py_DECREF(f->f_back); f->f_back = NULL; ! ! return result; } *************** *** 169,178 **** return NULL; ! result = gen_iternext(gen); ! if (result == NULL && !PyErr_Occurred()) { PyErr_SetObject(PyExc_StopIteration, Py_None); return NULL; ! } return result; --- 179,188 ---- return NULL; ! result = gen_iternext(gen); ! if (result == NULL && !PyErr_Occurred()) { PyErr_SetObject(PyExc_StopIteration, Py_None); return NULL; ! } return result; *************** *** 569,575 **** } - f->f_back = tstate->frame; tstate->frame = f; - co = f->f_code; fastlocals = f->f_localsplus; --- 579,583 ---- *************** *** 2483,2488 **** if (co->co_flags & CO_GENERATOR) { ! /* create a new generator that owns the ready to run frame ! * and return that as the value */ return gen_new(f); } --- 2491,2501 ---- if (co->co_flags & CO_GENERATOR) { ! /* 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; ! ! /* Create a new generator that owns the ready to run frame ! * and return that as the value. */ return gen_new(f); } From tim_one@users.sourceforge.net Thu Jun 21 03:49:57 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 20 Jun 2001 19:49:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.185,1.186 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv4479/python/dist/src/Misc Modified Files: NEWS Log Message: Teach the UNPACK_SEQUENCE opcode how to tease an iterable object into giving up the goods. NEEDS DOC CHANGES Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.185 retrieving revision 1.186 diff -C2 -r1.185 -r1.186 *** NEWS 2001/06/16 05:42:57 1.185 --- NEWS 2001/06/21 02:49:55 1.186 *************** *** 109,112 **** --- 109,114 ---- 'x in y' and 'x not in y' (PySequence_Contains() in C API) operator.countOf() (PySequence_Count() in C API) + right-hand side of assignment statements with multiple targets, such as + x, y, z = some_iterable_object_returning_exactly_3_values - Accessing module attributes is significantly faster (for example, From tim_one@users.sourceforge.net Thu Jun 21 03:49:57 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 20 Jun 2001 19:49:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_iter.py,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv4479/python/dist/src/Lib/test Modified Files: test_iter.py Log Message: Teach the UNPACK_SEQUENCE opcode how to tease an iterable object into giving up the goods. NEEDS DOC CHANGES Index: test_iter.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_iter.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -r1.16 -r1.17 *** test_iter.py 2001/05/06 01:05:01 1.16 --- test_iter.py 2001/06/21 02:49:54 1.17 *************** *** 595,597 **** --- 595,650 ---- 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) From tim_one@users.sourceforge.net Thu Jun 21 03:49:57 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 20 Jun 2001 19:49:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.252,2.253 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv4479/python/dist/src/Python Modified Files: ceval.c Log Message: Teach the UNPACK_SEQUENCE opcode how to tease an iterable object into giving up the goods. NEEDS DOC CHANGES Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.252 retrieving revision 2.253 diff -C2 -r2.252 -r2.253 *** ceval.c 2001/06/21 02:41:10 2.252 --- ceval.c 2001/06/21 02:49:55 2.253 *************** *** 477,481 **** static enum why_code do_raise(PyObject *, PyObject *, PyObject *); ! static int unpack_sequence(PyObject *, int, PyObject **); --- 477,481 ---- static enum why_code do_raise(PyObject *, PyObject *, PyObject *); ! static int unpack_iterable(PyObject *, int, PyObject **); *************** *** 1489,1504 **** } } ! else if (PySequence_Check(v)) { ! if (unpack_sequence(v, oparg, ! stack_pointer + oparg)) ! stack_pointer += oparg; ! else ! why = WHY_EXCEPTION; ! } ! else { ! PyErr_SetString(PyExc_TypeError, ! "unpack non-sequence"); why = WHY_EXCEPTION; - } Py_DECREF(v); break; --- 1489,1497 ---- } } ! else if (unpack_iterable(v, oparg, ! stack_pointer + oparg)) ! stack_pointer += oparg; ! else why = WHY_EXCEPTION; Py_DECREF(v); break; *************** *** 2695,2729 **** } static int ! unpack_sequence(PyObject *v, int argcnt, PyObject **sp) { ! int i; PyObject *w; ! for (i = 0; i < argcnt; i++) { ! if (! (w = PySequence_GetItem(v, i))) { ! if (PyErr_ExceptionMatches(PyExc_IndexError)) ! PyErr_SetString(PyExc_ValueError, ! "unpack sequence of wrong size"); ! goto finally; } *--sp = w; } ! /* we better get an IndexError now */ ! if (PySequence_GetItem(v, i) == NULL) { ! if (PyErr_ExceptionMatches(PyExc_IndexError)) { ! PyErr_Clear(); ! return 1; ! } ! /* some other exception occurred. fall through to finally */ } ! else ! PyErr_SetString(PyExc_ValueError, ! "unpack sequence of wrong size"); /* fall through */ ! finally: for (; i > 0; i--, sp++) Py_DECREF(*sp); ! return 0; } --- 2688,2735 ---- } + /* Iterate v argcnt times and store the results on the stack (via decreasing + sp). Return 1 for success, 0 if error. */ + static int ! unpack_iterable(PyObject *v, int argcnt, PyObject **sp) { ! int i = 0; ! PyObject *it; /* iter(v) */ PyObject *w; ! assert(v != NULL); ! ! it = PyObject_GetIter(v); ! if (it == NULL) ! goto Error; ! ! for (; i < argcnt; i++) { ! w = PyIter_Next(it); ! if (w == NULL) { ! /* Iterator done, via error or exhaustion. */ ! if (!PyErr_Occurred()) { ! PyErr_Format(PyExc_ValueError, ! "need more than %d value%s to unpack", ! i, i == 1 ? "" : "s"); ! } ! goto Error; } *--sp = w; } ! ! /* We better have exhausted the iterator now. */ ! w = PyIter_Next(it); ! if (w == NULL) { ! if (PyErr_Occurred()) ! goto Error; ! Py_DECREF(it); ! return 1; } ! PyErr_SetString(PyExc_ValueError, "too many values to unpack"); /* fall through */ ! Error: for (; i > 0; i--, sp++) Py_DECREF(*sp); ! Py_XDECREF(it); return 0; } From gvanrossum@users.sourceforge.net Thu Jun 21 13:34:52 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 21 Jun 2001 05:34:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include config.h,2.1,NONE rename1.h,2.11,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv30510 Removed Files: config.h rename1.h Log Message: Somehow, under certain circumstances, config.h and rename1.h would pop back up. Try to see if 'cvs delete' fixes this. --- config.h DELETED --- --- rename1.h DELETED --- From jvr@users.sourceforge.net Thu Jun 21 15:50:06 2001 From: jvr@users.sourceforge.net (Just van Rossum) Date: Thu, 21 Jun 2001 07:50:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules macconfig.c,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules In directory usw-pr-cvs1:/tmp/cvs-serv24010 Modified Files: macconfig.c Log Message: Added support for the gc module (!). Index: macconfig.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/macconfig.c,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -r1.23 -r1.24 *** macconfig.c 2001/02/27 12:59:49 1.23 --- macconfig.c 2001/06/21 14:50:03 1.24 *************** *** 163,166 **** --- 163,169 ---- extern void initpyexpat(); #endif + #ifdef WITH_CYCLE_GC + extern void initgc(); + #endif extern void initcPickle(); *************** *** 286,289 **** --- 289,295 ---- #ifdef USE_PYEXPAT {"pyexpat", initpyexpat}, + #endif + #ifdef WITH_CYCLE_GC + {"gc", initgc}, #endif {"cPickle", initcPickle}, From tim_one@users.sourceforge.net Thu Jun 21 17:56:43 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 21 Jun 2001 09:56:43 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0255.txt,1.9,1.10 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv19871/peps Modified Files: pep-0255.txt Log Message: Added BDFL Pronouncement on reusing "def". Index: pep-0255.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0255.txt,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -r1.9 -r1.10 *** pep-0255.txt 2001/06/20 20:56:07 1.9 --- pep-0255.txt 2001/06/21 16:56:41 1.10 *************** *** 303,308 **** Q & A ! Q. Why a new keyword? Why not a builtin function instead? A. Control flow is much better expressed via keyword in Python, and yield is a control construct. It's also believed that efficient --- 303,312 ---- Q & A ! Q. Why not a new keyword instead of reusing "def"? + A. See BDFL Pronouncements section below. + + Q. Why a new keyword for "yield"? Why not a builtin function instead? + A. Control flow is much better expressed via keyword in Python, and yield is a control construct. It's also believed that efficient *************** *** 328,331 **** --- 332,366 ---- for "return expr", it's simply cleaner to use "yield" exclusively for delivering values. + + + BDFL Pronouncements + + Issue: Introduce another new keyword (say, "gen" or "generator") in + place of "def", or otherwise alter the syntax, to distinguish + generator-functions from non-generator functions. + + Con: In practice (how you think about them), generators *are* + functions, but with the twist that they're resumable. The mechanics of + how they're set up is a comparatively minor technical issue, and + introducing a new keyword would unhelpfully overemphasize the + mechanics of how generators get started (a vital but tiny part of a + generator's life). + + Pro: In reality (how you think about them), generator-functions are + actually factory functions that produce generator-iterators as if by + magic. In this respect they're radically different from non-generator + functions, acting more like a constructor than a function, so reusing + "def" is at best confusing. A "yield" statement buried in the body is + not enough warning that the semantics are so different. + + BDFL: "def" it stays. No argument on either side is totally + convincing, so I have consulted my language designer's intuition. It + tells me that the syntax proposed in the PEP is exactly right - not too + hot, not too cold. But, like the Oracle at Delphi in Greek mythology, + it doesn't tell me why, so I don't have a rebuttal for the arguments + against the PEP syntax. The best I can come up with (apart from + agreeing with the rebuttals ... already made) is "FUD". If this had + been part of the language from day one, I very much doubt it would have + made Andrew Kuchling's "Python Warts" page. From jvr@users.sourceforge.net Thu Jun 21 18:51:19 2001 From: jvr@users.sourceforge.net (Just van Rossum) Date: Thu, 21 Jun 2001 10:51:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Tools/IDE Wtext.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Tools/IDE In directory usw-pr-cvs1:/tmp/cvs-serv32009 Modified Files: Wtext.py Log Message: repaired expandselection and uncomment breakage Index: Wtext.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/Wtext.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -r1.10 -r1.11 *** Wtext.py 2001/06/19 21:37:33 1.10 --- Wtext.py 2001/06/21 17:51:17 1.11 *************** *** 280,285 **** if selstart <> selend and chr(self.ted.WEGetChar(selend-1)) == '\r': selend = selend - 1 ! newselstart, dummy = self.ted.WEFindLine(selstart, 0) ! dummy, newselend = self.ted.WEFindLine(selend, 0) if oldselstart <> newselstart or oldselend <> newselend: self.ted.WESetSelection(newselstart, newselend) --- 280,285 ---- if selstart <> selend and chr(self.ted.WEGetChar(selend-1)) == '\r': selend = selend - 1 ! newselstart, dummy = self.ted.WEFindLine(selstart, 1) ! dummy, newselend = self.ted.WEFindLine(selend, 1) if oldselstart <> newselstart or oldselend <> newselend: self.ted.WESetSelection(newselstart, newselend) *************** *** 609,614 **** import re ! commentPat = re.compile("[ \t]*\(#\)") ! indentPat = re.compile("\t*") class PyEditor(TextEditor): --- 609,615 ---- import re ! commentPat = re.compile("[ \t]*(#)") ! indentPat = re.compile("[ \t]*") ! class PyEditor(TextEditor): From fdrake@users.sourceforge.net Thu Jun 21 19:41:14 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 21 Jun 2001 11:41:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc Makefile.deps,1.48,1.48.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv9924 Modified Files: Tag: release20-maint Makefile.deps Log Message: Added the new license.tex as shared dependency. Index: Makefile.deps =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile.deps,v retrieving revision 1.48 retrieving revision 1.48.2.1 diff -C2 -r1.48 -r1.48.2.1 *** Makefile.deps 2000/10/14 05:44:32 1.48 --- Makefile.deps 2001/06/21 18:41:12 1.48.2.1 *************** *** 7,10 **** --- 7,11 ---- COMMONTEX= ../texinputs/copyright.tex \ + ../texinputs/license.tex \ ../texinputs/boilerplate.tex From fdrake@users.sourceforge.net Thu Jun 21 19:45:04 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 21 Jun 2001 11:45:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.96,1.96.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv10733/api Modified Files: Tag: release20-maint api.tex Log Message: Adjust so that the copyright statements remain at the front but all the long licenses move to the back, so as not to annoy as many readers. Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.96 retrieving revision 1.96.2.1 diff -C2 -r1.96 -r1.96.2.1 *** api.tex 2000/10/14 05:49:30 1.96 --- api.tex 2001/06/21 18:45:01 1.96.2.1 *************** *** 4829,4832 **** --- 4829,4835 ---- \input{reportingbugs} + \chapter{History and License} + \input{license} + \input{api.ind} % Index -- must be last From fdrake@users.sourceforge.net Thu Jun 21 19:45:04 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 21 Jun 2001 11:45:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ext ext.tex,1.86,1.86.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ext In directory usw-pr-cvs1:/tmp/cvs-serv10733/ext Modified Files: Tag: release20-maint ext.tex Log Message: Adjust so that the copyright statements remain at the front but all the long licenses move to the back, so as not to annoy as many readers. Index: ext.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ext/ext.tex,v retrieving revision 1.86 retrieving revision 1.86.2.1 diff -C2 -r1.86 -r1.86.2.1 *** ext.tex 2000/10/02 22:38:09 1.86 --- ext.tex 2001/06/21 18:45:02 1.86.2.1 *************** *** 2159,2161 **** --- 2159,2164 ---- \input{reportingbugs} + \chapter{History and License} + \input{license} + \end{document} From fdrake@users.sourceforge.net Thu Jun 21 19:45:04 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 21 Jun 2001 11:45:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ref ref.tex,1.34,1.34.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory usw-pr-cvs1:/tmp/cvs-serv10733/ref Modified Files: Tag: release20-maint ref.tex Log Message: Adjust so that the copyright statements remain at the front but all the long licenses move to the back, so as not to annoy as many readers. Index: ref.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref.tex,v retrieving revision 1.34 retrieving revision 1.34.4.1 diff -C2 -r1.34 -r1.34.4.1 *** ref.tex 1999/11/10 16:13:25 1.34 --- ref.tex 2001/06/21 18:45:02 1.34.4.1 *************** *** 59,62 **** --- 59,66 ---- \input{ref8} % Top-level components + \appendix + \chapter{History and License} + \input{license} + \input{ref.ind} From fdrake@users.sourceforge.net Thu Jun 21 19:45:04 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 21 Jun 2001 11:45:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/mac mac.tex,1.6,1.6.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/mac In directory usw-pr-cvs1:/tmp/cvs-serv10733/mac Modified Files: Tag: release20-maint mac.tex Log Message: Adjust so that the copyright statements remain at the front but all the long licenses move to the back, so as not to annoy as many readers. Index: mac.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/mac/mac.tex,v retrieving revision 1.6 retrieving revision 1.6.2.1 diff -C2 -r1.6 -r1.6.2.1 *** mac.tex 2000/10/14 05:41:17 1.6 --- mac.tex 2001/06/21 18:45:02 1.6.2.1 *************** *** 71,74 **** --- 71,78 ---- \input{undoc} % Undocumented Modules + \appendix + \chapter{History and License} + \input{license} + % % The ugly "%begin{latexonly}" pseudo-environments are really just to From fdrake@users.sourceforge.net Thu Jun 21 19:45:04 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 21 Jun 2001 11:45:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib lib.tex,1.169,1.169.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv10733/lib Modified Files: Tag: release20-maint lib.tex Log Message: Adjust so that the copyright statements remain at the front but all the long licenses move to the back, so as not to annoy as many readers. Index: lib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/lib.tex,v retrieving revision 1.169 retrieving revision 1.169.2.1 diff -C2 -r1.169 -r1.169.2.1 *** lib.tex 2000/10/12 20:07:09 1.169 --- lib.tex 2001/06/21 18:45:02 1.169.2.1 *************** *** 299,304 **** --- 299,308 ---- \appendix \input{libundoc} + \chapter{Reporting Bugs} \input{reportingbugs} + + \chapter{History and License} + \input{license} % From fdrake@users.sourceforge.net Thu Jun 21 19:45:04 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 21 Jun 2001 11:45:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tut tut.tex,1.118.2.1,1.118.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tut In directory usw-pr-cvs1:/tmp/cvs-serv10733/tut Modified Files: Tag: release20-maint tut.tex Log Message: Adjust so that the copyright statements remain at the front but all the long licenses move to the back, so as not to annoy as many readers. Index: tut.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tut/tut.tex,v retrieving revision 1.118.2.1 retrieving revision 1.118.2.2 diff -C2 -r1.118.2.1 -r1.118.2.2 *** tut.tex 2001/04/25 20:58:34 1.118.2.1 --- tut.tex 2001/06/21 18:45:02 1.118.2.2 *************** *** 4062,4064 **** --- 4062,4067 ---- + \chapter{History and License} + \input{license} + \end{document} From fdrake@users.sourceforge.net Thu Jun 21 19:45:04 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 21 Jun 2001 11:45:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/texinputs copyright.tex,1.9,1.9.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory usw-pr-cvs1:/tmp/cvs-serv10733/texinputs Modified Files: Tag: release20-maint copyright.tex Log Message: Adjust so that the copyright statements remain at the front but all the long licenses move to the back, so as not to annoy as many readers. Index: copyright.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/copyright.tex,v retrieving revision 1.9 retrieving revision 1.9.2.1 diff -C2 -r1.9 -r1.9.2.1 *** copyright.tex 2000/10/14 04:07:49 1.9 --- copyright.tex 2001/06/21 18:45:02 1.9.2.1 *************** *** 1,90 **** ! \centerline{\strong{BEOPEN.COM TERMS AND CONDITIONS FOR PYTHON 2.0}} ! \centerline{\strong{BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1}} ! \begin{enumerate} ! \item ! This LICENSE AGREEMENT is between BeOpen.com (``BeOpen''), having an ! office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the ! Individual or Organization (``Licensee'') accessing and otherwise ! using this software in source or binary form and its associated ! documentation (``the Software''). ! \item ! Subject to the terms and conditions of this BeOpen Python License ! Agreement, BeOpen hereby grants Licensee a non-exclusive, ! royalty-free, world-wide license to reproduce, analyze, test, perform ! and/or display publicly, prepare derivative works, distribute, and ! otherwise use the Software alone or in any derivative version, ! provided, however, that the BeOpen Python License is retained in the ! Software, alone or in any derivative version prepared by Licensee. ! ! \item ! BeOpen is making the Software available to Licensee on an ``AS IS'' ! basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR ! IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND ! DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS ! FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT ! INFRINGE ANY THIRD PARTY RIGHTS. ! ! \item ! BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE ! SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS ! AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY ! DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. ! ! \item ! This License Agreement will automatically terminate upon a material ! breach of its terms and conditions. ! ! \item ! This License Agreement shall be governed by and interpreted in all ! respects by the law of the State of California, excluding conflict of ! law provisions. Nothing in this License Agreement shall be deemed to ! create any relationship of agency, partnership, or joint venture ! between BeOpen and Licensee. This License Agreement does not grant ! permission to use BeOpen trademarks or trade names in a trademark ! sense to endorse or promote products or services of Licensee, or any ! third party. As an exception, the ``BeOpen Python'' logos available ! at http://www.pythonlabs.com/logos.html may be used according to the ! permissions granted on that web page. ! ! \item ! By copying, installing or otherwise using the software, Licensee ! agrees to be bound by the terms and conditions of this License ! Agreement. ! \end{enumerate} ! ! ! \centerline{\strong{CNRI OPEN SOURCE LICENSE AGREEMENT}} ! ! Python 1.6 is made available subject to the terms and conditions in ! CNRI's License Agreement. This Agreement together with Python 1.6 may ! be located on the Internet using the following unique, persistent ! identifier (known as a handle): 1895.22/1012. This Agreement may also ! be obtained from a proxy server on the Internet using the following ! URL: \url{http://hdl.handle.net/1895.22/1012}. ! ! ! \centerline{\strong{CWI PERMISSIONS STATEMENT AND DISCLAIMER}} ! ! Copyright \copyright{} 1991 - 1995, 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 name 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. --- 1,14 ---- ! Copyright \copyright{} 2001 Python Software Foundation. ! All rights reserved. ! Copyright \copyright{} 2000 BeOpen.com. ! All rights reserved. ! Copyright \copyright{} 1995-2000 Corporation for National Research Initiatives. ! All rights reserved. ! Copyright \copyright{} 1991-1995 Stichting Mathematisch Centrum. ! All rights reserved. ! See the end of this document for complete license and permissions ! information. From fdrake@users.sourceforge.net Thu Jun 21 19:51:13 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 21 Jun 2001 11:51:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/texinputs license.tex,1.1,1.1.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory usw-pr-cvs1:/tmp/cvs-serv12086/texinputs Modified Files: Tag: release21-maint license.tex Log Message: Make sure 2.1.1 takes its proper place in the history of Python licenses. Index: license.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/license.tex,v retrieving revision 1.1 retrieving revision 1.1.4.1 diff -C2 -r1.1 -r1.1.4.1 *** license.tex 2001/06/20 21:34:35 1.1 --- license.tex 2001/06/21 18:51:11 1.1.4.1 *************** *** 26,33 **** other PythonLabs developers joined Digital Creations. All intellectual property added from this point on, including Python ! 2.0.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 \url{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 ---- other PythonLabs developers joined Digital Creations. All intellectual property added from this point on, including Python ! 2.0.1 and its alpha and beta releases, and Python 2.1.1, is owned by ! the Python Software Foundation (PSF), a non-profit modeled after the ! Apache Software Foundation. See \url{http://www.python.org/psf/} for ! more information about the PSF. Thanks to the many outside volunteers who have worked under Guido's From fdrake@users.sourceforge.net Thu Jun 21 19:52:52 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 21 Jun 2001 11:52:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc Makefile.deps,1.65,1.65.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv12325 Modified Files: Tag: release21-maint Makefile.deps Log Message: Adjust the documents so that the copyright is at the front of the documents and the license statements are at the end. This is less annoying to readers. Index: Makefile.deps =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile.deps,v retrieving revision 1.65 retrieving revision 1.65.2.1 diff -C2 -r1.65 -r1.65.2.1 *** Makefile.deps 2001/04/13 04:50:01 1.65 --- Makefile.deps 2001/06/21 18:52:50 1.65.2.1 *************** *** 6,9 **** --- 6,10 ---- COMMONTEX= texinputs/copyright.tex \ + texinputs/license.tex \ texinputs/boilerplate.tex From fdrake@users.sourceforge.net Thu Jun 21 19:52:52 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 21 Jun 2001 11:52:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/mac mac.tex,1.7,1.7.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/mac In directory usw-pr-cvs1:/tmp/cvs-serv12325/mac Modified Files: Tag: release21-maint mac.tex Log Message: Adjust the documents so that the copyright is at the front of the documents and the license statements are at the end. This is less annoying to readers. Index: mac.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/mac/mac.tex,v retrieving revision 1.7 retrieving revision 1.7.2.1 diff -C2 -r1.7 -r1.7.2.1 *** mac.tex 2001/04/13 04:49:30 1.7 --- mac.tex 2001/06/21 18:52:50 1.7.2.1 *************** *** 72,75 **** --- 72,79 ---- \input{undoc} % Undocumented Modules + \appendix + \chapter{History and License} + \input{license} + % % The ugly "%begin{latexonly}" pseudo-environments are really just to From fdrake@users.sourceforge.net Thu Jun 21 19:52:52 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 21 Jun 2001 11:52:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ext ext.tex,1.95,1.95.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ext In directory usw-pr-cvs1:/tmp/cvs-serv12325/ext Modified Files: Tag: release21-maint ext.tex Log Message: Adjust the documents so that the copyright is at the front of the documents and the license statements are at the end. This is less annoying to readers. Index: ext.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ext/ext.tex,v retrieving revision 1.95 retrieving revision 1.95.2.1 diff -C2 -r1.95 -r1.95.2.1 *** ext.tex 2001/03/19 04:19:56 1.95 --- ext.tex 2001/06/21 18:52:50 1.95.2.1 *************** *** 2579,2581 **** --- 2579,2584 ---- \input{reportingbugs} + \chapter{History and License} + \input{license} + \end{document} From fdrake@users.sourceforge.net Thu Jun 21 19:52:52 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 21 Jun 2001 11:52:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.117.2.4,1.117.2.5 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv12325/api Modified Files: Tag: release21-maint api.tex Log Message: Adjust the documents so that the copyright is at the front of the documents and the license statements are at the end. This is less annoying to readers. Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.117.2.4 retrieving revision 1.117.2.5 diff -C2 -r1.117.2.4 -r1.117.2.5 *** api.tex 2001/06/03 03:16:04 1.117.2.4 --- api.tex 2001/06/21 18:52:50 1.117.2.5 *************** *** 5271,5274 **** --- 5271,5277 ---- \input{reportingbugs} + \chapter{History and License} + \input{license} + \input{api.ind} % Index -- must be last From fdrake@users.sourceforge.net Thu Jun 21 19:52:52 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 21 Jun 2001 11:52:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tut tut.tex,1.133.2.2,1.133.2.3 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tut In directory usw-pr-cvs1:/tmp/cvs-serv12325/tut Modified Files: Tag: release21-maint tut.tex Log Message: Adjust the documents so that the copyright is at the front of the documents and the license statements are at the end. This is less annoying to readers. Index: tut.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tut/tut.tex,v retrieving revision 1.133.2.2 retrieving revision 1.133.2.3 diff -C2 -r1.133.2.2 -r1.133.2.3 *** tut.tex 2001/05/21 17:02:57 1.133.2.2 --- tut.tex 2001/06/21 18:52:50 1.133.2.3 *************** *** 4081,4083 **** --- 4081,4086 ---- + \chapter{History and License} + \input{license} + \end{document} From fdrake@users.sourceforge.net Thu Jun 21 19:52:52 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 21 Jun 2001 11:52:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ref ref.tex,1.35,1.35.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory usw-pr-cvs1:/tmp/cvs-serv12325/ref Modified Files: Tag: release21-maint ref.tex Log Message: Adjust the documents so that the copyright is at the front of the documents and the license statements are at the end. This is less annoying to readers. Index: ref.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref.tex,v retrieving revision 1.35 retrieving revision 1.35.2.1 diff -C2 -r1.35 -r1.35.2.1 *** ref.tex 2001/03/23 16:21:15 1.35 --- ref.tex 2001/06/21 18:52:50 1.35.2.1 *************** *** 62,65 **** --- 62,69 ---- \input{refa1} % Future statements and nested scopes + \appendix + \chapter{History and License} + \input{license} + \input{ref.ind} From fdrake@users.sourceforge.net Thu Jun 21 19:52:52 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 21 Jun 2001 11:52:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/texinputs copyright.tex,1.11,1.11.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory usw-pr-cvs1:/tmp/cvs-serv12325/texinputs Modified Files: Tag: release21-maint copyright.tex Log Message: Adjust the documents so that the copyright is at the front of the documents and the license statements are at the end. This is less annoying to readers. Index: copyright.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/copyright.tex,v retrieving revision 1.11 retrieving revision 1.11.2.1 diff -C2 -r1.11 -r1.11.2.1 *** copyright.tex 2001/04/10 05:26:29 1.11 --- copyright.tex 2001/06/21 18:52:50 1.11.2.1 *************** *** 1,3 **** - \begin{small} Copyright \copyright{} 2001 Python Software Foundation. All rights reserved. --- 1,2 ---- *************** *** 12,108 **** All rights reserved. ! %%begin{latexonly} ! \vskip 4mm ! %%end{latexonly} ! ! \centerline{\strong{BEOPEN.COM TERMS AND CONDITIONS FOR PYTHON 2.0}} ! ! \centerline{\strong{BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1}} ! ! \begin{enumerate} ! ! \item ! This LICENSE AGREEMENT is between BeOpen.com (``BeOpen''), having an ! office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the ! Individual or Organization (``Licensee'') accessing and otherwise ! using this software in source or binary form and its associated ! documentation (``the Software''). ! ! \item ! Subject to the terms and conditions of this BeOpen Python License ! Agreement, BeOpen hereby grants Licensee a non-exclusive, ! royalty-free, world-wide license to reproduce, analyze, test, perform ! and/or display publicly, prepare derivative works, distribute, and ! otherwise use the Software alone or in any derivative version, ! provided, however, that the BeOpen Python License is retained in the ! Software, alone or in any derivative version prepared by Licensee. ! ! \item ! BeOpen is making the Software available to Licensee on an ``AS IS'' ! basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR ! IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND ! DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS ! FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT ! INFRINGE ANY THIRD PARTY RIGHTS. ! ! \item ! BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE ! SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS ! AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY ! DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. ! ! \item ! This License Agreement will automatically terminate upon a material ! breach of its terms and conditions. ! ! \item ! This License Agreement shall be governed by and interpreted in all ! respects by the law of the State of California, excluding conflict of ! law provisions. Nothing in this License Agreement shall be deemed to ! create any relationship of agency, partnership, or joint venture ! between BeOpen and Licensee. This License Agreement does not grant ! permission to use BeOpen trademarks or trade names in a trademark ! sense to endorse or promote products or services of Licensee, or any ! third party. As an exception, the ``BeOpen Python'' logos available ! at http://www.pythonlabs.com/logos.html may be used according to the ! permissions granted on that web page. ! ! \item ! By copying, installing or otherwise using the software, Licensee ! agrees to be bound by the terms and conditions of this License ! Agreement. ! \end{enumerate} ! ! ! \centerline{\strong{CNRI OPEN SOURCE GPL-COMPATIBLE LICENSE AGREEMENT}} ! ! Python 1.6.1 is made available subject to the terms and conditions in ! CNRI's License Agreement. This Agreement together with Python 1.6.1 may ! be located on the Internet using the following unique, persistent ! identifier (known as a handle): 1895.22/1013. This Agreement may also ! be obtained from a proxy server on the Internet using the following ! URL: \url{http://hdl.handle.net/1895.22/1013}. ! ! ! \centerline{\strong{CWI PERMISSIONS STATEMENT AND DISCLAIMER}} ! ! Copyright \copyright{} 1991 - 1995, 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 name 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. ! \end{small} --- 11,14 ---- All rights reserved. ! See the end of this document for complete license and permissions ! information. From fdrake@users.sourceforge.net Thu Jun 21 19:56:51 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 21 Jun 2001 11:56:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.117.2.5,1.117.2.6 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv13090/api Modified Files: Tag: release21-maint api.tex Log Message: Added documentation for PyErr_SetFromErrnoWithFilename(). Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.117.2.5 retrieving revision 1.117.2.6 diff -C2 -r1.117.2.5 -r1.117.2.6 *** api.tex 2001/06/21 18:52:50 1.117.2.5 --- api.tex 2001/06/21 18:56:49 1.117.2.6 *************** *** 952,955 **** --- 952,965 ---- \end{cfuncdesc} + \begin{cfuncdesc}{PyObject*}{PyErr_SetFromErrnoWithFilename}{PyObject *type, + char *filename} + Similar to \cfunction{PyErr_SetFromErrno()}, with the additional + behavior that if \var{filename} is not \NULL, it is passed to the + constructor of \var{type} as a third parameter. In the case of + exceptions such as \exception{IOError} and \exception{OSError}, this + is used to define the \member{filename} attribute of the exception + instance. + \end{cfuncdesc} + \begin{cfuncdesc}{void}{PyErr_BadInternalCall}{} This is a shorthand for \samp{PyErr_SetString(PyExc_TypeError, From fdrake@users.sourceforge.net Thu Jun 21 19:58:41 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 21 Jun 2001 11:58:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.96.2.1,1.96.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv13395/api Modified Files: Tag: release20-maint api.tex Log Message: Added documentation for PyErr_SetFromErrnoWithFilename(). Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.96.2.1 retrieving revision 1.96.2.2 diff -C2 -r1.96.2.1 -r1.96.2.2 *** api.tex 2001/06/21 18:45:01 1.96.2.1 --- api.tex 2001/06/21 18:58:39 1.96.2.2 *************** *** 935,938 **** --- 935,948 ---- \end{cfuncdesc} + \begin{cfuncdesc}{PyObject*}{PyErr_SetFromErrnoWithFilename}{PyObject *type, + char *filename} + Similar to \cfunction{PyErr_SetFromErrno()}, with the additional + behavior that if \var{filename} is not \NULL, it is passed to the + constructor of \var{type} as a third parameter. In the case of + exceptions such as \exception{IOError} and \exception{OSError}, this + is used to define the \member{filename} attribute of the exception + instance. + \end{cfuncdesc} + \begin{cfuncdesc}{void}{PyErr_BadInternalCall}{} This is a shorthand for \samp{PyErr_SetString(PyExc_TypeError, From jvr@users.sourceforge.net Thu Jun 21 22:52:17 2001 From: jvr@users.sourceforge.net (Just van Rossum) Date: Thu, 21 Jun 2001 14:52:17 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Tools/IDE Wtraceback.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Tools/IDE In directory usw-pr-cvs1:/tmp/cvs-serv21940 Modified Files: Wtraceback.py Log Message: don't blow up when the charno SyntaxError value is None Index: Wtraceback.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/Wtraceback.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** Wtraceback.py 2001/06/19 21:37:33 1.5 --- Wtraceback.py 2001/06/21 21:52:15 1.6 *************** *** 56,60 **** if filename and os.path.exists(filename): filename = os.path.split(filename)[1] ! if lineno: charno = charno - 1 text = str(value) + '\rFile: "' + str(filename) + '", line ' + str(lineno) + '\r\r' + line[:charno] + "\xa5" + line[charno:-1] --- 56,60 ---- if filename and os.path.exists(filename): filename = os.path.split(filename)[1] ! if lineno and charno is not None: charno = charno - 1 text = str(value) + '\rFile: "' + str(filename) + '", line ' + str(lineno) + '\r\r' + line[:charno] + "\xa5" + line[charno:-1] *************** *** 85,88 **** --- 85,90 ---- self.syntaxclose() if lineno: + if charno is None: + charno = 1 W.getapplication().openscript(filename, lineno, charno - 1) else: From gvanrossum@users.sourceforge.net Fri Jun 22 02:23:08 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 21 Jun 2001 18:23:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.81.2.43,1.81.2.44 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv23494 Modified Files: Tag: release20-maint NEWS Log Message: Final update. Now Tim can cut the Windows installer and check in his changes to PCbuild, then I'll tag the tree and build the final tar file, and we can shove this puppy OUT OF THE DOOR...! Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.81.2.43 retrieving revision 1.81.2.44 diff -C2 -r1.81.2.43 -r1.81.2.44 *** NEWS 2001/06/20 14:56:22 1.81.2.43 --- NEWS 2001/06/22 01:23:05 1.81.2.44 *************** *** 6,10 **** - Bogus indentation in Lib/statcache.py was fixed. ! - A few small nits in the documentation were fixed. What's Fixed in Python 2.0.1c1 --- 6,11 ---- - Bogus indentation in Lib/statcache.py was fixed. ! - A few small nits in the documentation were fixed and the new license ! was included there. What's Fixed in Python 2.0.1c1 From tim_one@users.sourceforge.net Fri Jun 22 03:06:06 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 21 Jun 2001 19:06:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild BUILDno.txt,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv29738/python/dist/src/PCbuild Modified Files: BUILDno.txt Log Message: Record Windows build number for 2.0.1 final. Index: BUILDno.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/BUILDno.txt,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -r1.13 -r1.14 *** BUILDno.txt 2001/06/13 19:17:32 1.13 --- BUILDno.txt 2001/06/22 02:06:04 1.14 *************** *** 34,37 **** --- 34,39 ---- Windows Python BUILD numbers ---------------------------- + 18 2.0.1 + 22-Jun-2001 17 2.0.1c1 13-Jun-2001 From tim_one@users.sourceforge.net Fri Jun 22 03:15:37 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 21 Jun 2001 19:15:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild BUILDno.txt,1.4.2.1,1.4.2.2 python20.dsp,1.14.2.1,1.14.2.2 python20.wse,1.21.2.1,1.21.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv31204/python/dist/src/PCbuild Modified Files: Tag: release20-maint BUILDno.txt python20.dsp python20.wse Log Message: Windows fiddling for the 2.0.1 release. Index: BUILDno.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/BUILDno.txt,v retrieving revision 1.4.2.1 retrieving revision 1.4.2.2 diff -C2 -r1.4.2.1 -r1.4.2.2 *** BUILDno.txt 2001/06/13 19:26:00 1.4.2.1 --- BUILDno.txt 2001/06/22 02:15:35 1.4.2.2 *************** *** 34,37 **** --- 34,39 ---- Windows Python BUILD numbers ---------------------------- + 18 2.0.1 + 22-Jun-2001 17 2.0.1c1 13-Jun-2001 Index: python20.dsp =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/Attic/python20.dsp,v retrieving revision 1.14.2.1 retrieving revision 1.14.2.2 diff -C2 -r1.14.2.1 -r1.14.2.2 *** python20.dsp 2001/06/13 19:19:52 1.14.2.1 --- python20.dsp 2001/06/22 02:15:35 1.14.2.2 *************** *** 695,703 **** !IF "$(CFG)" == "python20 - Win32 Release" ! # ADD CPP /D BUILD=17 !ELSEIF "$(CFG)" == "python20 - Win32 Debug" ! # ADD CPP /D BUILD=17 !ELSEIF "$(CFG)" == "python20 - Win32 Alpha Debug" --- 695,703 ---- !IF "$(CFG)" == "python20 - Win32 Release" ! # ADD CPP /D BUILD=18 !ELSEIF "$(CFG)" == "python20 - Win32 Debug" ! # ADD CPP /D BUILD=18 !ELSEIF "$(CFG)" == "python20 - Win32 Alpha Debug" Index: python20.wse =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/python20.wse,v retrieving revision 1.21.2.1 retrieving revision 1.21.2.2 diff -C2 -r1.21.2.1 -r1.21.2.2 *** python20.wse 2001/06/13 19:11:24 1.21.2.1 --- python20.wse 2001/06/22 02:15:35 1.21.2.2 *************** *** 2,6 **** item: Global Version=5.0 ! Title=Python 2.0.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.0.1 Flags=00010100 Languages=65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 *************** *** 65,69 **** item: Set Variable Variable=APPTITLE ! Value=Python 2.0.1c1 end item: Set Variable --- 65,69 ---- item: Set Variable Variable=APPTITLE ! Value=Python 2.0.1 end item: Set Variable From tim_one@users.sourceforge.net Fri Jun 22 07:43:04 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 21 Jun 2001 23:43:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include patchlevel.h,2.42.2.2,2.42.2.3 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv2936/python/dist/src/Include Modified Files: Tag: release20-maint patchlevel.h Log Message: We surely intended to fiddle the version number #defines for this release. Index: patchlevel.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/patchlevel.h,v retrieving revision 2.42.2.2 retrieving revision 2.42.2.3 diff -C2 -r2.42.2.2 -r2.42.2.3 *** patchlevel.h 2001/06/13 16:02:09 2.42.2.2 --- patchlevel.h 2001/06/22 06:43:01 2.42.2.3 *************** *** 23,34 **** #define PY_MINOR_VERSION 0 #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.0.1c1" /* Historic */ ! #define PATCHLEVEL "2.0.1c1" /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. --- 23,34 ---- #define PY_MINOR_VERSION 0 #define PY_MICRO_VERSION 1 ! #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL ! #define PY_RELEASE_SERIAL 0 /* Version as a string */ ! #define PY_VERSION "2.0.1" /* Historic */ ! #define PATCHLEVEL "2.0.1" /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. From jvr@users.sourceforge.net Fri Jun 22 16:09:58 2001 From: jvr@users.sourceforge.net (Just van Rossum) Date: Fri, 22 Jun 2001 08:09:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Resources dialogs.rsrc,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Resources In directory usw-pr-cvs1:/tmp/cvs-serv27279 Modified Files: dialogs.rsrc Log Message: Changed the order of the buttons for EasyDialogs.AskYesNoCancel() from the unusual [cancel, no, yes] to the more standard [no, cancel, yes]. Index: dialogs.rsrc =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Resources/dialogs.rsrc,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -r1.14 -r1.15 Binary files /tmp/cvsglLQRe and /tmp/cvskTWjqj differ From gvanrossum@users.sourceforge.net Fri Jun 22 16:36:33 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 22 Jun 2001 08:36:33 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0251.txt,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv321 Modified Files: pep-0251.txt Log Message: Add some text to the release schedule. The release dates are picked pretty arbitrary: 3 weeks apart, on Wednesdays. Index: pep-0251.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0251.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** pep-0251.txt 2001/04/18 10:28:43 1.1 --- pep-0251.txt 2001/06/22 15:36:31 1.2 *************** *** 2,6 **** Title: Python 2.2 Release Schedule Version: $Revision$ ! Author: Barry Warsaw Status: Incomplete Type: Informational --- 2,6 ---- Title: Python 2.2 Release Schedule Version: $Revision$ ! Author: Guido van Rossum Status: Incomplete Type: Informational *************** *** 16,28 **** the first beta release. Release Schedule ! Python 2.2 is in the very early planning stages, and Guido ! expressed a desire to release Python 2.2 in October of 2001. ! Tentative future release dates ! October-2001: 2.2 final release --- 16,68 ---- the first beta release. + NOTE: the schedule below and the list of features under + consideration are all subject to change! If the energy in the + community changes or the feedback on a PEP is particularly + positive or negative, this may affect decisions. + Release Schedule + + Tentative future release dates (compare pep-0226) + + 17-Oct-2001: 2.2 (final release) + 10-Oct-2001: 2.2c1 (release candidate) + 19-Sep-2001: 2.2b2 + 29-Aug-2001: 2.2b1 + 8-Aug-2001: 2.2a2 + 18-Jul-2001: 2.2a1 + + + Release Mechanics + + I'd like to experiment with a new mechanism for releases: a week + before every alpha, beta or other release, I'll fork off a branch + which will become the release; changes to the branch will have to + be approved before they can be checked in. This is how some other + large projects (e.g. Mozilla) work, and I hope it will help reduce + the number of bugs introduced in releases at the last minute. + + + Planned features for 2.2 + + The following features are already checked in on the head revision + (for a more detailed account, see Misc/NEWS): + + - iterators (pep-0234) + + The following features are scheduled to go in; work is still + ongoing in defining the exact appearance of the features: + + - generators (pep-0255) + - unification of types and classes (pep-0252, pep-0253, pep-0254) ! The following features are under consideration: ! - a standard set API (implemented in Python for now) (pep-0218) ! - a 'directive' statement (pep-0244) ! - unifying long ints and plain ints (pep-0237) ! There needs to be more discussion of each of these before we can ! decide. From gvanrossum@users.sourceforge.net Fri Jun 22 16:37:03 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 22 Jun 2001 08:37:03 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0000.txt,1.98,1.99 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv406 Modified Files: pep-0000.txt Log Message: Change 2.2 release schedule author to GvR. Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.98 retrieving revision 1.99 diff -C2 -r1.98 -r1.99 *** pep-0000.txt 2001/06/18 19:19:51 1.98 --- pep-0000.txt 2001/06/22 15:37:01 1.99 *************** *** 53,57 **** S 246 pep-0246.txt Object Adaptation Evans S 250 pep-0250.txt Using site-packages on All Platforms Moore ! I 251 pep-0251.txt Python 2.2 Release Schedule Warsaw S 252 pep-0252.txt Making Types Look More Like Classes van Rossum S 253 pep-0253.txt Subtyping Built-in Types van Rossum --- 53,57 ---- S 246 pep-0246.txt Object Adaptation Evans S 250 pep-0250.txt Using site-packages on All Platforms Moore ! I 251 pep-0251.txt Python 2.2 Release Schedule van Rossum S 252 pep-0252.txt Making Types Look More Like Classes van Rossum S 253 pep-0253.txt Subtyping Built-in Types van Rossum *************** *** 178,182 **** I 249 pep-0249.txt Python Database API Specification v2.0 Lemburg S 250 pep-0250.txt Using site-packages on All Platforms Moore ! I 251 pep-0251.txt Python 2.2 Release Schedule Warsaw S 252 pep-0252.txt Making Types Look More Like Classes van Rossum S 253 pep-0253.txt Subtyping Built-in Types van Rossum --- 178,182 ---- I 249 pep-0249.txt Python Database API Specification v2.0 Lemburg S 250 pep-0250.txt Using site-packages on All Platforms Moore ! I 251 pep-0251.txt Python 2.2 Release Schedule van Rossum S 252 pep-0252.txt Making Types Look More Like Classes van Rossum S 253 pep-0253.txt Subtyping Built-in Types van Rossum From fdrake@users.sourceforge.net Fri Jun 22 16:42:00 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 08:42:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libos.tex,1.53.4.5,1.53.4.6 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv1418/lib Modified Files: Tag: release21-maint libos.tex Log Message: Properly mark the availability of tempnam() and tmpnam(). Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.53.4.5 retrieving revision 1.53.4.6 diff -C2 -r1.53.4.5 -r1.53.4.6 *** libos.tex 2001/06/11 18:26:04 1.53.4.5 --- libos.tex 2001/06/22 15:41:58 1.53.4.6 *************** *** 782,785 **** --- 782,786 ---- managing files created using paths returned by \function{tempnam()}; no automatic cleanup is provided. + Availability: \UNIX. \end{funcdesc} *************** *** 791,794 **** --- 792,796 ---- paths returned by \function{tmpnam()}; no automatic cleanup is provided. + Availability: \UNIX. \end{funcdesc} *************** *** 796,799 **** --- 798,802 ---- The maximum number of unique names that \function{tmpnam()} will generate before reusing names. + Availability: \UNIX, Windows. \end{datadesc} From fdrake@users.sourceforge.net Fri Jun 22 16:51:30 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 08:51:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/texinputs python.sty,1.73.2.1,1.73.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory usw-pr-cvs1:/tmp/cvs-serv3264/texinputs Modified Files: Tag: release21-maint python.sty Log Message: Add support for the classdesc* environment and the \releaseinfo and \setreleaseinfo macros added to the CVS head. Index: python.sty =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/python.sty,v retrieving revision 1.73.2.1 retrieving revision 1.73.2.2 diff -C2 -r1.73.2.1 -r1.73.2.2 *** python.sty 2001/04/18 17:30:26 1.73.2.1 --- python.sty 2001/06/22 15:51:28 1.73.2.2 *************** *** 624,627 **** --- 624,636 ---- }{\end{fulllineitems}} + % \begin{classdesc*}{name} + \newenvironment{classdesc*}[1]{ + % Using \renewcommand doesn't work for this, for unknown reasons: + \global\def\py@thisclass{#1} + \begin{fulllineitems} + \item[\strong{class }\code{\bfcode{#1}}% + \index{#1@{\py@idxcode{#1}} (class in \py@thismodule)}] + }{\end{fulllineitems}} + % \begin{excclassdesc}{name}{constructor args} % but indexes as an exception *************** *** 634,637 **** --- 643,649 ---- }{\end{fulllineitems}} + % There is no corresponding {excclassdesc*} environment. To describe + % a class exception without parameters, use the {excdesc} environment. + \let\py@classbadkey=\@undefined *************** *** 1037,1040 **** --- 1049,1053 ---- \newcommand{\version}{} \newcommand{\shortversion}{} + \newcommand{\releaseinfo}{} \newcommand{\releasename}{Release} \newcommand{\release}[1]{% *************** *** 1043,1046 **** --- 1056,1061 ---- \newcommand{\setshortversion}[1]{% \renewcommand{\shortversion}{#1}} + \newcommand{\setreleaseinfo}[1]{% + \renewcommand{\releaseinfo}{#1}} % Allow specification of the author's address separately from the From fdrake@users.sourceforge.net Fri Jun 22 16:51:30 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 08:51:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/perl l2hinit.perl,1.53,1.53.4.1 python.perl,1.98.2.2,1.98.2.3 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/perl In directory usw-pr-cvs1:/tmp/cvs-serv3264/perl Modified Files: Tag: release21-maint l2hinit.perl python.perl Log Message: Add support for the classdesc* environment and the \releaseinfo and \setreleaseinfo macros added to the CVS head. Index: l2hinit.perl =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/perl/l2hinit.perl,v retrieving revision 1.53 retrieving revision 1.53.4.1 diff -C2 -r1.53 -r1.53.4.1 *** l2hinit.perl 2001/01/09 22:02:10 1.53 --- l2hinit.perl 2001/06/22 15:51:28 1.53.4.1 *************** *** 182,191 **** if ($PACKAGE_VERSION ne '' && $t_date) { return ("" ! . "Release $PACKAGE_VERSION," . " documentation updated on $t_date."); } if ($PACKAGE_VERSION ne '') { return ("" ! . "Release $PACKAGE_VERSION."); } if ($t_date) { --- 182,191 ---- if ($PACKAGE_VERSION ne '' && $t_date) { return ("" ! . "Release $PACKAGE_VERSION$RELEASE_INFO," . " documentation updated on $t_date."); } if ($PACKAGE_VERSION ne '') { return ("" ! . "Release $PACKAGE_VERSION$RELEASE_INFO."); } if ($t_date) { *************** *** 416,420 **** $the_version = ",\n$t_date"; if ($PACKAGE_VERSION) { ! $the_version .= ", Release $PACKAGE_VERSION"; } } --- 416,420 ---- $the_version = ",\n$t_date"; if ($PACKAGE_VERSION) { ! $the_version .= ", Release $PACKAGE_VERSION$RELEASE_INFO"; } } Index: python.perl =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/perl/python.perl,v retrieving revision 1.98.2.2 retrieving revision 1.98.2.3 diff -C2 -r1.98.2.2 -r1.98.2.3 *** python.perl 2001/04/21 05:56:28 1.98.2.2 --- python.perl 2001/06/22 15:51:28 1.98.2.3 *************** *** 105,108 **** --- 105,109 ---- $DEVELOPER_ADDRESS = ''; $SHORT_VERSION = ''; + $RELEASE_INFO = ''; $PACKAGE_VERSION = ''; *************** *** 115,118 **** --- 116,125 ---- } + sub do_cmd_setreleaseinfo{ + local($_) = @_; + $RELEASE_INFO = next_argument(); + return $_; + } + sub do_cmd_setshortversion{ local($_) = @_; *************** *** 907,910 **** --- 914,928 ---- } + sub do_env_classdescstar{ + local($_) = @_; + $THIS_CLASS = next_argument(); + $idx = make_str_index_entry( + "$THIS_CLASS (class in $THIS_MODULE)"); + $idx =~ s/ \(.*\)//; + return ("
class $idx\n
" + . $_ + . '
'); + } + sub do_env_excclassdesc{ return handle_classlike_descriptor(@_[0], "exception"); *************** *** 1297,1301 **** $the_title .= "\n

"; if ($PACKAGE_VERSION) { ! $the_title .= "Release $PACKAGE_VERSION
\n"; } $the_title .= "$t_date

" --- 1315,1320 ---- $the_title .= "\n

"; if ($PACKAGE_VERSION) { ! $the_title .= ('Release ' ! . "$PACKAGE_VERSION$RELEASE_INFO
\n"); } $the_title .= "$t_date

" From fdrake@users.sourceforge.net Fri Jun 22 16:52:16 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 08:52:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/texinputs boilerplate.tex,1.58.2.1,1.58.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory usw-pr-cvs1:/tmp/cvs-serv3487/texinputs Modified Files: Tag: release21-maint boilerplate.tex Log Message: Separate the version number and release status information. Index: boilerplate.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/boilerplate.tex,v retrieving revision 1.58.2.1 retrieving revision 1.58.2.2 diff -C2 -r1.58.2.1 -r1.58.2.2 *** boilerplate.tex 2001/04/18 05:24:30 1.58.2.1 --- boilerplate.tex 2001/06/22 15:52:13 1.58.2.2 *************** *** 7,10 **** \date{\today} % XXX update before release! ! \release{2.1.1a0} % software release, not documentation \setshortversion{2.1} % major.minor only for software --- 7,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 From fdrake@users.sourceforge.net Fri Jun 22 17:00:56 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 09:00:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libposix.tex,1.56.4.1,1.56.4.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv5557/lib Modified Files: Tag: release21-maint libposix.tex Log Message: Fix & clean up the information about building Python with large file support for Linux. This closes SF bug #434975. Index: libposix.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libposix.tex,v retrieving revision 1.56.4.1 retrieving revision 1.56.4.2 diff -C2 -r1.56.4.1 -r1.56.4.2 *** libposix.tex 2001/05/09 15:52:56 1.56.4.1 --- libposix.tex 2001/06/22 16:00:54 1.56.4.2 *************** *** 63,70 **** \begin{verbatim} ! CC="-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64" ! export CC ! ./configure ! \end{verbatim} --- 63,69 ---- \begin{verbatim} ! CFLAGS='-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64' OPT="-g -O2 $CFLAGS" \ ! ./configure ! \end{verbatim} % $ <-- bow to font-lock From fdrake@users.sourceforge.net Fri Jun 22 17:01:22 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 09:01:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libposix.tex,1.57,1.58 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv5666/lib Modified Files: libposix.tex Log Message: Fix & clean up the information about building Python with large file support for Linux. This closes SF bug #434975. Index: libposix.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libposix.tex,v retrieving revision 1.57 retrieving revision 1.58 diff -C2 -r1.57 -r1.58 *** libposix.tex 2001/05/09 15:50:17 1.57 --- libposix.tex 2001/06/22 16:01:20 1.58 *************** *** 63,70 **** \begin{verbatim} ! CC="-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64" ! export CC ! ./configure ! \end{verbatim} --- 63,69 ---- \begin{verbatim} ! CFLAGS='-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64' OPT="-g -O2 $CFLAGS" \ ! ./configure ! \end{verbatim} % $ <-- bow to font-lock From gvanrossum@users.sourceforge.net Fri Jun 22 17:05:50 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 22 Jun 2001 09:05:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/scripts md5sum.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory usw-pr-cvs1:/tmp/cvs-serv6511 Added Files: md5sum.py Log Message: This is a trivial command line utility to print MD5 checksums. I published it on the web as http://www.python.org/2.1/md5sum.py so I thought I might as well check it in. Works with Python 1.5.2 and later. Works like the Linux tool ``mdfsum file ...'' except it doesn't take any options or read stdin. --- 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() From fdrake@users.sourceforge.net Fri Jun 22 18:07:04 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 10:07:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc Makefile.deps,1.66,1.67 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv23451 Modified Files: Makefile.deps Log Message: Add the new texinputs/license.tex to the shared dependencies. Index: Makefile.deps =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile.deps,v retrieving revision 1.66 retrieving revision 1.67 diff -C2 -r1.66 -r1.67 *** Makefile.deps 2001/05/30 04:59:50 1.66 --- Makefile.deps 2001/06/22 17:07:02 1.67 *************** *** 6,9 **** --- 6,10 ---- COMMONTEX= texinputs/copyright.tex \ + texinputs/license.tex \ texinputs/boilerplate.tex From fdrake@users.sourceforge.net Fri Jun 22 18:11:33 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 10:11:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools mkmodindex,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools In directory usw-pr-cvs1:/tmp/cvs-serv24523/tools Modified Files: mkmodindex Log Message: Adjust to understand use of either single- or double-quotes to quote attribute values, and make the logic surrounding the platform annotations just a little easier to read. Also make the platform notes appear in the generated page; they were supposed to, but did not. Index: mkmodindex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/mkmodindex,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -r1.11 -r1.12 *** mkmodindex 2001/02/12 19:12:55 1.11 --- mkmodindex 2001/06/22 17:11:30 1.12 *************** *** 50,73 **** class Node(buildindex.Node): ! annotation = "" ! ! def __init__(self, link, str, seqno): ! parts = string.split(str, None, 1) ! if parts[0][-5:] == "
": ! self.modname = parts[0][:-5] ! else: ! self.modname = parts[0] ! if len(parts) == 2: ! self.annotation = parts[1] buildindex.Node.__init__(self, link, self.modname, seqno) def __str__(self): ! return '%s %s' \ ! % (self.modname, self.annotation) _rx = re.compile( ! "
" ! "([a-zA-Z_][a-zA-Z0-9_.]*(\s*" ! "\(.*\))?)") def main(): --- 50,77 ---- class Node(buildindex.Node): ! def __init__(self, link, str, seqno, platinfo): ! self.annotation = platinfo or None ! if str[0][-5:] == "": ! str = str[:-5] ! self.modname = str buildindex.Node.__init__(self, link, self.modname, seqno) + if platinfo: + s = '%s %s' \ + % (self.modname, self.annotation) + else: + s = '%s' % str + self.text = [s] def __str__(self): ! if self.annotation: ! return '%s %s' \ ! % (self.modname, self.annotation) ! else: ! return '%s' % self.modname _rx = re.compile( ! "
" ! "([a-zA-Z_][a-zA-Z0-9_.]*)\s*(" ! "\(.*\))?") def main(): *************** *** 82,86 **** # nodes = [] - seqno = 0 has_plat_flag = 0 for ifn in args: --- 86,89 ---- *************** *** 98,106 **** if m: # This line specifies a module! ! basename, modname = m.group(1, 2) ! has_plat_flag = has_plat_flag or m.group(3) linkfile = os.path.join(dirname, basename) ! nodes.append(Node('' % linkfile, modname, seqno)) ! seqno = seqno + 1 ifp.close() # --- 101,109 ---- if m: # This line specifies a module! ! basename, modname, platinfo = m.group(1, 2, 3) ! has_plat_flag = has_plat_flag or platinfo linkfile = os.path.join(dirname, basename) ! nodes.append(Node('' % linkfile, modname, ! len(nodes), platinfo)) ifp.close() # From fdrake@users.sourceforge.net Fri Jun 22 18:17:04 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 10:17:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools mkmodindex,1.11,1.11.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools In directory usw-pr-cvs1:/tmp/cvs-serv25830/tools Modified Files: Tag: release21-maint mkmodindex Log Message: Adjust to understand use of either single- or double-quotes to quote attribute values, and make the logic surrounding the platform annotations just a little easier to read. Also make the platform notes appear in the generated page; they were supposed to, but did not. Index: mkmodindex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/mkmodindex,v retrieving revision 1.11 retrieving revision 1.11.4.1 diff -C2 -r1.11 -r1.11.4.1 *** mkmodindex 2001/02/12 19:12:55 1.11 --- mkmodindex 2001/06/22 17:17:02 1.11.4.1 *************** *** 50,73 **** class Node(buildindex.Node): ! annotation = "" ! ! def __init__(self, link, str, seqno): ! parts = string.split(str, None, 1) ! if parts[0][-5:] == "": ! self.modname = parts[0][:-5] ! else: ! self.modname = parts[0] ! if len(parts) == 2: ! self.annotation = parts[1] buildindex.Node.__init__(self, link, self.modname, seqno) def __str__(self): ! return '%s %s' \ ! % (self.modname, self.annotation) _rx = re.compile( ! "
" ! "([a-zA-Z_][a-zA-Z0-9_.]*(\s*" ! "\(.*\))?)") def main(): --- 50,77 ---- class Node(buildindex.Node): ! def __init__(self, link, str, seqno, platinfo): ! self.annotation = platinfo or None ! if str[0][-5:] == "": ! str = str[:-5] ! self.modname = str buildindex.Node.__init__(self, link, self.modname, seqno) + if platinfo: + s = '%s %s' \ + % (self.modname, self.annotation) + else: + s = '%s' % str + self.text = [s] def __str__(self): ! if self.annotation: ! return '%s %s' \ ! % (self.modname, self.annotation) ! else: ! return '%s' % self.modname _rx = re.compile( ! "
" ! "([a-zA-Z_][a-zA-Z0-9_.]*)\s*(" ! "\(.*\))?") def main(): *************** *** 82,86 **** # nodes = [] - seqno = 0 has_plat_flag = 0 for ifn in args: --- 86,89 ---- *************** *** 98,106 **** if m: # This line specifies a module! ! basename, modname = m.group(1, 2) ! has_plat_flag = has_plat_flag or m.group(3) linkfile = os.path.join(dirname, basename) ! nodes.append(Node('' % linkfile, modname, seqno)) ! seqno = seqno + 1 ifp.close() # --- 101,109 ---- if m: # This line specifies a module! ! basename, modname, platinfo = m.group(1, 2, 3) ! has_plat_flag = has_plat_flag or platinfo linkfile = os.path.join(dirname, basename) ! nodes.append(Node('' % linkfile, modname, ! len(nodes), platinfo)) ifp.close() # From fdrake@users.sourceforge.net Fri Jun 22 18:20:07 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 10:20:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libweakref.tex,1.7.2.1,1.7.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv26372/lib Modified Files: Tag: release21-maint libweakref.tex Log Message: Corrected an error in the information on supporting weak references in extension types (the docs reflected a development version of the API). This closes SF bug #435066. Index: libweakref.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libweakref.tex,v retrieving revision 1.7.2.1 retrieving revision 1.7.2.2 diff -C2 -r1.7.2.1 -r1.7.2.2 *** libweakref.tex 2001/05/10 17:23:10 1.7.2.1 --- libweakref.tex 2001/06/22 17:20:05 1.7.2.2 *************** *** 227,231 **** "instance", ! /* lots of stuff omitted for brevity */ offsetof(PyInstanceObject, in_weakreflist) /* tp_weaklistoffset */ --- 227,231 ---- "instance", ! /* Lots of stuff omitted for brevity... */ offsetof(PyInstanceObject, in_weakreflist) /* tp_weaklistoffset */ *************** *** 234,240 **** The only further addition is that the destructor needs to call the ! weak reference manager to clear any weak references and return if the ! object has been resurrected. This needs to occur before any other ! parts of the destruction have occurred: \begin{verbatim} --- 234,239 ---- The only further addition is that the destructor needs to call the ! weak reference manager to clear any weak references. This should be ! done before any other parts of the destruction have occurred: \begin{verbatim} *************** *** 242,253 **** instance_dealloc(PyInstanceObject *inst) { ! /* allocate tempories if needed, but do not begin ! destruction here */ ! if (!PyObject_ClearWeakRefs((PyObject *) inst)) ! return; ! /* proceed with object destuction normally */ } \end{verbatim} --- 241,251 ---- instance_dealloc(PyInstanceObject *inst) { ! /* Allocate tempories if needed, but do not begin ! destruction just yet. */ ! PyObject_ClearWeakRefs((PyObject *) inst); ! /* Proceed with object destuction normally. */ } \end{verbatim} From fdrake@users.sourceforge.net Fri Jun 22 18:20:31 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 10:20:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libweakref.tex,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv26469/lib Modified Files: libweakref.tex Log Message: Corrected an error in the information on supporting weak references in extension types (the docs reflected a development version of the API). This closes SF bug #435066. Index: libweakref.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libweakref.tex,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** libweakref.tex 2001/05/10 17:22:17 1.8 --- libweakref.tex 2001/06/22 17:20:29 1.9 *************** *** 227,231 **** "instance", ! /* lots of stuff omitted for brevity */ offsetof(PyInstanceObject, in_weakreflist) /* tp_weaklistoffset */ --- 227,231 ---- "instance", ! /* Lots of stuff omitted for brevity... */ offsetof(PyInstanceObject, in_weakreflist) /* tp_weaklistoffset */ *************** *** 234,240 **** The only further addition is that the destructor needs to call the ! weak reference manager to clear any weak references and return if the ! object has been resurrected. This needs to occur before any other ! parts of the destruction have occurred: \begin{verbatim} --- 234,239 ---- The only further addition is that the destructor needs to call the ! weak reference manager to clear any weak references. This should be ! done before any other parts of the destruction have occurred: \begin{verbatim} *************** *** 242,253 **** instance_dealloc(PyInstanceObject *inst) { ! /* allocate tempories if needed, but do not begin ! destruction here */ ! if (!PyObject_ClearWeakRefs((PyObject *) inst)) ! return; ! /* proceed with object destuction normally */ } \end{verbatim} --- 241,251 ---- instance_dealloc(PyInstanceObject *inst) { ! /* Allocate tempories if needed, but do not begin ! destruction just yet. */ ! PyObject_ClearWeakRefs((PyObject *) inst); ! /* Proceed with object destuction normally. */ } \end{verbatim} From fdrake@users.sourceforge.net Fri Jun 22 19:19:19 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 11:19:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib rexec.py,1.29,1.30 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv6941 Modified Files: rexec.py Log Message: Add sha and _sre to the list of allowed built-in modules. Index: rexec.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/rexec.py,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -r1.29 -r1.30 *** rexec.py 2001/06/18 12:33:36 1.29 --- rexec.py 2001/06/22 18:19:16 1.30 *************** *** 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', From fdrake@users.sourceforge.net Fri Jun 22 19:21:55 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 11:21:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib librexec.tex,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv7645/lib Modified Files: librexec.tex Log Message: Re-organize a little, clean up some markup. Added some comments about sys.exit(), SystemExit, and preventing restricted code from exiting the interpreter. This closes SF bug #434743. Index: librexec.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/librexec.tex,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -r1.14 -r1.15 *** librexec.tex 1999/04/22 21:23:22 1.14 --- librexec.tex 2001/06/22 18:21:53 1.15 *************** *** 47,107 **** \end{classdesc} ! The \class{RExec} class has the following class attributes, which are ! used by the \method{__init__()} method. Changing them on an existing ! instance won't have any effect; instead, create a subclass of ! \class{RExec} and assign them new values in the class definition. ! Instances of the new class will then use those new values. All these ! attributes are tuples of strings. - \begin{memberdesc}{nok_builtin_names} - Contains the names of built-in functions which will \emph{not} be - available to programs running in the restricted environment. The - value for \class{RExec} is \code{('open',} \code{'reload',} - \code{'__import__')}. (This gives the exceptions, because by far the - majority of built-in functions are harmless. A subclass that wants to - override this variable should probably start with the value from the - base class and concatenate additional forbidden functions --- when new - dangerous built-in functions are added to Python, they will also be - added to this module.) - \end{memberdesc} ! \begin{memberdesc}{ok_builtin_modules} ! Contains the names of built-in modules which can be safely imported. ! The value for \class{RExec} is \code{('audioop',} \code{'array',} ! \code{'binascii',} \code{'cmath',} \code{'errno',} \code{'imageop',} ! \code{'marshal',} \code{'math',} \code{'md5',} \code{'operator',} ! \code{'parser',} \code{'regex',} \code{'rotor',} \code{'select',} ! \code{'strop',} \code{'struct',} \code{'time')}. A similar remark ! about overriding this variable applies --- use the value from the base ! class as a starting point. ! \end{memberdesc} - \begin{memberdesc}{ok_path} - Contains the directories which will be searched when an \keyword{import} - is performed in the restricted environment. - The value for \class{RExec} is the same as \code{sys.path} (at the time - the module is loaded) for unrestricted code. - \end{memberdesc} - - \begin{memberdesc}{ok_posix_names} - % Should this be called ok_os_names? - Contains the names of the functions in the \refmodule{os} module which will be - available to programs running in the restricted environment. The - value for \class{RExec} is \code{('error',} \code{'fstat',} - \code{'listdir',} \code{'lstat',} \code{'readlink',} \code{'stat',} - \code{'times',} \code{'uname',} \code{'getpid',} \code{'getppid',} - \code{'getcwd',} \code{'getuid',} \code{'getgid',} \code{'geteuid',} - \code{'getegid')}. - \end{memberdesc} - - \begin{memberdesc}{ok_sys_names} - Contains the names of the functions and variables in the \refmodule{sys} - module which will be available to programs running in the restricted - environment. The value for \class{RExec} is \code{('ps1',} - \code{'ps2',} \code{'copyright',} \code{'version',} \code{'platform',} - \code{'exit',} \code{'maxint')}. - \end{memberdesc} - - \class{RExec} instances support the following methods: --- 47,73 ---- \end{classdesc} ! It is important to be aware that code running in a restricted ! environment can still call the \function{sys.exit()} function. To ! disallow restricted code from exiting the interpreter, always protect ! calls that cause restricted code to run with a ! \keyword{try}/\keyword{except} statement that catches the ! \exception{SystemExit} exception. Removing the \function{sys.exit()} ! function from the restricted environment is not sufficient --- the ! restricted code could still use \code{raise SystemExit}. Removing ! \exception{SystemExit} is not a reasonable option; some library code ! makes use of this and would break were it not available. ! ! ! \begin{seealso} ! \seetitle[http://grail.sourceforge.net/]{Grail Home Page}{Grail is a ! Web browser written entirely in Python. It uses the ! \module{rexec} module as a foundation for supporting ! Python applets, and can be used as an example usage of ! this module.} ! \end{seealso} ! \subsection{RExec Objects \label{rexec-objects}} \class{RExec} instances support the following methods: *************** *** 190,193 **** --- 156,214 ---- % XXX what are the semantics of this? \end{methoddesc} + + + \subsection{Defining restricted environments \label{rexec-extension}} + + The \class{RExec} class has the following class attributes, which are + used by the \method{__init__()} method. Changing them on an existing + instance won't have any effect; instead, create a subclass of + \class{RExec} and assign them new values in the class definition. + Instances of the new class will then use those new values. All these + attributes are tuples of strings. + + \begin{memberdesc}{nok_builtin_names} + Contains the names of built-in functions which will \emph{not} be + available to programs running in the restricted environment. The + value for \class{RExec} is \code{('open', 'reload', '__import__')}. + (This gives the exceptions, because by far the majority of built-in + functions are harmless. A subclass that wants to override this + variable should probably start with the value from the base class and + concatenate additional forbidden functions --- when new dangerous + built-in functions are added to Python, they will also be added to + this module.) + \end{memberdesc} + + \begin{memberdesc}{ok_builtin_modules} + Contains the names of built-in modules which can be safely imported. + The value for \class{RExec} is \code{('audioop', 'array', 'binascii', + 'cmath', 'errno', 'imageop', 'marshal', 'math', 'md5', 'operator', + 'parser', 'regex', 'rotor', 'select', 'sha', '_sre', 'strop', + 'struct', 'time')}. A similar remark about overriding this variable + applies --- use the value from the base class as a starting point. + \end{memberdesc} + + \begin{memberdesc}{ok_path} + Contains the directories which will be searched when an \keyword{import} + is performed in the restricted environment. + The value for \class{RExec} is the same as \code{sys.path} (at the time + the module is loaded) for unrestricted code. + \end{memberdesc} + + \begin{memberdesc}{ok_posix_names} + % Should this be called ok_os_names? + Contains the names of the functions in the \refmodule{os} module which will be + available to programs running in the restricted environment. The + value for \class{RExec} is \code{('error', 'fstat', 'listdir', + 'lstat', 'readlink', 'stat', 'times', 'uname', 'getpid', 'getppid', + 'getcwd', 'getuid', 'getgid', 'geteuid', 'getegid')}. + \end{memberdesc} + + \begin{memberdesc}{ok_sys_names} + Contains the names of the functions and variables in the \refmodule{sys} + module which will be available to programs running in the restricted + environment. The value for \class{RExec} is \code{('ps1', 'ps2', + 'copyright', 'version', 'platform', 'exit', 'maxint')}. + \end{memberdesc} + \subsection{An example} From fdrake@users.sourceforge.net Fri Jun 22 19:22:12 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 11:22:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib librexec.tex,1.14,1.14.12.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv7764/lib Modified Files: Tag: release21-maint librexec.tex Log Message: Re-organize a little, clean up some markup. Added some comments about sys.exit(), SystemExit, and preventing restricted code from exiting the interpreter. This closes SF bug #434743. Index: librexec.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/librexec.tex,v retrieving revision 1.14 retrieving revision 1.14.12.1 diff -C2 -r1.14 -r1.14.12.1 *** librexec.tex 1999/04/22 21:23:22 1.14 --- librexec.tex 2001/06/22 18:22:10 1.14.12.1 *************** *** 47,107 **** \end{classdesc} ! The \class{RExec} class has the following class attributes, which are ! used by the \method{__init__()} method. Changing them on an existing ! instance won't have any effect; instead, create a subclass of ! \class{RExec} and assign them new values in the class definition. ! Instances of the new class will then use those new values. All these ! attributes are tuples of strings. - \begin{memberdesc}{nok_builtin_names} - Contains the names of built-in functions which will \emph{not} be - available to programs running in the restricted environment. The - value for \class{RExec} is \code{('open',} \code{'reload',} - \code{'__import__')}. (This gives the exceptions, because by far the - majority of built-in functions are harmless. A subclass that wants to - override this variable should probably start with the value from the - base class and concatenate additional forbidden functions --- when new - dangerous built-in functions are added to Python, they will also be - added to this module.) - \end{memberdesc} ! \begin{memberdesc}{ok_builtin_modules} ! Contains the names of built-in modules which can be safely imported. ! The value for \class{RExec} is \code{('audioop',} \code{'array',} ! \code{'binascii',} \code{'cmath',} \code{'errno',} \code{'imageop',} ! \code{'marshal',} \code{'math',} \code{'md5',} \code{'operator',} ! \code{'parser',} \code{'regex',} \code{'rotor',} \code{'select',} ! \code{'strop',} \code{'struct',} \code{'time')}. A similar remark ! about overriding this variable applies --- use the value from the base ! class as a starting point. ! \end{memberdesc} - \begin{memberdesc}{ok_path} - Contains the directories which will be searched when an \keyword{import} - is performed in the restricted environment. - The value for \class{RExec} is the same as \code{sys.path} (at the time - the module is loaded) for unrestricted code. - \end{memberdesc} - - \begin{memberdesc}{ok_posix_names} - % Should this be called ok_os_names? - Contains the names of the functions in the \refmodule{os} module which will be - available to programs running in the restricted environment. The - value for \class{RExec} is \code{('error',} \code{'fstat',} - \code{'listdir',} \code{'lstat',} \code{'readlink',} \code{'stat',} - \code{'times',} \code{'uname',} \code{'getpid',} \code{'getppid',} - \code{'getcwd',} \code{'getuid',} \code{'getgid',} \code{'geteuid',} - \code{'getegid')}. - \end{memberdesc} - - \begin{memberdesc}{ok_sys_names} - Contains the names of the functions and variables in the \refmodule{sys} - module which will be available to programs running in the restricted - environment. The value for \class{RExec} is \code{('ps1',} - \code{'ps2',} \code{'copyright',} \code{'version',} \code{'platform',} - \code{'exit',} \code{'maxint')}. - \end{memberdesc} - - \class{RExec} instances support the following methods: --- 47,73 ---- \end{classdesc} ! It is important to be aware that code running in a restricted ! environment can still call the \function{sys.exit()} function. To ! disallow restricted code from exiting the interpreter, always protect ! calls that cause restricted code to run with a ! \keyword{try}/\keyword{except} statement that catches the ! \exception{SystemExit} exception. Removing the \function{sys.exit()} ! function from the restricted environment is not sufficient --- the ! restricted code could still use \code{raise SystemExit}. Removing ! \exception{SystemExit} is not a reasonable option; some library code ! makes use of this and would break were it not available. ! ! ! \begin{seealso} ! \seetitle[http://grail.sourceforge.net/]{Grail Home Page}{Grail is a ! Web browser written entirely in Python. It uses the ! \module{rexec} module as a foundation for supporting ! Python applets, and can be used as an example usage of ! this module.} ! \end{seealso} ! \subsection{RExec Objects \label{rexec-objects}} \class{RExec} instances support the following methods: *************** *** 190,193 **** --- 156,214 ---- % XXX what are the semantics of this? \end{methoddesc} + + + \subsection{Defining restricted environments \label{rexec-extension}} + + The \class{RExec} class has the following class attributes, which are + used by the \method{__init__()} method. Changing them on an existing + instance won't have any effect; instead, create a subclass of + \class{RExec} and assign them new values in the class definition. + Instances of the new class will then use those new values. All these + attributes are tuples of strings. + + \begin{memberdesc}{nok_builtin_names} + Contains the names of built-in functions which will \emph{not} be + available to programs running in the restricted environment. The + value for \class{RExec} is \code{('open', 'reload', '__import__')}. + (This gives the exceptions, because by far the majority of built-in + functions are harmless. A subclass that wants to override this + variable should probably start with the value from the base class and + concatenate additional forbidden functions --- when new dangerous + built-in functions are added to Python, they will also be added to + this module.) + \end{memberdesc} + + \begin{memberdesc}{ok_builtin_modules} + Contains the names of built-in modules which can be safely imported. + The value for \class{RExec} is \code{('audioop', 'array', 'binascii', + 'cmath', 'errno', 'imageop', 'marshal', 'math', 'md5', 'operator', + 'parser', 'regex', 'rotor', 'select', 'strop', 'struct', 'time')}. A + similar remark about overriding this variable applies --- use the + value from the base class as a starting point. + \end{memberdesc} + + \begin{memberdesc}{ok_path} + Contains the directories which will be searched when an \keyword{import} + is performed in the restricted environment. + The value for \class{RExec} is the same as \code{sys.path} (at the time + the module is loaded) for unrestricted code. + \end{memberdesc} + + \begin{memberdesc}{ok_posix_names} + % Should this be called ok_os_names? + Contains the names of the functions in the \refmodule{os} module which will be + available to programs running in the restricted environment. The + value for \class{RExec} is \code{('error', 'fstat', 'listdir', + 'lstat', 'readlink', 'stat', 'times', 'uname', 'getpid', 'getppid', + 'getcwd', 'getuid', 'getgid', 'geteuid', 'getegid')}. + \end{memberdesc} + + \begin{memberdesc}{ok_sys_names} + Contains the names of the functions and variables in the \refmodule{sys} + module which will be available to programs running in the restricted + environment. The value for \class{RExec} is \code{('ps1', 'ps2', + 'copyright', 'version', 'platform', 'exit', 'maxint')}. + \end{memberdesc} + \subsection{An example} From fdrake@users.sourceforge.net Fri Jun 22 19:36:09 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 11:36:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/texinputs boilerplate.tex,1.60,1.61 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory usw-pr-cvs1:/tmp/cvs-serv11084/texinputs Modified Files: boilerplate.tex Log Message: Remove an extra tab character. Index: boilerplate.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/boilerplate.tex,v retrieving revision 1.60 retrieving revision 1.61 diff -C2 -r1.60 -r1.61 *** boilerplate.tex 2001/06/20 21:33:13 1.60 --- boilerplate.tex 2001/06/22 18:36:07 1.61 *************** *** 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{a0} % empty for final release \setshortversion{2.2} % major.minor only for software From lemburg@users.sourceforge.net Fri Jun 22 21:53:59 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Fri, 22 Jun 2001 13:53:59 -0700 Subject: [Python-checkins] CVS: python/dist/encodings - New directory Message-ID: Update of /cvsroot/python/python/dist/encodings In directory usw-pr-cvs1:/tmp/cvs-serv21891/encodings Log Message: Directory /cvsroot/python/python/dist/encodings added to the repository From tim_one@users.sourceforge.net Sat Jun 23 03:07:11 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 22 Jun 2001 19:07:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python compile.c,2.202,2.203 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv12658/python/dist/src/Python Modified Files: compile.c Log Message: Disallow 'yield' in a 'try' block when there's a 'finally' clause. Derived from Thomas Wouters's patch on the Iterators list, but doesn't try to read c->c_block[c->c_nblocks]. Index: compile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v retrieving revision 2.202 retrieving revision 2.203 diff -C2 -r2.202 -r2.203 *** compile.c 2001/06/18 22:08:13 2.202 --- compile.c 2001/06/23 02:07:08 2.203 *************** *** 2660,2666 **** --- 2660,2676 ---- 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)); From fdrake@users.sourceforge.net Sat Jun 23 04:06:03 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 20:06:03 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools mkhowto,1.26,1.27 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools In directory usw-pr-cvs1:/tmp/cvs-serv20233/tools Modified Files: mkhowto Log Message: Miscellaneous code cleanups. Make sure we do not lose track of the build directory -- convert a user- supplied directory to an absolute path. Index: mkhowto =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/mkhowto,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -r1.26 -r1.27 *** mkhowto 2001/05/29 16:10:07 1.26 --- mkhowto 2001/06/23 03:06:01 1.27 *************** *** 48,51 **** --- 48,52 ---- if not hasattr(os.path, "abspath"): + # Python 1.5.1 or earlier def abspath(path): """Return an absolute path.""" *************** *** 215,218 **** --- 216,221 ---- os.path.join(TOPDIR, "texinputs"), ] + texinputs + if self.builddir: + self.builddir = os.path.abspath(self.builddir) *************** *** 224,228 **** self.doctype = get_doctype(path) self.filedir, self.doc = split_pathname(path) ! self.log_filename = self.doc + ".how" if os.path.exists(self.log_filename): os.unlink(self.log_filename) --- 227,234 ---- self.doctype = get_doctype(path) 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) *************** *** 244,248 **** if "html" in formats: self.require_temps() ! self.build_html(self.options.builddir or self.doc) if self.options.icon_server == ".": pattern = os.path.join(TOPDIR, "html", "icons", --- 250,254 ---- if "html" in formats: self.require_temps() ! self.build_html(self.builddir) if self.options.icon_server == ".": pattern = os.path.join(TOPDIR, "html", "icons", *************** *** 347,351 **** def build_html(self, builddir=None, max_split_depth=None): if builddir is None: ! builddir = self.doc if max_split_depth is None: max_split_depth = self.options.max_split_depth --- 353,357 ---- 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 *************** *** 521,525 **** def split_pathname(path): ! path = os.path.normpath(os.path.join(os.getcwd(), path)) dirname, basename = os.path.split(path) if basename[-4:] == ".tex": --- 527,531 ---- def split_pathname(path): ! path = os.path.abspath(path) dirname, basename = os.path.split(path) if basename[-4:] == ".tex": From fdrake@users.sourceforge.net Sat Jun 23 04:11:47 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 20:11:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/texinputs python.sty,1.76,1.77 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory usw-pr-cvs1:/tmp/cvs-serv20834/texinputs Modified Files: python.sty Log Message: \infinity, \plusminus: New macros to allow us to avoid math mode for these symbols. Index: python.sty =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/python.sty,v retrieving revision 1.76 retrieving revision 1.77 diff -C2 -r1.76 -r1.77 *** python.sty 2001/06/20 21:17:09 1.76 --- python.sty 2001/06/23 03:11:45 1.77 *************** *** 753,756 **** --- 753,758 ---- \newcommand{\EOF}{{\sc eof}} \newcommand{\NULL}{\constant{NULL}} + \newcommand{\infinity}{\ensuremath{\infty}} + \newcommand{\plusminus}{\ensuremath{\pm}} % Also for consistency: spell Python "Python", not "python"! From fdrake@users.sourceforge.net Sat Jun 23 04:13:32 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 20:13:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/perl python.perl,1.103,1.104 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/perl In directory usw-pr-cvs1:/tmp/cvs-serv21009/perl Modified Files: python.perl Log Message: Added support for our new \infinity and \plusminus macros, and the standard \textbar macro (not supported in many versions of LaTeX2HTML). Added newline to error message. Index: python.perl =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/perl/python.perl,v retrieving revision 1.103 retrieving revision 1.104 diff -C2 -r1.103 -r1.104 *** python.perl 2001/06/20 21:29:30 1.103 --- python.perl 2001/06/23 03:13:30 1.104 *************** *** 88,91 **** --- 88,94 ---- sub do_cmd_textasciitilde{ '~' . @_[0]; } sub do_cmd_textasciicircum{ '^' . @_[0]; } + sub do_cmd_textbar{ '|' . @_[0]; } + sub do_cmd_infinity{ '∞' . @_[0]; } + sub do_cmd_plusminus{ '±' . @_[0]; } *************** *** 1463,1467 **** } else { ! print "\nsynopsis table $key has no file association"; } } --- 1466,1470 ---- } else { ! print "\nsynopsis table $key has no file association\n"; } } From fdrake@users.sourceforge.net Sat Jun 23 04:16:31 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 20:16:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libcmath.tex,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv21334/lib Modified Files: libcmath.tex Log Message: Contributed updates from Harald Hanche-Olsen, giving details of the branch cuts for the complex math functions. Includes a brief description of what branch cuts are. Index: libcmath.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcmath.tex,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -r1.12 -r1.13 *** libcmath.tex 1999/06/29 15:53:52 1.12 --- libcmath.tex 2001/06/23 03:16:29 1.13 *************** *** 10,33 **** --- 10,63 ---- \begin{funcdesc}{acos}{x} Return the arc cosine of \var{x}. + There are two branch cuts: + One extends right from 1 along the real axis to \infinity, continuous + from below. + The other extends left from -1 along the real axis to -\infinity, + continuous from above. \end{funcdesc} \begin{funcdesc}{acosh}{x} Return the hyperbolic arc cosine of \var{x}. + There is one branch cut, extending left from 1 along the real axis + to -\infinity, continuous from above. \end{funcdesc} \begin{funcdesc}{asin}{x} Return the arc sine of \var{x}. + This has the same branch cuts as \function{acos()}. \end{funcdesc} \begin{funcdesc}{asinh}{x} Return the hyperbolic arc sine of \var{x}. + There are two branch cuts, extending left from \plusminus\code{1j} to + \plusminus-\infinity\code{j}, both continuous from above. + These branch cuts should be considered a bug to be corrected in a + future release. + The correct branch cuts should extend along the imaginary axis, + one from \code{1j} up to \infinity\code{j} and continuous from the + right, and one from -\code{1j} down to -\infinity\code{j} and + continuous from the left. \end{funcdesc} \begin{funcdesc}{atan}{x} Return the arc tangent of \var{x}. + There are two branch cuts: + One extends from \code{1j} along the imaginary axis to + \infinity\code{j}, continuous from the left. + The other extends from -\code{1j} along the imaginary axis to + -\infinity\code{j}, continuous from the left. + (This should probably be changed so the upper cut becomes continuous + from the other side.) \end{funcdesc} \begin{funcdesc}{atanh}{x} Return the hyperbolic arc tangent of \var{x}. + There are two branch cuts: + One extends from 1 along the real axis to \infinity, continuous + from above. + The other extends from -1 along the real axis to -\infinity, + continuous from above. + (This should probably be changed so the right cut becomes continuous from + the other side.) \end{funcdesc} *************** *** 46,53 **** --- 76,86 ---- \begin{funcdesc}{log}{x} Return the natural logarithm of \var{x}. + There is one branch cut, from 0 along the negative real axis to + -\infinity, continuous from above. \end{funcdesc} \begin{funcdesc}{log10}{x} Return the base-10 logarithm of \var{x}. + This has the same branch cut as \function{log()}. \end{funcdesc} *************** *** 62,65 **** --- 95,99 ---- \begin{funcdesc}{sqrt}{x} Return the square root of \var{x}. + This has the same branch cut as \function{log()}. \end{funcdesc} *************** *** 90,91 **** --- 124,140 ---- complex number, even if the answer can be expressed as a real number (in which case the complex number has an imaginary part of zero). + + A note on branch cuts: They are curves along which the given function + fails to be continuous. They are a necessary feature of many complex + functions. It is assumed that if you need to compute with complex + functions, you will understand about branch cuts. Consult almost any + (not too elementary) book on complex variables for enlightenment. For + information of the proper choice of branch cuts for numerical + purposes, a good reference should be the following: + + \begin{seealso} + \seetext{Kahan, W: Branch cuts for complex elementary functions; + or, Much ado about nothings's sign bit. In Iserles, A., + and Powell, M. (eds.), \citetitle{The state of the art in + numerical analysis}. Clarendon Press (1987) pp165-211.} + \end{seealso} From fdrake@users.sourceforge.net Sat Jun 23 04:17:04 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 20:17:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc ACKS,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv21461 Modified Files: ACKS Log Message: Added several names. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ACKS,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -r1.17 -r1.18 *** ACKS 2001/05/20 05:29:01 1.17 --- ACKS 2001/06/23 03:17:02 1.18 *************** *** 17,20 **** --- 17,21 ---- Aahz + Michael Abbott Jim Ahlstrom A. Amoroso *************** *** 36,39 **** --- 37,41 ---- Gilles Civario Steve Clift + Matthew Cowles Andrew Dalke Ben Darnell *************** *** 57,60 **** --- 59,63 ---- Anders Hammarquist Mark Hammond + Harald Hanche-Olsen Manus Hand Travis B. Hartwell *************** *** 114,117 **** --- 117,121 ---- Denis S. Otkidach William Park + Harri Pasanen Tim Peters Christopher Petrilli From fdrake@users.sourceforge.net Sat Jun 23 05:35:11 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 21:35:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools node2label.pl,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools In directory usw-pr-cvs1:/tmp/cvs-serv32363/tools Modified Files: node2label.pl Log Message: Give the pattern used to pick out a source anchor a more specific pattern. Index: node2label.pl =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/node2label.pl,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -r1.11 -r1.12 *** node2label.pl 2001/05/29 19:53:46 1.11 --- node2label.pl 2001/06/23 04:35:09 1.12 *************** *** 40,44 **** # don't want to do one s/// per line per node # so look for lines with hrefs, then do s/// on nodes present ! if (/(HREF|href)=[\"\']([^\#\"\']*)html[\#\"\']/) { @parts = split(/(HREF|href)\=[\"\']/); shift @parts; --- 40,44 ---- # don't want to do one s/// per line per node # so look for lines with hrefs, then do s/// on nodes present ! if (/(HREF|href)=[\"\']node\d+\.html[\#\"\']/) { @parts = split(/(HREF|href)\=[\"\']/); shift @parts; From fdrake@users.sourceforge.net Sat Jun 23 05:53:45 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 21:53:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/html style.css,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/html In directory usw-pr-cvs1:/tmp/cvs-serv2030/html Modified Files: style.css Log Message: Consistently use semi-colons after the last property for each selector. Index: style.css =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/html/style.css,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -r1.14 -r1.15 *** style.css 2001/03/08 22:17:54 1.14 --- style.css 2001/06/23 04:53:43 1.15 *************** *** 12,23 **** /* Implement both fixed-size and relative sizes: */ ! small.xtiny { font-size : xx-small } ! small.tiny { font-size : x-small } ! small.scriptsize { font-size : smaller } ! small.footnotesize { font-size : small } ! big.xlarge { font-size : large } ! big.xxlarge { font-size : x-large } ! big.huge { font-size : larger } ! big.xhuge { font-size : xx-large } /* --- 12,23 ---- /* Implement both fixed-size and relative sizes: */ ! small.xtiny { font-size : xx-small; } ! small.tiny { font-size : x-small; } ! small.scriptsize { font-size : smaller; } ! small.footnotesize { font-size : small; } ! big.xlarge { font-size : large; } ! big.xxlarge { font-size : x-large; } ! big.huge { font-size : larger; } ! big.xhuge { font-size : xx-large; } /* *************** *** 38,54 **** h1, h2, h3, h4, h5, h6 { font-family: avantgarde, sans-serif; ! font-weight: bold } ! h1 { font-size: 180% } ! h2 { font-size: 150% } ! h3, h4 { font-size: 120% } ! code, tt { font-family: monospace } var { font-family: times, serif; font-style: italic; ! font-weight: normal } .navigation td { background-color: #99ccff; font-weight: bold; font-family: avantgarde, sans-serif; ! font-size: 110% } .release-info { font-style: italic; } --- 38,54 ---- h1, h2, h3, h4, h5, h6 { font-family: avantgarde, sans-serif; ! font-weight: bold; } ! h1 { font-size: 180%; } ! h2 { font-size: 150%; } ! h3, h4 { font-size: 120%; } ! code, tt { font-family: monospace; } var { font-family: times, serif; font-style: italic; ! font-weight: normal; } .navigation td { background-color: #99ccff; font-weight: bold; font-family: avantgarde, sans-serif; ! font-size: 110%; } .release-info { font-style: italic; } *************** *** 56,73 **** .titlegraphic { vertical-align: top; } ! .verbatim { color: #00008b } ! .email { font-family: avantgarde, sans-serif } ! .mimetype { font-family: avantgarde, sans-serif } ! .newsgroup { font-family: avantgarde, sans-serif } ! .url { font-family: avantgarde, sans-serif } ! .file { font-family: avantgarde, sans-serif } .tableheader { background-color: #99ccff; font-family: avantgarde, sans-serif; } ! .refcount-info { font-style: italic } .refcount-info .value { font-weight: bold; ! color: #006600 } /* --- 56,73 ---- .titlegraphic { vertical-align: top; } ! .verbatim { color: #00008b; } ! .email { font-family: avantgarde, sans-serif; } ! .mimetype { font-family: avantgarde, sans-serif; } ! .newsgroup { font-family: avantgarde, sans-serif; } ! .url { font-family: avantgarde, sans-serif; } ! .file { font-family: avantgarde, sans-serif; } .tableheader { background-color: #99ccff; font-family: avantgarde, sans-serif; } ! .refcount-info { font-style: italic; } .refcount-info .value { font-weight: bold; ! color: #006600; } /* *************** *** 78,84 **** .seealso { background-color: #fffaf0; border: thin solid black; ! padding: 4pt } ! .seealso .heading { font-size: 110% } /* --- 78,84 ---- .seealso { background-color: #fffaf0; border: thin solid black; ! padding: 4pt; } ! .seealso .heading { font-size: 110%; } /* *************** *** 86,88 **** * the top of modules. */ ! .availability .platform { font-weight: bold } --- 86,88 ---- * the top of modules. */ ! .availability .platform { font-weight: bold; } From fdrake@users.sourceforge.net Sat Jun 23 06:26:55 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 22:26:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ref ref2.tex,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory usw-pr-cvs1:/tmp/cvs-serv5476/ref Modified Files: ref2.tex Log Message: Add "yeild" to the list of keywords. Fix a very minor (but annoying when looking for things!) markup nit. Index: ref2.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref2.tex,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -r1.23 -r1.24 *** ref2.tex 2001/02/14 04:03:51 1.23 --- ref2.tex 2001/06/23 05:26:52 1.24 *************** *** 29,32 **** --- 29,33 ---- set. + \section{Line structure\label{line-structure}} *************** *** 34,37 **** --- 35,39 ---- \index{line structure} + \subsection{Logical lines\label{logical}} *************** *** 47,50 **** --- 49,53 ---- \index{NEWLINE token} + \subsection{Physical lines\label{physical}} *************** *** 55,58 **** --- 58,62 ---- character. + \subsection{Comments\label{comments}} *************** *** 65,68 **** --- 69,73 ---- \index{hash character} + \subsection{Explicit line joining\label{explicit-joining}} *************** *** 204,207 **** --- 209,213 ---- \code{return r} does not match a level popped off the stack.) + \subsection{Whitespace between tokens\label{whitespace}} *************** *** 212,215 **** --- 218,222 ---- different token (e.g., ab is one token, but a b is two tokens). + \section{Other tokens\label{other-tokens}} *************** *** 223,226 **** --- 230,234 ---- forms a legal token, when read from left to right. + \section{Identifiers and keywords\label{identifiers}} *************** *** 240,243 **** --- 248,252 ---- Identifiers are unlimited in length. Case is significant. + \subsection{Keywords\label{keywords}} *************** *** 252,257 **** assert elif from lambda return break else global not try ! class except if or while ! continue exec import pass def finally in print \end{verbatim} --- 261,266 ---- assert elif from lambda return break else global not try ! class except if or yeild ! continue exec import pass while def finally in print \end{verbatim} *************** *** 259,262 **** --- 268,272 ---- % When adding keywords, use reswords.py for reformatting + \subsection{Reserved classes of identifiers\label{id-classes}} *************** *** 288,291 **** --- 298,302 ---- \index{constant} + \subsection{String literals\label{strings}} *************** *** 385,388 **** --- 396,400 ---- as part of the string, \emph{not} as a line continuation. + \subsection{String literal concatenation\label{string-catenation}} *************** *** 435,438 **** --- 447,451 ---- `\code{-}' and the literal \code{1}. + \subsection{Integer and long integer literals\label{integers}} *************** *** 469,472 **** --- 482,486 ---- \end{verbatim} + \subsection{Floating point literals\label{floating}} *************** *** 499,502 **** --- 513,517 ---- \code{-} and the literal \code{1}. + \subsection{Imaginary literals\label{imaginary}} *************** *** 532,535 **** --- 547,551 ---- spellings of the same operator. \code{!=} is the preferred spelling; \code{<>} is obsolescent. + \section{Delimiters\label{delimiters}} From tim_one@users.sourceforge.net Sat Jun 23 06:26:58 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 22 Jun 2001 22:26:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include frameobject.h,2.32,2.33 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv4915/python/dist/src/Include Modified Files: frameobject.h Log Message: PyFrameObject: rename f_stackbottom to f_stacktop, since it points to the next free valuestack slot, not to the base (in America, stacks push and pop at the top -- they mutate at the bottom in Australia ). eval_frame(): assert that f_stacktop isn't NULL upon entry. frame_delloc(): avoid ordered pointer comparisons involving f_stacktop when f_stacktop is NULL. Index: frameobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/frameobject.h,v retrieving revision 2.32 retrieving revision 2.33 diff -C2 -r2.32 -r2.33 *** frameobject.h 2001/06/18 22:08:13 2.32 --- frameobject.h 2001/06/23 05:26:56 2.33 *************** *** 22,27 **** PyObject *f_locals; /* local symbol table (PyDictObject) */ PyObject **f_valuestack; /* points after the last local */ ! PyObject **f_stackbottom; /* points to the last item on the stack if ! frame has yielded. */ PyObject *f_trace; /* Trace function */ PyObject *f_exc_type, *f_exc_value, *f_exc_traceback; --- 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; From tim_one@users.sourceforge.net Sat Jun 23 06:26:58 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 22 Jun 2001 22:26:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects frameobject.c,2.51,2.52 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv4915/python/dist/src/Objects Modified Files: frameobject.c Log Message: PyFrameObject: rename f_stackbottom to f_stacktop, since it points to the next free valuestack slot, not to the base (in America, stacks push and pop at the top -- they mutate at the bottom in Australia ). eval_frame(): assert that f_stacktop isn't NULL upon entry. frame_delloc(): avoid ordered pointer comparisons involving f_stacktop when f_stacktop is NULL. Index: frameobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/frameobject.c,v retrieving revision 2.51 retrieving revision 2.52 diff -C2 -r2.51 -r2.52 *** frameobject.c 2001/06/18 22:08:13 2.51 --- frameobject.c 2001/06/23 05:26:56 2.52 *************** *** 79,85 **** /* Free stack */ ! for (p = f->f_valuestack; p < f->f_stackbottom; p++) { ! Py_XDECREF(*p); } Py_XDECREF(f->f_back); Py_XDECREF(f->f_code); --- 79,87 ---- /* 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); *************** *** 227,231 **** f->f_valuestack = f->f_localsplus + (f->f_nlocals + ncells + nfrees); ! f->f_stackbottom = f->f_valuestack; return f; --- 229,233 ---- f->f_valuestack = f->f_localsplus + (f->f_nlocals + ncells + nfrees); ! f->f_stacktop = f->f_valuestack; return f; From tim_one@users.sourceforge.net Sat Jun 23 06:26:58 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 22 Jun 2001 22:26:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.253,2.254 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv4915/python/dist/src/Python Modified Files: ceval.c Log Message: PyFrameObject: rename f_stackbottom to f_stacktop, since it points to the next free valuestack slot, not to the base (in America, stacks push and pop at the top -- they mutate at the bottom in Australia ). eval_frame(): assert that f_stacktop isn't NULL upon entry. frame_delloc(): avoid ordered pointer comparisons involving f_stacktop when f_stacktop is NULL. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.253 retrieving revision 2.254 diff -C2 -r2.253 -r2.254 *** ceval.c 2001/06/21 02:49:55 2.253 --- ceval.c 2001/06/23 05:26:56 2.254 *************** *** 148,154 **** return NULL; } ! if (f->f_stackbottom == NULL) { return NULL; - } /* Generators always return to their most recent caller, not --- 148,153 ---- return NULL; } ! if (f->f_stacktop == NULL) return NULL; /* Generators always return to their most recent caller, not *************** *** 585,590 **** _PyCode_GETCODEPTR(co, &first_instr); next_instr = first_instr + f->f_lasti; ! stack_pointer = f->f_stackbottom; ! f->f_stackbottom = NULL; #ifdef LLTRACE --- 584,590 ---- _PyCode_GETCODEPTR(co, &first_instr); next_instr = first_instr + f->f_lasti; ! stack_pointer = f->f_stacktop; ! assert(stack_pointer != NULL); ! f->f_stacktop = NULL; #ifdef LLTRACE *************** *** 1372,1376 **** case YIELD_VALUE: retval = POP(); ! f->f_stackbottom = stack_pointer; f->f_lasti = INSTR_OFFSET(); why = WHY_YIELD; --- 1372,1376 ---- case YIELD_VALUE: retval = POP(); ! f->f_stacktop = stack_pointer; f->f_lasti = INSTR_OFFSET(); why = WHY_YIELD; From fdrake@users.sourceforge.net Sat Jun 23 06:27:22 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 22:27:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ref ref1.tex,1.12,1.13 ref3.tex,1.67,1.68 ref4.tex,1.27,1.28 ref5.tex,1.46,1.47 ref6.tex,1.37,1.38 ref7.tex,1.25,1.26 ref8.tex,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory usw-pr-cvs1:/tmp/cvs-serv5563/ref Modified Files: ref1.tex ref3.tex ref4.tex ref5.tex ref6.tex ref7.tex ref8.tex Log Message: Fix a very minor (but annoying when looking for things!) markup nit. Index: ref1.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref1.tex,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -r1.12 -r1.13 *** ref1.tex 2000/07/16 19:05:38 1.12 --- ref1.tex 2001/06/23 05:27:20 1.13 *************** *** 34,37 **** --- 34,38 ---- with the language definition. + \section{Notation\label{notation}} Index: ref3.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref3.tex,v retrieving revision 1.67 retrieving revision 1.68 diff -C2 -r1.67 -r1.68 *** ref3.tex 2001/05/29 16:02:35 1.67 --- ref3.tex 2001/06/23 05:27:20 1.68 *************** *** 1,4 **** --- 1,5 ---- \chapter{Data model\label{datamodel}} + \section{Objects, values and types\label{objects}} *************** *** 95,98 **** --- 96,100 ---- (Note that \samp{c = d = []} assigns the same object to both \code{c} and \code{d}.) + \section{The standard type hierarchy\label{types}} Index: ref4.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref4.tex,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -r1.27 -r1.28 *** ref4.tex 2001/05/29 15:44:27 1.27 --- ref4.tex 2001/06/23 05:27:20 1.28 *************** *** 2,5 **** --- 2,6 ---- \index{execution model} + \section{Code blocks, execution frames, and namespaces \label{execframes}} \index{code block} Index: ref5.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref5.tex,v retrieving revision 1.46 retrieving revision 1.47 diff -C2 -r1.46 -r1.47 *** ref5.tex 2001/06/05 02:17:02 1.46 --- ref5.tex 2001/06/23 05:27:20 1.47 *************** *** 17,20 **** --- 17,21 ---- \index{syntax} + \section{Arithmetic conversions\label{conversions}} \indexii{arithmetic}{conversion} *************** *** 55,58 **** --- 56,60 ---- \end{verbatim} + \subsection{Identifiers (Names)\label{atom-identifiers}} \index{name} *************** *** 100,103 **** --- 102,106 ---- consists only of underscores, no transformation is done. + \subsection{Literals\label{atom-literals}} \index{literal} *************** *** 123,126 **** --- 126,130 ---- \indexii{immutable}{object} + \subsection{Parenthesized forms\label{parenthesized}} \index{parenthesized form} *************** *** 151,154 **** --- 155,159 ---- \indexii{tuple}{display} + \subsection{List displays\label{lists}} \indexii{list}{display} *************** *** 182,185 **** --- 187,191 ---- \indexii{empty}{list} + \subsection{Dictionary displays\label{dict}} \indexii{dictionary}{display} *************** *** 211,214 **** --- 217,221 ---- \indexii{immutable}{object} + \subsection{String conversions\label{string-conversions}} \indexii{string}{conversion} *************** *** 250,253 **** --- 257,261 ---- \bifuncindex{str} + \section{Primaries\label{primaries}} \index{primary} *************** *** 260,263 **** --- 268,272 ---- \end{verbatim} + \subsection{Attribute references\label{attribute-references}} \indexii{attribute}{reference} *************** *** 280,283 **** --- 289,293 ---- \obindex{list} + \subsection{Subscriptions\label{subscriptions}} \index{subscription} *************** *** 317,320 **** --- 327,331 ---- \indexii{string}{item} + \subsection{Slicings\label{slicings}} \index{slicing} *************** *** 383,386 **** --- 394,398 ---- \ttindex{stop}\ttindex{step}} + \subsection{Calls\label{calls}} \index{call} *************** *** 557,560 **** --- 569,573 ---- \exindex{TypeError} + \section{Binary arithmetic operations\label{binary}} \indexiii{binary}{arithmetic}{operation} *************** *** 627,630 **** --- 640,644 ---- \index{subtraction} + \section{Shifting operations\label{shifting}} \indexii{shifting}{operation} *************** *** 651,654 **** --- 665,669 ---- \exindex{ValueError} + \section{Binary bit-wise operations\label{bitwise}} \indexiii{binary}{bit-wise}{operation} *************** *** 679,682 **** --- 694,698 ---- \indexii{inclusive}{or} + \section{Comparisons\label{comparisons}} \index{comparison} *************** *** 808,811 **** --- 824,828 ---- \opindex{is not} \indexii{identity}{test} + \section{Boolean operations\label{Booleans}} Index: ref6.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref6.tex,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -r1.37 -r1.38 *** ref6.tex 2001/04/13 15:55:25 1.37 --- ref6.tex 2001/06/23 05:27:20 1.38 *************** *** 23,26 **** --- 23,27 ---- \end{verbatim} + \section{Expression statements \label{exprstmts}} \indexii{expression}{statement} *************** *** 53,56 **** --- 54,58 ---- \indexii{procedure}{call} + \section{Assert statements \label{assert}} *************** *** 90,93 **** --- 92,96 ---- built-in variable is determined when the interpreter starts. + \section{Assignment statements \label{assignment}} *************** *** 307,310 **** --- 310,314 ---- \end{verbatim} + \section{The \keyword{del} statement \label{del}} \stindex{del} *************** *** 335,338 **** --- 339,343 ---- \indexii{attribute}{deletion} + \section{The \keyword{print} statement \label{print}} \stindex{print} *************** *** 386,389 **** --- 391,395 ---- used as the file for output. + \section{The \keyword{return} statement \label{return}} \stindex{return} *************** *** 409,412 **** --- 415,419 ---- \kwindex{finally} + \section{The \keyword{raise} statement \label{raise}} \stindex{raise} *************** *** 449,452 **** --- 456,460 ---- \obindex{traceback} + \section{The \keyword{break} statement \label{break}} \stindex{break} *************** *** 476,479 **** --- 484,488 ---- \kwindex{finally} + \section{The \keyword{continue} statement \label{continue}} \stindex{continue} *************** *** 495,498 **** --- 504,508 ---- \kwindex{finally} + \section{The \keyword{import} statement \label{import}} \stindex{import} *************** *** 595,598 **** --- 605,609 ---- \bifuncindex{__import__} + \section{The \keyword{global} statement \label{global}} \stindex{global} *************** *** 634,637 **** --- 645,649 ---- \bifuncindex{execfile} \bifuncindex{compile} + \section{The \keyword{exec} statement \label{exec}} Index: ref7.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref7.tex,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -r1.25 -r1.26 *** ref7.tex 2001/05/10 15:09:36 1.25 --- ref7.tex 2001/06/23 05:27:20 1.26 *************** *** 61,64 **** --- 61,65 ---- each clause on a separate line for clarity. + \section{The \keyword{if} statement\label{if}} \stindex{if} *************** *** 81,84 **** --- 82,86 ---- \kwindex{else} + \section{The \keyword{while} statement\label{while}} \stindex{while} *************** *** 106,109 **** --- 108,112 ---- \stindex{continue} + \section{The \keyword{for} statement\label{for}} \stindex{for} *************** *** 170,173 **** --- 173,177 ---- \end{verbatim} + \section{The \keyword{try} statement\label{try}} \stindex{try} *************** *** 279,282 **** --- 283,287 ---- \stindex{continue} + \section{Function definitions\label{function}} \indexii{function}{definition} *************** *** 368,371 **** --- 373,377 ---- function will change in Python 2.2. See the appendix for a description of the new semantics. + \section{Class definitions\label{class}} Index: ref8.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref8.tex,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -r1.12 -r1.13 *** ref8.tex 2001/01/26 15:27:35 1.12 --- ref8.tex 2001/06/23 05:27:20 1.13 *************** *** 7,10 **** --- 7,11 ---- \index{interpreter} + \section{Complete Python programs\label{programs}} \index{program} *************** *** 44,47 **** --- 45,49 ---- \index{standard input} + \section{File input\label{file-input}} *************** *** 64,67 **** --- 66,70 ---- \end{itemize} + \section{Interactive input\label{interactive}} *************** *** 75,78 **** --- 78,82 ---- line in interactive mode; this is needed to help the parser detect the end of the input. + \section{Expression input\label{expression-input}} From tim_one@users.sourceforge.net Sat Jun 23 06:47:58 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 22 Jun 2001 22:47:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.254,2.255 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv7071/python/dist/src/Python Modified Files: ceval.c Log Message: gen_iternext(): Don't assume that the current thread state's frame is not NULL. I don't think it can be NULL from Python code, but if using generators via the C API I expect a NULL frame is possible. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.254 retrieving revision 2.255 diff -C2 -r2.254 -r2.255 *** ceval.c 2001/06/23 05:26:56 2.254 --- ceval.c 2001/06/23 05:47:56 2.255 *************** *** 153,157 **** /* Generators always return to their most recent caller, not * necessarily their creator. */ ! Py_INCREF(tstate->frame); assert(f->f_back == NULL); f->f_back = tstate->frame; --- 153,157 ---- /* Generators always return to their most recent caller, not * necessarily their creator. */ ! Py_XINCREF(tstate->frame); assert(f->f_back == NULL); f->f_back = tstate->frame; *************** *** 164,168 **** * may keep a chain of frames alive or it could create a reference * cycle. */ ! Py_DECREF(f->f_back); f->f_back = NULL; --- 164,168 ---- * may keep a chain of frames alive or it could create a reference * cycle. */ ! Py_XDECREF(f->f_back); f->f_back = NULL; From fdrake@users.sourceforge.net Sat Jun 23 07:06:23 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 23:06:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ref ref5.tex,1.47,1.48 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory usw-pr-cvs1:/tmp/cvs-serv10202/ref Modified Files: ref5.tex Log Message: Use a named reference to another chapter instead of hard coding the chapter number. This also makes the reference a hyperlink in the HTML version. Index: ref5.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref5.tex,v retrieving revision 1.47 retrieving revision 1.48 diff -C2 -r1.47 -r1.48 *** ref5.tex 2001/06/23 05:27:20 1.47 --- ref5.tex 2001/06/23 06:06:21 1.48 *************** *** 24,29 **** ``the numeric arguments are converted to a common type,'' the arguments are coerced using the coercion rules listed at the end of ! chapter 3. If both arguments are standard numeric types, the ! following coercions are applied: \begin{itemize} --- 24,29 ---- ``the numeric arguments are converted to a common type,'' the arguments are coerced using the coercion rules listed at the end of ! chapter \ref{datamodel}. If both arguments are standard numeric ! types, the following coercions are applied: \begin{itemize} From fdrake@users.sourceforge.net Sat Jun 23 07:06:54 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 23:06:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ref ref6.tex,1.38,1.39 ref7.tex,1.26,1.27 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory usw-pr-cvs1:/tmp/cvs-serv10246/ref Modified Files: ref6.tex ref7.tex Log Message: Fix minor markup nits. Index: ref6.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref6.tex,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -r1.38 -r1.39 *** ref6.tex 2001/06/23 05:27:20 1.38 --- ref6.tex 2001/06/23 06:06:52 1.39 *************** *** 658,662 **** a code object. If it is a string, the string is parsed as a suite of Python statements which is then executed (unless a syntax error ! occurs). If it is an open file, the file is parsed until EOF and executed. If it is a code object, it is simply executed. --- 658,662 ---- a code object. If it is a string, the string is parsed as a suite of Python statements which is then executed (unless a syntax error ! occurs). If it is an open file, the file is parsed until \EOF{} and executed. If it is a code object, it is simply executed. Index: ref7.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref7.tex,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -r1.26 -r1.27 *** ref7.tex 2001/06/23 05:27:20 1.26 --- ref7.tex 2001/06/23 06:06:52 1.27 *************** *** 114,118 **** The \keyword{for} statement is used to iterate over the elements of a ! sequence (string, tuple or list): \obindex{sequence} --- 114,118 ---- The \keyword{for} statement is used to iterate over the elements of a ! sequence (such as a string, tuple or list) or other iterable object: \obindex{sequence} *************** *** 353,360 **** dictionary receiving any excess keyword arguments, defaulting to a new empty dictionary. - - - - It is also possible to create anonymous functions (functions not bound --- 353,356 ---- From fdrake@users.sourceforge.net Sat Jun 23 07:16:54 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 22 Jun 2001 23:16:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ref ref6.tex,1.39,1.40 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory usw-pr-cvs1:/tmp/cvs-serv11334/ref Modified Files: ref6.tex Log Message: Remove some bogus trailing whitespace. Index: ref6.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref6.tex,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -r1.39 -r1.40 *** ref6.tex 2001/06/23 06:06:52 1.39 --- ref6.tex 2001/06/23 06:16:52 1.40 *************** *** 349,355 **** \keyword{print} evaluates each expression in turn and writes the resulting object to standard output (see below). If an object is not ! a string, it is first converted to a string using the rules for string conversions. The (resulting or original) string is then written. A ! space is written before each object is (converted and) written, unless the output system believes it is positioned at the beginning of a line. This is the case (1) when no characters have yet been written --- 349,355 ---- \keyword{print} evaluates each expression in turn and writes the resulting object to standard output (see below). If an object is not ! a string, it is first converted to a string using the rules for string conversions. The (resulting or original) string is then written. A ! space is written before each object is (converted and) written, unless the output system believes it is positioned at the beginning of a line. This is the case (1) when no characters have yet been written From tim_one@users.sourceforge.net Sat Jun 23 07:19:18 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 22 Jun 2001 23:19:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.255,2.256 compile.c,2.203,2.204 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv10949/python/dist/src/Python Modified Files: ceval.c compile.c Log Message: Change the semantics of "return" in generators, as discussed on the Iterators list and Python-Dev; e.g., these all pass now: def g1(): try: return except: yield 1 assert list(g1()) == [] def g2(): try: return finally: yield 1 assert list(g2()) == [1] def g3(): for i in range(3): yield None yield None assert list(g3()) == [None] * 4 compile.c: compile_funcdef and com_return_stmt: Just van Rossum's patch to compile the same code for "return" regardless of function type (this goes back to the previous scheme of returning Py_None). ceval.c: gen_iternext: take a return (but not a yield) of Py_None as meaning the generator is exhausted. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.255 retrieving revision 2.256 diff -C2 -r2.255 -r2.256 *** ceval.c 2001/06/23 05:47:56 2.255 --- ceval.c 2001/06/23 06:19:16 2.256 *************** *** 167,170 **** --- 167,177 ---- f->f_back = NULL; + /* If the generator just returned (as opposed to yielding), signal + * that the generator is exhausted. */ + if (result == Py_None && f->f_stacktop == NULL) { + Py_DECREF(result); + result = NULL; + } + return result; } Index: compile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v retrieving revision 2.203 retrieving revision 2.204 diff -C2 -r2.203 -r2.204 *** compile.c 2001/06/23 02:07:08 2.203 --- compile.c 2001/06/23 06:19:16 2.204 *************** *** 2640,2657 **** "'return' with argument inside generator"); } - com_addoparg(c, LOAD_CONST, - com_addconst(c, PyExc_StopIteration)); - com_push(c, 1); - com_addoparg(c, RAISE_VARARGS, 1); } ! else { ! if (NCH(n) < 2) { ! com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None)); ! com_push(c, 1); ! } ! else ! com_node(c, CHILD(n, 1)); ! com_addbyte(c, RETURN_VALUE); } com_pop(c, 1); } --- 2640,2651 ---- "'return' with argument inside generator"); } } ! if (NCH(n) < 2) { ! com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None)); ! com_push(c, 1); } + else + com_node(c, CHILD(n, 1)); + com_addbyte(c, RETURN_VALUE); com_pop(c, 1); } *************** *** 3712,3728 **** com_node(c, CHILD(n, 4)); c->c_infunction = 0; ! if (c->c_flags & CO_GENERATOR) { ! com_addoparg(c, LOAD_CONST, ! com_addconst(c, PyExc_StopIteration)); ! com_push(c, 1); ! com_addoparg(c, RAISE_VARARGS, 1); ! com_pop(c, 1); ! } ! else { ! com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None)); ! com_push(c, 1); ! com_addbyte(c, RETURN_VALUE); ! com_pop(c, 1); ! } } --- 3706,3713 ---- com_node(c, CHILD(n, 4)); c->c_infunction = 0; ! com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None)); ! com_push(c, 1); ! com_addbyte(c, RETURN_VALUE); ! com_pop(c, 1); } From tim_one@users.sourceforge.net Sat Jun 23 09:53:23 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 23 Jun 2001 01:53:23 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0255.txt,1.10,1.11 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv28002/peps Modified Files: pep-0255.txt Log Message: Lotsa changes: more details and examples covering recent decisions wrt return stmts, try/except, try/finally; more Q&A. I expect this is the last major revision of this PEP, so I'm going to post it again too. Index: pep-0255.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0255.txt,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -r1.10 -r1.11 *** pep-0255.txt 2001/06/21 16:56:41 1.10 --- pep-0255.txt 2001/06/23 08:53:21 1.11 *************** *** 11,15 **** Created: 18-May-2001 Python-Version: 2.2 ! Post-History: 14-Jun-2001 --- 11,15 ---- Created: 18-May-2001 Python-Version: 2.2 ! Post-History: 14-Jun-2001, 23-Jun-2001 *************** *** 119,123 **** ! Specification A new statement is introduced: --- 119,123 ---- ! Specification: Yield A new statement is introduced: *************** *** 126,133 **** "yield" is a new keyword, so a future statement[8] is needed to phase ! this in. [XXX spell this out] The yield statement may only be used inside functions. A function that ! contains a yield statement is called a generator function. When a generator function is called, the actual arguments are bound to --- 126,138 ---- "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 ! contains a yield statement is called a generator function. A generator ! function is an ordinary function object in all respects, but has the ! new CO_GENERATOR flag set in the code object's co_flags member. When a generator function is called, the actual arguments are bound to *************** *** 154,157 **** --- 159,171 ---- call. + Restriction: A yield statement is not allowed in the try clause of a + try/finally construct. The difficulty is that there's no guarantee + the generator will ever be resumed, hence no guarantee that the finally + block will ever get executed; that's too much a violation of finally's + purpose to bear. + + + Specification: Return + A generator function can also contain return statements of the form: *************** *** 162,175 **** the bodies of non-generator functions nested within the generator). ! When a return statement is encountered, nothing is returned, but a ! StopIteration exception is raised, signalling that the iterator is ! exhausted. The same is true if control flows off the end of the ! function. Note that return means "I'm done, and have nothing ! interesting to return", for both generator functions and non-generator ! functions. - Generators and Exception Propagation If an unhandled exception-- including, but not limited to, StopIteration --is raised by, or passes through, a generator function, --- 176,216 ---- the bodies of non-generator functions nested within the generator). ! When a return statement is encountered, control proceeds as in any ! function return, executing the appropriate finally clauses (if any ! exist). Then a StopIteration exception is raised, signalling that the ! iterator is exhausted. A StopIteration exception is also raised if ! control flows off the end of the generator without an explict return. ! ! Note that return means "I'm done, and have nothing interesting to ! return", for both generator functions and non-generator functions. ! ! Note that return isn't always equivalent to raising StopIteration: the ! difference lies in how enclosing try/except constructs are treated. ! For example, ! ! >>> def f1(): ! ... try: ! ... return ! ... except: ! ... yield 1 ! >>> print list(f1()) ! [] ! ! because, as in any function, return simply exits, but ! ! >>> def f2(): ! ... try: ! ... raise StopIteration ! ... except: ! ... yield 42 ! >>> print list(f2()) ! [42] + because StopIteration is captured by a bare "except", as is any + exception. + Specification: Generators and Exception Propagation + If an unhandled exception-- including, but not limited to, StopIteration --is raised by, or passes through, a generator function, *************** *** 193,197 **** File "", line 2, in f ZeroDivisionError: integer division or modulo by zero ! >>> k.next() # and the generator function cannot be resumed Traceback (most recent call last): File "", line 1, in ? --- 234,238 ---- File "", line 2, in f ZeroDivisionError: integer division or modulo by zero ! >>> k.next() # and the generator cannot be resumed Traceback (most recent call last): File "", line 1, in ? *************** *** 200,234 **** ! Yield and Try/Except/Finally ! While "yield" is a control-flow statement, and in most respects acts ! like a "return" statement from the caller's point of view, within a ! generator it acts more like a callback function. In particular, it has ! no special semantics with respect to try/except/finally. This is best ! illustrated by a contrived example; the primary lesson to take from ! this is that using yield in a finally block is a dubious idea! ! >>> def g(): ... try: ... yield 1 ! ... 1/0 # raises exception ! ... yield 2 # we never get here ... finally: ! ... yield 3 # yields, and we raise the exception *next* time ! ... yield 4 # we never get here ! >>> k = g() ! >>> k.next() ! 1 ! >>> k.next() ! 3 ! >>> k.next() # as if "yield 3" were a callback, exception raised now ! Traceback (most recent call last): ! File "", line 1, in ? ! File "", line 4, in g ! ZeroDivisionError: integer division or modulo by zero ! >>> k.next() # unhandled exception terminated the generator ! Traceback (most recent call last): ! File "", line 1, in ? ! StopIteration >>> --- 241,276 ---- ! Specification: Try/Except/Finally ! As noted earlier, yield is not allowed in the try clause of a try/ ! finally construct. A consequence is that generators should allocate ! critical resources with great care. There is no restriction on yield ! otherwise appearing in finally clauses, except clauses, or in the try ! clause of a try/except construct: ! >>> def f(): ... try: ... yield 1 ! ... try: ! ... yield 2 ! ... 1/0 ! ... yield 3 # never get here ! ... except ZeroDivisionError: ! ... yield 4 ! ... yield 5 ! ... raise ! ... except: ! ... yield 6 ! ... yield 7 # the "raise" above stops this ! ... except: ! ... yield 8 ! ... yield 9 ! ... try: ! ... x = 12 ... finally: ! ... yield 10 ! ... yield 11 ! >>> print list(f()) ! [1, 2, 4, 5, 8, 9, 10, 11] >>> *************** *** 300,303 **** --- 342,349 ---- print + Both output blocks display: + + A B C D E F G H I J K L M N O P Q R S T U V W X Y Z + Q & A *************** *** 313,317 **** implementation in Jython requires that the compiler be able to determine potential suspension points at compile-time, and a new ! keyword makes that easy. Q. Why allow "return" at all? Why not force termination to be spelled --- 359,390 ---- implementation in Jython requires that the compiler be able to determine potential suspension points at compile-time, and a new ! keyword makes that easy. The CPython referrence implementation also ! exploits it heavily, to detect which functions *are* generator- ! functions (although a new keyword in place of "def" would solve that ! for CPython -- but people asking the "why a new keyword?" question ! don't want any new keyword). ! ! Q: Then why not some other special syntax without a new keyword? For ! example, one of these instead of "yield 3": ! ! return 3 and continue ! return and continue 3 ! return generating 3 ! continue return 3 ! return >> , 3 ! from generator return 3 ! return >> 3 ! return << 3 ! >> 3 ! << 3 ! ! A: Did I miss one ? Out of hundreds of messages, I counted two ! suggesting such an alternative, and extracted the above from them. ! It would be nice not to need a new keyword, but nicer to make yield ! very clear -- I don't want to have to *deduce* that a yield is ! occurring from making sense of a previous senseless sequence of ! keywords or operators. Still, if this attracts enough interest, ! proponents should settle on a single consensus suggestion, and Guido ! will Pronounce on it. Q. Why allow "return" at all? Why not force termination to be spelled *************** *** 324,327 **** --- 397,403 ---- forcing everyone to work at that level, though. "return" means "I'm done" in any kind of function, and that's easy to explain and to use. + Note that "return" isn't always equivalent to "raise StopIteration" + in try/except construct, either (see the "Specification: Return" + section). Q. Then why not allow an expression on "return" too? From tim_one@users.sourceforge.net Sat Jun 23 09:56:44 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 23 Jun 2001 01:56:44 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0255.txt,1.11,1.12 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv28617 Modified Files: pep-0255.txt Log Message: Typos. Index: pep-0255.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0255.txt,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -r1.11 -r1.12 *** pep-0255.txt 2001/06/23 08:53:21 1.11 --- pep-0255.txt 2001/06/23 08:56:42 1.12 *************** *** 383,387 **** It would be nice not to need a new keyword, but nicer to make yield very clear -- I don't want to have to *deduce* that a yield is ! occurring from making sense of a previous senseless sequence of keywords or operators. Still, if this attracts enough interest, proponents should settle on a single consensus suggestion, and Guido --- 383,387 ---- It would be nice not to need a new keyword, but nicer to make yield very clear -- I don't want to have to *deduce* that a yield is ! occurring from making sense of a previously senseless sequence of keywords or operators. Still, if this attracts enough interest, proponents should settle on a single consensus suggestion, and Guido *************** *** 397,401 **** forcing everyone to work at that level, though. "return" means "I'm done" in any kind of function, and that's easy to explain and to use. ! Note that "return" isn't always equivalent to "raise StopIteration" in try/except construct, either (see the "Specification: Return" section). --- 397,401 ---- forcing everyone to work at that level, though. "return" means "I'm done" in any kind of function, and that's easy to explain and to use. ! Note that "return" isn't always equivalent to "raise StopIteration" in try/except construct, either (see the "Specification: Return" section). From esr@users.sourceforge.net Sat Jun 23 15:42:45 2001 From: esr@users.sourceforge.net (Eric S. Raymond) Date: Sat, 23 Jun 2001 07:42:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libcmd.tex,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv620 Modified Files: libcmd.tex Log Message: Correct erroneous description of precmd. Index: libcmd.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcmd.tex,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** libcmd.tex 2001/03/24 19:17:35 1.7 --- libcmd.tex 2001/06/23 14:42:43 1.8 *************** *** 74,78 **** \begin{methoddesc}{precmd}{} ! Hook method executed just before the input prompt is issued. This method is a stub in \class{Cmd}; it exists to be overridden by subclasses. --- 74,79 ---- \begin{methoddesc}{precmd}{} ! Hook method executed just before the command line is interpreted, but ! after the input prompt is generated and issued. This method is a stub in \class{Cmd}; it exists to be overridden by subclasses. *************** *** 143,146 **** \function{raw_input()} to display a prompt and read the next command; if false, \function{sys.stdout.write()} and ! \function{sys.stdin.readline()} are used. \end{memberdesc} --- 144,150 ---- \function{raw_input()} to display a prompt and read the next command; if false, \function{sys.stdout.write()} and ! \function{sys.stdin.readline()} are used. (This means that by ! importing \module{readline}, on systems that support it, the ! interpreter will automatically support Emacs-like line editing ! and command-history keystrokes.) \end{memberdesc} From akuchling@users.sourceforge.net Sat Jun 23 17:23:50 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Sat, 23 Jun 2001 09:23:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib xmldom.tex,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv14503 Modified Files: xmldom.tex Log Message: Fix typo Index: xmldom.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/xmldom.tex,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -r1.13 -r1.14 *** xmldom.tex 2001/04/05 18:30:04 1.13 --- xmldom.tex 2001/06/23 16:23:47 1.14 *************** *** 809,813 **** \end{verbatim} ! yeilds three accessor functions: a ``get'' method for \member{someValue} (\method{_get_someValue()}), and ``get'' and ``set'' methods for --- 809,813 ---- \end{verbatim} ! yields three accessor functions: a ``get'' method for \member{someValue} (\method{_get_someValue()}), and ``get'' and ``set'' methods for From akuchling@users.sourceforge.net Sat Jun 23 17:26:46 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Sat, 23 Jun 2001 09:26:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ref ref2.tex,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory usw-pr-cvs1:/tmp/cvs-serv14778 Modified Files: ref2.tex Log Message: Fix typo Index: ref2.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref2.tex,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -r1.24 -r1.25 *** ref2.tex 2001/06/23 05:26:52 1.24 --- ref2.tex 2001/06/23 16:26:44 1.25 *************** *** 261,265 **** assert elif from lambda return break else global not try ! class except if or yeild continue exec import pass while def finally in print --- 261,265 ---- assert elif from lambda return break else global not try ! class except if or yield continue exec import pass while def finally in print From loewis@users.sourceforge.net Sat Jun 23 17:30:15 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sat, 23 Jun 2001 09:30:15 -0700 Subject: [Python-checkins] CVS: python/dist/src configure.in,1.219,1.220 configure,1.211,1.212 acconfig.h,1.46,1.47 config.h.in,2.94,2.95 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv15057 Modified Files: configure.in configure acconfig.h config.h.in Log Message: Patch #401196: Configuration machinery for IPv6. Contributed by Jun-ichiro "itojun" Hagino. get{addr,name}info emulation code taken from WIDE. Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.219 retrieving revision 1.220 diff -C2 -r1.219 -r1.220 *** configure.in 2001/06/19 15:00:23 1.219 --- configure.in 2001/06/23 16:30:12 1.220 *************** *** 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) *************** *** 1040,1043 **** --- 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 *************** *** 1064,1067 **** --- 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 *************** *** 1108,1111 **** --- 1382,1395 ---- AC_MSG_RESULT($bad_prototypes) 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 Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.211 retrieving revision 1.212 diff -C2 -r1.211 -r1.212 *** configure 2001/06/19 15:44:15 1.211 --- configure 2001/06/23 16:30:12 1.212 *************** *** 27,30 **** --- 27,33 ---- --with-suffix=.exe set executable suffix" ac_help="$ac_help + --enable-ipv6 Enable ipv6 (with ipv4) support + --disable-ipv6 Disable ipv6 support" + ac_help="$ac_help --with-pydebug build with Py_DEBUG defined" ac_help="$ac_help *************** *** 580,584 **** [...4736 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 < *************** *** 6243,6247 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6246: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then --- 6799,6803 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6802: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then Index: acconfig.h =================================================================== RCS file: /cvsroot/python/python/dist/src/acconfig.h,v retrieving revision 1.46 retrieving revision 1.47 diff -C2 -r1.46 -r1.47 *** acconfig.h 2001/03/20 13:09:13 1.46 --- acconfig.h 2001/06/23 16:30:13 1.47 *************** *** 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 Index: config.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/config.h.in,v retrieving revision 2.94 retrieving revision 2.95 diff -C2 -r2.94 -r2.95 *** config.h.in 2001/06/19 15:00:23 2.94 --- config.h.in 2001/06/23 16:30:13 2.95 *************** *** 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 *************** *** 342,345 **** --- 354,360 ---- #undef HAVE_FTRUNCATE + /* Define if you have the getaddrinfo function. */ + #undef HAVE_GETADDRINFO + /* Define if you have the getcwd function. */ #undef HAVE_GETCWD *************** *** 353,356 **** --- 368,374 ---- /* Define if you have the getlogin function. */ #undef HAVE_GETLOGIN + + /* Define if you have the getnameinfo function. */ + #undef HAVE_GETNAMEINFO /* Define if you have the getpeername function. */ From loewis@users.sourceforge.net Sat Jun 23 17:30:15 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sat, 23 Jun 2001 09:30:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules getnameinfo.c,NONE,1.1 getaddrinfo.c,NONE,1.1 addrinfo.h,NONE,1.1 socketmodule.c,1.143,1.144 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv15057/Modules Modified Files: socketmodule.c Added Files: getnameinfo.c getaddrinfo.c addrinfo.h Log Message: Patch #401196: Configuration machinery for IPv6. Contributed by Jun-ichiro "itojun" Hagino. get{addr,name}info emulation code taken from WIDE. --- 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) { snprintf(numserv, sizeof(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: 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: 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 Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.143 retrieving revision 1.144 diff -C2 -r1.143 -r1.144 *** socketmodule.c 2001/05/11 20:12:26 1.143 --- socketmodule.c 2001/06/23 16:30:13 1.144 *************** *** 188,191 **** --- 188,193 ---- #endif + #include "addrinfo.h" + #ifdef USE_SSL #include "openssl/rsa.h" *************** *** 196,199 **** --- 198,209 ---- #include "openssl/err.h" #endif /* USE_SSL */ + + /* 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 #if defined(MS_WINDOWS) || defined(__BEOS__) From loewis@users.sourceforge.net Sat Jun 23 20:55:40 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sat, 23 Jun 2001 12:55:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules parsermodule.c,2.60,2.61 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv10495 Modified Files: parsermodule.c Log Message: Properly use &&. Closes bug #434989. Index: parsermodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/parsermodule.c,v retrieving revision 2.60 retrieving revision 2.61 diff -C2 -r2.60 -r2.61 *** parsermodule.c 2001/01/07 05:59:59 2.60 --- parsermodule.c 2001/06/23 19:55:38 2.61 *************** *** 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; From loewis@users.sourceforge.net Sat Jun 23 20:58:48 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sat, 23 Jun 2001 12:58:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _cursesmodule.c,2.51,2.52 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv11013 Modified Files: _cursesmodule.c Log Message: Properly use &&. Closes bug #434988. Index: _cursesmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_cursesmodule.c,v retrieving revision 2.51 retrieving revision 2.52 diff -C2 -r2.51 -r2.52 *** _cursesmodule.c 2001/04/10 19:53:37 2.51 --- _cursesmodule.c 2001/06/23 19:58:46 2.52 *************** *** 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 { From tim_one@users.sourceforge.net Sat Jun 23 21:27:06 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 23 Jun 2001 13:27:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv16683/python/dist/src/Lib/test Added Files: test_generators.py Log Message: New std test for generators, initially populated with doctests NeilS put together. --- NEW FILE: test_generators.py --- simple_tests = """ Let's try a simple generator: >>> def f(): ... yield 1 ... yield 2 >>> g = f() >>> g.next() 1 >>> g.next() 2 >>> g.next() Traceback (most recent call last): File "", line 1, in ? File "", line 2, in g StopIteration "return" stops the generator: >>> def f(): ... yield 1 ... return ... yield 2 # never reached ... >>> g = f() >>> g.next() 1 >>> g.next() Traceback (most recent call last): File "", line 1, in ? File "", line 3, in f StopIteration >>> g.next() # once stopped, can't be resumed Traceback (most recent call last): File "", line 1, in ? StopIteration "raise StopIteration" stops the generator too: >>> def f(): ... yield 1 ... return ... yield 2 # never reached ... >>> g = f() >>> g.next() 1 >>> g.next() Traceback (most recent call last): File "", line 1, in ? StopIteration >>> g.next() Traceback (most recent call last): File "", line 1, in ? StopIteration However, they are not exactly equivalent: >>> def g1(): ... try: ... return ... except: ... yield 1 ... >>> list(g1()) [] >>> def g2(): ... try: ... raise StopIteration ... except: ... yield 42 >>> print list(g2()) [42] This may be surprising at first: >>> def g3(): ... try: ... return ... finally: ... yield 1 ... >>> list(g3()) [1] Let's create an alternate range() function implemented as a generator: >>> def yrange(n): ... for i in range(n): ... yield i ... >>> list(yrange(5)) [0, 1, 2, 3, 4] Generators always return to the most recent caller: >>> def creator(): ... r = yrange(5) ... print "creator", r.next() ... return r ... >>> def caller(): ... r = creator() ... for i in r: ... print "caller", i ... >>> caller() creator 0 caller 1 caller 2 caller 3 caller 4 Generators can call other generators: >>> def zrange(n): ... for i in yrange(n): ... yield i ... >>> list(zrange(5)) [0, 1, 2, 3, 4] """ __test__ = {"simple": simple_tests} # Magic test name that regrtest.py invokes *after* importing this module. # This worms around a bootstrap problem. # Note that doctest and regrtest both look in sys.argv for a "-v" argument, # so this works as expected in both ways of running regrtest. def test_main(): import doctest, test_generators doctest.testmod(test_generators) # This part isn't needed for regrtest, but for running the test directly. if __name__ == "__main__": test_main() From tim_one@users.sourceforge.net Sat Jun 23 21:45:45 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 23 Jun 2001 13:45:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv19568/python/dist/src/Lib/test Modified Files: test_generators.py Log Message: Add all the examples from PEP 255, and a few email examples. Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** test_generators.py 2001/06/23 20:27:04 1.1 --- test_generators.py 2001/06/23 20:45:43 1.2 *************** *** 1,3 **** ! simple_tests = """ Let's try a simple generator: --- 1,3 ---- ! tutorial_tests = """ Let's try a simple generator: *************** *** 125,129 **** """ ! __test__ = {"simple": simple_tests} # Magic test name that regrtest.py invokes *after* importing this module. --- 125,310 ---- """ ! # The examples from PEP 255. ! ! pep_tests = """ ! ! Specification: Return ! ! Note that return isn't always equivalent to raising StopIteration: the ! difference lies in how enclosing try/except constructs are treated. ! For example, ! ! >>> def f1(): ! ... try: ! ... return ! ... except: ! ... yield 1 ! >>> print list(f1()) ! [] ! ! because, as in any function, return simply exits, but ! ! >>> def f2(): ! ... try: ! ... raise StopIteration ! ... except: ! ... yield 42 ! >>> print list(f2()) ! [42] ! ! because StopIteration is captured by a bare "except", as is any ! exception. ! ! Specification: Generators and Exception Propagation ! ! >>> def f(): ! ... return 1/0 ! >>> def g(): ! ... yield f() # the zero division exception propagates ! ... yield 42 # and we'll never get here ! >>> k = g() ! >>> k.next() ! Traceback (most recent call last): ! File "", line 1, in ? ! File "", line 2, in g ! File "", line 2, in f ! ZeroDivisionError: integer division or modulo by zero ! >>> k.next() # and the generator cannot be resumed ! Traceback (most recent call last): ! File "", line 1, in ? ! StopIteration ! >>> ! ! Specification: Try/Except/Finally ! ! >>> def f(): ! ... try: ! ... yield 1 ! ... try: ! ... yield 2 ! ... 1/0 ! ... yield 3 # never get here ! ... except ZeroDivisionError: ! ... yield 4 ! ... yield 5 ! ... raise ! ... except: ! ... yield 6 ! ... yield 7 # the "raise" above stops this ! ... except: ! ... yield 8 ! ... yield 9 ! ... try: ! ... x = 12 ! ... finally: ! ... yield 10 ! ... yield 11 ! >>> print list(f()) ! [1, 2, 4, 5, 8, 9, 10, 11] ! >>> ! ! ! Guido's binary tree example. ! ! >>> # A binary tree class. ! >>> class Tree: ! ... ! ... def __init__(self, label, left=None, right=None): ! ... self.label = label ! ... self.left = left ! ... self.right = right ! ... ! ... def __repr__(self, level=0, indent=" "): ! ... s = level*indent + `self.label` ! ... if self.left: ! ... s = s + "\\n" + self.left.__repr__(level+1, indent) ! ... if self.right: ! ... s = s + "\\n" + self.right.__repr__(level+1, indent) ! ... return s ! ... ! ... def __iter__(self): ! ... return inorder(self) ! ! >>> # Create a Tree from a list. ! >>> def tree(list): ! ... n = len(list) ! ... if n == 0: ! ... return [] ! ... i = n / 2 ! ... return Tree(list[i], tree(list[:i]), tree(list[i+1:])) ! ! >>> # Show it off: create a tree. ! >>> t = tree("ABCDEFGHIJKLMNOPQRSTUVWXYZ") ! ! >>> # A recursive generator that generates Tree leaves in in-order. ! >>> def inorder(t): ! ... if t: ! ... for x in inorder(t.left): ! ... yield x ! ... yield t.label ! ... for x in inorder(t.right): ! ... yield x ! ! >>> # Show it off: create a tree. ! ... t = tree("ABCDEFGHIJKLMNOPQRSTUVWXYZ") ! ... # Print the nodes of the tree in in-order. ! ... for x in t: ! ... print x, ! A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ! ! >>> # A non-recursive generator. ! >>> def inorder(node): ! ... stack = [] ! ... while node: ! ... while node.left: ! ... stack.append(node) ! ... node = node.left ! ... yield node.label ! ... while not node.right: ! ... try: ! ... node = stack.pop() ! ... except IndexError: ! ... return ! ... yield node.label ! ... node = node.right ! ! >>> # Exercise the non-recursive generator. ! >>> for x in t: ! ... print x, ! A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ! ! """ ! ! # A few examples from Iterator-List and Python-Dev email. ! ! email_tests = """ ! ! The difference between yielding None and returning it. ! ! >>> def g(): ! ... for i in range(3): ! ... yield None ! ... yield None ! ... return ! >>> list(g()) ! [None, None, None, None] ! ! Ensure that explicitly raising StopIteration acts like any other exception ! in try/except, not like a return. ! ! >>> def g(): ! ... yield 1 ! ... try: ! ... raise StopIteration ! ... except: ! ... yield 2 ! ... yield 3 ! >>> list(g()) ! [1, 2, 3] ! """ ! ! __test__ = {"tut": tutorial_tests, ! "pep": pep_tests, ! "zemail": email_tests} # Magic test name that regrtest.py invokes *after* importing this module. From tim_one@users.sourceforge.net Sat Jun 23 22:01:49 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 23 Jun 2001 14:01:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv21480/python/dist/src/Lib/test Modified Files: test_generators.py Log Message: Add a recursive Sieve of Eratosthenes prime generator. Not practical, but it's a heck of a good generator exerciser (think about it ). Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** test_generators.py 2001/06/23 20:45:43 1.2 --- test_generators.py 2001/06/23 21:01:47 1.3 *************** *** 304,310 **** """ __test__ = {"tut": tutorial_tests, "pep": pep_tests, ! "zemail": email_tests} # Magic test name that regrtest.py invokes *after* importing this module. --- 304,348 ---- """ + # Fun tests (for sufficiently warped notions of "fun"). + + fun_tests = """ + + Build up to a recursive Sieve of Eratosthenes generator. + + >>> def firstn(g, n): + ... return [g.next() for i in range(n)] + + >>> def intsfrom(i): + ... while 1: + ... yield i + ... i += 1 + + >>> firstn(intsfrom(5), 7) + [5, 6, 7, 8, 9, 10, 11] + + >>> def exclude_multiples(n, ints): + ... for i in ints: + ... if i % n: + ... yield i + + >>> firstn(exclude_multiples(3, intsfrom(1)), 6) + [1, 2, 4, 5, 7, 8] + + >>> def sieve(ints): + ... prime = ints.next() + ... yield prime + ... not_divisible_by_prime = exclude_multiples(prime, ints) + ... for p in sieve(not_divisible_by_prime): + ... yield p + + >>> primes = sieve(intsfrom(2)) + >>> firstn(primes, 20) + [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71] + """ + __test__ = {"tut": tutorial_tests, "pep": pep_tests, ! "email": email_tests, ! "fun": fun_tests} # Magic test name that regrtest.py invokes *after* importing this module. From tim_one@users.sourceforge.net Sun Jun 24 04:44:54 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 23 Jun 2001 20:44:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv10451/python/dist/src/Lib/test Modified Files: test_generators.py Log Message: More tests. Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** test_generators.py 2001/06/23 21:01:47 1.3 --- test_generators.py 2001/06/24 03:44:52 1.4 *************** *** 6,9 **** --- 6,13 ---- ... yield 2 + >>> for i in f(): + ... print i + 1 + 2 >>> g = f() >>> g.next() *************** *** 204,208 **** >>> - Guido's binary tree example. --- 208,211 ---- *************** *** 302,305 **** --- 305,320 ---- >>> list(g()) [1, 2, 3] + + A generator can't be resumed while it's already running. + + >>> def g(): + ... i = me.next() + ... yield i + >>> me = g() + >>> me.next() + Traceback (most recent call last): + ... + File "", line 2, in g + ValueError: generator already executing """ *************** *** 339,342 **** --- 354,409 ---- >>> firstn(primes, 20) [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71] + + Another famous problem: generate all integers of the form + 2**i * 3**j * 5**k + in increasing order, where i,j,k >= 0. Trickier than it may look at first! + Try writing it without generators, and correctly, and without generating + 3 internal results for each result output. + + >>> def times(n, g): + ... for i in g: + ... yield n * i + >>> firstn(times(10, intsfrom(1)), 10) + [10, 20, 30, 40, 50, 60, 70, 80, 90, 100] + + >>> def merge(g, h): + ... ng = g.next() + ... nh = h.next() + ... while 1: + ... if ng < nh: + ... yield ng + ... ng = g.next() + ... elif ng > nh: + ... yield nh + ... nh = h.next() + ... else: + ... yield ng + ... ng = g.next() + ... nh = h.next() + + This works, but is doing a whale of a lot or redundant work -- it's not + clear how to get the internal uses of m235 to share a single generator. + Note that me_times2 (etc) each need to see every element in the result + sequence. So this is an example where lazy lists are more natural (you + can look at the head of a lazy list any number of times). + + >>> def m235(): + ... yield 1 + ... me_times2 = times(2, m235()) + ... me_times3 = times(3, m235()) + ... me_times5 = times(5, m235()) + ... for i in merge(merge(me_times2, + ... me_times3), + ... me_times5): + ... yield i + + >>> result = m235() + >>> for i in range(5): + ... print firstn(result, 15) + [1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24] + [25, 27, 30, 32, 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80] + [81, 90, 96, 100, 108, 120, 125, 128, 135, 144, 150, 160, 162, 180, 192] + [200, 216, 225, 240, 243, 250, 256, 270, 288, 300, 320, 324, 360, 375, 384] + [400, 405, 432, 450, 480, 486, 500, 512, 540, 576, 600, 625, 640, 648, 675] """ From tim_one@users.sourceforge.net Sun Jun 24 06:08:54 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 23 Jun 2001 22:08:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.144,1.145 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv18880/python/dist/src/Modules Modified Files: socketmodule.c Log Message: Pure brute-force hackery to allow Python to build on Windows again, because I need to make progress and don't have time now to think about whatever it is the new code is trying to accomplish. Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.144 retrieving revision 1.145 diff -C2 -r1.144 -r1.145 *** socketmodule.c 2001/06/23 16:30:13 1.144 --- socketmodule.c 2001/06/24 05:08:52 1.145 *************** *** 188,192 **** --- 188,197 ---- #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 *************** *** 199,202 **** --- 204,212 ---- #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 + /* I know this is a bad practice, but it is the easiest... */ #ifndef HAVE_GETADDRINFO *************** *** 206,209 **** --- 216,221 ---- #include "getnameinfo.c" #endif + + #endif /* ifndef MS_WINDOWS hack */ #if defined(MS_WINDOWS) || defined(__BEOS__) From tim_one@users.sourceforge.net Sun Jun 24 06:47:08 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 23 Jun 2001 22:47:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv21852/python/dist/src/Lib/test Modified Files: test_generators.py Log Message: Another variant of the 2-3-5 test, mixing generators with a LazyList class. Good news: Some of this stuff is pretty sophisticated (read nuts), and I haven't bumped into a bug yet. Bad news: If I run the doctest in an infinite loop, memory is clearly leaking. Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** test_generators.py 2001/06/24 03:44:52 1.4 --- test_generators.py 2001/06/24 05:47:06 1.5 *************** *** 406,410 **** --- 406,447 ---- [200, 216, 225, 240, 243, 250, 256, 270, 288, 300, 320, 324, 360, 375, 384] [400, 405, 432, 450, 480, 486, 500, 512, 540, 576, 600, 625, 640, 648, 675] + + Heh. Here's one way to get a shared list, complete with an excruciating + namespace renaming trick. The *pretty* part is that the times() and merge() + functions can be reused as-is, because they only assume their stream + arguments are iterable -- a LazyList is the same as a generator to times(). + + >>> class LazyList: + ... def __init__(self, g): + ... self.sofar = [] + ... self.fetch = g.next + ... + ... def __getitem__(self, i): + ... sofar, fetch = self.sofar, self.fetch + ... while i >= len(sofar): + ... sofar.append(fetch()) + ... return sofar[i] + + >>> def m235(): + ... yield 1 + ... # Gack: m235 below actually refers to a LazyList. + ... me_times2 = times(2, m235) + ... me_times3 = times(3, m235) + ... me_times5 = times(5, m235) + ... for i in merge(merge(me_times2, + ... me_times3), + ... me_times5): + ... yield i + + >>> m235 = LazyList(m235()) + >>> for i in range(5): + ... print [m235[j] for j in range(15*i, 15*(i+1))] + [1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24] + [25, 27, 30, 32, 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80] + [81, 90, 96, 100, 108, 120, 125, 128, 135, 144, 150, 160, 162, 180, 192] + [200, 216, 225, 240, 243, 250, 256, 270, 288, 300, 320, 324, 360, 375, 384] + [400, 405, 432, 450, 480, 486, 500, 512, 540, 576, 600, 625, 640, 648, 675] """ + __test__ = {"tut": tutorial_tests, From tim_one@users.sourceforge.net Sun Jun 24 07:47:01 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 23 Jun 2001 23:47:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib doctest.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv28580/Lib Modified Files: doctest.py Log Message: doctest doesn't handle intentional SyntaxError exceptions gracefully, because it picks up the first line of traceback.format_exception_only() instead of the last line. Pick up the last line instead! Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -r1.10 -r1.11 *** doctest.py 2001/03/21 23:07:59 1.10 --- doctest.py 2001/06/24 06:46:58 1.11 *************** *** 502,506 **** 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: --- 502,506 ---- want = want.split('\n')[-2] + '\n' exc_type, exc_val, exc_tb = sys.exc_info() ! got = traceback.format_exception_only(exc_type, exc_val)[-1] state = OK else: From tim_one@users.sourceforge.net Sun Jun 24 08:10:05 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 24 Jun 2001 00:10:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv31255/python/dist/src/Lib/test Modified Files: test_generators.py Log Message: New tests to provoke SyntaxErrors unique to generators. Minor fiddling of other tests. Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** test_generators.py 2001/06/24 05:47:06 1.5 --- test_generators.py 2001/06/24 07:10:02 1.6 *************** *** 15,18 **** --- 15,21 ---- >>> g.next() 2 + + "Falling off the end" stops the generator: + >>> g.next() Traceback (most recent call last): *************** *** 21,25 **** StopIteration ! "return" stops the generator: >>> def f(): --- 24,28 ---- StopIteration ! "return" also stops the generator: >>> def f(): *************** *** 425,429 **** >>> def m235(): ... yield 1 ! ... # Gack: m235 below actually refers to a LazyList. ... me_times2 = times(2, m235) ... me_times3 = times(3, m235) --- 428,432 ---- >>> def m235(): ... yield 1 ! ... # Gack: m235 below actually refers to a LazyList. ... me_times2 = times(2, m235) ... me_times3 = times(3, m235) *************** *** 444,452 **** """ ! __test__ = {"tut": tutorial_tests, ! "pep": pep_tests, ! "email": email_tests, ! "fun": fun_tests} # Magic test name that regrtest.py invokes *after* importing this module. --- 447,531 ---- """ + # syntax_tests mostly provokes SyntaxErrors. + + syntax_tests = """ + + >>> def f(): + ... return 22 + ... yield 1 + Traceback (most recent call last): + ... + SyntaxError: 'return' with argument inside generator (, line 2) + + >>> def f(): + ... yield 1 + ... return 22 + Traceback (most recent call last): + ... + SyntaxError: 'return' with argument inside generator (, line 3) + + "return None" is not the same as "return" in a generator: + + >>> def f(): + ... yield 1 + ... return None + Traceback (most recent call last): + ... + SyntaxError: 'return' with argument inside generator (, line 3) + + This one is fine: + + >>> def f(): + ... yield 1 + ... return + + >>> def f(): + ... try: + ... yield 1 + ... finally: + ... pass + Traceback (most recent call last): + ... + SyntaxError: 'yield' not allowed in a 'try' block with a 'finally' clause (, line 3) + + >>> def f(): + ... try: + ... try: + ... 1/0 + ... except ZeroDivisionError: + ... yield 666 # bad because *outer* try has finally + ... except: + ... pass + ... finally: + ... pass + Traceback (most recent call last): + ... + SyntaxError: 'yield' not allowed in a 'try' block with a 'finally' clause (, line 6) + + But this is fine: + + >>> def f(): + ... try: + ... try: + ... yield 12 + ... 1/0 + ... except ZeroDivisionError: + ... yield 666 + ... except: + ... try: + ... x = 12 + ... finally: + ... yield 12 + ... except: + ... return + >>> list(f()) + [12, 666] + """ ! __test__ = {"tut": tutorial_tests, ! "pep": pep_tests, ! "email": email_tests, ! "fun": fun_tests, ! "syntax": syntax_tests} # Magic test name that regrtest.py invokes *after* importing this module. From tim_one@users.sourceforge.net Sun Jun 24 08:13:13 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 24 Jun 2001 00:13:13 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0255.txt,1.12,1.13 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv31656/peps Modified Files: pep-0255.txt Log Message: Record that the CVS tree now has generator tests. Index: pep-0255.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0255.txt,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -r1.12 -r1.13 *** pep-0255.txt 2001/06/23 08:56:42 1.12 --- pep-0255.txt 2001/06/24 07:13:11 1.13 *************** *** 443,449 **** Reference Implementation ! The current implementation, in a preliminary state (no docs and no ! focused tests), is part of Python's CVS development tree[9]. ! Using this requires that you build Python from source. This was derived from an earlier patch by Neil Schemenauer[7]. --- 443,449 ---- Reference Implementation ! The current implementation, in a preliminary state (no docs), is part ! of Python's CVS development tree[9]. Using this requires that you ! build Python from source. This was derived from an earlier patch by Neil Schemenauer[7]. *************** *** 466,469 **** --- 466,471 ---- according to the instructions at http://sf.net/cvs/?group_id=5470 + Note that the std test Lib/test/test_generators.py contains many + examples, including all those in this PEP. From tim_one@users.sourceforge.net Sun Jun 24 11:14:29 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 24 Jun 2001 03:14:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv18557/python/dist/src/Lib/test Modified Files: test_generators.py Log Message: Added a "generate k-combinations of a list" example posted to c.l.py. Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -r1.6 -r1.7 *** test_generators.py 2001/06/24 07:10:02 1.6 --- test_generators.py 2001/06/24 10:14:27 1.7 *************** *** 282,286 **** """ ! # A few examples from Iterator-List and Python-Dev email. email_tests = """ --- 282,286 ---- """ ! # Examples from Iterator-List and Python-Dev and c.l.py. email_tests = """ *************** *** 320,323 **** --- 320,371 ---- File "", line 2, in g ValueError: generator already executing + + Next one was posted to c.l.py. + + >>> def gcomb(x, k): + ... "Generate all combinations of k elements from list x." + ... + ... if k > len(x): + ... return + ... if k == 0: + ... yield [] + ... else: + ... first, rest = x[0], x[1:] + ... # A combination does or doesn't contain first. + ... # If it does, the remainder is a k-1 comb of rest. + ... for c in gcomb(rest, k-1): + ... c.insert(0, first) + ... yield c + ... # If it doesn't contain first, it's a k comb of rest. + ... for c in gcomb(rest, k): + ... yield c + + >>> seq = range(1, 5) + >>> for k in range(len(seq) + 2): + ... print "%d-combs of %s:" % (k, seq) + ... for c in gcomb(seq, k): + ... print " ", c + 0-combs of [1, 2, 3, 4]: + [] + 1-combs of [1, 2, 3, 4]: + [1] + [2] + [3] + [4] + 2-combs of [1, 2, 3, 4]: + [1, 2] + [1, 3] + [1, 4] + [2, 3] + [2, 4] + [3, 4] + 3-combs of [1, 2, 3, 4]: + [1, 2, 3] + [1, 2, 4] + [1, 3, 4] + [2, 3, 4] + 4-combs of [1, 2, 3, 4]: + [1, 2, 3, 4] + 5-combs of [1, 2, 3, 4]: """ From tim_one@users.sourceforge.net Sun Jun 24 19:59:03 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 24 Jun 2001 11:59:03 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib doctest.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv30188/lib Modified Files: doctest.py Log Message: doctest systematically leaked memory when handling an exception in an example (an obvious trackback cycle). Repaired. Bugfix candidate. Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -r1.11 -r1.12 *** doctest.py 2001/06/24 06:46:58 1.11 --- doctest.py 2001/06/24 18:59:01 1.12 *************** *** 501,505 **** # 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)[-1] state = OK --- 501,505 ---- # 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 From tim_one@users.sourceforge.net Sun Jun 24 21:02:49 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 24 Jun 2001 13:02:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib doctest.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv4624/Lib Modified Files: doctest.py Log Message: Clear the copy of the globs dict after running examples. This helps to break cycles, which are a special problem when running generator tests that provoke exceptions by invoking the .next() method of a named generator-iterator: then the iterator is named in globs, and the iterator's frame gets a tracekback object pointing back to globs, and gc doesn't chase these types so the cycle leaks. Also changed _run_examples() to make a copy of globs itself, so its callers (direct and indirect) don't have to (and changed the callers to stop making their own copies); *that* much is a change I've been meaning to make for a long time (it's more robust the new way). Here's a way to provoke the symptom without doctest; it leaks at a prodigious rate; if the last two "source" lines are replaced with g().next() the iterator isn't named and then there's no leak: source = """\ def g(): yield 1/0 k = g() k.next() """ code = compile(source, "", "exec") def f(globs): try: exec code in globs except ZeroDivisionError: pass while 1: f(globals().copy()) After this change, running test_generators in an infinite loop still leaks, but reduced from a flood to a trickle. Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -r1.12 -r1.13 *** doctest.py 2001/06/24 18:59:01 1.12 --- doctest.py 2001/06/24 20:02:47 1.13 *************** *** 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,542 ---- return failures, len(examples) ! # Run list of examples, in a shallow copy of context (dict) globs. ! # Return (#failures, #tries). ! # CAUTION: globs is cleared before returning. This is to help break ! # cycles that may have been created by the examples. def _run_examples(examples, globs, verbose, name): import sys saveout = sys.stdout + globs = globs.copy() try: sys.stdout = fakeout = _SpoofOut() *************** *** 541,544 **** --- 545,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. + 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__" From tim_one@users.sourceforge.net Sun Jun 24 21:24:18 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 24 Jun 2001 13:24:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib doctest.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv10488/Lib Modified Files: doctest.py Log Message: Changed some comments. Removed the caution about clearing globs, since clearing a shallow copy _run_examples() makes itself can't hurt anything. Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -r1.13 -r1.14 *** doctest.py 2001/06/24 20:02:47 1.13 --- doctest.py 2001/06/24 20:24:16 1.14 *************** *** 532,537 **** # Run list of examples, in a shallow copy of context (dict) globs. # Return (#failures, #tries). - # CAUTION: globs is cleared before returning. This is to help break - # cycles that may have been created by the examples. def _run_examples(examples, globs, verbose, name): --- 532,535 ---- *************** *** 550,554 **** # 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. globs.clear() return x --- 548,554 ---- # 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 From loewis@users.sourceforge.net Sun Jun 24 21:59:47 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 24 Jun 2001 13:59:47 -0700 Subject: [Python-checkins] CVS: python/dist/src acconfig.h,1.47,1.48 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv15442 Modified Files: acconfig.h Log Message: Move USE_TOOLBOX_OBJECT_GLUE into acconfig.h. Index: acconfig.h =================================================================== RCS file: /cvsroot/python/python/dist/src/acconfig.h,v retrieving revision 1.47 retrieving revision 1.48 diff -C2 -r1.47 -r1.48 *** acconfig.h 2001/06/23 16:30:13 1.47 --- acconfig.h 2001/06/24 20:59:45 1.48 *************** *** 195,198 **** --- 195,201 ---- #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, From loewis@users.sourceforge.net Sun Jun 24 22:18:28 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 24 Jun 2001 14:18:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.145,1.146 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv18169/Modules Modified Files: socketmodule.c Log Message: Emulate inet_{pton,ntop} on systems that don't provide it. Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.145 retrieving revision 1.146 diff -C2 -r1.145 -r1.146 *** socketmodule.c 2001/06/24 05:08:52 1.145 --- socketmodule.c 2001/06/24 21:18:26 1.146 *************** *** 209,212 **** --- 209,217 ---- #ifndef MS_WINDOWS + #ifndef HAVE_INET_PTON + int inet_pton (int af, const 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 *************** *** 2944,2945 **** --- 2949,2986 ---- #endif } + + /* Simplistic emulation code for inet_pton that only works for IPv4 */ + #ifndef HAVE_INET_PTON + int my_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 * + my_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 From loewis@users.sourceforge.net Sun Jun 24 22:18:28 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 24 Jun 2001 14:18:28 -0700 Subject: [Python-checkins] CVS: python/dist/src configure,1.212,1.213 configure.in,1.220,1.221 config.h.in,2.95,2.96 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv18169 Modified Files: configure configure.in config.h.in Log Message: Emulate inet_{pton,ntop} on systems that don't provide it. Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.212 retrieving revision 1.213 diff -C2 -r1.212 -r1.213 *** configure 2001/06/23 16:30:12 1.212 --- configure 2001/06/24 21:18:25 1.213 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.219 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.220 # Guess values for system-dependent variables and create Makefiles. *************** *** 4481,4485 **** 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 \ --- 4481,4485 ---- 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 \ Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.220 retrieving revision 1.221 diff -C2 -r1.220 -r1.221 *** configure.in 2001/06/23 16:30:12 1.220 --- configure.in 2001/06/24 21:18:25 1.221 *************** *** 1163,1167 **** 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 \ --- 1163,1167 ---- 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 \ Index: config.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/config.h.in,v retrieving revision 2.95 retrieving revision 2.96 diff -C2 -r2.95 -r2.96 *** config.h.in 2001/06/23 16:30:13 2.95 --- config.h.in 2001/06/24 21:18:25 2.96 *************** *** 393,396 **** --- 393,399 ---- #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 From loewis@users.sourceforge.net Sun Jun 24 22:28:44 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 24 Jun 2001 14:28:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.146,1.147 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv19822 Modified Files: socketmodule.c Log Message: Provide a definition for offsetof. Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.146 retrieving revision 1.147 diff -C2 -r1.146 -r1.147 *** socketmodule.c 2001/06/24 21:18:26 1.146 --- socketmodule.c 2001/06/24 21:28:42 1.147 *************** *** 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? */ From loewis@users.sourceforge.net Sun Jun 24 22:35:45 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 24 Jun 2001 14:35:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.147,1.148 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv20657 Modified Files: socketmodule.c Log Message: Fix typos in inet_pton/inet_ntop. Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.147 retrieving revision 1.148 diff -C2 -r1.147 -r1.148 *** socketmodule.c 2001/06/24 21:28:42 1.147 --- socketmodule.c 2001/06/24 21:35:43 1.148 *************** *** 2960,2964 **** /* Simplistic emulation code for inet_pton that only works for IPv4 */ #ifndef HAVE_INET_PTON ! int my_inet_pton (int af, char *src, void *dst) { if(af == AF_INET){ --- 2960,2965 ---- /* 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){ *************** *** 2979,2983 **** char * ! my_inet_ntop(int af, void *src, char *dst, socklen_t size) { if (af == AF_INET) { --- 2980,2984 ---- char * ! inet_ntop(int af, void *src, char *dst, socklen_t size) { if (af == AF_INET) { From tim_one@users.sourceforge.net Mon Jun 25 02:30:14 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 24 Jun 2001 18:30:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv27883/python/dist/src/Lib/test Modified Files: test_generators.py Log Message: Repair indentation in comment. Add a temporary driver to help track down remaining leak(s). Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** test_generators.py 2001/06/24 10:14:27 1.7 --- test_generators.py 2001/06/25 01:30:12 1.8 *************** *** 16,20 **** 2 ! "Falling off the end" stops the generator: >>> g.next() --- 16,20 ---- 2 ! "Falling off the end" stops the generator: >>> g.next() *************** *** 583,587 **** def test_main(): import doctest, test_generators ! doctest.testmod(test_generators) # This part isn't needed for regrtest, but for running the test directly. --- 583,594 ---- def test_main(): import doctest, test_generators ! if 0: ! # Temporary block to help track down leaks. So far, the blame ! # has fallen mostly on doctest. ! for i in range(1000): ! doctest.master = None ! doctest.testmod(test_generators) ! else: ! doctest.testmod(test_generators) # This part isn't needed for regrtest, but for running the test directly. From loewis@users.sourceforge.net Mon Jun 25 07:37:04 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 24 Jun 2001 23:37:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules getnameinfo.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv13523 Modified Files: getnameinfo.c Log Message: Replace snprintf with sprintf. Index: getnameinfo.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/getnameinfo.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** getnameinfo.c 2001/06/23 16:30:13 1.1 --- getnameinfo.c 2001/06/25 06:37:02 1.2 *************** *** 131,135 **** /* what we should do? */ } else if (flags & NI_NUMERICSERV) { ! snprintf(numserv, sizeof(numserv), "%d", ntohs(port)); if (strlen(numserv) > servlen) return ENI_MEMORY; --- 131,135 ---- /* what we should do? */ } else if (flags & NI_NUMERICSERV) { ! sprintf(numserv, "%d", ntohs(port)); if (strlen(numserv) > servlen) return ENI_MEMORY; From loewis@users.sourceforge.net Mon Jun 25 07:38:05 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 24 Jun 2001 23:38:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.148,1.149 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv13856 Modified Files: socketmodule.c Log Message: Remove const-ness in inet_pton declaration. Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.148 retrieving revision 1.149 diff -C2 -r1.148 -r1.149 *** socketmodule.c 2001/06/24 21:35:43 1.148 --- socketmodule.c 2001/06/25 06:38:03 1.149 *************** *** 218,222 **** #ifndef HAVE_INET_PTON ! int inet_pton (int af, const char *src, void *dst); char *inet_ntop(int af, void *src, char *dst, socklen_t size); #endif --- 218,222 ---- #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 From jackjansen@users.sourceforge.net Mon Jun 25 09:48:07 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Mon, 25 Jun 2001 01:48:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Demo/quicktime VerySimplePlayer.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Demo/quicktime In directory usw-pr-cvs1:/tmp/cvs-serv11182/python/Mac/Demo/quicktime Modified Files: VerySimplePlayer.py Log Message: WaitNextEvent short vs. unsigned short fix. Index: VerySimplePlayer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Demo/quicktime/VerySimplePlayer.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** VerySimplePlayer.py 1997/04/09 15:54:54 1.3 --- VerySimplePlayer.py 2001/06/25 08:48:05 1.4 *************** *** 58,62 **** done = 0 while not done: ! gotone, evt = Evt.WaitNextEvent(-1, 0) (what, message, when, where, modifiers) = evt ## print what, message, when, where, modifiers # XXXX --- 58,62 ---- done = 0 while not done: ! gotone, evt = Evt.WaitNextEvent(0xffff, 0) (what, message, when, where, modifiers) = evt ## print what, message, when, where, modifiers # XXXX From fdrake@users.sourceforge.net Mon Jun 25 16:30:15 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 25 Jun 2001 08:30:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libzlib.tex,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv13436/lib Modified Files: libzlib.tex Log Message: Updated link to zlib's home page. Index: libzlib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libzlib.tex,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -r1.24 -r1.25 *** libzlib.tex 2001/04/18 20:16:51 1.24 --- libzlib.tex 2001/06/25 15:30:13 1.25 *************** *** 10,14 **** module allow compression and decompression, using the zlib library. The zlib library has its own home page at ! \url{http://www.info-zip.org/pub/infozip/zlib/}. Version 1.1.3 is the most recent version as of September 2000; use a later version if one is available. There are known incompatibilities between the Python --- 10,14 ---- module allow compression and decompression, using the zlib library. The zlib library has its own home page at ! \url{http://www.gzip.org/zlib/}. Version 1.1.3 is the most recent version as of September 2000; use a later version if one is available. There are known incompatibilities between the Python *************** *** 150,154 **** \begin{seealso} \seemodule{gzip}{Reading and writing \program{gzip}-format files.} ! \seeurl{http://www.info-zip.org/pub/infozip/zlib/}{The ! zlib library home page.} \end{seealso} --- 150,153 ---- \begin{seealso} \seemodule{gzip}{Reading and writing \program{gzip}-format files.} ! \seeurl{http://www.gzip.org/zlib/}{The zlib library home page.} \end{seealso} From fdrake@users.sourceforge.net Mon Jun 25 16:30:36 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 25 Jun 2001 08:30:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libzlib.tex,1.23.4.1,1.23.4.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv13537/lib Modified Files: Tag: release21-maint libzlib.tex Log Message: Updated link to zlib's home page. Index: libzlib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libzlib.tex,v retrieving revision 1.23.4.1 retrieving revision 1.23.4.2 diff -C2 -r1.23.4.1 -r1.23.4.2 *** libzlib.tex 2001/04/18 20:17:23 1.23.4.1 --- libzlib.tex 2001/06/25 15:30:33 1.23.4.2 *************** *** 10,14 **** module allow compression and decompression, using the zlib library. The zlib library has its own home page at ! \url{http://www.info-zip.org/pub/infozip/zlib/}. Version 1.1.3 is the most recent version as of September 2000; use a later version if one is available. There are known incompatibilities between the Python --- 10,14 ---- module allow compression and decompression, using the zlib library. The zlib library has its own home page at ! \url{http://www.gzip.org/zlib/}. Version 1.1.3 is the most recent version as of September 2000; use a later version if one is available. There are known incompatibilities between the Python *************** *** 150,154 **** \begin{seealso} \seemodule{gzip}{Reading and writing \program{gzip}-format files.} ! \seeurl{http://www.info-zip.org/pub/infozip/zlib/}{The ! zlib library home page.} \end{seealso} --- 150,153 ---- \begin{seealso} \seemodule{gzip}{Reading and writing \program{gzip}-format files.} ! \seeurl{http://www.gzip.org/zlib/}{The zlib library home page.} \end{seealso} From jvr@users.sourceforge.net Mon Jun 25 19:01:26 2001 From: jvr@users.sourceforge.net (Just van Rossum) Date: Mon, 25 Jun 2001 11:01:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib bdb.py,1.31,1.32 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv19069 Modified Files: bdb.py Log Message: Return self.trace_dispatch from dispatch_return() to enable stepping through generators. (An alternative would be to create a new "yield" debugger event, but that involves many more changes, and might break Bdb subclasses.) Index: bdb.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bdb.py,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -r1.31 -r1.32 *** bdb.py 2001/04/08 15:05:16 1.31 --- bdb.py 2001/06/25 18:01:24 1.32 *************** *** 75,78 **** --- 75,79 ---- self.user_return(frame, arg) if self.quitting: raise BdbQuit + return self.trace_dispatch def dispatch_exception(self, frame, arg): From tim_one@users.sourceforge.net Mon Jun 25 20:46:27 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 25 Jun 2001 12:46:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libtypes.tex,1.49,1.50 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv12643/python/dist/src/Doc/lib Modified Files: libtypes.tex Log Message: Teach the types module about generators. Thanks to James Althoff on the Iterators list for bringing it up! Index: libtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libtypes.tex,v retrieving revision 1.49 retrieving revision 1.50 diff -C2 -r1.49 -r1.50 *** libtypes.tex 2000/04/06 15:05:04 1.49 --- libtypes.tex 2001/06/25 19:46:25 1.50 *************** *** 84,87 **** --- 84,93 ---- \end{datadesc} + \begin{datadesc}{GeneratorType} + The type of generator-iterator objects, produced by calling a + generator function. + \versionadded{2.2} + \end{datadesc} + \begin{datadesc}{CodeType} The type for code objects such as returned by From tim_one@users.sourceforge.net Mon Jun 25 20:46:27 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 25 Jun 2001 12:46:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv12643/python/dist/src/Lib/test Modified Files: test_generators.py Log Message: Teach the types module about generators. Thanks to James Althoff on the Iterators list for bringing it up! Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** test_generators.py 2001/06/25 01:30:12 1.8 --- test_generators.py 2001/06/25 19:46:25 1.9 *************** *** 368,371 **** --- 368,391 ---- [1, 2, 3, 4] 5-combs of [1, 2, 3, 4]: + + # From the Iterators list, about the types of these things. + + >>> def g(): + ... yield 1 + ... + >>> type(g) + + >>> i = g() + >>> type(i) + + >>> dir(i) + ['next'] + >>> print i.next.__doc__ + next() -- get the next value, or raise StopIteration + >>> iter(i) is i + 1 + >>> import types + >>> isinstance(i, types.GeneratorType) + 1 """ From tim_one@users.sourceforge.net Mon Jun 25 20:46:27 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 25 Jun 2001 12:46:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib types.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv12643/python/dist/src/Lib Modified Files: types.py Log Message: Teach the types module about generators. Thanks to James Althoff on the Iterators list for bringing it up! Index: types.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/types.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -r1.14 -r1.15 *** types.py 2000/03/10 23:18:11 1.14 --- types.py 2001/06/25 19:46:25 1.15 *************** *** 33,36 **** --- 33,41 ---- pass + def g(): + yield 1 + GeneratorType = type(g()) + del g + class _C: def _m(self): pass From tim_one@users.sourceforge.net Tue Jun 26 04:36:30 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 25 Jun 2001 20:36:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python compile.c,2.204,2.205 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv21977/python/dist/src/Python Modified Files: compile.c Log Message: SF bug #436207: "if 0: yield x" is ignored. Not anymore . Pure hack. Doesn't fix any other "if 0:" glitches. Index: compile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v retrieving revision 2.204 retrieving revision 2.205 diff -C2 -r2.204 -r2.205 *** compile.c 2001/06/23 06:19:16 2.204 --- compile.c 2001/06/26 03:36:28 2.205 *************** *** 4841,4844 **** --- 4841,4872 ---- #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. */ + 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: + /* 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) *************** *** 4884,4889 **** 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)); --- 4912,4921 ---- 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)); From tim_one@users.sourceforge.net Tue Jun 26 04:36:30 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 25 Jun 2001 20:36:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv21977/python/dist/src/Lib/test Modified Files: test_generators.py Log Message: SF bug #436207: "if 0: yield x" is ignored. Not anymore . Pure hack. Doesn't fix any other "if 0:" glitches. Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -r1.9 -r1.10 *** test_generators.py 2001/06/25 19:46:25 1.9 --- test_generators.py 2001/06/26 03:36:28 1.10 *************** *** 432,435 **** --- 432,438 ---- 3 internal results for each result output. + XXX Suspect there's memory leaks in this one; definitely in the next + XXX version. + >>> def times(n, g): ... for i in g: *************** *** 483,486 **** --- 486,491 ---- arguments are iterable -- a LazyList is the same as a generator to times(). + XXX Massive memory leaks in this; see Python-Iterators. + >>> class LazyList: ... def __init__(self, g): *************** *** 515,519 **** """ ! # syntax_tests mostly provokes SyntaxErrors. syntax_tests = """ --- 520,525 ---- """ ! # syntax_tests mostly provokes SyntaxErrors. Also fiddling with #if 0 ! # hackery. syntax_tests = """ *************** *** 589,599 **** >>> list(f()) [12, 666] """ ! __test__ = {"tut": tutorial_tests, ! "pep": pep_tests, ! "email": email_tests, ! "fun": fun_tests, ! "syntax": syntax_tests} # Magic test name that regrtest.py invokes *after* importing this module. --- 595,720 ---- >>> list(f()) [12, 666] + + >>> def f(): + ... if 0: + ... yield 1 + >>> type(f()) + + + >>> def f(): + ... if "": + ... yield None + >>> type(f()) + + + >>> def f(): + ... return + ... try: + ... if x==4: + ... pass + ... elif 0: + ... try: + ... 1/0 + ... except SyntaxError: + ... pass + ... else: + ... if 0: + ... while 12: + ... x += 1 + ... yield 2 # don't blink + ... f(a, b, c, d, e) + ... else: + ... pass + ... except: + ... x = 1 + ... return + >>> type(f()) + + + >>> def f(): + ... if 0: + ... def g(): + ... yield 1 + ... + >>> type(f()) + + + >>> def f(): + ... if 0: + ... class C: + ... def __init__(self): + ... yield 1 + ... def f(self): + ... yield 2 + >>> type(f()) + + """ + + + x_tests = """ + + >>> def firstn(g, n): + ... return [g.next() for i in range(n)] + + >>> def times(n, g): + ... for i in g: + ... yield n * i + + >>> def merge(g, h): + ... ng = g.next() + ... nh = h.next() + ... while 1: + ... if ng < nh: + ... yield ng + ... ng = g.next() + ... elif ng > nh: + ... yield nh + ... nh = h.next() + ... else: + ... yield ng + ... ng = g.next() + ... nh = h.next() + + >>> class LazyList: + ... def __init__(self, g): + ... self.sofar = [] + ... self.fetch = g.next + ... + ... def __getitem__(self, i): + ... sofar, fetch = self.sofar, self.fetch + ... while i >= len(sofar): + ... sofar.append(fetch()) + ... return sofar[i] + + >>> def m235(): + ... yield 1 + ... # Gack: m235 below actually refers to a LazyList. + ... me_times2 = times(2, m235) + ... me_times3 = times(3, m235) + ... me_times5 = times(5, m235) + ... for i in merge(merge(me_times2, + ... me_times3), + ... me_times5): + ... yield i + + >>> m235 = LazyList(m235()) + >>> for i in range(5): + ... x = [m235[j] for j in range(15*i, 15*(i+1))] + + + [1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24] + [25, 27, 30, 32, 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80] + [81, 90, 96, 100, 108, 120, 125, 128, 135, 144, 150, 160, 162, 180, 192] + [200, 216, 225, 240, 243, 250, 256, 270, 288, 300, 320, 324, 360, 375, 384] + [400, 405, 432, 450, 480, 486, 500, 512, 540, 576, 600, 625, 640, 648, 675] """ ! __test__ = {"tut": tutorial_tests, # clean ! "pep": pep_tests, # clean ! "email": email_tests, # clean ! "fun": fun_tests, # leaks ! "syntax": syntax_tests # clean ! #"x": x_tests ! } # Magic test name that regrtest.py invokes *after* importing this module. *************** *** 606,610 **** # Temporary block to help track down leaks. So far, the blame # has fallen mostly on doctest. ! for i in range(1000): doctest.master = None doctest.testmod(test_generators) --- 727,731 ---- # Temporary block to help track down leaks. So far, the blame # has fallen mostly on doctest. ! for i in range(5000): doctest.master = None doctest.testmod(test_generators) From jvr@users.sourceforge.net Tue Jun 26 07:54:36 2001 From: jvr@users.sourceforge.net (Just van Rossum) Date: Mon, 25 Jun 2001 23:54:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Python macimport.c,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Python In directory usw-pr-cvs1:/tmp/cvs-serv21311 Modified Files: macimport.c Log Message: Fixed bug that prevented shared libs that are submodules of a package to be loaded from a PYD resource. Index: macimport.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Python/macimport.c,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -r1.10 -r1.11 *** macimport.c 2001/05/22 14:13:02 1.10 --- macimport.c 2001/06/26 06:54:33 1.11 *************** *** 231,235 **** } sprintf(funcname, FUNCNAME_PATTERN, shortname); ! if( !findnamedresource((PyStringObject *)0, shortname, pathname, 'PYD ', fragmentname)) { PyErr_SetString(PyExc_ImportError, "PYD resource not found"); return NULL; --- 231,235 ---- } sprintf(funcname, FUNCNAME_PATTERN, shortname); ! if( !findnamedresource((PyStringObject *)0, name, pathname, 'PYD ', fragmentname)) { PyErr_SetString(PyExc_ImportError, "PYD resource not found"); return NULL; From jvr@users.sourceforge.net Tue Jun 26 07:57:14 2001 From: jvr@users.sourceforge.net (Just van Rossum) Date: Mon, 25 Jun 2001 23:57:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Lib EasyDialogs.py,1.31,1.32 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Lib In directory usw-pr-cvs1:/tmp/cvs-serv21866 Modified Files: EasyDialogs.py Log Message: Fixed typo in doc string. Index: EasyDialogs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Lib/EasyDialogs.py,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -r1.31 -r1.32 *** EasyDialogs.py 2001/02/23 22:18:27 1.31 --- EasyDialogs.py 2001/06/26 06:57:12 1.32 *************** *** 159,163 **** If omitted, this is 0 (No). ! The QUESTION strign ca be at most 255 characters. """ --- 159,163 ---- If omitted, this is 0 (No). ! The QUESTION string can be at most 255 characters. """ From jackjansen@users.sourceforge.net Tue Jun 26 09:07:01 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 26 Jun 2001 01:07:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Distributions readme.txt,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Distributions In directory usw-pr-cvs1:/tmp/cvs-serv4679/python/Mac/Distributions Modified Files: readme.txt Log Message: Added a note about recompiling OSAm before distributing. Index: readme.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/readme.txt,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** readme.txt 2001/04/25 22:11:22 1.4 --- readme.txt 2001/06/26 08:06:59 1.5 *************** *** 15,18 **** --- 15,19 ---- - Update Numeric and build/install it both with Classic and with Carbon python - Run configurepython + - Recompile OSAm and possibly other Contrib stuff - mkdistr binary.include - mkdistr dev.include From effbot@users.sourceforge.net Tue Jun 26 16:11:02 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Tue, 26 Jun 2001 08:11:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _codecsmodule.c,2.7,2.8 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv28944/Modules Modified Files: _codecsmodule.c Log Message: experimental UCS-4 support: don't assume that MS_WIN32 implies HAVE_USABLE_WCHAR_T Index: _codecsmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_codecsmodule.c,v retrieving revision 2.7 retrieving revision 2.8 diff -C2 -r2.7 -r2.8 *** _codecsmodule.c 2001/06/17 18:32:36 2.7 --- _codecsmodule.c 2001/06/26 15:11:00 2.8 *************** *** 300,304 **** } ! #ifdef MS_WIN32 static PyObject * --- 300,304 ---- } ! #if defined(MS_WIN32) && defined(HAVE_USABLE_WCHAR_T) static PyObject * *************** *** 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}, From effbot@users.sourceforge.net Tue Jun 26 16:11:02 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Tue, 26 Jun 2001 08:11:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects unicodeobject.c,2.94,2.95 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv28944/Objects Modified Files: unicodeobject.c Log Message: experimental UCS-4 support: don't assume that MS_WIN32 implies HAVE_USABLE_WCHAR_T Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.94 retrieving revision 2.95 diff -C2 -r2.94 -r2.95 *** unicodeobject.c 2001/06/14 17:52:02 2.94 --- unicodeobject.c 2001/06/26 15:11:00 2.95 *************** *** 1380,1384 **** Py_UNICODE ch = *s++; /* Escape quotes */ ! if (quotes && (ch == q[1] || ch == '\\')) { *p++ = '\\'; *p++ = (char) ch; --- 1380,1384 ---- Py_UNICODE ch = *s++; /* Escape quotes */ ! if (quotes && (ch == (Py_UNICODE) q[1] || ch == '\\')) { *p++ = '\\'; *p++ = (char) ch; *************** *** 1832,1836 **** } ! #ifdef MS_WIN32 /* --- MBCS codecs for Windows -------------------------------------------- */ --- 1832,1836 ---- } ! #if defined(MS_WIN32) && defined(HAVE_USABLE_WCHAR_T) /* --- MBCS codecs for Windows -------------------------------------------- */ From effbot@users.sourceforge.net Tue Jun 26 17:39:38 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Tue, 26 Jun 2001 09:39:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects unicodeobject.c,2.95,2.96 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv21139/Objects Modified Files: unicodeobject.c Log Message: experimental UCS-4 support: made compare a bit more robust, in case sizeof(Py_UNICODE) >= sizeof(long). also changed surrogate expansion to work if sizeof(Py_UNICODE) > 2. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.95 retrieving revision 2.96 diff -C2 -r2.95 -r2.96 *** unicodeobject.c 2001/06/26 15:11:00 2.95 --- unicodeobject.c 2001/06/26 16:39:36 2.96 *************** *** 788,792 **** /* low surrogate = bottom 10 bits added to DC00 */ ! *p++ = (Py_UNICODE)(0xDC00 + (ch & ~0xFC00)); break; --- 788,792 ---- /* low surrogate = bottom 10 bits added to DC00 */ ! *p++ = (Py_UNICODE)(0xDC00 + (ch & 0x03FF)); break; *************** *** 1275,1279 **** chr -= 0x10000L; *p++ = 0xD800 + (Py_UNICODE) (chr >> 10); ! *p++ = 0xDC00 + (Py_UNICODE) (chr & ~0xFC00); } else { if (unicodeescape_decoding_error( --- 1275,1279 ---- chr -= 0x10000L; *p++ = 0xD800 + (Py_UNICODE) (chr >> 10); ! *p++ = 0xDC00 + (Py_UNICODE) (chr & 0x03FF); } else { if (unicodeescape_decoding_error( *************** *** 3261,3277 **** 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--; } --- 3261,3277 ---- 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--; } *************** *** 3294,3302 **** while (len1 > 0 && len2 > 0) { ! register long diff; - diff = (long)*s1++ - (long)*s2++; - if (diff) - return (diff < 0) ? -1 : (diff != 0); len1--; len2--; } --- 3294,3305 ---- while (len1 > 0 && len2 > 0) { ! Py_UNICODE c1, c2; ! ! c1 = *s1++; ! c2 = *s2++; ! ! if (c1 != c2) ! return (c1 < c2) ? -1 : 1; len1--; len2--; } From effbot@users.sourceforge.net Tue Jun 26 18:17:09 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Tue, 26 Jun 2001 10:17:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include unicodeobject.h,2.21,2.22 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv28886/Include Modified Files: unicodeobject.h Log Message: experimental UCS-4 support: added USE_UCS4_STORAGE define to unicodeobject.h, which forces sizeof(Py_UNICODE) == sizeof(Py_UCS4). (this may be good enough for platforms that doesn't have a 16-bit type. the UTF-16 codecs don't work, though) Index: unicodeobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/unicodeobject.h,v retrieving revision 2.21 retrieving revision 2.22 diff -C2 -r2.21 -r2.22 *** unicodeobject.h 2001/05/21 20:30:15 2.21 --- unicodeobject.h 2001/06/26 17:17:07 2.22 *************** *** 59,62 **** --- 59,75 ---- /* --- Internal Unicode Format -------------------------------------------- */ + /* experimental UCS-4 support. enable at your own risk! */ + #undef USE_UCS4_STORAGE + + /* + * Use this typedef when you need to represent a UTF-16 surrogate pair + * as single unsigned integer. + */ + #if SIZEOF_INT >= 4 + typedef unsigned int Py_UCS4; + #elif SIZEOF_LONG >= 4 + typedef unsigned long Py_UCS4; + #endif + /* Set these flags if the platform has "wchar.h", "wctype.h" and the wchar_t type is a 16-bit unsigned type */ *************** *** 67,72 **** #ifndef HAVE_USABLE_WCHAR_T ! /* Windows has a usable wchar_t type */ ! # if defined(MS_WIN32) # define HAVE_USABLE_WCHAR_T # endif --- 80,85 ---- #ifndef HAVE_USABLE_WCHAR_T ! /* Windows has a usable wchar_t type (unless we're using UCS-4) */ ! # if defined(MS_WIN32) && !defined(USE_UCS4_STORAGE) # define HAVE_USABLE_WCHAR_T # endif *************** *** 106,122 **** 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 ! * as single unsigned integer. ! */ ! #if SIZEOF_INT >= 4 ! typedef unsigned int Py_UCS4; ! #elif SIZEOF_LONG >= 4 ! typedef unsigned long Py_UCS4; ! #endif --- 119,129 ---- typedef below, or the module initialization code will complain. */ + #ifdef USE_UCS4_STORAGE + typedef Py_UCS4 Py_UNICODE; + #else typedef unsigned short Py_UNICODE; #endif ! #endif From effbot@users.sourceforge.net Tue Jun 26 18:17:09 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Tue, 26 Jun 2001 10:17:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules sre.h,2.18,2.19 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv28886/Modules Modified Files: sre.h Log Message: experimental UCS-4 support: added USE_UCS4_STORAGE define to unicodeobject.h, which forces sizeof(Py_UNICODE) == sizeof(Py_UCS4). (this may be good enough for platforms that doesn't have a 16-bit type. the UTF-16 codecs don't work, though) Index: sre.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/sre.h,v retrieving revision 2.18 retrieving revision 2.19 diff -C2 -r2.18 -r2.19 *** sre.h 2000/08/03 16:29:50 2.18 --- sre.h 2001/06/26 17:17:07 2.19 *************** *** 15,19 **** --- 15,23 ---- /* size of a code word (must be unsigned short or larger) */ + #ifdef USE_UCS4_STORAGE + #define SRE_CODE unsigned long + #else #define SRE_CODE unsigned short + #endif typedef struct { From effbot@users.sourceforge.net Tue Jun 26 18:17:09 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Tue, 26 Jun 2001 10:17:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects unicodeobject.c,2.96,2.97 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv28886/Objects Modified Files: unicodeobject.c Log Message: experimental UCS-4 support: added USE_UCS4_STORAGE define to unicodeobject.h, which forces sizeof(Py_UNICODE) == sizeof(Py_UCS4). (this may be good enough for platforms that doesn't have a 16-bit type. the UTF-16 codecs don't work, though) Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.96 retrieving revision 2.97 diff -C2 -r2.96 -r2.97 *** unicodeobject.c 2001/06/26 16:39:36 2.96 --- unicodeobject.c 2001/06/26 17:17:07 2.97 *************** *** 5283,5289 **** --- 5283,5291 ---- /* Doublecheck the configuration... */ + #ifndef USE_UCS4_STORAGE if (sizeof(Py_UNICODE) != 2) Py_FatalError("Unicode configuration error: " "sizeof(Py_UNICODE) != 2 bytes"); + #endif /* Init the implementation */ From effbot@users.sourceforge.net Tue Jun 26 18:46:12 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Tue, 26 Jun 2001 10:46:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.209,2.210 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv3520/Python Modified Files: bltinmodule.c Log Message: experimental UCS-4 support: don't assume that MS_WIN32 implies HAVE_USABLE_WCHAR_T Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.209 retrieving revision 2.210 diff -C2 -r2.209 -r2.210 *** bltinmodule.c 2001/05/28 22:30:08 2.209 --- bltinmodule.c 2001/06/26 17:46:10 2.210 *************** *** 17,21 **** Can remain NULL for all platforms that don't have such a concept */ ! #ifdef MS_WIN32 const char *Py_FileSystemDefaultEncoding = "mbcs"; #else --- 17,21 ---- 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 From gvanrossum@users.sourceforge.net Tue Jun 26 18:57:13 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 26 Jun 2001 10:57:13 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0260.txt,NONE,1.1 pep-0000.txt,1.99,1.100 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv6344 Modified Files: pep-0000.txt Added Files: pep-0260.txt Log Message: PEP 260: simplify xrange() --- NEW FILE: pep-0260.txt --- PEP: 260 Title: Simplify xrange() Version: $Revision: 1.1 $ Author: guido@python.org (Guido van Rossum) Status: Draft Type: Standards Track Python-Version: 2.2 Created: 26-Jun-2001 Post-History: 26-Jun-2001 Abstract This PEP proposes to strip the xrange() object from some rarely used behavior like x[i:j] and x*n. Problem The xrange() function has one idiomatic use: for i in xrange(...): ... However, the xrange() object has a bunch of rarely used behaviors that attempt to make it more sequence-like. These are so rarely used that historically they have has serious bugs (e.g. off-by-one errors) that went undetected for several releases. I claim that it's better to drop these unused features. This will simplify the implementation, testing, and documentation, and reduce maintenance and code size. Proposed Solution I propose to strip the xrange() object to the bare minimum. The only retained sequence behaviors are x[i], len(x), and repr(x). In particular, these behaviors will be dropped: x[i:j] (slicing) x*n, n*x (sequence-repeat) cmp(x1, x2) (comparisons) i in x (containment test) x.tolist() method 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. Risks Somebody's code could be relying on the extended code, and this code would break. However, given that historically bugs in the extended code have gone undetected for so long, it's unlikely that much code is affected. 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.99 retrieving revision 1.100 diff -C2 -r1.99 -r1.100 *** pep-0000.txt 2001/06/22 15:37:01 1.99 --- pep-0000.txt 2001/06/26 17:57:11 1.100 *************** *** 61,64 **** --- 61,65 ---- S 257 pep-0257.txt Docstring Conventions Goodger, van Rossum S 258 pep-0258.txt DPS Generic Implementation Details Goodger + S 260 pep-0260.txt Simplify xrange() van Rossum Py-in-the-sky PEPs (not ready; may become active yet) *************** *** 187,190 **** --- 188,192 ---- S 258 pep-0258.txt DPS Generic Implementation Details Goodger SR 259 pep-0259.txt Omit printing newline after newline van Rossum + S 260 pep-0260.txt Simplify xrange() van Rossum From effbot@users.sourceforge.net Tue Jun 26 21:01:58 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Tue, 26 Jun 2001 13:01:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.210,2.211 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv30924/python Modified Files: bltinmodule.c Log Message: more unicode tweaks: make unichr(0xdddddddd) behave like u"\Udddddddd" wrt surrogates. (this extends the valid range from 65535 to 1114111) Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.210 retrieving revision 2.211 diff -C2 -r2.210 -r2.211 *** bltinmodule.c 2001/06/26 17:46:10 2.210 --- bltinmodule.c 2001/06/26 20:01:56 2.211 *************** *** 309,323 **** { 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); } --- 309,334 ---- { 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(0x10ffff)"); return NULL; + } + + if (x <= 0xffff) { + /* UCS-2 character */ + s[0] = (Py_UNICODE) x; + return PyUnicode_FromUnicode(s, 1); + } else { + /* 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); } } *************** *** 325,329 **** "unichr(i) -> Unicode character\n\ \n\ ! Return a Unicode string of one character with ordinal i; 0 <= i < 65536."; --- 336,340 ---- "unichr(i) -> Unicode character\n\ \n\ ! Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff."; From bwarsaw@users.sourceforge.net Tue Jun 26 21:08:34 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 26 Jun 2001 13:08:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.105,2.106 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv32745 Modified Files: dictobject.c Log Message: dict_update(): Generalize this method so {}.update() accepts any "mapping" object, specifically one that supports PyMapping_Keys() and PyObject_GetItem(). This allows you to say e.g. {}.update(UserDict()) We keep the special case for concrete dict objects, although that seems moderately questionable. OTOH, the code exists and works, so why change that? .update()'s docstring already claims that D.update(E) implies calling E.keys() so it's appropriate not to transform AttributeErrors in PyMapping_Keys() to TypeErrors. Patch eyeballed by Tim. Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.105 retrieving revision 2.106 diff -C2 -r2.105 -r2.106 *** dictobject.c 2001/06/16 07:52:53 2.105 --- dictobject.c 2001/06/26 20:08:32 2.106 *************** *** 1048,1071 **** dictobject *other; dictentry *entry; ! if (!PyArg_Parse(args, "O!", &PyDict_Type, &other)) return NULL; ! if (other == mp || other->ma_used == 0) ! goto done; /* a.update(a) or a.update({}); nothing to do */ ! /* Do one big resize at the start, rather than incrementally ! resizing as we insert new items. Expect that there will be ! no (or few) overlapping keys. */ ! if ((mp->ma_fill + other->ma_used)*3 >= (mp->ma_mask+1)*2) { ! if (dictresize(mp, (mp->ma_used + other->ma_used)*3/2) != 0) ! return NULL; } ! for (i = 0; i <= other->ma_mask; i++) { ! entry = &other->ma_table[i]; ! if (entry->me_value != NULL) { ! Py_INCREF(entry->me_key); ! Py_INCREF(entry->me_value); ! insertdict(mp, entry->me_key, entry->me_hash, ! entry->me_value); } } done: Py_INCREF(Py_None); --- 1048,1124 ---- dictobject *other; dictentry *entry; ! PyObject *param; ! /* We accept for the argument either a concrete dictionary object, ! * or an abstract "mapping" object. For the former, we can do ! * things quite efficiently. For the latter, we only require that ! * PyMapping_Keys() and PyObject_GetItem() be supported. ! */ ! if (!PyArg_ParseTuple(args, "O:update", ¶m)) return NULL; ! ! if (PyDict_Check(param)) { ! other = (dictobject*)param; ! if (other == mp || other->ma_used == 0) ! /* a.update(a) or a.update({}); nothing to do */ ! goto done; ! /* Do one big resize at the start, rather than ! * incrementally resizing as we insert new items. Expect ! * that there will be no (or few) overlapping keys. ! */ ! if ((mp->ma_fill + other->ma_used)*3 >= (mp->ma_mask+1)*2) { ! if (dictresize(mp, (mp->ma_used + other->ma_used)*3/2) != 0) ! return NULL; ! } ! for (i = 0; i <= other->ma_mask; i++) { ! entry = &other->ma_table[i]; ! if (entry->me_value != NULL) { ! Py_INCREF(entry->me_key); ! Py_INCREF(entry->me_value); ! insertdict(mp, entry->me_key, entry->me_hash, ! entry->me_value); ! } ! } } ! else { ! /* Do it the generic, slower way */ ! PyObject *keys = PyMapping_Keys(param); ! PyObject *iter; ! PyObject *key, *value; ! int status; ! ! if (keys == NULL) ! /* Docstring says this is equivalent to E.keys() so ! * if E doesn't have a .keys() method we want ! * AttributeError to percolate up. Might as well ! * do the same for any other error. ! */ ! return NULL; ! ! iter = PyObject_GetIter(keys); ! Py_DECREF(keys); ! if (iter == NULL) ! return NULL; ! ! for (key = PyIter_Next(iter); key; key = PyIter_Next(iter)) { ! value = PyObject_GetItem(param, key); ! if (value == NULL) { ! Py_DECREF(iter); ! Py_DECREF(key); ! return NULL; ! } ! status = PyDict_SetItem((PyObject*)mp, key, value); ! Py_DECREF(key); ! Py_DECREF(value); ! if (status < 0) { ! Py_DECREF(iter); ! return NULL; ! } } + Py_DECREF(iter); + if (PyErr_Occurred()) + /* Iterator completed, via error */ + return NULL; } + done: Py_INCREF(Py_None); *************** *** 1627,1631 **** {"values", (PyCFunction)dict_values, METH_OLDARGS, values__doc__}, ! {"update", (PyCFunction)dict_update, METH_OLDARGS, update__doc__}, {"clear", (PyCFunction)dict_clear, METH_OLDARGS, --- 1680,1684 ---- {"values", (PyCFunction)dict_values, METH_OLDARGS, values__doc__}, ! {"update", (PyCFunction)dict_update, METH_VARARGS, update__doc__}, {"clear", (PyCFunction)dict_clear, METH_OLDARGS, From bwarsaw@users.sourceforge.net Tue Jun 26 21:09:30 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 26 Jun 2001 13:09:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_types.py,1.20,1.21 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv475 Modified Files: test_types.py Log Message: Add a bunch of tests for extended dict.update() where the argument is a non-dictionary mapping object. Include tests for several expected failure modes. Index: test_types.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_types.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -r1.20 -r1.21 *** test_types.py 2001/04/20 16:50:40 1.20 --- test_types.py 2001/06/26 20:09:28 1.21 *************** *** 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' From bwarsaw@users.sourceforge.net Tue Jun 26 21:12:52 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 26 Jun 2001 13:12:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.186,1.187 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv1024 Modified Files: NEWS Log Message: Add an item about the extension to {}.update() to allow generic mapping objects as an argument. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.186 retrieving revision 1.187 diff -C2 -r1.186 -r1.187 *** NEWS 2001/06/21 02:49:55 1.186 --- NEWS 2001/06/26 20:12:50 1.187 *************** *** 91,94 **** --- 91,99 ---- the same as dict.has_key(x). + - The update() method of dictionaries now accepts generic mapping + objects. Specifically the argument object must support the .keys() + and __getitem__() methods. This allows you to say, for example, + {}.update(UserDict()) + - Iterators were added; this is a generalized way of providing values to a for loop. See PEP 234. There's a new built-in function iter() From gvanrossum@users.sourceforge.net Tue Jun 26 21:17:00 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 26 Jun 2001 13:17:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include object.h,2.79.2.17,2.79.2.18 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv550/Include Modified Files: Tag: descr-branch object.h Log Message: Rename tp_introduced to tp_defined. It turns out I misread the definitions: an "introduced" method doesn't override a base class method; a "defined" method may or may not override a base class. And an "inherited" method is defined in a base class and not overridden; a "supported" method is defined or inherited. Maybe this diagram helps: | defined here | not defined here ----------------------------+--------------+----------------- defined in a base class | overridden | inherited ----------------------------+--------------+----------------- not defined in a base class | introduced | not supported Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.79.2.17 retrieving revision 2.79.2.18 diff -C2 -r2.79.2.17 -r2.79.2.18 *** object.h 2001/06/19 12:26:46 2.79.2.17 --- object.h 2001/06/26 20:16:57 2.79.2.18 *************** *** 276,280 **** PyObject *tp_bases; PyObject *tp_mro; /* method resolution order */ ! PyObject *tp_introduced; #ifdef COUNT_ALLOCS --- 276,280 ---- PyObject *tp_bases; PyObject *tp_mro; /* method resolution order */ ! PyObject *tp_defined; #ifdef COUNT_ALLOCS From gvanrossum@users.sourceforge.net Tue Jun 26 21:17:00 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 26 Jun 2001 13:17:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.47,2.16.8.48 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv550/Objects Modified Files: Tag: descr-branch typeobject.c Log Message: Rename tp_introduced to tp_defined. It turns out I misread the definitions: an "introduced" method doesn't override a base class method; a "defined" method may or may not override a base class. And an "inherited" method is defined in a base class and not overridden; a "supported" method is defined or inherited. Maybe this diagram helps: | defined here | not defined here ----------------------------+--------------+----------------- defined in a base class | overridden | inherited ----------------------------+--------------+----------------- not defined in a base class | introduced | not supported Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.47 retrieving revision 2.16.8.48 diff -C2 -r2.16.8.47 -r2.16.8.48 *** typeobject.c 2001/06/19 14:14:00 2.16.8.47 --- typeobject.c 2001/06/26 20:16:58 2.16.8.48 *************** *** 40,50 **** static PyObject * ! type_introduced(PyTypeObject *type, void *context) { ! if (type->tp_introduced == NULL) { Py_INCREF(Py_None); return Py_None; } ! return PyDictProxy_New(type->tp_introduced); } --- 40,50 ---- static PyObject * ! type_defined(PyTypeObject *type, void *context) { ! if (type->tp_defined == NULL) { Py_INCREF(Py_None); return Py_None; } ! return PyDictProxy_New(type->tp_defined); } *************** *** 52,56 **** {"__module__", (getter)type_module, NULL, NULL}, {"__dict__", (getter)type_dict, NULL, NULL}, ! {"__introduced__", (getter)type_introduced, NULL, NULL}, {0} }; --- 52,56 ---- {"__module__", (getter)type_module, NULL, NULL}, {"__dict__", (getter)type_dict, NULL, NULL}, ! {"__defined__", (getter)type_defined, NULL, NULL}, {0} }; *************** *** 482,487 **** type->tp_base = base; ! /* Initialize tp_introduced from passed-in dict */ ! type->tp_introduced = dict = PyDict_Copy(dict); if (dict == NULL) { Py_DECREF(type); --- 482,487 ---- type->tp_base = base; ! /* Initialize tp_defined from passed-in dict */ ! type->tp_defined = dict = PyDict_Copy(dict); if (dict == NULL) { Py_DECREF(type); *************** *** 559,563 **** Py_XDECREF(type->tp_bases); Py_XDECREF(type->tp_mro); ! Py_XDECREF(type->tp_introduced); /* XXX more? */ Py_XDECREF(et->name); --- 559,563 ---- Py_XDECREF(type->tp_bases); Py_XDECREF(type->tp_mro); ! Py_XDECREF(type->tp_defined); /* XXX more? */ Py_XDECREF(et->name); *************** *** 687,691 **** add_methods(PyTypeObject *type, PyMethodDef *meth) { ! PyObject *dict = type->tp_introduced; for (; meth->ml_name != NULL; meth++) { --- 687,691 ---- add_methods(PyTypeObject *type, PyMethodDef *meth) { ! PyObject *dict = type->tp_defined; for (; meth->ml_name != NULL; meth++) { *************** *** 706,710 **** add_wrappers(PyTypeObject *type, struct wrapperbase *base, void *wrapped) { ! PyObject *dict = type->tp_introduced; for (; base->name != NULL; base++) { --- 706,710 ---- add_wrappers(PyTypeObject *type, struct wrapperbase *base, void *wrapped) { ! PyObject *dict = type->tp_defined; for (; base->name != NULL; base++) { *************** *** 725,729 **** add_members(PyTypeObject *type, struct memberlist *memb) { ! PyObject *dict = type->tp_introduced; for (; memb->name != NULL; memb++) { --- 725,729 ---- add_members(PyTypeObject *type, struct memberlist *memb) { ! PyObject *dict = type->tp_defined; for (; memb->name != NULL; memb++) { *************** *** 744,748 **** add_getset(PyTypeObject *type, struct getsetlist *gsp) { ! PyObject *dict = type->tp_introduced; for (; gsp->name != NULL; gsp++) { --- 744,748 ---- add_getset(PyTypeObject *type, struct getsetlist *gsp) { ! PyObject *dict = type->tp_defined; for (; gsp->name != NULL; gsp++) { *************** *** 969,982 **** } ! /* Initialize tp_introduced */ ! dict = type->tp_introduced; if (dict == NULL) { dict = PyDict_New(); if (dict == NULL) return -1; ! type->tp_introduced = dict; } ! /* Add type-specific descriptors to tp_introduced */ if (add_operators(type) < 0) return -1; --- 969,982 ---- } ! /* Initialize tp_defined */ ! dict = type->tp_defined; if (dict == NULL) { dict = PyDict_New(); if (dict == NULL) return -1; ! type->tp_defined = dict; } ! /* Add type-specific descriptors to tp_defined */ if (add_operators(type) < 0) return -1; *************** *** 994,998 **** } ! /* Initialize tp_dict from tp_introduced */ type->tp_dict = PyDict_Copy(dict); if (type->tp_dict == NULL) --- 994,998 ---- } ! /* Initialize tp_dict from tp_defined */ type->tp_dict = PyDict_Copy(dict); if (type->tp_dict == NULL) *************** *** 1023,1027 **** base = (PyTypeObject *)PyTuple_GET_ITEM(bases, i); assert(PyType_Check(base)); ! x = base->tp_introduced; if (x != NULL) { x = PyObject_CallMethod(type->tp_dict, "update","O",x); --- 1023,1027 ---- base = (PyTypeObject *)PyTuple_GET_ITEM(bases, i); assert(PyType_Check(base)); ! x = base->tp_defined; if (x != NULL) { x = PyObject_CallMethod(type->tp_dict, "update","O",x); From bwarsaw@users.sourceforge.net Tue Jun 26 21:33:01 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 26 Jun 2001 13:33:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libstdtypes.tex,1.60,1.61 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv6442 Modified Files: libstdtypes.tex Log Message: Remove the restriction on a mapping's .update() method. Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.60 retrieving revision 1.61 diff -C2 -r1.60 -r1.61 *** libstdtypes.tex 2001/06/12 03:31:56 1.60 --- libstdtypes.tex 2001/06/26 20:32:59 1.61 *************** *** 934,950 **** \lineiii{\var{a}.update(\var{b})} {\code{for k in \var{b}.keys(): \var{a}[k] = \var{b}[k]}} ! {(4)} \lineiii{\var{a}.values()}{a copy of \var{a}'s list of values}{(3)} \lineiii{\var{a}.get(\var{k}\optional{, \var{x}})} {\code{\var{a}[\var{k}]} if \code{\var{k} in \var{a}}, else \var{x}} ! {(5)} \lineiii{\var{a}.setdefault(\var{k}\optional{, \var{x}})} {\code{\var{a}[\var{k}]} if \code{\var{k} in \var{a}}, else \var{x} (also setting it)} ! {(6)} \lineiii{\var{a}.popitem()} {remove and return an arbitrary (\var{key}, \var{value}) pair} ! {(7)} \lineiii{\var{a}.iteritems()} {return an iterator over (\var{key}, \var{value}) pairs} --- 934,950 ---- \lineiii{\var{a}.update(\var{b})} {\code{for k in \var{b}.keys(): \var{a}[k] = \var{b}[k]}} ! {} \lineiii{\var{a}.values()}{a copy of \var{a}'s list of values}{(3)} \lineiii{\var{a}.get(\var{k}\optional{, \var{x}})} {\code{\var{a}[\var{k}]} if \code{\var{k} in \var{a}}, else \var{x}} ! {(4)} \lineiii{\var{a}.setdefault(\var{k}\optional{, \var{x}})} {\code{\var{a}[\var{k}]} if \code{\var{k} in \var{a}}, else \var{x} (also setting it)} ! {(5)} \lineiii{\var{a}.popitem()} {remove and return an arbitrary (\var{key}, \var{value}) pair} ! {(6)} \lineiii{\var{a}.iteritems()} {return an iterator over (\var{key}, \var{value}) pairs} *************** *** 972,987 **** \var{key})} pairs using \function{zip()}: \samp{pairs = zip(\var{a}.values(), \var{a}.keys())}. - - \item[(4)] \var{b} must be of the same type as \var{a}. ! \item[(5)] Never raises an exception if \var{k} is not in the map, instead it returns \var{x}. \var{x} is optional; when \var{x} is not provided and \var{k} is not in the map, \code{None} is returned. ! \item[(6)] \function{setdefault()} is like \function{get()}, except that if \var{k} is missing, \var{x} is both returned and inserted into the dictionary as the value of \var{k}. ! \item[(7)] \function{popitem()} is useful to destructively iterate over a dictionary, as often used in set algorithms. \end{description} --- 972,985 ---- \var{key})} pairs using \function{zip()}: \samp{pairs = zip(\var{a}.values(), \var{a}.keys())}. ! \item[(4)] Never raises an exception if \var{k} is not in the map, instead it returns \var{x}. \var{x} is optional; when \var{x} is not provided and \var{k} is not in the map, \code{None} is returned. ! \item[(5)] \function{setdefault()} is like \function{get()}, except that if \var{k} is missing, \var{x} is both returned and inserted into the dictionary as the value of \var{k}. ! \item[(6)] \function{popitem()} is useful to destructively iterate over a dictionary, as often used in set algorithms. \end{description} From effbot@users.sourceforge.net Tue Jun 26 21:36:15 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Tue, 26 Jun 2001 13:36:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects unicodectype.c,2.7,2.8 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv7096/Objects Modified Files: unicodectype.c Log Message: more unicode tweaks: fix unicodectype for sizeof(Py_UNICODE) > sizeof(int) Index: unicodectype.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodectype.c,v retrieving revision 2.7 retrieving revision 2.8 diff -C2 -r2.7 -r2.8 *** unicodectype.c 2000/09/25 21:48:13 2.7 --- unicodectype.c 2001/06/26 20:36:12 2.8 *************** *** 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< Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv12198/python/dist/src/Python Modified Files: ceval.c Log Message: Add "gi_" (generator-iterator) prefix to names of genobject members. Makes it much easier to find references via dumb editor search (former "frame" in particular was near-hopeless). Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.256 retrieving revision 2.257 diff -C2 -r2.256 -r2.257 *** ceval.c 2001/06/23 06:19:16 2.256 --- ceval.c 2001/06/26 20:58:58 2.257 *************** *** 112,117 **** typedef struct { PyObject_HEAD ! PyFrameObject *frame; ! int running; /* true if generator is being executed */ } genobject; --- 112,121 ---- typedef struct { PyObject_HEAD ! /* The gi_ prefix is intended to remind of generator-iterator. */ ! ! PyFrameObject *gi_frame; ! ! /* True if generator is being executed. */ ! int gi_running; } genobject; *************** *** 124,129 **** return NULL; } ! gen->frame = f; ! gen->running = 0; return (PyObject *)gen; } --- 128,133 ---- return NULL; } ! gen->gi_frame = f; ! gen->gi_running = 0; return (PyObject *)gen; } *************** *** 132,136 **** gen_dealloc(genobject *gen) { ! Py_DECREF(gen->frame); PyObject_DEL(gen); } --- 136,140 ---- gen_dealloc(genobject *gen) { ! Py_DECREF(gen->gi_frame); PyObject_DEL(gen); } *************** *** 140,147 **** { PyThreadState *tstate = PyThreadState_GET(); ! PyFrameObject *f = gen->frame; PyObject *result; ! if (gen->running) { PyErr_SetString(PyExc_ValueError, "generator already executing"); --- 144,151 ---- { PyThreadState *tstate = PyThreadState_GET(); ! PyFrameObject *f = gen->gi_frame; PyObject *result; ! if (gen->gi_running) { PyErr_SetString(PyExc_ValueError, "generator already executing"); *************** *** 157,163 **** f->f_back = tstate->frame; ! gen->running = 1; result = eval_frame(f); ! gen->running = 0; /* Don't keep the reference to f_back any longer than necessary. It --- 161,167 ---- f->f_back = tstate->frame; ! gen->gi_running = 1; result = eval_frame(f); ! gen->gi_running = 0; /* Don't keep the reference to f_back any longer than necessary. It From jackjansen@users.sourceforge.net Tue Jun 26 22:49:15 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 26 Jun 2001 14:49:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/cf - New directory Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/cf In directory usw-pr-cvs1:/tmp/cvs-serv24243/cf Log Message: Directory /cvsroot/python/python/dist/src/Mac/Modules/cf added to the repository From jackjansen@users.sourceforge.net Tue Jun 26 22:51:12 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 26 Jun 2001 14:51:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/cf CFmodule.c,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/cf In directory usw-pr-cvs1:/tmp/cvs-serv24696/Python/Mac/Modules/cf Added Files: CFmodule.c Log Message: First small step towards bgen-generated CoreFoundation. there is hardly any real functionality yet, but method chains seem to work, and so do Retain/Release semantics. --- NEW FILE: CFmodule.c --- /* =========================== Module CF ============================ */ #include "Python.h" #include "macglue.h" #include "pymactoolbox.h" #ifdef WITHOUT_FRAMEWORKS #include #else #include #endif /* For now we declare them forward here. They'll go to mactoolbox later */ extern PyObject *CFTypeRefObj_New(CFTypeRef); extern int CFTypeRefObj_Convert(PyObject *, CFTypeRef *); extern PyObject *CFStringRefObj_New(CFStringRef); extern int CFStringRefObj_Convert(PyObject *, CFStringRef *); #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 static PyObject *CF_Error; /* --------------------- Object type CFTypeRef ---------------------- */ PyTypeObject CFTypeRef_Type; #define CFTypeRefObj_Check(x) ((x)->ob_type == &CFTypeRef_Type) typedef struct CFTypeRefObject { PyObject_HEAD CFTypeRef ob_itself; void (*ob_freeit)(CFTypeRef ptr); } CFTypeRefObject; PyObject *CFTypeRefObj_New(CFTypeRef itself) { CFTypeRefObject *it; if (itself == NULL) return PyMac_Error(resNotFound); CFRetain(itself); it = PyObject_NEW(CFTypeRefObject, &CFTypeRef_Type); if (it == NULL) return NULL; it->ob_itself = itself; it->ob_freeit = CFRelease; return (PyObject *)it; } CFTypeRefObj_Convert(PyObject *v, CFTypeRef *p_itself) { if (v == Py_None) { *p_itself = NULL; return 1; } /* Check for other CF objects here */ if (!CFTypeRefObj_Check(v)) { PyErr_SetString(PyExc_TypeError, "CFTypeRef required"); return 0; } *p_itself = ((CFTypeRefObject *)v)->ob_itself; return 1; } static void CFTypeRefObj_dealloc(CFTypeRefObject *self) { if (self->ob_freeit && self->ob_itself) { self->ob_freeit((CFTypeRef)self->ob_itself); } PyMem_DEL(self); } static PyObject *CFTypeRefObj_CFGetTypeID(CFTypeRefObject *_self, PyObject *_args) { PyObject *_res = NULL; CFTypeID _rv; if (!PyArg_ParseTuple(_args, "")) return NULL; _rv = CFGetTypeID(_self->ob_itself); _res = Py_BuildValue("l", _rv); return _res; } static PyObject *CFTypeRefObj_CFRetain(CFTypeRefObject *_self, PyObject *_args) { PyObject *_res = NULL; CFTypeRef _rv; if (!PyArg_ParseTuple(_args, "")) return NULL; _rv = CFRetain(_self->ob_itself); _res = Py_BuildValue("O&", CFTypeRefObj_New, _rv); return _res; } static PyObject *CFTypeRefObj_CFRelease(CFTypeRefObject *_self, PyObject *_args) { PyObject *_res = NULL; if (!PyArg_ParseTuple(_args, "")) return NULL; CFRelease(_self->ob_itself); Py_INCREF(Py_None); _res = Py_None; return _res; } static PyObject *CFTypeRefObj_CFGetRetainCount(CFTypeRefObject *_self, PyObject *_args) { PyObject *_res = NULL; CFIndex _rv; if (!PyArg_ParseTuple(_args, "")) return NULL; _rv = CFGetRetainCount(_self->ob_itself); _res = Py_BuildValue("l", _rv); return _res; } static PyObject *CFTypeRefObj_CFEqual(CFTypeRefObject *_self, PyObject *_args) { PyObject *_res = NULL; Boolean _rv; CFTypeRef cf2; if (!PyArg_ParseTuple(_args, "O&", CFTypeRefObj_Convert, &cf2)) return NULL; _rv = CFEqual(_self->ob_itself, cf2); _res = Py_BuildValue("l", _rv); return _res; } static PyObject *CFTypeRefObj_CFHash(CFTypeRefObject *_self, PyObject *_args) { PyObject *_res = NULL; CFHashCode _rv; if (!PyArg_ParseTuple(_args, "")) return NULL; _rv = CFHash(_self->ob_itself); _res = Py_BuildValue("l", _rv); return _res; } static PyObject *CFTypeRefObj_CFCopyDescription(CFTypeRefObject *_self, PyObject *_args) { PyObject *_res = NULL; CFStringRef _rv; if (!PyArg_ParseTuple(_args, "")) return NULL; _rv = CFCopyDescription(_self->ob_itself); _res = Py_BuildValue("O&", CFStringRefObj_New, _rv); return _res; } static PyMethodDef CFTypeRefObj_methods[] = { {"CFGetTypeID", (PyCFunction)CFTypeRefObj_CFGetTypeID, 1, "() -> (CFTypeID _rv)"}, {"CFRetain", (PyCFunction)CFTypeRefObj_CFRetain, 1, "() -> (CFTypeRef _rv)"}, {"CFRelease", (PyCFunction)CFTypeRefObj_CFRelease, 1, "() -> None"}, {"CFGetRetainCount", (PyCFunction)CFTypeRefObj_CFGetRetainCount, 1, "() -> (CFIndex _rv)"}, {"CFEqual", (PyCFunction)CFTypeRefObj_CFEqual, 1, "(CFTypeRef cf2) -> (Boolean _rv)"}, {"CFHash", (PyCFunction)CFTypeRefObj_CFHash, 1, "() -> (CFHashCode _rv)"}, {"CFCopyDescription", (PyCFunction)CFTypeRefObj_CFCopyDescription, 1, "() -> (CFStringRef _rv)"}, {NULL, NULL, 0} }; PyMethodChain CFTypeRefObj_chain = { CFTypeRefObj_methods, NULL }; static PyObject *CFTypeRefObj_getattr(CFTypeRefObject *self, char *name) { return Py_FindMethodInChain(&CFTypeRefObj_chain, (PyObject *)self, name); } #define CFTypeRefObj_setattr NULL static int CFTypeRefObj_compare(CFTypeRefObject *self, CFTypeRefObject *other) { /* XXXX Or should we use CFEqual?? */ if ( self->ob_itself > other->ob_itself ) return 1; if ( self->ob_itself < other->ob_itself ) return -1; return 0; } static PyObject * CFTypeRefObj_repr(CFTypeRefObject *self) { char buf[100]; sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself); return PyString_FromString(buf); } static int CFTypeRefObj_hash(CFTypeRefObject *self) { /* XXXX Or should we use CFHash?? */ return (int)self->ob_itself; } PyTypeObject CFTypeRef_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, /*ob_size*/ "CFTypeRef", /*tp_name*/ sizeof(CFTypeRefObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ (destructor) CFTypeRefObj_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ (getattrfunc) CFTypeRefObj_getattr, /*tp_getattr*/ (setattrfunc) CFTypeRefObj_setattr, /*tp_setattr*/ (cmpfunc) CFTypeRefObj_compare, /*tp_compare*/ (reprfunc) CFTypeRefObj_repr, /*tp_repr*/ (PyNumberMethods *)0, /* tp_as_number */ (PySequenceMethods *)0, /* tp_as_sequence */ (PyMappingMethods *)0, /* tp_as_mapping */ (hashfunc) CFTypeRefObj_hash, /*tp_hash*/ }; /* ------------------- End object type CFTypeRef -------------------- */ /* -------------------- Object type CFStringRef --------------------- */ PyTypeObject CFStringRef_Type; #define CFStringRefObj_Check(x) ((x)->ob_type == &CFStringRef_Type) typedef struct CFStringRefObject { PyObject_HEAD CFStringRef ob_itself; void (*ob_freeit)(CFTypeRef ptr); } CFStringRefObject; PyObject *CFStringRefObj_New(CFStringRef itself) { CFStringRefObject *it; if (itself == NULL) return PyMac_Error(resNotFound); CFRetain(itself); it = PyObject_NEW(CFStringRefObject, &CFStringRef_Type); if (it == NULL) return NULL; it->ob_itself = itself; it->ob_freeit = CFRelease; return (PyObject *)it; } CFStringRefObj_Convert(PyObject *v, CFStringRef *p_itself) { if (v == Py_None) { *p_itself = NULL; return 1; } /* Check for other CF objects here */ if (!CFStringRefObj_Check(v)) { PyErr_SetString(PyExc_TypeError, "CFStringRef required"); return 0; } *p_itself = ((CFStringRefObject *)v)->ob_itself; return 1; } static void CFStringRefObj_dealloc(CFStringRefObject *self) { if (self->ob_freeit && self->ob_itself) { self->ob_freeit((CFTypeRef)self->ob_itself); } PyMem_DEL(self); } static PyMethodDef CFStringRefObj_methods[] = { {NULL, NULL, 0} }; PyMethodChain CFStringRefObj_chain = { CFStringRefObj_methods, NULL }; static PyObject *CFStringRefObj_getattr(CFStringRefObject *self, char *name) { return Py_FindMethodInChain(&CFStringRefObj_chain, (PyObject *)self, name); } #define CFStringRefObj_setattr NULL static int CFStringRefObj_compare(CFStringRefObject *self, CFStringRefObject *other) { /* XXXX Or should we use CFEqual?? */ if ( self->ob_itself > other->ob_itself ) return 1; if ( self->ob_itself < other->ob_itself ) return -1; return 0; } static PyObject * CFStringRefObj_repr(CFStringRefObject *self) { char buf[100]; sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself); return PyString_FromString(buf); } static int CFStringRefObj_hash(CFStringRefObject *self) { /* XXXX Or should we use CFHash?? */ return (int)self->ob_itself; } PyTypeObject CFStringRef_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, /*ob_size*/ "CFStringRef", /*tp_name*/ sizeof(CFStringRefObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ (destructor) CFStringRefObj_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ (getattrfunc) CFStringRefObj_getattr, /*tp_getattr*/ (setattrfunc) CFStringRefObj_setattr, /*tp_setattr*/ (cmpfunc) CFStringRefObj_compare, /*tp_compare*/ (reprfunc) CFStringRefObj_repr, /*tp_repr*/ (PyNumberMethods *)0, /* tp_as_number */ (PySequenceMethods *)0, /* tp_as_sequence */ (PyMappingMethods *)0, /* tp_as_mapping */ (hashfunc) CFStringRefObj_hash, /*tp_hash*/ }; /* ------------------ End object type CFStringRef ------------------- */ static PyObject *CF_CFAllocatorGetTypeID(PyObject *_self, PyObject *_args) { PyObject *_res = NULL; CFTypeID _rv; if (!PyArg_ParseTuple(_args, "")) return NULL; _rv = CFAllocatorGetTypeID(); _res = Py_BuildValue("l", _rv); return _res; } static PyObject *CF_CFAllocatorGetPreferredSizeForSize(PyObject *_self, PyObject *_args) { PyObject *_res = NULL; CFIndex _rv; CFIndex size; CFOptionFlags hint; if (!PyArg_ParseTuple(_args, "ll", &size, &hint)) return NULL; _rv = CFAllocatorGetPreferredSizeForSize((CFAllocatorRef)NULL, size, hint); _res = Py_BuildValue("l", _rv); return _res; } static PyObject *CF_CFCopyTypeIDDescription(PyObject *_self, PyObject *_args) { PyObject *_res = NULL; CFStringRef _rv; CFTypeID theType; if (!PyArg_ParseTuple(_args, "l", &theType)) return NULL; _rv = CFCopyTypeIDDescription(theType); _res = Py_BuildValue("O&", CFStringRefObj_New, _rv); return _res; } static PyMethodDef CF_methods[] = { {"CFAllocatorGetTypeID", (PyCFunction)CF_CFAllocatorGetTypeID, 1, "() -> (CFTypeID _rv)"}, {"CFAllocatorGetPreferredSizeForSize", (PyCFunction)CF_CFAllocatorGetPreferredSizeForSize, 1, "(CFIndex size, CFOptionFlags hint) -> (CFIndex _rv)"}, {"CFCopyTypeIDDescription", (PyCFunction)CF_CFCopyTypeIDDescription, 1, "(CFTypeID theType) -> (CFStringRef _rv)"}, {NULL, NULL, 0} }; void initCF(void) { PyObject *m; PyObject *d; // PyMac_INIT_TOOLBOX_OBJECT_NEW(Track, TrackObj_New); // PyMac_INIT_TOOLBOX_OBJECT_CONVERT(Track, TrackObj_Convert); m = Py_InitModule("CF", CF_methods); d = PyModule_GetDict(m); CF_Error = PyMac_GetOSErrException(); if (CF_Error == NULL || PyDict_SetItemString(d, "Error", CF_Error) != 0) return; CFTypeRef_Type.ob_type = &PyType_Type; Py_INCREF(&CFTypeRef_Type); if (PyDict_SetItemString(d, "CFTypeRefType", (PyObject *)&CFTypeRef_Type) != 0) Py_FatalError("can't initialize CFTypeRefType"); CFStringRef_Type.ob_type = &PyType_Type; Py_INCREF(&CFStringRef_Type); if (PyDict_SetItemString(d, "CFStringRefType", (PyObject *)&CFStringRef_Type) != 0) Py_FatalError("can't initialize CFStringRefType"); } /* ========================= End module CF ========================== */ From jackjansen@users.sourceforge.net Tue Jun 26 22:51:16 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 26 Jun 2001 14:51:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/cf cfscan.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/cf In directory usw-pr-cvs1:/tmp/cvs-serv24722/Python/Mac/Modules/cf Added Files: cfscan.py Log Message: First small step towards bgen-generated CoreFoundation. there is hardly any real functionality yet, but method chains seem to work, and so do Retain/Release semantics. --- NEW FILE: cfscan.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 = "CoreFoundation" SHORT = "cf" OBJECTS = ("CFTypeRef", "CFStringRef") def main(): input = [ "CFBase.h", ### "CFArray.h", ## "CFBag.h", ## "CFBundle.h", ## "CFCharacterSet.h", ### "CFData.h", ## "CFDate.h", ### "CFDictionary.h", ## "CFNumber.h", ## "CFPlugIn.h", ## "CFPreferences.h", ## "CFPropertyList.h", ## "CFSet.h", ### "CFString.h", ## "CFStringEncodingExt.h", ## "CFTimeZone.h", ## "CFURL.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 [ # Memory allocator functions "CFAllocatorGetDefault", "CFAllocatorSetDefault", "CFAllocatorAllocate", "CFAllocatorReallocate", "CFAllocatorDeallocate", "CFGetAllocator", ] def makegreylist(self): return [] def makeblacklisttypes(self): return [ "CFAllocatorContext", ] def makerepairinstructions(self): return [ ] if __name__ == "__main__": main() From jackjansen@users.sourceforge.net Tue Jun 26 22:51:20 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 26 Jun 2001 14:51:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/cf cfsupport.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/cf In directory usw-pr-cvs1:/tmp/cvs-serv24741/Python/Mac/Modules/cf Added Files: cfsupport.py Log Message: First small step towards bgen-generated CoreFoundation. there is hardly any real functionality yet, but method chains seem to work, and so do Retain/Release semantics. --- NEW FILE: cfsupport.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 = 'CF' # 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 */ extern PyObject *CFTypeRefObj_New(CFTypeRef); extern int CFTypeRefObj_Convert(PyObject *, CFTypeRef *); extern PyObject *CFStringRefObj_New(CFStringRef); extern int CFStringRefObj_Convert(PyObject *, CFStringRef *); #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 """ initstuff = initstuff + """ // PyMac_INIT_TOOLBOX_OBJECT_NEW(Track, TrackObj_New); // PyMac_INIT_TOOLBOX_OBJECT_CONVERT(Track, TrackObj_Convert); """ Boolean = Type("Boolean", "l") CFTypeID = Type("CFTypeID", "l") # XXXX a guess, seems better than OSTypeType. CFHashCode = Type("CFHashCode", "l") CFIndex = Type("CFIndex", "l") CFOptionFlags = Type("CFOptionFlags", "l") ## CFStringRef = XXXX CFAllocatorRef = FakeType("(CFAllocatorRef)NULL") # The real objects CFTypeRef = OpaqueByValueType("CFTypeRef", "CFTypeRefObj") CFStringRef = OpaqueByValueType("CFStringRef", "CFStringRefObj") # Our (opaque) objects class MyGlobalObjectDefinition(GlobalObjectDefinition): def outputCheckNewArg(self): Output("if (itself == NULL) return PyMac_Error(resNotFound);") Output("CFRetain(itself);") def outputStructMembers(self): GlobalObjectDefinition.outputStructMembers(self) Output("void (*ob_freeit)(CFTypeRef ptr);") def outputInitStructMembers(self): GlobalObjectDefinition.outputInitStructMembers(self) ## Output("it->ob_freeit = NULL;") Output("it->ob_freeit = CFRelease;") def outputCheckConvertArg(self): Out(""" if (v == Py_None) { *p_itself = NULL; return 1; } /* Check for other CF objects here */ """) def outputCleanupStructMembers(self): Output("if (self->ob_freeit && self->ob_itself)") OutLbrace() Output("self->ob_freeit((CFTypeRef)self->ob_itself);") OutRbrace() def outputCompare(self): Output() Output("static int %s_compare(%s *self, %s *other)", self.prefix, self.objecttype, self.objecttype) OutLbrace() Output("/* XXXX Or should we use CFEqual?? */") Output("if ( self->ob_itself > other->ob_itself ) return 1;") Output("if ( self->ob_itself < other->ob_itself ) return -1;") Output("return 0;") OutRbrace() def outputHash(self): Output() Output("static int %s_hash(%s *self)", self.prefix, self.objecttype) OutLbrace() Output("/* XXXX Or should we use CFHash?? */") Output("return (int)self->ob_itself;") OutRbrace() def outputRepr(self): Output() Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype) OutLbrace() Output("char buf[100];") Output("""sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() class CFTypeRefObjectDefinition(MyGlobalObjectDefinition): pass class CFStringRefObjectDefinition(MyGlobalObjectDefinition): basechain = "&CFTypeRefObj_chain" def outputRepr(self): Output() Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype) OutLbrace() Output("char buf[100];") Output("""sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() # From here on it's basically all boiler plate... # Create the generator groups and link them module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff) CFTypeRef_object = CFTypeRefObjectDefinition('CFTypeRef', 'CFTypeRefObj', 'CFTypeRef') CFStringRef_object = CFTypeRefObjectDefinition('CFStringRef', 'CFStringRefObj', 'CFStringRef') module.addobject(CFTypeRef_object) module.addobject(CFStringRef_object) # Create the generator classes used to populate the lists Function = OSErrFunctionGenerator Method = OSErrMethodGenerator # Create and populate the lists functions = [] CFTypeRef_methods = [] CFStringRef_methods = [] 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 CFTypeRef_methods: CFTypeRef_object.add(f) for f in CFStringRef_methods: CFStringRef_object.add(f) # generate output (open the output file as late as possible) SetOutputFileName(OUTPUTFILE) module.generate() From jackjansen@users.sourceforge.net Tue Jun 26 22:52:05 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 26 Jun 2001 14:52:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/scripts fullbuild.py,1.65,1.66 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory usw-pr-cvs1:/tmp/cvs-serv24869/Python/Mac/scripts Modified Files: fullbuild.py Log Message: Added CF module build and project generation (carbon only). Index: fullbuild.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/fullbuild.py,v retrieving revision 1.65 retrieving revision 1.66 diff -C2 -r1.65 -r1.66 *** fullbuild.py 2001/03/20 23:30:06 1.65 --- fullbuild.py 2001/06/26 21:52:03 1.66 *************** *** 288,291 **** --- 288,293 ---- (":Mac:Build:Sndihooks.carbon.mcp", "Sndihooks.carbon"), (":Mac:Build:TE.carbon.mcp", "TE.carbon"), + + (":Mac:Build:CF.carbon.mcp", "CF.carbon"), ]), From jackjansen@users.sourceforge.net Tue Jun 26 22:52:10 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 26 Jun 2001 14:52:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/scripts genpluginprojects.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory usw-pr-cvs1:/tmp/cvs-serv24896/Python/Mac/scripts Modified Files: genpluginprojects.py Log Message: Added CF module build and project generation (carbon only). Index: genpluginprojects.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/genpluginprojects.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -r1.12 -r1.13 *** genpluginprojects.py 2001/05/17 22:12:55 1.12 --- genpluginprojects.py 2001/06/26 21:52:08 1.13 *************** *** 146,149 **** --- 146,152 ---- genpluginproject("carbon", "TE") + # OSX Only? + genpluginproject("carbon", "CF") + # Other Mac modules genpluginproject("all", "calldll", sources=["calldll.c"]) From jackjansen@users.sourceforge.net Tue Jun 26 22:53:27 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 26 Jun 2001 14:53:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/bgen/bgen scantools.py,1.20,1.21 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/bgen/bgen In directory usw-pr-cvs1:/tmp/cvs-serv25079/Python/Tools/bgen/bgen Modified Files: scantools.py Log Message: Added a Parser_OSX class that can parse new-style (C-only) headers, such as the Core Foundation ones. Index: scantools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/scantools.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -r1.20 -r1.21 *** scantools.py 2001/02/27 11:04:20 1.20 --- scantools.py 2001/06/26 21:53:25 1.21 *************** *** 234,241 **** def initpatterns(self): - # self.head_pat = "^extern pascal[ \t]+" # XXX Mac specific! self.head_pat = "^EXTERN_API[^_]" self.tail_pat = "[;={}]" - # self.type_pat = "pascal[ \t\n]+\([a-zA-Z0-9_ \t]*[a-zA-Z0-9_]\)[ \t\n]+" self.type_pat = "EXTERN_API" + \ "[ \t\n]*([ \t\n]*" + \ --- 234,239 ---- *************** *** 245,250 **** 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'\"(][^\t\n,;}]*\),?" self.sym_pat = "^[ \t]*\([a-zA-Z0-9_]+\)[ \t]*=" + \ "[ \t]*\([-0-9_a-zA-Z'\"(][^\t\n,;}]*\),?" --- 243,246 ---- *************** *** 586,589 **** --- 582,604 ---- "[ \t]*\([-0-9'\"][^\t\n,;}]*\),?" self.asplit_pat = "^\(.*[^a-zA-Z0-9_]\)\([a-zA-Z0-9_]+\)$" + + class Scanner_OSX(Scanner): + """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 = "\(.*\)/\*.*\*/\(.*\)" From loewis@users.sourceforge.net Tue Jun 26 23:22:39 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Tue, 26 Jun 2001 15:22:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.211,2.212 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv31084/Python Modified Files: bltinmodule.c Log Message: Support using UCS-4 as the Py_UNICODE type: Add configure option --enable-unicode. Add config.h macros Py_USING_UNICODE, PY_UNICODE_TYPE, Py_UNICODE_SIZE, SIZEOF_WCHAR_T. Define Py_UCS2. Encode and decode large UTF-8 characters into single Py_UNICODE values for wide Unicode types; likewise for UTF-16. Remove test whether sizeof Py_UNICODE is two. Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.211 retrieving revision 2.212 diff -C2 -r2.211 -r2.212 *** bltinmodule.c 2001/06/26 20:01:56 2.211 --- bltinmodule.c 2001/06/26 22:22:37 2.212 *************** *** 325,328 **** --- 325,329 ---- return PyUnicode_FromUnicode(s, 1); } else { + #if Py_UNICODE_SIZE == 2 /* UCS-4 character. store as two surrogate characters */ x -= 0x10000L; *************** *** 330,334 **** --- 331,338 ---- s[1] = 0xDC00 + (Py_UNICODE) (x & 0x03FF); return PyUnicode_FromUnicode(s, 2); + #endif } + s[0] = (Py_UNICODE)x; + return PyUnicode_FromUnicode(s, 1); } From loewis@users.sourceforge.net Tue Jun 26 23:22:39 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Tue, 26 Jun 2001 15:22:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include unicodeobject.h,2.22,2.23 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv31084/Include Modified Files: unicodeobject.h Log Message: Support using UCS-4 as the Py_UNICODE type: Add configure option --enable-unicode. Add config.h macros Py_USING_UNICODE, PY_UNICODE_TYPE, Py_UNICODE_SIZE, SIZEOF_WCHAR_T. Define Py_UCS2. Encode and decode large UTF-8 characters into single Py_UNICODE values for wide Unicode types; likewise for UTF-16. Remove test whether sizeof Py_UNICODE is two. Index: unicodeobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/unicodeobject.h,v retrieving revision 2.22 retrieving revision 2.23 diff -C2 -r2.22 -r2.23 *** unicodeobject.h 2001/06/26 17:17:07 2.22 --- unicodeobject.h 2001/06/26 22:22:37 2.23 *************** *** 61,74 **** /* experimental UCS-4 support. enable at your own risk! */ #undef USE_UCS4_STORAGE ! ! /* ! * Use this typedef when you need to represent a UTF-16 surrogate pair ! * as single unsigned integer. ! */ ! #if SIZEOF_INT >= 4 ! typedef unsigned int Py_UCS4; ! #elif SIZEOF_LONG >= 4 ! typedef unsigned long Py_UCS4; ! #endif /* Set these flags if the platform has "wchar.h", "wctype.h" and the --- 61,67 ---- /* experimental UCS-4 support. enable at your own risk! */ #undef USE_UCS4_STORAGE ! #if Py_UNICODE_SIZE == 4 ! #define USE_UCS4_STORAGE ! #endif /* Set these flags if the platform has "wchar.h", "wctype.h" and the *************** *** 78,86 **** /* Defaults for various platforms */ ! #ifndef HAVE_USABLE_WCHAR_T /* Windows has a usable wchar_t type (unless we're using UCS-4) */ # if defined(MS_WIN32) && !defined(USE_UCS4_STORAGE) # define HAVE_USABLE_WCHAR_T # endif --- 71,84 ---- /* 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) && !defined(USE_UCS4_STORAGE) # define HAVE_USABLE_WCHAR_T + # define PY_UNICODE_TYPE wchar_t + # endif + + # if defined(USE_UCS4_STORAGE) + # define PY_UNICODE_TYPE Py_UCS4 # endif *************** *** 104,130 **** # include "wchar.h" #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. */ ! ! #ifdef USE_UCS4_STORAGE ! typedef Py_UCS4 Py_UNICODE; ! #else ! typedef unsigned short Py_UNICODE; #endif ! #endif /* --- Internal Unicode Operations ---------------------------------------- */ --- 102,123 ---- # include "wchar.h" #endif ! /* ! * Use this typedef when you need to represent a UTF-16 surrogate pair ! * as single unsigned integer. ! */ ! #if SIZEOF_INT >= 4 ! typedef unsigned int Py_UCS4; ! #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 ---------------------------------------- */ From loewis@users.sourceforge.net Tue Jun 26 23:22:39 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Tue, 26 Jun 2001 15:22:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects unicodeobject.c,2.97,2.98 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv31084/Objects Modified Files: unicodeobject.c Log Message: Support using UCS-4 as the Py_UNICODE type: Add configure option --enable-unicode. Add config.h macros Py_USING_UNICODE, PY_UNICODE_TYPE, Py_UNICODE_SIZE, SIZEOF_WCHAR_T. Define Py_UCS2. Encode and decode large UTF-8 characters into single Py_UNICODE values for wide Unicode types; likewise for UTF-16. Remove test whether sizeof Py_UNICODE is two. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.97 retrieving revision 2.98 diff -C2 -r2.97 -r2.98 *** unicodeobject.c 2001/06/26 17:17:07 2.97 --- unicodeobject.c 2001/06/26 22:22:37 2.98 *************** *** 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: */ --- 772,786 ---- ((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; } + #if Py_UNICODE_SIZE == 4 + *p++ = (Py_UNICODE)ch; + #else /* compute and append the two surrogates: */ *************** *** 789,792 **** --- 793,797 ---- /* 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) { --- 884,894 ---- cbWritten += 2; } ! else if (ch < 0x10000) { ! #if Py_UNICODE_SIZE == 4 ! *p++ = 0xe0 | (ch>>12); ! *p++ = 0x80 | ((ch>>6) & 0x3f); ! *p++ = 0x80 | (ch & 0x3f); ! cbWritten += 3; ! #else /* Check for high surrogate */ if (0xD800 <= ch && ch <= 0xDBFF) { *************** *** 910,914 **** *p++ = (char)(0x80 | ((ch >> 6) & 0x3f)); *p++ = (char)(0x80 | (ch & 0x3f)); ! } } *p = '\0'; --- 921,932 ---- *p++ = (char)(0x80 | ((ch >> 6) & 0x3f)); *p++ = (char)(0x80 | (ch & 0x3f)); ! #endif ! } 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, --- 954,958 ---- 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; --- 992,1001 ---- 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,1001 **** /* Unpack UTF-16 encoded data */ p = unicode->str; ! q = (Py_UNICODE *)s; ! e = q + (size / sizeof(Py_UNICODE)); if (byteorder) --- 1014,1019 ---- /* Unpack UTF-16 encoded data */ p = unicode->str; ! q = (Py_UCS2 *)s; ! e = q + (size / sizeof(Py_UCS2)); if (byteorder) *************** *** 1027,1031 **** while (q < e) { ! register Py_UNICODE ch = *q++; /* Swap input bytes if needed. (This assumes --- 1045,1049 ---- while (q < e) { ! register Py_UCS2 ch = *q++; /* Swap input bytes if needed. (This assumes *************** *** 1049,1054 **** } 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 --- 1067,1080 ---- } if (0xDC00 <= *q && *q <= 0xDFFF) { ! Py_UCS2 ch2 = *q++; ! #ifdef BYTEORDER_IS_LITTLE_ENDIAN ! if (bo == 1) ! ch = (ch >> 8) | (ch << 8); ! #else ! if (bo == -1) ! ch = (ch >> 8) | (ch << 8); ! #endif ! if (0xD800 <= ch && ch <= 0xDBFF) { ! #if Py_UNICODE_SIZE == 2 /* This is valid data (a UTF-16 surrogate pair), but we are not able to store this information since our *************** *** 1057,1063 **** errmsg = "code pairs are not supported"; goto utf16Error; ! } ! else continue; } errmsg = "illegal encoding"; --- 1083,1097 ---- 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"; *************** *** 1091,1105 **** { 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; --- 1125,1142 ---- { 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; *************** *** 1113,1122 **** #endif ) ! Py_UNICODE_COPY(p, s, size); ! else ! while (size-- > 0) { ! Py_UNICODE ch = *s++; *p++ = (ch >> 8) | (ch << 8); } return v; } --- 1150,1171 ---- #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; } *************** *** 1272,1279 **** *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 & 0x03FF); } else { if (unicodeescape_decoding_error( --- 1321,1332 ---- *p++ = (Py_UNICODE) chr; else if (chr <= 0x10ffff) { ! /* UCS-4 character. Either store directly, or as surrogate pair. */ ! #if Py_UNICODE_SIZE == 4 ! *p++ = chr; ! #else chr -= 0x10000L; *p++ = 0xD800 + (Py_UNICODE) (chr >> 10); *p++ = 0xDC00 + (Py_UNICODE) (chr & 0x03FF); + #endif } else { if (unicodeescape_decoding_error( *************** *** 1384,1387 **** --- 1437,1453 ---- *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) { *************** *** 5281,5291 **** { int i; - - /* Doublecheck the configuration... */ - #ifndef USE_UCS4_STORAGE - if (sizeof(Py_UNICODE) != 2) - Py_FatalError("Unicode configuration error: " - "sizeof(Py_UNICODE) != 2 bytes"); - #endif /* Init the implementation */ --- 5347,5350 ---- From loewis@users.sourceforge.net Tue Jun 26 23:22:39 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Tue, 26 Jun 2001 15:22:39 -0700 Subject: [Python-checkins] CVS: python/dist/src acconfig.h,1.48,1.49 config.h.in,2.96,2.97 configure,1.213,1.214 configure.in,1.221,1.222 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv31084 Modified Files: acconfig.h config.h.in configure configure.in Log Message: Support using UCS-4 as the Py_UNICODE type: Add configure option --enable-unicode. Add config.h macros Py_USING_UNICODE, PY_UNICODE_TYPE, Py_UNICODE_SIZE, SIZEOF_WCHAR_T. Define Py_UCS2. Encode and decode large UTF-8 characters into single Py_UNICODE values for wide Unicode types; likewise for UTF-16. Remove test whether sizeof Py_UNICODE is two. Index: acconfig.h =================================================================== RCS file: /cvsroot/python/python/dist/src/acconfig.h,v retrieving revision 1.48 retrieving revision 1.49 diff -C2 -r1.48 -r1.49 *** acconfig.h 2001/06/24 20:59:45 1.48 --- acconfig.h 2001/06/26 22:22:36 1.49 *************** *** 105,108 **** --- 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 Index: config.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/config.h.in,v retrieving revision 2.96 retrieving revision 2.97 diff -C2 -r2.96 -r2.97 *** config.h.in 2001/06/24 21:18:25 2.96 --- config.h.in 2001/06/26 22:22:36 2.97 *************** *** 164,167 **** --- 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 *************** *** 284,287 **** --- 293,299 ---- /* The number of bytes in a void *. */ #undef SIZEOF_VOID_P + + /* The number of bytes in a wchar_t. */ + #undef SIZEOF_WCHAR_T /* Define if you have the _getpty function. */ Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.213 retrieving revision 1.214 diff -C2 -r1.213 -r1.214 *** configure 2001/06/24 21:18:25 1.213 --- configure 2001/06/26 22:22:36 1.214 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.220 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.221 [...4643 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 < *************** *** 6799,6803 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6802: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then --- 6881,6885 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6884: 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.221 retrieving revision 1.222 diff -C2 -r1.221 -r1.222 *** configure.in 2001/06/24 21:18:25 1.221 --- configure.in 2001/06/26 22:22:36 1.222 *************** *** 373,378 **** 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) --- 373,378 ---- 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) *************** *** 1579,1599 **** ) ! # 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,1634 ---- ) ! # 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 ! # Let Py_UNICODE size depend on wchar_t size ! case "$ac_cv_sizeof_wchar_t" in ! 2) enable_unicode="ucs2";; ! 4) enable_unicode="ucs4";; ! *) enable_unicode="ucs4";; # default to UCS-4 ! esac ! 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 From tim_one@users.sourceforge.net Tue Jun 26 23:24:53 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 26 Jun 2001 15:24:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv32237/python/dist/src/Lib/test Modified Files: test_generators.py Log Message: gen_getattr: make the gi_running and gi_frame members discoverable (but not writable -- too dangerous!) from Python code. Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -r1.10 -r1.11 *** test_generators.py 2001/06/26 03:36:28 1.10 --- test_generators.py 2001/06/26 22:24:51 1.11 *************** *** 369,373 **** 5-combs of [1, 2, 3, 4]: ! # From the Iterators list, about the types of these things. >>> def g(): --- 369,373 ---- 5-combs of [1, 2, 3, 4]: ! From the Iterators list, about the types of these things. >>> def g(): *************** *** 380,384 **** >>> dir(i) ! ['next'] >>> print i.next.__doc__ next() -- get the next value, or raise StopIteration --- 380,384 ---- >>> dir(i) ! ['gi_frame', 'gi_running', 'next'] >>> print i.next.__doc__ next() -- get the next value, or raise StopIteration *************** *** 388,391 **** --- 388,411 ---- >>> isinstance(i, types.GeneratorType) 1 + + And more, added later. + + >>> i.gi_running + 0 + >>> type(i.gi_frame) + + >>> i.gi_running = 42 + Traceback (most recent call last): + ... + TypeError: object has read-only attributes + >>> def g(): + ... yield me.gi_running + >>> me = g() + >>> me.gi_running + 0 + >>> me.next() + 1 + >>> me.gi_running + 0 """ From tim_one@users.sourceforge.net Tue Jun 26 23:24:53 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 26 Jun 2001 15:24:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.257,2.258 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv32237/python/dist/src/Python Modified Files: ceval.c Log Message: gen_getattr: make the gi_running and gi_frame members discoverable (but not writable -- too dangerous!) from Python code. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.257 retrieving revision 2.258 diff -C2 -r2.257 -r2.258 *** ceval.c 2001/06/26 20:58:58 2.257 --- ceval.c 2001/06/26 22:24:51 2.258 *************** *** 116,121 **** PyFrameObject *gi_frame; ! /* True if generator is being executed. */ ! int gi_running; } genobject; --- 116,121 ---- PyFrameObject *gi_frame; ! /* True if generator is being executed. */ ! int gi_running; } genobject; *************** *** 208,212 **** static struct PyMethodDef gen_methods[] = { {"next", (PyCFunction)gen_next, METH_VARARGS, ! "next() -- get the next value, or raise StopIteration"}, {NULL, NULL} /* Sentinel */ }; --- 208,212 ---- static struct PyMethodDef gen_methods[] = { {"next", (PyCFunction)gen_next, METH_VARARGS, ! "next() -- get the next value, or raise StopIteration"}, {NULL, NULL} /* Sentinel */ }; *************** *** 215,219 **** gen_getattr(genobject *gen, char *name) { ! return Py_FindMethod(gen_methods, (PyObject *)gen, name); } --- 215,232 ---- 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; } From tim_one@users.sourceforge.net Tue Jun 26 23:40:49 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 26 Jun 2001 15:40:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _testcapimodule.c,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv2927/python/dist/src/Modules Modified Files: _testcapimodule.c Log Message: Windows build broke from recent Unicode changes -- need to #define SIZEOF_SHORT by hand here. Also added dynamic check that SIZEOF_SHORT is correct for the platform (in _testcapimodule). Index: _testcapimodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_testcapimodule.c,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** _testcapimodule.c 2001/06/16 08:10:13 1.8 --- _testcapimodule.c 2001/06/26 22:40:47 1.9 *************** *** 53,56 **** --- 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); From tim_one@users.sourceforge.net Tue Jun 26 23:40:49 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 26 Jun 2001 15:40:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/PC config.h,1.52,1.53 Message-ID: Update of /cvsroot/python/python/dist/src/PC In directory usw-pr-cvs1:/tmp/cvs-serv2927/python/dist/src/PC Modified Files: config.h Log Message: Windows build broke from recent Unicode changes -- need to #define SIZEOF_SHORT by hand here. Also added dynamic check that SIZEOF_SHORT is correct for the platform (in _testcapimodule). Index: config.h =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/config.h,v retrieving revision 1.52 retrieving revision 1.53 diff -C2 -r1.52 -r1.53 *** config.h 2001/05/14 22:32:33 1.52 --- config.h 2001/06/26 22:40:47 1.53 *************** *** 345,348 **** --- 345,349 ---- #endif + #define SIZEOF_SHORT 2 #define SIZEOF_INT 4 #define SIZEOF_LONG 4 From loewis@users.sourceforge.net Tue Jun 26 23:43:43 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Tue, 26 Jun 2001 15:43:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects unicodeobject.c,2.98,2.99 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv4283 Modified Files: unicodeobject.c Log Message: When decoding UTF-16, don't assume that the buffer is in native endianness when checking surrogates. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.98 retrieving revision 2.99 diff -C2 -r2.98 -r2.99 *** unicodeobject.c 2001/06/26 22:22:37 2.98 --- unicodeobject.c 2001/06/26 22:43:40 2.99 *************** *** 1066,1079 **** goto utf16Error; } ! if (0xDC00 <= *q && *q <= 0xDFFF) { Py_UCS2 ch2 = *q++; #ifdef BYTEORDER_IS_LITTLE_ENDIAN if (bo == 1) ! ch = (ch >> 8) | (ch << 8); #else if (bo == -1) ! ch = (ch >> 8) | (ch << 8); #endif ! if (0xD800 <= ch && ch <= 0xDBFF) { #if Py_UNICODE_SIZE == 2 /* This is valid data (a UTF-16 surrogate pair), but --- 1066,1079 ---- 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) { #if Py_UNICODE_SIZE == 2 /* This is valid data (a UTF-16 surrogate pair), but From effbot@users.sourceforge.net Tue Jun 26 23:59:51 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Tue, 26 Jun 2001 15:59:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/PC config.h,1.53,1.54 Message-ID: Update of /cvsroot/python/python/dist/src/PC In directory usw-pr-cvs1:/tmp/cvs-serv7485/PC Modified Files: config.h Log Message: Make Unicode work a bit better on Windows... Index: config.h =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/config.h,v retrieving revision 1.53 retrieving revision 1.54 diff -C2 -r1.53 -r1.54 *** config.h 2001/06/26 22:40:47 1.53 --- config.h 2001/06/26 22:59:49 1.54 *************** *** 485,488 **** --- 485,497 ---- /* #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 want cycle garbage collection */ #define WITH_CYCLE_GC 1 From effbot@users.sourceforge.net Tue Jun 26 23:59:51 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Tue, 26 Jun 2001 15:59:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include unicodeobject.h,2.23,2.24 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv7485/Include Modified Files: unicodeobject.h Log Message: Make Unicode work a bit better on Windows... Index: unicodeobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/unicodeobject.h,v retrieving revision 2.23 retrieving revision 2.24 diff -C2 -r2.23 -r2.24 *** unicodeobject.h 2001/06/26 22:22:37 2.23 --- unicodeobject.h 2001/06/26 22:59:49 2.24 *************** *** 59,62 **** --- 59,70 ---- /* --- 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 + /* experimental UCS-4 support. enable at your own risk! */ #undef USE_UCS4_STORAGE From gvanrossum@users.sourceforge.net Wed Jun 27 00:12:27 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 26 Jun 2001 16:12:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.212,2.213 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv11087 Modified Files: bltinmodule.c Log Message: Cosmetic changes to MvL's change to unichr(): - the correct range for the error message is range(0x110000); - put the 4-byte Unicode-size code inside the same else branch as the 2-byte code, rather generating unreachable code in the 2-byte case. - Don't hide the 'else' behine the '}'. (I would prefer that in 4-byte mode, any value should be accepted, but reasonable people can argue about that, so I'll put that off.) Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.212 retrieving revision 2.213 diff -C2 -r2.212 -r2.213 *** bltinmodule.c 2001/06/26 22:22:37 2.212 --- bltinmodule.c 2001/06/26 23:12:25 2.213 *************** *** 316,320 **** if (x < 0 || x > 0x10ffff) { PyErr_SetString(PyExc_ValueError, ! "unichr() arg not in range(0x10ffff)"); return NULL; } --- 316,320 ---- if (x < 0 || x > 0x10ffff) { PyErr_SetString(PyExc_ValueError, ! "unichr() arg not in range(0x110000)"); return NULL; } *************** *** 324,328 **** s[0] = (Py_UNICODE) x; return PyUnicode_FromUnicode(s, 1); ! } else { #if Py_UNICODE_SIZE == 2 /* UCS-4 character. store as two surrogate characters */ --- 324,329 ---- s[0] = (Py_UNICODE) x; return PyUnicode_FromUnicode(s, 1); ! } ! else { #if Py_UNICODE_SIZE == 2 /* UCS-4 character. store as two surrogate characters */ *************** *** 331,338 **** s[1] = 0xDC00 + (Py_UNICODE) (x & 0x03FF); return PyUnicode_FromUnicode(s, 2); #endif } - s[0] = (Py_UNICODE)x; - return PyUnicode_FromUnicode(s, 1); } --- 332,340 ---- s[1] = 0xDC00 + (Py_UNICODE) (x & 0x03FF); return PyUnicode_FromUnicode(s, 2); + #else + s[0] = (Py_UNICODE)x; + return PyUnicode_FromUnicode(s, 1); #endif } } From loewis@users.sourceforge.net Wed Jun 27 07:28:58 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Tue, 26 Jun 2001 23:28:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include unicodeobject.h,2.24,2.25 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv21016/Include Modified Files: unicodeobject.h Log Message: Encode surrogates in UTF-8 even for a wide Py_UNICODE. Implement sys.maxunicode. Explicitly wrap around upper/lower computations for wide Py_UNICODE. When decoding large characters with UTF-8, represent expected test results using the \U notation. Index: unicodeobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/unicodeobject.h,v retrieving revision 2.24 retrieving revision 2.25 diff -C2 -r2.24 -r2.25 *** unicodeobject.h 2001/06/26 22:59:49 2.24 --- unicodeobject.h 2001/06/27 06:28:56 2.25 *************** *** 275,278 **** --- 275,281 ---- ); + /* 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. From loewis@users.sourceforge.net Wed Jun 27 07:28:58 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Tue, 26 Jun 2001 23:28:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python sysmodule.c,2.86,2.87 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv21016/Python Modified Files: sysmodule.c Log Message: Encode surrogates in UTF-8 even for a wide Py_UNICODE. Implement sys.maxunicode. Explicitly wrap around upper/lower computations for wide Py_UNICODE. When decoding large characters with UTF-8, represent expected test results using the \U notation. Index: sysmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/sysmodule.c,v retrieving revision 2.86 retrieving revision 2.87 diff -C2 -r2.86 -r2.87 *** sysmodule.c 2001/06/16 21:02:31 2.86 --- sysmodule.c 2001/06/27 06:28:56 2.87 *************** *** 534,537 **** --- 534,538 ---- \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\ *************** *** 643,646 **** --- 644,650 ---- 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 loewis@users.sourceforge.net Wed Jun 27 07:28:58 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Tue, 26 Jun 2001 23:28:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_unicode.py,1.33,1.34 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv21016/Lib/test Modified Files: test_unicode.py Log Message: Encode surrogates in UTF-8 even for a wide Py_UNICODE. Implement sys.maxunicode. Explicitly wrap around upper/lower computations for wide Py_UNICODE. When decoding large characters with UTF-8, represent expected test results using the \U notation. Index: test_unicode.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_unicode.py,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -r1.33 -r1.34 *** test_unicode.py 2001/05/13 00:19:31 1.33 --- test_unicode.py 2001/06/27 06:28:56 1.34 *************** *** 387,393 **** # UTF-8 specific decoding tests verify(unicode(''.join((chr(0xf0), chr(0xa3), chr(0x91), chr(0x96))), ! 'utf-8') == u'\ud84d\udc56' ) verify(unicode(''.join((chr(0xf0), chr(0x90), chr(0x80), chr(0x82))), ! 'utf-8') == u'\ud800\udc02' ) verify(unicode(''.join((chr(0xe2), chr(0x82), chr(0xac))), 'utf-8') == u'\u20ac' ) --- 387,393 ---- # UTF-8 specific decoding tests verify(unicode(''.join((chr(0xf0), chr(0xa3), chr(0x91), chr(0x96))), ! 'utf-8') == u'\U00023456' ) verify(unicode(''.join((chr(0xf0), chr(0x90), chr(0x80), chr(0x82))), ! 'utf-8') == u'\U00010002' ) verify(unicode(''.join((chr(0xe2), chr(0x82), chr(0xac))), 'utf-8') == u'\u20ac' ) From loewis@users.sourceforge.net Wed Jun 27 07:28:58 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Tue, 26 Jun 2001 23:28:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects unicodectype.c,2.8,2.9 unicodeobject.c,2.99,2.100 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv21016/Objects Modified Files: unicodectype.c unicodeobject.c Log Message: Encode surrogates in UTF-8 even for a wide Py_UNICODE. Implement sys.maxunicode. Explicitly wrap around upper/lower computations for wide Py_UNICODE. When decoding large characters with UTF-8, represent expected test results using the \U notation. Index: unicodectype.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodectype.c,v retrieving revision 2.8 retrieving revision 2.9 diff -C2 -r2.8 -r2.9 *** unicodectype.c 2001/06/26 20:36:12 2.8 --- unicodectype.c 2001/06/27 06:28:56 2.9 *************** *** 60,71 **** ch if no titlecase mapping is known. */ ! Py_UNICODE _PyUnicode_ToTitlecase(register const Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); if (ctype->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 USE_UCS4_STORAGE ! /* The database assumes that the values wrap around at 0x10000. */ ! if (ch > 0x10000) ! ch -= 0x10000; ! #endif ! return ch; } *************** *** 349,357 **** 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(register Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); ! ch += ctype->upper; ! #ifdef USE_UCS4_STORAGE ! /* The database assumes that the values wrap around at 0x10000. */ ! if (ch > 0x10000) ! ch -= 0x10000; ! #endif ! return ch; } *************** *** 359,367 **** 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(register Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); ! ch += ctype->lower; ! #ifdef USE_UCS4_STORAGE ! /* The database assumes that the values wrap around at 0x10000. */ ! if (ch > 0x10000) ! ch -= 0x10000; ! #endif ! return ch; } Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.99 retrieving revision 2.100 diff -C2 -r2.99 -r2.100 *** unicodeobject.c 2001/06/26 22:43:40 2.99 --- unicodeobject.c 2001/06/27 06:28:56 2.100 *************** *** 104,107 **** --- 104,119 ---- static char unicode_default_encoding[100]; + Py_UNICODE + PyUnicode_GetMax() + { + #ifdef USE_UCS4_STORAGE + return 0x10FFFF; + #else + /* This is actually an illegal character, so it should + not be passed to unichr. */ + return 0xFFFF; + #endif + } + /* --- Unicode Object ----------------------------------------------------- */ *************** *** 885,894 **** } else if (ch < 0x10000) { - #if Py_UNICODE_SIZE == 4 - *p++ = 0xe0 | (ch>>12); - *p++ = 0x80 | ((ch>>6) & 0x3f); - *p++ = 0x80 | (ch & 0x3f); - cbWritten += 3; - #else /* Check for high surrogate */ if (0xD800 <= ch && ch <= 0xDBFF) { --- 897,900 ---- *************** *** 921,925 **** *p++ = (char)(0x80 | ((ch >> 6) & 0x3f)); *p++ = (char)(0x80 | (ch & 0x3f)); - #endif } else { *p++ = 0xf0 | (ch>>18); --- 927,930 ---- From tim_one@users.sourceforge.net Wed Jun 27 08:17:59 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 27 Jun 2001 00:17:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv27500/python/dist/src/Lib/test Modified Files: test_generators.py Log Message: This no longer leaks memory when run in an infinite loop. However, that required explicitly calling LazyList.clear() in the two tests that use LazyList (I added a LazyList Fibonacci generator too). A real bitch: the extremely inefficient first version of the 2-3-5 test *looked* like a slow leak on Win98SE, but it wasn't "really": it generated so many results that the heap grew over 4Mb (tons of frames! the number of frames grows exponentially in that test). Then Win98SE malloc() starts fragmenting address space allocating more and more heaps, and the visible memory use grew very slowly while the disk was thrashing like mad. Printing fewer results (i.e., keeping the heap burden under 4Mb) made that illusion vanish. Looks like there's no hope for plugging the LazyList leaks automatically short of adding frameobjects and genobjects to gc. OTOH, they're very easy to break by hand, and they're the only *kind* of plausibly realistic leaks I've been able to provoke. Dilemma. Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -r1.11 -r1.12 *** test_generators.py 2001/06/26 22:24:51 1.11 --- test_generators.py 2001/06/27 07:17:57 1.12 *************** *** 446,449 **** --- 446,450 ---- [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71] + Another famous problem: generate all integers of the form 2**i * 3**j * 5**k *************** *** 452,458 **** 3 internal results for each result output. - XXX Suspect there's memory leaks in this one; definitely in the next - XXX version. - >>> def times(n, g): ... for i in g: --- 453,456 ---- *************** *** 476,484 **** ... nh = h.next() ! This works, but is doing a whale of a lot or redundant work -- it's not ! clear how to get the internal uses of m235 to share a single generator. ! Note that me_times2 (etc) each need to see every element in the result ! sequence. So this is an example where lazy lists are more natural (you ! can look at the head of a lazy list any number of times). >>> def m235(): --- 474,482 ---- ... nh = h.next() ! The following works, but is doing a whale of a lot of redundant work -- ! it's not clear how to get the internal uses of m235 to share a single ! generator. Note that me_times2 (etc) each need to see every element in the ! result sequence. So this is an example where lazy lists are more natural ! (you can look at the head of a lazy list any number of times). >>> def m235(): *************** *** 492,503 **** ... yield i >>> result = m235() ! >>> for i in range(5): ... print firstn(result, 15) [1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24] [25, 27, 30, 32, 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80] [81, 90, 96, 100, 108, 120, 125, 128, 135, 144, 150, 160, 162, 180, 192] - [200, 216, 225, 240, 243, 250, 256, 270, 288, 300, 320, 324, 360, 375, 384] - [400, 405, 432, 450, 480, 486, 500, 512, 540, 576, 600, 625, 640, 648, 675] Heh. Here's one way to get a shared list, complete with an excruciating --- 490,507 ---- ... yield i + Don't print "too many" of these -- the implementation above is extremely + inefficient: each call of m235() leads to 3 recursive calls, and in + turn each of those 3 more, and so on, and so on, until we've descended + enough levels to satisfy the print stmts. Very odd: when I printed 5 + lines of results below, this managed to screw up Win98's malloc in "the + usual" way, i.e. the heap grew over 4Mb so Win98 started fragmenting + address space, and it *looked* like a very slow leak. + >>> result = m235() ! >>> for i in range(3): ... print firstn(result, 15) [1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24] [25, 27, 30, 32, 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80] [81, 90, 96, 100, 108, 120, 125, 128, 135, 144, 150, 160, 162, 180, 192] Heh. Here's one way to get a shared list, complete with an excruciating *************** *** 506,511 **** arguments are iterable -- a LazyList is the same as a generator to times(). - XXX Massive memory leaks in this; see Python-Iterators. - >>> class LazyList: ... def __init__(self, g): --- 510,513 ---- *************** *** 518,521 **** --- 520,526 ---- ... sofar.append(fetch()) ... return sofar[i] + ... + ... def clear(self): + ... self.__dict__.clear() >>> def m235(): *************** *** 530,533 **** --- 535,541 ---- ... yield i + 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()) >>> for i in range(5): *************** *** 538,541 **** --- 546,577 ---- [200, 216, 225, 240, 243, 250, 256, 270, 288, 300, 320, 324, 360, 375, 384] [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. + + >>> def fibgen(a, b): + ... + ... def sum(g, h): + ... while 1: + ... yield g.next() + h.next() + ... + ... def tail(g): + ... g.next() # throw first away + ... for x in g: + ... yield x + ... + ... yield a + ... yield b + ... for s in sum(iter(fib), + ... tail(iter(fib))): + ... yield s + + >>> fib = LazyList(fibgen(1, 2)) + >>> 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 """ *************** *** 670,740 **** """ - - - x_tests = """ - - >>> def firstn(g, n): - ... return [g.next() for i in range(n)] - - >>> def times(n, g): - ... for i in g: - ... yield n * i - - >>> def merge(g, h): - ... ng = g.next() - ... nh = h.next() - ... while 1: - ... if ng < nh: - ... yield ng - ... ng = g.next() - ... elif ng > nh: - ... yield nh - ... nh = h.next() - ... else: - ... yield ng - ... ng = g.next() - ... nh = h.next() - - >>> class LazyList: - ... def __init__(self, g): - ... self.sofar = [] - ... self.fetch = g.next - ... - ... def __getitem__(self, i): - ... sofar, fetch = self.sofar, self.fetch - ... while i >= len(sofar): - ... sofar.append(fetch()) - ... return sofar[i] - - >>> def m235(): - ... yield 1 - ... # Gack: m235 below actually refers to a LazyList. - ... me_times2 = times(2, m235) - ... me_times3 = times(3, m235) - ... me_times5 = times(5, m235) - ... for i in merge(merge(me_times2, - ... me_times3), - ... me_times5): - ... yield i - - >>> m235 = LazyList(m235()) - >>> for i in range(5): - ... x = [m235[j] for j in range(15*i, 15*(i+1))] - - - [1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24] - [25, 27, 30, 32, 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80] - [81, 90, 96, 100, 108, 120, 125, 128, 135, 144, 150, 160, 162, 180, 192] - [200, 216, 225, 240, 243, 250, 256, 270, 288, 300, 320, 324, 360, 375, 384] - [400, 405, 432, 450, 480, 486, 500, 512, 540, 576, 600, 625, 640, 648, 675] - """ ! __test__ = {"tut": tutorial_tests, # clean ! "pep": pep_tests, # clean ! "email": email_tests, # clean ! "fun": fun_tests, # leaks ! "syntax": syntax_tests # clean ! #"x": x_tests ! } # Magic test name that regrtest.py invokes *after* importing this module. --- 706,715 ---- """ ! __test__ = {"tut": tutorial_tests, ! "pep": pep_tests, ! "email": email_tests, ! "fun": fun_tests, ! "syntax": syntax_tests} # Magic test name that regrtest.py invokes *after* importing this module. *************** *** 746,751 **** if 0: # Temporary block to help track down leaks. So far, the blame ! # has fallen mostly on doctest. ! for i in range(5000): doctest.master = None doctest.testmod(test_generators) --- 721,728 ---- 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) From twouters@users.sourceforge.net Wed Jun 27 12:25:50 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 27 Jun 2001 04:25:50 -0700 Subject: [Python-checkins] CVS: python/dist/src LICENSE,1.15.2.1,1.15.2.2 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv27032 Modified Files: Tag: release21-maint LICENSE Log Message: Python 2.1 (and 2.0) -> Python 2.1.1 in the licence text. Index: LICENSE =================================================================== RCS file: /cvsroot/python/python/dist/src/LICENSE,v retrieving revision 1.15.2.1 retrieving revision 1.15.2.2 diff -C2 -r1.15.2.1 -r1.15.2.2 *** LICENSE 2001/05/04 18:55:39 1.15.2.1 --- LICENSE 2001/06/27 11:25:48 1.15.2.2 *************** *** 44,48 **** 1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and the Individual or Organization ("Licensee") accessing and ! otherwise using Python 2.1 software in source or binary form and its associated documentation. --- 44,48 ---- 1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and the Individual or Organization ("Licensee") accessing and ! otherwise using Python 2.1.1 software in source or binary form and its associated documentation. *************** *** 50,75 **** hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, ! prepare derivative works, distribute, and otherwise use Python 2.1 alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001 Python Software Foundation; All Rights Reserved" are retained in ! Python 2.1 alone or in any derivative version prepared by Licensee. 3. In the event Licensee prepares a derivative work that is based on ! or incorporates Python 2.1 or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of ! the changes made to Python 2.1. ! 4. PSF is making Python 2.1 available to Licensee on an "AS IS" basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS ! FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.1 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON ! 2.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS ! A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.1, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. --- 50,75 ---- hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, ! prepare derivative works, distribute, and otherwise use Python 2.1.1 alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001 Python Software Foundation; All Rights Reserved" are retained in ! Python 2.1.1 alone or in any derivative version prepared by Licensee. 3. In the event Licensee prepares a derivative work that is based on ! or incorporates Python 2.1.1 or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of ! the changes made to Python 2.1.1. ! 4. PSF is making Python 2.1.1 available to Licensee on an "AS IS" basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS ! FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.1.1 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON ! 2.1.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS ! A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.1.1, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. *************** *** 83,92 **** products or services of Licensee, or any third party. ! 8. By copying, installing or otherwise using Python 2.1, Licensee agrees to be bound by the terms and conditions of this License Agreement. ! BEOPEN.COM TERMS AND CONDITIONS FOR PYTHON 2.0 ---------------------------------------------- --- 83,92 ---- products or services of Licensee, or any third party. ! 8. By copying, installing or otherwise using Python 2.1.1, Licensee agrees to be bound by the terms and conditions of this License Agreement. ! BEOPEN.COM TERMS AND CONDITIONS FOR PYTHON 2.1.1 ---------------------------------------------- From twouters@users.sourceforge.net Wed Jun 27 12:57:53 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 27 Jun 2001 04:57:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/mac toolbox.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-serv2304 Modified Files: Tag: release21-maint toolbox.tex Log Message: Backport Fred's checkin 1.3: Write a better synopsis for the Scrap module, and provide a link to useful documentation on the Scrap Manager. Index: toolbox.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/mac/toolbox.tex,v retrieving revision 1.2 retrieving revision 1.2.2.1 diff -C2 -r1.2 -r1.2.2.1 *** toolbox.tex 2001/04/13 17:37:00 1.2 --- toolbox.tex 2001/06/27 11:57:51 1.2.2.1 *************** *** 94,98 **** \declaremodule{standard}{Scrap} \platform{Mac} ! \modulesynopsis{Interface to the Scrap Manager} --- 94,106 ---- \declaremodule{standard}{Scrap} \platform{Mac} ! \modulesynopsis{The Scrap Manager provides basic services for ! implementing cut \&\ paste and clipboard operations.} ! ! \begin{seealso} ! \seetitle[http://developer.apple.com/techpubs/mac/MoreToolbox/MoreToolbox-109.html]{Scrap ! Manager}{Apple's documentation for the Scrap Manager gives ! a lot of useful information about using the Scrap Manager ! in applications.} ! \end{seealso} From twouters@users.sourceforge.net Wed Jun 27 14:01:56 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 27 Jun 2001 06:01:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules timemodule.c,2.110,2.110.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv17228/Modules Modified Files: Tag: release21-maint timemodule.c Log Message: Backport of Tim's checkin 2.111: SF patch #418147 Fixes to allow compiling w/ Borland, from Stephen Hansen. Index: timemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/timemodule.c,v retrieving revision 2.110 retrieving revision 2.110.2.1 diff -C2 -r2.110 -r2.110.2.1 *** timemodule.c 2001/04/10 22:07:07 2.110 --- timemodule.c 2001/06/27 13:01:54 2.110.2.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 * From twouters@users.sourceforge.net Wed Jun 27 14:01:15 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 27 Jun 2001 06:01:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules posixmodule.c,2.187,2.187.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv17036/Modules Modified Files: Tag: release21-maint posixmodule.c Log Message: Backport of Tim's checkin 2.190: SF patch #418147 Fixes to allow compiling w/ Borland, from Stephen Hansen. Index: posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.187 retrieving revision 2.187.2.1 diff -C2 -r2.187 -r2.187.2.1 *** posixmodule.c 2001/04/14 17:55:09 2.187 --- posixmodule.c 2001/06/27 13:01:12 2.187.2.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); *************** *** 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 --- 5616,5630 ---- ! #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 From twouters@users.sourceforge.net Wed Jun 27 14:04:26 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 27 Jun 2001 06:04:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include pyport.h,2.26,2.26.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv17628/Include Modified Files: Tag: release21-maint pyport.h Log Message: Backport of Tim's checkin 2.27: SF patch #418147 Fixes to allow compiling w/ Borland, from Stephen Hansen. Index: pyport.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pyport.h,v retrieving revision 2.26 retrieving revision 2.26.4.1 diff -C2 -r2.26 -r2.26.4.1 *** pyport.h 2001/01/22 16:50:11 2.26 --- pyport.h 2001/06/27 13:04:24 2.26.4.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 } From twouters@users.sourceforge.net Wed Jun 27 14:05:08 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 27 Jun 2001 06:05:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/PC config.h,1.49,1.49.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/PC In directory usw-pr-cvs1:/tmp/cvs-serv17877/PC Modified Files: Tag: release21-maint config.h Log Message: Backport of Tim's checkin 1.52: SF patch #418147 Fixes to allow compiling w/ Borland, from Stephen Hansen. Index: config.h =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/config.h,v retrieving revision 1.49 retrieving revision 1.49.4.1 diff -C2 -r1.49 -r1.49.4.1 *** config.h 2001/02/28 08:15:16 1.49 --- config.h 2001/06/27 13:05:05 1.49.4.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 ---- #else /* !_WIN32 */ + #undef HAVE_SYS_UTIME_H + #define HAVE_UTIME_H + #define HAVE_DIRENT_H + #define HAVE_CLOCK #error "Only Win32 and later are supported" #endif /* !_WIN32 */ *************** *** 592,596 **** /* Define if you have the header file. */ ! #define HAVE_SYS_UTIME_H 1 /* Define if you have the header file. */ --- 597,601 ---- /* Define if you have the header file. */ ! /* #define HAVE_SYS_UTIME_H 1 */ /* Define if you have the header file. */ From twouters@users.sourceforge.net Wed Jun 27 14:09:47 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 27 Jun 2001 06:09:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.238,2.238.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv18077/Python Modified Files: Tag: release21-maint ceval.c Log Message: Backport Jeremy's checkin 2.244: Add a second special case to the inline function call code in eval_code2(). If we have a PyCFunction (builtin) and it is METH_VARARGS only, load the args and dispatch to call_cfunction() directly. This provides a small speedup for perhaps the most common function calls -- builtins. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.238 retrieving revision 2.238.2.1 diff -C2 -r2.238 -r2.238.2.1 *** ceval.c 2001/04/13 16:51:46 2.238 --- ceval.c 2001/06/27 13:09:44 2.238.2.1 *************** *** 1942,1946 **** */ if (PyCFunction_Check(func)) { ! if (PyCFunction_GET_FLAGS(func) == 0) { x = fast_cfunction(func, &stack_pointer, na); --- 1942,1952 ---- */ if (PyCFunction_Check(func)) { ! int flags = PyCFunction_GET_FLAGS(func); ! if (flags == METH_VARARGS) { ! PyObject *callargs; ! callargs = load_args(&stack_pointer, na); ! x = call_cfunction(func, callargs, NULL); ! Py_XDECREF(callargs); ! } else if (flags == 0) { x = fast_cfunction(func, &stack_pointer, na); From twouters@users.sourceforge.net Wed Jun 27 14:11:11 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 27 Jun 2001 06:11:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python getargs.c,2.54,2.54.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv19273/Python Modified Files: Tag: release21-maint getargs.c Log Message: Backport Jeremy's checkin 2.57: vgetargs1() and vgetargskeywords(): Replace uses of PyTuple_Size() and PyTuple_GetItem() with PyTuple_GET_SIZE() and PyTuple_GET_ITEM(). The code has already done a PyTuple_Check(). Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.54 retrieving revision 2.54.4.1 diff -C2 -r2.54 -r2.54.4.1 *** getargs.c 2001/02/12 22:13:26 2.54 --- getargs.c 2001/06/27 13:11:09 2.54.4.1 *************** *** 167,171 **** } ! len = PyTuple_Size(args); if (len < min || max < len) { --- 167,171 ---- } ! len = PyTuple_GET_SIZE(args); if (len < min || max < len) { *************** *** 189,194 **** if (*format == '|') format++; ! msg = convertitem(PyTuple_GetItem(args, i), &format, p_va, ! levels, msgbuf); if (msg) { seterror(i+1, msg, levels, fname, message); --- 189,194 ---- if (*format == '|') format++; ! msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va, ! levels, msgbuf); if (msg) { seterror(i+1, msg, levels, fname, message); *************** *** 996,1005 **** fname = format; break; ! } ! else if (c == ';') { message = format; break; ! } ! else if (c == 'e') ; /* Pass */ else if (isalpha(c)) --- 996,1003 ---- fname = format; break; ! } else if (c == ';') { message = format; break; ! } else if (c == 'e') ; /* Pass */ else if (isalpha(c)) *************** *** 1020,1024 **** } ! tplen = PyTuple_Size(args); /* do a cursory check of the keywords just to see how many we got */ --- 1018,1022 ---- } ! 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) { --- 1094,1098 ---- if (*format == '|') format++; ! msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va, levels, msgbuf); if (msg) { From twouters@users.sourceforge.net Wed Jun 27 14:12:50 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 27 Jun 2001 06:12:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules selectmodule.c,2.50,2.50.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv19976/Modules Modified Files: Tag: release21-maint selectmodule.c Log Message: Backport Fred's checkin 2.51: Add :method info to the PyArg_ParseTuple() format strings for poll objects. Index: selectmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/selectmodule.c,v retrieving revision 2.50 retrieving revision 2.50.4.1 diff -C2 -r2.50 -r2.50.4.1 *** selectmodule.c 2001/03/02 06:28:17 2.50 --- selectmodule.c 2001/06/27 13:12:47 2.50.4.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; } From twouters@users.sourceforge.net Wed Jun 27 14:43:54 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 27 Jun 2001 06:43:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/idle extend.txt,1.3,1.3.10.1 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/idle In directory usw-pr-cvs1:/tmp/cvs-serv26775 Modified Files: Tag: release21-maint extend.txt Log Message: Backport Guido's checkin 1.4: Quick update to the extension mechanism (extend.py is gone, long live config.txt). Index: extend.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/idle/extend.txt,v retrieving revision 1.3 retrieving revision 1.3.10.1 diff -C2 -r1.3 -r1.3.10.1 *** extend.txt 1999/04/20 17:32:52 1.3 --- extend.txt 2001/06/27 13:43:51 1.3.10.1 *************** *** 8,12 **** The list of extensions loaded at startup time is configured by editing ! the file extend.py; see below for details. An IDLE extension is defined by a class. Methods of the class define --- 8,12 ---- The list of extensions loaded at startup time is configured by editing ! the file config.txt; see below for details. An IDLE extension is defined by a class. Methods of the class define *************** *** 87,95 **** "...Do what you want here..." ! The final piece of the puzzle is the file "extend.py", which contains a ! simple table used to configure the loading of extensions. This file ! currently contains a single list variable named "standard", which is a ! list of extension names that are to be loaded. (In the future, other ! configuration variables may be added to this module.) Extensions can define key bindings and menu entries that reference --- 87,109 ---- "...Do what you want here..." ! The final piece of the puzzle is the file "config.txt", which is used ! to to configure the loading of extensions. For each extension, ! you must include a section in config.txt (or in any of the other ! configuration files that are consulted at startup: config-unix.txt, ! config-win.txt, or ~/.idle). A section is headed by the module name ! in square brackets, e.g. ! ! [ZoomHeight] ! ! The section may be empty, or it may define configuration options for ! the extension. (See ParenMatch.py for an example.) A special option ! is 'enable': including ! ! enable = 0 ! ! in a section disables that extension. More than one configuration ! file may specify options for the same extension, so a user may disable ! an extension that is loaded by default, or enable an extension that is ! disabled by default. Extensions can define key bindings and menu entries that reference From twouters@users.sourceforge.net Wed Jun 27 14:45:03 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 27 Jun 2001 06:45:03 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib dbhash.py,1.5,1.5.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv27142/Lib Modified Files: Tag: release21-maint dbhash.py Log Message: Backport Martin's checkin 1.6: Fix bug #422702: Make flag argument to open optional, and document it that way. Index: dbhash.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/dbhash.py,v retrieving revision 1.5 retrieving revision 1.5.4.1 diff -C2 -r1.5 -r1.5.4.1 *** dbhash.py 2001/01/25 13:47:00 1.5 --- dbhash.py 2001/06/27 13:45:01 1.5.4.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) From twouters@users.sourceforge.net Wed Jun 27 14:50:01 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 27 Jun 2001 06:50:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libdbhash.tex,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv28434 Modified Files: libdbhash.tex Log Message: Remove duplicate ', ' in dbhash.open()'s argument list. Index: libdbhash.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdbhash.tex,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** libdbhash.tex 2001/06/05 05:33:19 1.4 --- libdbhash.tex 2001/06/27 13:49:59 1.5 *************** *** 22,26 **** \end{excdesc} ! \begin{funcdesc}{open}{path, \optional{, flag\optional{, mode}}} Open a \code{db} database and return the database object. The \var{path} argument is the name of the database file. --- 22,26 ---- \end{excdesc} ! \begin{funcdesc}{open}{path\optional{, flag\optional{, mode}}} Open a \code{db} database and return the database object. The \var{path} argument is the name of the database file. From twouters@users.sourceforge.net Wed Jun 27 14:51:38 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 27 Jun 2001 06:51:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libdbhash.tex,1.3,1.3.12.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv28744/Doc/lib Modified Files: Tag: release21-maint libdbhash.tex Log Message: Backport Martin's checkin 1.4 (with minor fix): Fix bug #422702: Make flag argument to open optional, and document it that way. Index: libdbhash.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdbhash.tex,v retrieving revision 1.3 retrieving revision 1.3.12.1 diff -C2 -r1.3 -r1.3.12.1 *** libdbhash.tex 1999/04/19 21:19:21 1.3 --- libdbhash.tex 2001/06/27 13:51:36 1.3.12.1 *************** *** 22,26 **** \end{excdesc} ! \begin{funcdesc}{open}{path, flag\optional{, mode}} Open a \code{db} database and return the database object. The \var{path} argument is the name of the database file. --- 22,26 ---- \end{excdesc} ! \begin{funcdesc}{open}{path\optional{, flag\optional{, mode}}} Open a \code{db} database and return the database object. The \var{path} argument is the name of the database file. From twouters@users.sourceforge.net Wed Jun 27 14:52:58 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 27 Jun 2001 06:52:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include rangeobject.h,2.15,2.15.6.1 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv29126/Include Modified Files: Tag: release21-maint rangeobject.h Log Message: Backport Martin's checkin 2.16: Wrap with extern "C". Fixes bug #428419. Also protect against multiple inclusion. Index: rangeobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/rangeobject.h,v retrieving revision 2.15 retrieving revision 2.15.6.1 diff -C2 -r2.15 -r2.15.6.1 *** rangeobject.h 2000/09/01 23:29:26 2.15 --- rangeobject.h 2001/06/27 13:52:56 2.15.6.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; *************** *** 15,16 **** --- 21,27 ---- extern DL_IMPORT(PyObject *) PyRange_New(long, long, long, int); + + #ifdef __cplusplus + } + #endif + #endif /* !Py_RANGEOBJECT_H */ From twouters@users.sourceforge.net Wed Jun 27 15:02:16 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 27 Jun 2001 07:02:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.94,1.94.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv31599/Misc Modified Files: Tag: release21-maint ACKS Log Message: Backport Tim's checkin 1.97: SF bug 430991: wrong co_lnotab Armin Rigo pointed out that the way the line-# table got built didn't work for lines generating more than 255 bytes of bytecode. Fixed as he suggested, plus corresponding changes to pyassem.py, plus added some long overdue docs about this subtle table to compile.c. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.94 retrieving revision 1.94.2.1 diff -C2 -r1.94 -r1.94.2.1 *** ACKS 2001/04/15 20:48:27 1.94 --- ACKS 2001/06/27 14:02:14 1.94.2.1 *************** *** 319,322 **** --- 319,323 ---- Steven Reiz Jan Pieter Riegel + Armin Rigo Nicholas Riley Jean-Claude Rimbault From twouters@users.sourceforge.net Wed Jun 27 15:03:32 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 27 Jun 2001 07:03:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/compiler/compiler pyassem.py,1.19,1.19.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/compiler/compiler In directory usw-pr-cvs1:/tmp/cvs-serv31867/Tools/compiler/compiler Modified Files: Tag: release21-maint pyassem.py Log Message: Backport Tim's checkin 1.20: SF bug 430991: wrong co_lnotab Armin Rigo pointed out that the way the line-# table got built didn't work for lines generating more than 255 bytes of bytecode. Fixed as he suggested, plus corresponding changes to pyassem.py, plus added some long overdue docs about this subtle table to compile.c. Index: pyassem.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/compiler/compiler/pyassem.py,v retrieving revision 1.19 retrieving revision 1.19.2.1 diff -C2 -r1.19 -r1.19.2.1 *** pyassem.py 2001/04/12 20:21:39 1.19 --- pyassem.py 2001/06/27 14:03:30 1.19.2.1 *************** *** 614,619 **** """lnotab ! This class builds the lnotab, which is undocumented but described ! by com_set_lineno in compile.c. Here's an attempt at explanation: For each SET_LINENO instruction after the first one, two bytes are --- 614,619 ---- """lnotab ! This class builds the lnotab, which is documented in compile.c. ! Here's a brief recap: For each SET_LINENO instruction after the first one, two bytes are *************** *** 622,627 **** instruction for the last SET_LINENO and the current SET_LINENO. The second byte is offset in line numbers. If either offset is ! greater than 255, multiple two-byte entries are added -- one entry ! for each factor of 255. """ --- 622,627 ---- instruction for the last SET_LINENO and the current SET_LINENO. The second byte is offset in line numbers. If either offset is ! greater than 255, multiple two-byte entries are added -- see ! compile.c for the delicate details. """ *************** *** 658,674 **** # for the assignment. if line > 0: ! while addr > 0 or line > 0: ! # write the values in 1-byte chunks that sum ! # to desired value ! trunc_addr = addr ! trunc_line = line ! if trunc_addr > 255: ! trunc_addr = 255 ! if trunc_line > 255: ! trunc_line = 255 ! self.lnotab.append(trunc_addr) ! self.lnotab.append(trunc_line) ! addr = addr - trunc_addr ! line = line - trunc_line self.lastline = lineno self.lastoff = self.codeOffset --- 658,671 ---- # for the assignment. if line > 0: ! push = self.lnotab.append ! while addr > 255: ! push(255); push(0) ! addr -= 255 ! while line > 255: ! push(addr); push(255) ! line -= 255 ! addr = 0 ! if addr > 0 or line > 0: ! push(addr); push(line) self.lastline = lineno self.lastoff = self.codeOffset From twouters@users.sourceforge.net Wed Jun 27 15:04:06 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 27 Jun 2001 07:04:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python compile.c,2.196.2.1,2.196.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv32093/Python Modified Files: Tag: release21-maint compile.c Log Message: Backport Tim's checkin 2.201: SF bug 430991: wrong co_lnotab Armin Rigo pointed out that the way the line-# table got built didn't work for lines generating more than 255 bytes of bytecode. Fixed as he suggested, plus corresponding changes to pyassem.py, plus added some long overdue docs about this subtle table to compile.c. Index: compile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v retrieving revision 2.196.2.1 retrieving revision 2.196.2.2 diff -C2 -r2.196.2.1 -r2.196.2.2 *** compile.c 2001/05/23 12:11:35 2.196.2.1 --- compile.c 2001/06/27 14:04:03 2.196.2.2 *************** *** 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; From twouters@users.sourceforge.net Wed Jun 27 15:07:52 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 27 Jun 2001 07:07:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib traceback.py,1.25,1.25.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv32502/Lib Modified Files: Tag: release21-maint traceback.py Log Message: Backport Tim's checkin 1.26 (patch probably by Michael Hudson, not Hundson): SF bug 431772: traceback.print_exc() causes traceback Patch from Michael Hundson. format_exception_only() blew up when trying to report a SyntaxError from a string input (line is None in this case, but it assumed a string). Index: traceback.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/traceback.py,v retrieving revision 1.25 retrieving revision 1.25.2.1 diff -C2 -r1.25 -r1.25.2.1 *** traceback.py 2001/03/29 04:36:08 1.25 --- traceback.py 2001/06/27 14:07:50 1.25.2.1 *************** *** 172,188 **** list.append(' File "%s", line %d\n' % (filename, lineno)) ! i = 0 ! while i < len(line) and line[i].isspace(): ! i = i+1 ! list.append(' %s\n' % line.strip()) ! if offset is not None: ! s = ' ' ! for c in line[i:offset-1]: ! if c.isspace(): ! s = s + c ! else: ! s = s + ' ' ! list.append('%s^\n' % s) ! value = msg s = _some_str(value) if s: --- 172,189 ---- list.append(' File "%s", line %d\n' % (filename, lineno)) ! if line is not None: ! i = 0 ! while i < len(line) and line[i].isspace(): ! i = i+1 ! list.append(' %s\n' % line.strip()) ! if offset is not None: ! s = ' ' ! for c in line[i:offset-1]: ! if c.isspace(): ! s = s + c ! else: ! s = s + ' ' ! list.append('%s^\n' % s) ! value = msg s = _some_str(value) if s: From twouters@users.sourceforge.net Wed Jun 27 15:11:15 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 27 Jun 2001 07:11:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules main.c,1.52.2.1,1.52.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv706/Modules Modified Files: Tag: release21-maint main.c Log Message: Set PYTHONHOMEHELP to 2.1 Index: main.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/main.c,v retrieving revision 1.52.2.1 retrieving revision 1.52.2.2 diff -C2 -r1.52.2.1 -r1.52.2.2 *** main.c 2001/06/12 16:29:12 1.52.2.1 --- main.c 2001/06/27 14:11:12 1.52.2.2 *************** *** 15,19 **** #define PYTHONHOMEHELP "\\lib" #else ! #define PYTHONHOMEHELP "/pythonX.X" #endif --- 15,19 ---- #define PYTHONHOMEHELP "\\lib" #else ! #define PYTHONHOMEHELP "/python2.1" #endif From twouters@users.sourceforge.net Wed Jun 27 15:13:35 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 27 Jun 2001 07:13:35 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.238.2.1,2.238.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv1989/Python Modified Files: Tag: release21-maint ceval.c Log Message: Backport Tim's checkin 2.247: SF bug 433228: repr(list) woes when len(list) big call_object: If the object isn't callable, display its type in the error msg rather than its repr. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.238.2.1 retrieving revision 2.238.2.2 diff -C2 -r2.238.2.1 -r2.238.2.2 *** ceval.c 2001/06/27 13:09:44 2.238.2.1 --- ceval.c 2001/06/27 14:13:32 2.238.2.2 *************** *** 2813,2818 **** result = (*call)(func, arg, kw); else { ! PyErr_Format(PyExc_TypeError, "object is not callable: %s", ! PyString_AS_STRING(PyObject_Repr(func))); return NULL; } --- 2813,2819 ---- result = (*call)(func, arg, kw); else { ! PyErr_Format(PyExc_TypeError, ! "object of type '%.100s' is not callable", ! func->ob_type->tp_name); return NULL; } From twouters@users.sourceforge.net Wed Jun 27 15:24:14 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 27 Jun 2001 07:24:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects intobject.c,2.56,2.56.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv4929/Objects Modified Files: Tag: release21-maint intobject.c Log Message: Backport of Tim's checkin 2.57: SF bug 434186: 0x80000000/2 != 0x80000000>>1 i_divmod: New and simpler algorithm. Old one returned gibberish on most boxes when the numerator was -sys.maxint-1. Oddly enough, it worked in the release (not debug) build on Windows, because the compiler optimized away some tricky sign manipulations that were incorrect in this case. Makes you wonder ... Index: intobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v retrieving revision 2.56 retrieving revision 2.56.4.1 diff -C2 -r2.56 -r2.56.4.1 *** intobject.c 2001/03/06 12:12:02 2.56 --- intobject.c 2001/06/27 14:24:12 2.56.4.1 *************** *** 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; From twouters@users.sourceforge.net Wed Jun 27 15:27:00 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 27 Jun 2001 07:27:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_b1.py,1.34,1.34.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv5352/Lib/test Modified Files: Tag: release21-maint test_b1.py Log Message: Backport of Tim's checkin 1.35: SF bug 434186: 0x80000000/2 != 0x80000000>>1 i_divmod: New and simpler algorithm. Old one returned gibberish on most boxes when the numerator was -sys.maxint-1. Oddly enough, it worked in the release (not debug) build on Windows, because the compiler optimized away some tricky sign manipulations that were incorrect in this case. Makes you wonder ... 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.4.1 diff -C2 -r1.34 -r1.34.4.1 *** test_b1.py 2001/01/22 19:30:07 1.34 --- test_b1.py 2001/06/27 14:26:58 1.34.4.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: From twouters@users.sourceforge.net Wed Jun 27 16:07:19 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 27 Jun 2001 08:07:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib doctest.py,1.10,1.10.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv19885/Lib Modified Files: Tag: release21-maint doctest.py Log Message: Backport Tim's checkin 1.12: doctest systematically leaked memory when handling an exception in an example (an obvious trackback cycle). Repaired. Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.10 retrieving revision 1.10.2.1 diff -C2 -r1.10 -r1.10.2.1 *** doctest.py 2001/03/21 23:07:59 1.10 --- doctest.py 2001/06/27 15:07:17 1.10.2.1 *************** *** 501,505 **** # 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 --- 501,505 ---- # 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)[0] state = OK From bwarsaw@users.sourceforge.net Wed Jun 27 18:11:35 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Wed, 27 Jun 2001 10:11:35 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0100.txt,NONE,1.7 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv19535 Added Files: Tag: 1.7 pep-0100.txt Log Message: A reformat of Misc/unicode.txt (with some editorial comments). Tagging at revision 1.7 to match the latest revision from Misc/unicode.txt. --- NEW FILE: pep-0100.txt --- PEP: 100 Title: Python Unicode Integration Version: $Revision: 1.7 $ Author: mal@lemburg.com (Marc-Andre Lemburg) Status: Final Type: Standards Track Created: 10-Mar-2000 Python-Version: 2.0 Post-History: Historical Note This document was first written by Marc-Andre in the pre-PEP days, and was originally distributed as Misc/unicode.txt in Python distributions up to and included Python 2.1. The last revision of the proposal in that location was labeled version 1.7 (CVS revision 3.10). Because the document clearly serves the purpose of an informational PEP in the post-PEP era, it has been moved [...1096 lines suppressed...] 0.5: moved sys.bom to unicodec.BOM; added sections on case mapping, private use encodings and Unicode character properties 0.4: added Codec interface, notes on %-formatting, changed some encoding details, added comments on stream wrappers, fixed some discussion points (most important: Internal Format), clarified the 'unicode-escape' encoding, added encoding references 0.3: added references, comments on codec modules, the internal format, bf_getcharbuffer and the RE engine; added 'unicode-escape' encoding proposed by Tim Peters and fixed repr(u) accordingly 0.2: integrated Guido's suggestions, added stream codecs and file wrapping 0.1: first version Local Variables: mode: indented-text indent-tabs-mode: nil End: From bwarsaw@users.sourceforge.net Wed Jun 27 18:12:07 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Wed, 27 Jun 2001 10:12:07 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0000.txt,1.100,1.101 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv19950 Modified Files: pep-0000.txt Log Message: Added PEP 100, Python Unicode Integration, Lemburg Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.100 retrieving revision 1.101 diff -C2 -r1.100 -r1.101 *** pep-0000.txt 2001/06/26 17:57:11 1.100 --- pep-0000.txt 2001/06/27 17:12:05 1.101 *************** *** 78,81 **** --- 78,82 ---- Finished PEPs (done, implemented) + SF 100 pep-0100.txt Python Unicode Integration Lemburg IF 160 pep-0160.txt Python 1.6 Release Schedule Drake IF 200 pep-0200.txt Python 2.0 Release Schedule Hylton *************** *** 125,128 **** --- 126,130 ---- I 6 pep-0006.txt Bug Fix Releases Aahz 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 bwarsaw@users.sourceforge.net Wed Jun 27 18:14:06 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Wed, 27 Jun 2001 10:14:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc unicode.txt,3.10,3.11 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv20567 Modified Files: unicode.txt Log Message: Replace the text with a link to the PEP-ified version. Index: unicode.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/unicode.txt,v retrieving revision 3.10 retrieving revision 3.11 diff -C2 -r3.10 -r3.11 *** unicode.txt 2000/09/21 21:21:59 3.10 --- unicode.txt 2001/06/27 17:14:04 3.11 *************** *** 1,1115 **** ! ============================================================================= ! Python Unicode Integration Proposal Version: 1.7 ! ----------------------------------------------------------------------------- ! Introduction: ! ------------- ! ! The idea of this proposal is to add native Unicode 3.0 support to ! Python in a way that makes use of Unicode strings as simple as [...1091 lines suppressed...] ! details, added comments on stream wrappers, fixed some discussion ! points (most important: Internal Format), clarified the ! 'unicode-escape' encoding, added encoding references ! 0.3: added references, comments on codec modules, the internal format, ! bf_getcharbuffer and the RE engine; added 'unicode-escape' encoding ! proposed by Tim Peters and fixed repr(u) accordingly ! 0.2: integrated Guido's suggestions, added stream codecs and file ! wrapping ! 0.1: first version ! ! ! ----------------------------------------------------------------------------- ! Written by Marc-Andre Lemburg, 1999-2000, mal@lemburg.com ! ----------------------------------------------------------------------------- --- 1,5 ---- ! This document has been PEP-ified. Please see PEP 100 at: + http://www.python.org/peps/pep-0100.html ! -Barry From effbot@users.sourceforge.net Wed Jun 27 19:59:45 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Wed, 27 Jun 2001 11:59:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include unicodeobject.h,2.25,2.26 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv12059/Include Modified Files: unicodeobject.h Log Message: use Py_UNICODE_WIDE instead of USE_UCS4_STORAGE and Py_UNICODE_SIZE tests. Index: unicodeobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/unicodeobject.h,v retrieving revision 2.25 retrieving revision 2.26 diff -C2 -r2.25 -r2.26 *** unicodeobject.h 2001/06/27 06:28:56 2.25 --- unicodeobject.h 2001/06/27 18:59:43 2.26 *************** *** 67,74 **** #endif ! /* experimental UCS-4 support. enable at your own risk! */ ! #undef USE_UCS4_STORAGE ! #if Py_UNICODE_SIZE == 4 ! #define USE_UCS4_STORAGE #endif --- 67,75 ---- #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 *************** *** 82,91 **** /* Windows has a usable wchar_t type (unless we're using UCS-4) */ ! # if defined(MS_WIN32) && !defined(USE_UCS4_STORAGE) # define HAVE_USABLE_WCHAR_T # define PY_UNICODE_TYPE wchar_t # endif ! # if defined(USE_UCS4_STORAGE) # define PY_UNICODE_TYPE Py_UCS4 # endif --- 83,92 ---- /* 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 From effbot@users.sourceforge.net Wed Jun 27 19:59:45 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Wed, 27 Jun 2001 11:59:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects unicodeobject.c,2.100,2.101 unicodectype.c,2.9,2.10 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv12059/Objects Modified Files: unicodeobject.c unicodectype.c Log Message: use Py_UNICODE_WIDE instead of USE_UCS4_STORAGE and Py_UNICODE_SIZE tests. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.100 retrieving revision 2.101 diff -C2 -r2.100 -r2.101 *** unicodeobject.c 2001/06/27 06:28:56 2.100 --- unicodeobject.c 2001/06/27 18:59:43 2.101 *************** *** 107,111 **** PyUnicode_GetMax() { ! #ifdef USE_UCS4_STORAGE return 0x10FFFF; #else --- 107,111 ---- PyUnicode_GetMax() { ! #ifdef Py_UNICODE_WIDE return 0x10FFFF; #else *************** *** 792,796 **** goto utf8Error; } ! #if Py_UNICODE_SIZE == 4 *p++ = (Py_UNICODE)ch; #else --- 792,796 ---- goto utf8Error; } ! #ifdef Py_UNICODE_WIDE *p++ = (Py_UNICODE)ch; #else *************** *** 1081,1085 **** #endif if (0xDC00 <= ch2 && ch2 <= 0xDFFF) { ! #if Py_UNICODE_SIZE == 2 /* This is valid data (a UTF-16 surrogate pair), but we are not able to store this information since our --- 1081,1085 ---- #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 *************** *** 1327,1331 **** else if (chr <= 0x10ffff) { /* UCS-4 character. Either store directly, or as surrogate pair. */ ! #if Py_UNICODE_SIZE == 4 *p++ = chr; #else --- 1327,1331 ---- else if (chr <= 0x10ffff) { /* UCS-4 character. Either store directly, or as surrogate pair. */ ! #ifdef Py_UNICODE_WIDE *p++ = chr; #else Index: unicodectype.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodectype.c,v retrieving revision 2.9 retrieving revision 2.10 diff -C2 -r2.9 -r2.10 *** unicodectype.c 2001/06/27 06:28:56 2.9 --- unicodectype.c 2001/06/27 18:59:43 2.10 *************** *** 69,73 **** ch += ctype->upper; ! #ifdef USE_UCS4_STORAGE /* The database assumes that the values wrap around at 0x10000. */ if (ch > 0x10000) --- 69,73 ---- ch += ctype->upper; ! #ifdef Py_UNICODE_WIDE /* The database assumes that the values wrap around at 0x10000. */ if (ch > 0x10000) *************** *** 361,365 **** ch += ctype->upper; ! #ifdef USE_UCS4_STORAGE /* The database assumes that the values wrap around at 0x10000. */ if (ch > 0x10000) --- 361,365 ---- ch += ctype->upper; ! #ifdef Py_UNICODE_WIDE /* The database assumes that the values wrap around at 0x10000. */ if (ch > 0x10000) *************** *** 377,381 **** ch += ctype->lower; ! #ifdef USE_UCS4_STORAGE /* The database assumes that the values wrap around at 0x10000. */ if (ch > 0x10000) --- 377,381 ---- ch += ctype->lower; ! #ifdef Py_UNICODE_WIDE /* The database assumes that the values wrap around at 0x10000. */ if (ch > 0x10000) From effbot@users.sourceforge.net Wed Jun 27 19:59:45 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Wed, 27 Jun 2001 11:59:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.213,2.214 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv12059/Python Modified Files: bltinmodule.c Log Message: use Py_UNICODE_WIDE instead of USE_UCS4_STORAGE and Py_UNICODE_SIZE tests. Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.213 retrieving revision 2.214 diff -C2 -r2.213 -r2.214 *** bltinmodule.c 2001/06/26 23:12:25 2.213 --- bltinmodule.c 2001/06/27 18:59:43 2.214 *************** *** 326,330 **** } else { ! #if Py_UNICODE_SIZE == 2 /* UCS-4 character. store as two surrogate characters */ x -= 0x10000L; --- 326,330 ---- } else { ! #ifndef Py_UNICODE_WIDE /* UCS-4 character. store as two surrogate characters */ x -= 0x10000L; From effbot@users.sourceforge.net Wed Jun 27 19:59:45 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Wed, 27 Jun 2001 11:59:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules sre.h,2.19,2.20 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv12059/Modules Modified Files: sre.h Log Message: use Py_UNICODE_WIDE instead of USE_UCS4_STORAGE and Py_UNICODE_SIZE tests. Index: sre.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/sre.h,v retrieving revision 2.19 retrieving revision 2.20 diff -C2 -r2.19 -r2.20 *** sre.h 2001/06/26 17:17:07 2.19 --- sre.h 2001/06/27 18:59:43 2.20 *************** *** 14,19 **** #include "sre_constants.h" ! /* size of a code word (must be unsigned short or larger) */ ! #ifdef USE_UCS4_STORAGE #define SRE_CODE unsigned long #else --- 14,20 ---- #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 From fdrake@users.sourceforge.net Wed Jun 27 20:18:05 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 27 Jun 2001 12:18:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include ceval.h,2.41,2.42 pystate.h,2.14,2.15 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv18080/Include Modified Files: ceval.h pystate.h Log Message: Revise the interface to the profiling and tracing support for the Python interpreter. This change adds two new C-level APIs: PyEval_SetProfile() and PyEval_SetTrace(). These can be used to install profile and trace functions implemented in C, which can operate at much higher speeds than Python-based functions. The overhead for calling a C-based profile function is a very small fraction of a percent of the overhead involved in calling a Python-based function. The machinery required to call a Python-based profile or trace function been moved to sysmodule.c, where sys.setprofile() and sys.setprofile() simply become users of the new interface. Index: ceval.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/ceval.h,v retrieving revision 2.41 retrieving revision 2.42 diff -C2 -r2.41 -r2.42 *** ceval.h 2001/03/22 02:32:48 2.41 --- ceval.h 2001/06/27 19:18:03 2.42 *************** *** 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: pystate.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pystate.h,v retrieving revision 2.14 retrieving revision 2.15 diff -C2 -r2.14 -r2.15 *** pystate.h 2001/01/23 01:44:35 2.14 --- pystate.h 2001/06/27 19:18:03 2.15 *************** *** 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 { *************** *** 42,47 **** int tracing; ! PyObject *sys_profilefunc; ! PyObject *sys_tracefunc; PyObject *curexc_type; --- 51,58 ---- int tracing; ! Py_tracefunc c_profilefunc; ! Py_tracefunc c_tracefunc; ! PyObject *c_profileobj; ! PyObject *c_traceobj; PyObject *curexc_type; From fdrake@users.sourceforge.net Wed Jun 27 20:19:48 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 27 Jun 2001 12:19:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.258,2.259 pystate.c,2.16,2.17 sysmodule.c,2.87,2.88 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv18718/Python Modified Files: ceval.c pystate.c sysmodule.c Log Message: Revise the interface to the profiling and tracing support for the Python interpreter. This change adds two new C-level APIs: PyEval_SetProfile() and PyEval_SetTrace(). These can be used to install profile and trace functions implemented in C, which can operate at much higher speeds than Python-based functions. The overhead for calling a C-based profile function is a very small fraction of a percent of the overhead involved in calling a Python-based function. The machinery required to call a Python-based profile or trace function been moved to sysmodule.c, where sys.setprofile() and sys.setprofile() simply become users of the new interface. As a side effect, SF bug #436058 is fixed; there is no longer a _PyTrace_Init() function to declare. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.258 retrieving revision 2.259 diff -C2 -r2.258 -r2.259 *** ceval.c 2001/06/26 22:24:51 2.258 --- ceval.c 2001/06/27 19:19:46 2.259 *************** *** 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 XXX document it! *************** *** 62,68 **** static int prtrace(PyObject *, char *); #endif ! static void call_exc_trace(PyObject **, PyObject**, PyFrameObject *); ! static int call_trace(PyObject **, PyObject **, ! PyFrameObject *, PyObject *, PyObject *); static PyObject *loop_subscript(PyObject *, PyObject *); static PyObject *apply_slice(PyObject *, PyObject *, PyObject *); --- 62,68 ---- static int prtrace(PyObject *, char *); #endif ! static int call_trace(Py_tracefunc, PyObject *, PyFrameObject *, ! int, PyObject *); ! static void call_exc_trace(Py_tracefunc, PyObject *, PyFrameObject *); static PyObject *loop_subscript(PyObject *, PyObject *); static PyObject *apply_slice(PyObject *, PyObject *, PyObject *); *************** *** 99,111 **** #endif - /* Cached interned string objects used for calling the profile and - * trace functions. - */ - static PyObject *str_call = NULL; - static PyObject *str_exception = NULL; - static PyObject *str_line = NULL; - static PyObject *str_return = NULL; - staticforward PyTypeObject gentype; --- 99,103 ---- *************** *** 1893,1902 **** #endif f->f_lineno = oparg; ! if (f->f_trace == NULL) continue; /* Trace each line of code reached */ f->f_lasti = INSTR_OFFSET(); ! err = call_trace(&f->f_trace, &f->f_trace, ! f, str_line, Py_None); break; --- 1885,1897 ---- #endif f->f_lineno = oparg; ! if (tstate->c_tracefunc == NULL || tstate->tracing) continue; /* Trace each line of code reached */ f->f_lasti = INSTR_OFFSET(); ! /* Inline call_trace() for performance: */ ! tstate->tracing++; ! err = (tstate->c_tracefunc)(tstate->c_traceobj, f, ! PyTrace_LINE, Py_None); ! tstate->tracing--; break; *************** *** 2148,2156 **** PyTraceBack_Here(f); ! if (f->f_trace) ! call_exc_trace(&f->f_trace, &f->f_trace, f); ! if (tstate->sys_profilefunc) ! call_exc_trace(&tstate->sys_profilefunc, ! (PyObject**)0, f); } --- 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); } *************** *** 2233,2240 **** retval = NULL; ! if (f->f_trace) { if (why == WHY_RETURN || why == WHY_YIELD) { ! if (call_trace(&f->f_trace, &f->f_trace, f, ! str_return, retval)) { Py_XDECREF(retval); retval = NULL; --- 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; *************** *** 2244,2251 **** } ! if (tstate->sys_profilefunc && ! (why == WHY_RETURN || why == WHY_YIELD)) { ! if (call_trace(&tstate->sys_profilefunc, (PyObject**)0, ! f, str_return, retval)) { Py_XDECREF(retval); retval = NULL; --- 2240,2247 ---- } ! 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; *************** *** 2476,2480 **** } ! if (tstate->sys_tracefunc != NULL) { /* tstate->sys_tracefunc, if defined, is a function that will be called on *every* entry to a code block. --- 2472,2476 ---- } ! 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. *************** *** 2489,2495 **** (sys.trace) is also called whenever an exception is detected. */ ! if (call_trace(&tstate->sys_tracefunc, ! &f->f_trace, f, str_call, ! Py_None/*XXX how to compute arguments now?*/)) { /* Trace function raised an error */ goto fail; --- 2485,2491 ---- (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; *************** *** 2497,2506 **** } ! if (tstate->sys_profilefunc != NULL) { /* Similar for sys_profilefunc, except it needn't return itself and isn't called for "line" events */ ! if (call_trace(&tstate->sys_profilefunc, ! (PyObject**)0, f, str_call, ! Py_None/*XXX*/)) { goto fail; } --- 2493,2503 ---- } ! 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; } *************** *** 2773,2777 **** static void ! call_exc_trace(PyObject **p_trace, PyObject **p_newtrace, PyFrameObject *f) { PyObject *type, *value, *traceback, *arg; --- 2770,2774 ---- static void ! call_exc_trace(Py_tracefunc func, PyObject *self, PyFrameObject *f) { PyObject *type, *value, *traceback, *arg; *************** *** 2787,2791 **** return; } ! err = call_trace(p_trace, p_newtrace, f, str_exception, arg); Py_DECREF(arg); if (err == 0) --- 2784,2788 ---- return; } ! err = call_trace(func, self, f, PyTrace_EXCEPTION, arg); Py_DECREF(arg); if (err == 0) *************** *** 2798,2905 **** } - /* PyObject **p_trace: in/out; may not be NULL; - may not point to NULL variable initially - PyObject **p_newtrace: in/out; may be NULL; - may point to NULL variable; - may be same variable as p_newtrace - PyObject *msg: in; must not be NULL - */ - static int ! call_trace(PyObject **p_trace, PyObject **p_newtrace, PyFrameObject *f, ! PyObject *msg, PyObject *arg) { ! PyThreadState *tstate = f->f_tstate; ! PyObject *args; ! PyObject *res = NULL; ! ! if (tstate->tracing) { ! /* Don't do recursive traces */ ! if (p_newtrace) { ! Py_XDECREF(*p_newtrace); ! *p_newtrace = NULL; ! } return 0; - } - - args = PyTuple_New(3); - if (args == NULL) - goto cleanup; - Py_INCREF(msg); - Py_INCREF(f); - PyTuple_SET_ITEM(args, 0, (PyObject *)f); - PyTuple_SET_ITEM(args, 1, msg); - if (arg == NULL) - arg = Py_None; - Py_INCREF(arg); - PyTuple_SET_ITEM(args, 2, arg); tstate->tracing++; ! PyFrame_FastToLocals(f); ! res = PyEval_CallObject(*p_trace, args); /* May clear *p_trace! */ ! PyFrame_LocalsToFast(f, 1); tstate->tracing--; ! cleanup: ! Py_XDECREF(args); ! if (res == NULL) { ! /* The trace proc raised an exception */ ! PyTraceBack_Here(f); ! Py_XDECREF(*p_trace); ! *p_trace = NULL; ! if (p_newtrace) { ! Py_XDECREF(*p_newtrace); ! *p_newtrace = NULL; ! } ! /* to be extra double plus sure we don't get recursive ! * calls inf either tracefunc or profilefunc gets an ! * exception, zap the global variables. ! */ ! Py_XDECREF(tstate->sys_tracefunc); ! tstate->sys_tracefunc = NULL; ! Py_XDECREF(tstate->sys_profilefunc); ! tstate->sys_profilefunc = NULL; ! return -1; ! } ! else { ! if (p_newtrace) { ! Py_XDECREF(*p_newtrace); ! if (res == Py_None) ! *p_newtrace = NULL; ! else { ! Py_INCREF(res); ! *p_newtrace = res; ! } ! } ! Py_DECREF(res); ! return 0; ! } } ! /* Initialize the strings that get passed to the profile and trace functions; ! * this avoids doing this while we're actually profiling/tracing. ! */ ! int ! _PyTrace_Init(void) { ! if (str_call == NULL) { ! str_call = PyString_InternFromString("call"); ! if (str_call == NULL) ! return -1; ! } ! if (str_exception == NULL) { ! str_exception = PyString_InternFromString("exception"); ! if (str_exception == NULL) ! return -1; ! } ! if (str_line == NULL) { ! str_line = PyString_InternFromString("line"); ! if (str_line == NULL) ! return -1; ! } ! if (str_return == NULL) { ! str_return = PyString_InternFromString("return"); ! if (str_return == NULL) ! return -1; ! } ! return 0; } --- 2795,2836 ---- } static int ! call_trace(Py_tracefunc func, PyObject *obj, PyFrameObject *frame, ! int what, PyObject *arg) { ! register PyThreadState *tstate = frame->f_tstate; ! int result; ! if (tstate->tracing) return 0; tstate->tracing++; ! result = func(obj, frame, what, arg); tstate->tracing--; ! return result; } ! void ! PyEval_SetProfile(Py_tracefunc func, PyObject *arg) { ! PyThreadState *tstate = PyThreadState_Get(); ! PyObject *temp = tstate->c_profileobj; ! Py_XINCREF(arg); ! tstate->c_profilefunc = NULL; ! tstate->c_profileobj = NULL; ! Py_XDECREF(temp); ! tstate->c_profilefunc = func; ! tstate->c_profileobj = arg; ! } ! ! void ! PyEval_SetTrace(Py_tracefunc func, PyObject *arg) ! { ! PyThreadState *tstate = PyThreadState_Get(); ! PyObject *temp = tstate->c_traceobj; ! Py_XINCREF(arg); ! tstate->c_tracefunc = NULL; ! tstate->c_traceobj = NULL; ! Py_XDECREF(temp); ! tstate->c_tracefunc = func; ! tstate->c_traceobj = arg; } Index: pystate.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pystate.c,v retrieving revision 2.16 retrieving revision 2.17 diff -C2 -r2.16 -r2.17 *** pystate.c 2001/01/23 01:46:06 2.16 --- pystate.c 2001/06/27 19:19:46 2.17 *************** *** 121,126 **** tstate->exc_traceback = NULL; ! tstate->sys_profilefunc = NULL; ! tstate->sys_tracefunc = NULL; HEAD_LOCK(); --- 121,128 ---- 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); } --- 155,162 ---- ZAP(tstate->exc_traceback); ! tstate->c_profilefunc = NULL; ! tstate->c_tracefunc = NULL; ! ZAP(tstate->c_profileobj); ! ZAP(tstate->c_traceobj); } Index: sysmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/sysmodule.c,v retrieving revision 2.87 retrieving revision 2.88 diff -C2 -r2.87 -r2.88 *** sysmodule.c 2001/06/27 06:28:56 2.87 --- sysmodule.c 2001/06/27 19:19:46 2.88 *************** *** 197,214 **** Set the current default string encoding used by the Unicode implementation."; ! extern int _PyTrace_Init(void); static PyObject * sys_settrace(PyObject *self, PyObject *args) { ! PyThreadState *tstate = PyThreadState_Get(); ! if (_PyTrace_Init() == -1) return NULL; 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; *************** *** 224,236 **** sys_setprofile(PyObject *self, PyObject *args) { ! PyThreadState *tstate = PyThreadState_Get(); ! if (_PyTrace_Init() == -1) return NULL; 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; From effbot@users.sourceforge.net Wed Jun 27 20:49:19 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Wed, 27 Jun 2001 12:49:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/PC config.h,1.54,1.55 Message-ID: Update of /cvsroot/python/python/dist/src/PC In directory usw-pr-cvs1:/tmp/cvs-serv25151/PC Modified Files: config.h Log Message: make wchar_t usable again on Windows (this enables the MBCS codecs) Index: config.h =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/config.h,v retrieving revision 1.54 retrieving revision 1.55 diff -C2 -r1.54 -r1.55 *** config.h 2001/06/26 22:59:49 1.54 --- config.h 2001/06/27 19:49:17 1.55 *************** *** 494,497 **** --- 494,504 ---- #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 From loewis@users.sourceforge.net Wed Jun 27 21:22:06 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 27 Jun 2001 13:22:06 -0700 Subject: [Python-checkins] CVS: python/dist/src configure,1.214,1.215 configure.in,1.222,1.223 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv1000 Modified Files: configure configure.in Log Message: Default to ucs2 when no argument to --enable-unicode is specified. Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.214 retrieving revision 1.215 diff -C2 -r1.214 -r1.215 *** configure 2001/06/26 22:22:36 1.214 --- configure 2001/06/27 20:22:04 1.215 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.221 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.222 # Guess values for system-dependent variables and create Makefiles. *************** *** 6580,6589 **** if test $enable_unicode = yes then ! # Let Py_UNICODE size depend on wchar_t size ! case "$ac_cv_sizeof_wchar_t" in ! 2) enable_unicode="ucs2";; ! 4) enable_unicode="ucs4";; ! *) enable_unicode="ucs4";; # default to UCS-4 ! esac fi --- 6580,6585 ---- if test $enable_unicode = yes then ! # Without any arguments, Py_UNICODE defaults to two-byte mode ! enable_unicode="ucs2" fi *************** *** 6644,6648 **** # check for endianness echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6 ! echo "configure:6647: checking whether byte ordering is bigendian" >&5 if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 --- 6640,6644 ---- # check for endianness echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6 ! echo "configure:6643: checking whether byte ordering is bigendian" >&5 if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 *************** *** 6651,6655 **** # See if sys/param.h defines the BYTE_ORDER macro. cat > conftest.$ac_ext < --- 6647,6651 ---- # See if sys/param.h defines the BYTE_ORDER macro. cat > conftest.$ac_ext < *************** *** 6662,6670 **** ; return 0; } EOF ! if { (eval echo configure:6665: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* # It does; now see whether it defined to BIG_ENDIAN or not. cat > conftest.$ac_ext < --- 6658,6666 ---- ; return 0; } EOF ! if { (eval echo configure:6661: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* # It does; now see whether it defined to BIG_ENDIAN or not. cat > conftest.$ac_ext < *************** *** 6677,6681 **** ; return 0; } EOF ! if { (eval echo configure:6680: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_bigendian=yes --- 6673,6677 ---- ; return 0; } EOF ! if { (eval echo configure:6676: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_bigendian=yes *************** *** 6697,6701 **** else cat > conftest.$ac_ext < conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_bigendian=no --- 6706,6710 ---- } EOF ! if { (eval echo configure:6709: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_bigendian=no *************** *** 6737,6741 **** # or fills with zeros (like the Cray J90, according to Tim Peters). echo $ac_n "checking whether right shift extends the sign bit""... $ac_c" 1>&6 ! echo "configure:6740: checking whether right shift extends the sign bit" >&5 if eval "test \"`echo '$''{'ac_cv_rshift_extends_sign'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 --- 6733,6737 ---- # or fills with zeros (like the Cray J90, according to Tim Peters). echo $ac_n "checking whether right shift extends the sign bit""... $ac_c" 1>&6 ! echo "configure:6736: checking whether right shift extends the sign bit" >&5 if eval "test \"`echo '$''{'ac_cv_rshift_extends_sign'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 *************** *** 6746,6750 **** else cat > conftest.$ac_ext < conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_rshift_extends_sign=yes --- 6751,6755 ---- EOF ! if { (eval echo configure:6754: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_rshift_extends_sign=yes *************** *** 6780,6784 **** # check for getc_unlocked and related locking functions echo $ac_n "checking for getc_unlocked() and friends""... $ac_c" 1>&6 ! echo "configure:6783: checking for getc_unlocked() and friends" >&5 if eval "test \"`echo '$''{'ac_cv_have_getc_unlocked'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 --- 6776,6780 ---- # check for getc_unlocked and related locking functions echo $ac_n "checking for getc_unlocked() and friends""... $ac_c" 1>&6 ! echo "configure:6779: checking for getc_unlocked() and friends" >&5 if eval "test \"`echo '$''{'ac_cv_have_getc_unlocked'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 *************** *** 6786,6790 **** cat > conftest.$ac_ext < --- 6782,6786 ---- cat > conftest.$ac_ext < *************** *** 6798,6802 **** ; return 0; } EOF ! if { (eval echo configure:6801: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_have_getc_unlocked=yes --- 6794,6798 ---- ; return 0; } EOF ! if { (eval echo configure:6797: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_have_getc_unlocked=yes *************** *** 6827,6836 **** EOF echo $ac_n "checking for socklen_t""... $ac_c" 1>&6 ! echo "configure:6830: 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 < --- 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 < *************** *** 6881,6885 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:6884: 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 Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.222 retrieving revision 1.223 diff -C2 -r1.222 -r1.223 *** configure.in 2001/06/26 22:22:36 1.222 --- configure.in 2001/06/27 20:22:04 1.223 *************** *** 1591,1600 **** if test $enable_unicode = yes then ! # Let Py_UNICODE size depend on wchar_t size ! case "$ac_cv_sizeof_wchar_t" in ! 2) enable_unicode="ucs2";; ! 4) enable_unicode="ucs4";; ! *) enable_unicode="ucs4";; # default to UCS-4 ! esac fi --- 1591,1596 ---- if test $enable_unicode = yes then ! # Without any arguments, Py_UNICODE defaults to two-byte mode ! enable_unicode="ucs2" fi From jackjansen@users.sourceforge.net Wed Jun 27 22:58:43 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 27 Jun 2001 14:58:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/bgen/bgen macsupport.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/bgen/bgen In directory usw-pr-cvs1:/tmp/cvs-serv26153/Python/Tools/bgen/bgen Modified Files: macsupport.py Log Message: Added a couple more types that Apple has taken a fancy to. Index: macsupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/macsupport.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -r1.21 -r1.22 *** macsupport.py 2001/02/27 11:05:00 1.21 --- macsupport.py 2001/06/27 21:58:40 1.22 *************** *** 42,46 **** ConstStr255Param = OpaqueArrayType("Str255", "PyMac_BuildStr255", "PyMac_GetStr255") Str255 = OpaqueArrayType("Str255", "PyMac_BuildStr255", "PyMac_GetStr255") ! StringPtr = OpaqueByValueType("StringPtr", "PyMac_BuildStr255", "BUG") # File System Specifications --- 42,47 ---- ConstStr255Param = OpaqueArrayType("Str255", "PyMac_BuildStr255", "PyMac_GetStr255") Str255 = OpaqueArrayType("Str255", "PyMac_BuildStr255", "PyMac_GetStr255") ! StringPtr = OpaqueByValueType("StringPtr", "PyMac_BuildStr255", "PyMac_GetStr255") ! ConstStringPtr = StringPtr # File System Specifications *************** *** 101,104 **** --- 102,106 ---- InBuffer = VarInputBufferType('char', 'long', 'l') # (buf, len) + UcharInBuffer = VarInputBufferType('unsigned char', 'long', 'l') # (buf, len) OptionalInBuffer = OptionalVarInputBufferType('char', 'long', 'l') # (buf, len) From jackjansen@users.sourceforge.net Wed Jun 27 23:00:48 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 27 Jun 2001 15:00:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/cf CFmodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/cf In directory usw-pr-cvs1:/tmp/cvs-serv26774/Python/Mac/Modules/cf Modified Files: CFmodule.c Log Message: CFArray, CFData and CFDictonary are now covered, but mainly opaque. CFStrings are in better shape, but Unicode support and automatic conversion to/from Python strings remains to be done. Index: CFmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/cf/CFmodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** CFmodule.c 2001/06/26 21:51:10 1.1 --- CFmodule.c 2001/06/27 22:00:46 1.2 *************** *** 21,24 **** --- 21,25 ---- extern int CFStringRefObj_Convert(PyObject *, CFStringRef *); + // ADD declarations #ifdef NOTYET_USE_TOOLBOX_OBJECT_GLUE //extern PyObject *_CFTypeRefObj_New(CFTypeRef); *************** *** 29,33 **** --- 30,54 ---- #endif [...2492 lines suppressed...] + if (PyDict_SetItemString(d, "CFMutableDictionaryRefType", (PyObject *)&CFMutableDictionaryRef_Type) != 0) + Py_FatalError("can't initialize CFMutableDictionaryRefType"); + CFDataRef_Type.ob_type = &PyType_Type; + Py_INCREF(&CFDataRef_Type); + if (PyDict_SetItemString(d, "CFDataRefType", (PyObject *)&CFDataRef_Type) != 0) + Py_FatalError("can't initialize CFDataRefType"); + CFMutableDataRef_Type.ob_type = &PyType_Type; + Py_INCREF(&CFMutableDataRef_Type); + if (PyDict_SetItemString(d, "CFMutableDataRefType", (PyObject *)&CFMutableDataRef_Type) != 0) + Py_FatalError("can't initialize CFMutableDataRefType"); CFStringRef_Type.ob_type = &PyType_Type; Py_INCREF(&CFStringRef_Type); if (PyDict_SetItemString(d, "CFStringRefType", (PyObject *)&CFStringRef_Type) != 0) Py_FatalError("can't initialize CFStringRefType"); + CFMutableStringRef_Type.ob_type = &PyType_Type; + Py_INCREF(&CFMutableStringRef_Type); + if (PyDict_SetItemString(d, "CFMutableStringRefType", (PyObject *)&CFMutableStringRef_Type) != 0) + Py_FatalError("can't initialize CFMutableStringRefType"); } From jackjansen@users.sourceforge.net Wed Jun 27 23:00:53 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 27 Jun 2001 15:00:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/cf cfscan.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/cf In directory usw-pr-cvs1:/tmp/cvs-serv26821/Python/Mac/Modules/cf Modified Files: cfscan.py Log Message: CFArray, CFData and CFDictonary are now covered, but mainly opaque. CFStrings are in better shape, but Unicode support and automatic conversion to/from Python strings remains to be done. Index: cfscan.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/cf/cfscan.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cfscan.py 2001/06/26 21:51:14 1.1 --- cfscan.py 2001/06/27 22:00:50 1.2 *************** *** 10,25 **** LONG = "CoreFoundation" SHORT = "cf" ! OBJECTS = ("CFTypeRef", "CFStringRef") def main(): input = [ "CFBase.h", ! ### "CFArray.h", ## "CFBag.h", ## "CFBundle.h", ## "CFCharacterSet.h", ! ### "CFData.h", ## "CFDate.h", ! ### "CFDictionary.h", ## "CFNumber.h", ## "CFPlugIn.h", --- 10,31 ---- LONG = "CoreFoundation" SHORT = "cf" ! OBJECTS = ("CFTypeRef", ! "CFArrayRef", "CFMutableArrayRef", ! "CFDataRef", "CFMutableDataRef", ! "CFDictionaryRef", "CFMutableDictionaryRef", ! "CFStringRef", "CFMutableStringRef", ! ) ! # ADD object typenames here def main(): input = [ "CFBase.h", ! "CFArray.h", ## "CFBag.h", ## "CFBundle.h", ## "CFCharacterSet.h", ! "CFData.h", ## "CFDate.h", ! "CFDictionary.h", ## "CFNumber.h", ## "CFPlugIn.h", *************** *** 27,31 **** ## "CFPropertyList.h", ## "CFSet.h", ! ### "CFString.h", ## "CFStringEncodingExt.h", ## "CFTimeZone.h", --- 33,37 ---- ## "CFPropertyList.h", ## "CFSet.h", ! "CFString.h", ## "CFStringEncodingExt.h", ## "CFTimeZone.h", *************** *** 66,69 **** --- 72,86 ---- "CFAllocatorDeallocate", "CFGetAllocator", + # Array functions we skip for now. + "CFArrayGetValueAtIndex", + # Data pointer functions. Skip for now. + "CFDataGetBytePtr", + "CFDataGetMutableBytePtr", + "CFDataGetBytes", # XXXX Should support this one + # String functions + "CFStringGetPascalString", # Use the C-string methods. + "CFStringGetPascalStringPtr", # TBD automatically + "CFStringGetCStringPtr", + "CFStringGetCharactersPtr", ] *************** *** 73,81 **** def makeblacklisttypes(self): return [ ! "CFAllocatorContext", ] def makerepairinstructions(self): return [ ] --- 90,112 ---- def makeblacklisttypes(self): return [ ! "CFComparatorFunction", # Callback function pointer ! "CFAllocatorContext", # Not interested in providing our own allocator ! "void_ptr_ptr", # Tricky. This is the initializer for arrays... ! "void_ptr", # Ditto for various array lookup methods ! "CFArrayApplierFunction", # Callback function pointer ! "CFDictionaryApplierFunction", # Callback function pointer ! "UniChar_ptr", # XXXX To be done ! "const_UniChar_ptr", # XXXX To be done ! "UniChar", # XXXX To be done ! "va_list", # For printf-to-a-cfstring. Use Python. ! "const_CFStringEncoding_ptr", # To be done, I guess ] def makerepairinstructions(self): return [ + ([("UInt8_ptr", "*", "InMode"), ("CFIndex", "*", "InMode")], + [("UcharInBuffer", "*", "*")]), + ([("const_char_ptr", "*", "ReturnMode")], + [("return_stringptr", "*", "*")]), ] From jackjansen@users.sourceforge.net Wed Jun 27 23:00:57 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 27 Jun 2001 15:00:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/cf cfsupport.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/cf In directory usw-pr-cvs1:/tmp/cvs-serv26842/Python/Mac/Modules/cf Modified Files: cfsupport.py Log Message: CFArray, CFData and CFDictonary are now covered, but mainly opaque. CFStrings are in better shape, but Unicode support and automatic conversion to/from Python strings remains to be done. Index: cfsupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/cf/cfsupport.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cfsupport.py 2001/06/26 21:51:18 1.1 --- cfsupport.py 2001/06/27 22:00:55 1.2 *************** *** 33,36 **** --- 33,37 ---- extern int CFStringRefObj_Convert(PyObject *, CFStringRef *); + // ADD declarations #ifdef NOTYET_USE_TOOLBOX_OBJECT_GLUE //extern PyObject *_CFTypeRefObj_New(CFTypeRef); *************** *** 41,44 **** --- 42,65 ---- #endif + /* + ** Parse/generate RGB records + */ + PyObject *CFRange_New(CFRange *itself) + { + + return Py_BuildValue("ll", (long)itself->location, (long)itself->length); + } + + CFRange_Convert(PyObject *v, CFRange *p_itself) + { + long location, length; + + if( !PyArg_ParseTuple(v, "ll", &location, &length) ) + return 0; + p_itself->location = (CFIndex)location; + p_itself->length = (CFIndex)length; + return 1; + } + """ *************** *** 52,62 **** CFHashCode = Type("CFHashCode", "l") CFIndex = Type("CFIndex", "l") CFOptionFlags = Type("CFOptionFlags", "l") ! ## CFStringRef = XXXX ! CFAllocatorRef = FakeType("(CFAllocatorRef)NULL") # The real objects CFTypeRef = OpaqueByValueType("CFTypeRef", "CFTypeRefObj") CFStringRef = OpaqueByValueType("CFStringRef", "CFStringRefObj") # Our (opaque) objects --- 73,101 ---- CFHashCode = Type("CFHashCode", "l") CFIndex = Type("CFIndex", "l") + CFRange = OpaqueByValueType('CFRange', 'CFRange') CFOptionFlags = Type("CFOptionFlags", "l") ! CFStringEncoding = Type("CFStringEncoding", "l") ! CFComparisonResult = Type("CFComparisonResult", "l") # a bit dangerous... + char_ptr = stringptr + return_stringptr = Type("char *", "s") # ONLY FOR RETURN VALUES!! + + CFAllocatorRef = FakeType("(CFAllocatorRef)NULL") + CFArrayCallBacks_ptr = FakeType("&kCFTypeArrayCallBacks") + CFDictionaryKeyCallBacks_ptr = FakeType("&kCFTypeDictionaryKeyCallBacks") + CFDictionaryValueCallBacks_ptr = FakeType("&kCFTypeDictionaryValueCallBacks") # The real objects CFTypeRef = OpaqueByValueType("CFTypeRef", "CFTypeRefObj") + CFArrayRef = OpaqueByValueType("CFArrayRef", "CFArrayRefObj") + CFMutableArrayRef = OpaqueByValueType("CFMutableArrayRef", "CFMutableArrayRefObj") + CFArrayRef = OpaqueByValueType("CFArrayRef", "CFArrayRefObj") + CFMutableArrayRef = OpaqueByValueType("CFMutableArrayRef", "CFMutableArrayRefObj") + CFDataRef = OpaqueByValueType("CFDataRef", "CFDataRefObj") + CFMutableDataRef = OpaqueByValueType("CFMutableDataRef", "CFMutableDataRefObj") + CFDictionaryRef = OpaqueByValueType("CFDictionaryRef", "CFDictionaryRefObj") + CFMutableDictionaryRef = OpaqueByValueType("CFMutableDictionaryRef", "CFMutableDictionaryRefObj") CFStringRef = OpaqueByValueType("CFStringRef", "CFStringRefObj") + CFMutableStringRef = OpaqueByValueType("CFMutableStringRef", "CFMutableStringRefObj") + # ADD object type here # Our (opaque) objects *************** *** 114,117 **** --- 153,228 ---- pass + class CFArrayRefObjectDefinition(MyGlobalObjectDefinition): + basechain = "&CFTypeRefObj_chain" + + def outputRepr(self): + Output() + Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype) + OutLbrace() + Output("char buf[100];") + Output("""sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself);""") + Output("return PyString_FromString(buf);") + OutRbrace() + + class CFMutableArrayRefObjectDefinition(MyGlobalObjectDefinition): + basechain = "&CFArrayRefObj_chain" + + def outputRepr(self): + Output() + Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype) + OutLbrace() + Output("char buf[100];") + Output("""sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself);""") + Output("return PyString_FromString(buf);") + OutRbrace() + + class CFDictionaryRefObjectDefinition(MyGlobalObjectDefinition): + basechain = "&CFTypeRefObj_chain" + + def outputRepr(self): + Output() + Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype) + OutLbrace() + Output("char buf[100];") + Output("""sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself);""") + Output("return PyString_FromString(buf);") + OutRbrace() + + class CFMutableDictionaryRefObjectDefinition(MyGlobalObjectDefinition): + basechain = "&CFDictionaryRefObj_chain" + + def outputRepr(self): + Output() + Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype) + OutLbrace() + Output("char buf[100];") + Output("""sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself);""") + Output("return PyString_FromString(buf);") + OutRbrace() + + class CFDataRefObjectDefinition(MyGlobalObjectDefinition): + basechain = "&CFTypeRefObj_chain" + + def outputRepr(self): + Output() + Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype) + OutLbrace() + Output("char buf[100];") + Output("""sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself);""") + Output("return PyString_FromString(buf);") + OutRbrace() + + class CFMutableDataRefObjectDefinition(MyGlobalObjectDefinition): + basechain = "&CFDataRefObj_chain" + + def outputRepr(self): + Output() + Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype) + OutLbrace() + Output("char buf[100];") + Output("""sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself);""") + Output("return PyString_FromString(buf);") + OutRbrace() + class CFStringRefObjectDefinition(MyGlobalObjectDefinition): basechain = "&CFTypeRefObj_chain" *************** *** 122,129 **** OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() # From here on it's basically all boiler plate... --- 233,255 ---- OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() + + class CFMutableStringRefObjectDefinition(CFStringRefObjectDefinition): + basechain = "&CFStringRefObj_chain" + def outputRepr(self): + Output() + Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype) + OutLbrace() + Output("char buf[100];") + Output("""sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself);""") + Output("return PyString_FromString(buf);") + OutRbrace() + + + # ADD object class here + # From here on it's basically all boiler plate... *************** *** 131,138 **** --- 257,281 ---- module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff) CFTypeRef_object = CFTypeRefObjectDefinition('CFTypeRef', 'CFTypeRefObj', 'CFTypeRef') + CFArrayRef_object = CFTypeRefObjectDefinition('CFArrayRef', 'CFArrayRefObj', 'CFArrayRef') + CFMutableArrayRef_object = CFTypeRefObjectDefinition('CFMutableArrayRef', 'CFMutableArrayRefObj', 'CFMutableArrayRef') + CFDictionaryRef_object = CFTypeRefObjectDefinition('CFDictionaryRef', 'CFDictionaryRefObj', 'CFDictionaryRef') + CFMutableDictionaryRef_object = CFTypeRefObjectDefinition('CFMutableDictionaryRef', 'CFMutableDictionaryRefObj', 'CFMutableDictionaryRef') + CFDataRef_object = CFTypeRefObjectDefinition('CFDataRef', 'CFDataRefObj', 'CFDataRef') + CFMutableDataRef_object = CFTypeRefObjectDefinition('CFMutableDataRef', 'CFMutableDataRefObj', 'CFMutableDataRef') CFStringRef_object = CFTypeRefObjectDefinition('CFStringRef', 'CFStringRefObj', 'CFStringRef') + CFMutableStringRef_object = CFTypeRefObjectDefinition('CFMutableStringRef', 'CFMutableStringRefObj', 'CFMutableStringRef') + + # ADD object here module.addobject(CFTypeRef_object) + module.addobject(CFArrayRef_object) + module.addobject(CFMutableArrayRef_object) + module.addobject(CFDictionaryRef_object) + module.addobject(CFMutableDictionaryRef_object) + module.addobject(CFDataRef_object) + module.addobject(CFMutableDataRef_object) module.addobject(CFStringRef_object) + module.addobject(CFMutableStringRef_object) + # ADD addobject call here # Create the generator classes used to populate the lists *************** *** 143,147 **** --- 286,299 ---- functions = [] CFTypeRef_methods = [] + CFArrayRef_methods = [] + CFMutableArrayRef_methods = [] + CFDictionaryRef_methods = [] + CFMutableDictionaryRef_methods = [] + CFDataRef_methods = [] + CFMutableDataRef_methods = [] CFStringRef_methods = [] + CFMutableStringRef_methods = [] + + # ADD _methods initializer here execfile(INPUTFILE) *************** *** 151,155 **** --- 303,316 ---- for f in functions: module.add(f) for f in CFTypeRef_methods: CFTypeRef_object.add(f) + for f in CFArrayRef_methods: CFArrayRef_object.add(f) + for f in CFMutableArrayRef_methods: CFMutableArrayRef_object.add(f) + for f in CFDictionaryRef_methods: CFDictionaryRef_object.add(f) + for f in CFMutableDictionaryRef_methods: CFMutableDictionaryRef_object.add(f) + for f in CFDataRef_methods: CFDataRef_object.add(f) + for f in CFMutableDataRef_methods: CFMutableDataRef_object.add(f) for f in CFStringRef_methods: CFStringRef_object.add(f) + for f in CFMutableStringRef_methods: CFMutableStringRef_object.add(f) + + # ADD add forloop here # generate output (open the output file as late as possible) From effbot@users.sourceforge.net Wed Jun 27 23:08:28 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Wed, 27 Jun 2001 15:08:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include unicodeobject.h,2.26,2.27 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv28328/Include Modified Files: unicodeobject.h Log Message: removed "register const" from scalar arguments to the unicode predicates Index: unicodeobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/unicodeobject.h,v retrieving revision 2.26 retrieving revision 2.27 diff -C2 -r2.26 -r2.27 *** unicodeobject.h 2001/06/27 18:59:43 2.26 --- unicodeobject.h 2001/06/27 22:08:26 2.27 *************** *** 865,925 **** 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 effbot@users.sourceforge.net Wed Jun 27 23:08:29 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Wed, 27 Jun 2001 15:08:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects unicodectype.c,2.10,2.11 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv28328/Objects Modified Files: unicodectype.c Log Message: removed "register const" from scalar arguments to the unicode predicates Index: unicodectype.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodectype.c,v retrieving revision 2.10 retrieving revision 2.11 diff -C2 -r2.10 -r2.11 *** unicodectype.c 2001/06/27 18:59:43 2.10 --- unicodectype.c 2001/06/27 22:08:26 2.11 *************** *** 50,54 **** 'B', 0 otherwise. */ ! int _PyUnicode_IsLinebreak(register const Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); --- 50,54 ---- 'B', 0 otherwise. */ ! int _PyUnicode_IsLinebreak(Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); *************** *** 80,84 **** 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); *************** *** 90,94 **** 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); *************** *** 97,101 **** } ! 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) *************** *** 107,111 **** 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); *************** *** 114,118 **** } ! 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) *************** *** 126,130 **** /* 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) { *************** *** 314,318 **** } ! 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) *************** *** 326,330 **** '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); *************** *** 336,340 **** 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); *************** *** 346,350 **** 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); *************** *** 356,360 **** ch if no uppercase mapping is known. */ ! Py_UNICODE _PyUnicode_ToUppercase(register Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); --- 356,360 ---- ch if no uppercase mapping is known. */ ! Py_UNICODE _PyUnicode_ToUppercase(Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); *************** *** 372,376 **** ch if no lowercase mapping is known. */ ! Py_UNICODE _PyUnicode_ToLowercase(register Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); --- 372,376 ---- ch if no lowercase mapping is known. */ ! Py_UNICODE _PyUnicode_ToLowercase(Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); *************** *** 388,392 **** '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); *************** *** 400,429 **** 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); From prescod@users.sourceforge.net Wed Jun 27 23:47:11 2001 From: prescod@users.sourceforge.net (Paul Prescod) Date: Wed, 27 Jun 2001 15:47:11 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0261.txt,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv4977 Added Files: pep-0261.txt Log Message: Add new PEP about handling non-BMP Unicode characters. --- NEW FILE: pep-0261.txt --- PEP: 261 Title: Python Support for "Wide" Unicode characters Version: 1.0 Author: paulp@activestate.com (Paul Prescod) Status: Draft Type: Standards Track Python-Version: 2.2 Created: 27-Jun-2001 Post-History: 27-Jun-2001 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? From bwarsaw@users.sourceforge.net Thu Jun 28 00:12:10 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Wed, 27 Jun 2001 16:12:10 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0261.txt,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv11486 Modified Files: pep-0261.txt Log Message: Formatting and a title change to fit the PEP 1 guidelines. Index: pep-0261.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0261.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** pep-0261.txt 2001/06/27 22:47:09 1.1 --- pep-0261.txt 2001/06/27 23:12:08 1.2 *************** *** 1,10 **** PEP: 261 ! Title: Python Support for "Wide" Unicode characters ! Version: 1.0 Author: paulp@activestate.com (Paul Prescod) Status: Draft Type: Standards Track - Python-Version: 2.2 Created: 27-Jun-2001 Post-History: 27-Jun-2001 --- 1,10 ---- PEP: 261 ! Title: Support for "wide" Unicode characters ! Version: $Revision$ Author: paulp@activestate.com (Paul Prescod) Status: Draft Type: Standards Track Created: 27-Jun-2001 + Python-Version: 2.2 Post-History: 27-Jun-2001 *************** *** 18,44 **** 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 --- 18,45 ---- 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 *************** *** 46,75 **** * 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 --- 47,76 ---- * 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 *************** *** 86,90 **** --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, --- 87,91 ---- --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, *************** *** 94,97 **** --- 95,99 ---- removes the Unicode type altogether; this is not yet implemented. + Notes *************** *** 104,125 **** ... ! 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? --- 106,135 ---- ... ! 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? + + + + Local Variables: + mode: indented-text + indent-tabs-mode: nil + End: From bwarsaw@users.sourceforge.net Thu Jun 28 00:12:56 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Wed, 27 Jun 2001 16:12:56 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0000.txt,1.101,1.102 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv11658 Modified Files: pep-0000.txt Log Message: Add PEP 261, Support for "wide" Unicode characters, Prescod Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.101 retrieving revision 1.102 diff -C2 -r1.101 -r1.102 *** pep-0000.txt 2001/06/27 17:12:05 1.101 --- pep-0000.txt 2001/06/27 23:12:54 1.102 *************** *** 62,65 **** --- 62,66 ---- S 258 pep-0258.txt DPS Generic Implementation Details Goodger S 260 pep-0260.txt Simplify xrange() van Rossum + S 261 pep-0261.txt Support for "wide" Unicode characters Prescod Py-in-the-sky PEPs (not ready; may become active yet) *************** *** 191,195 **** SR 259 pep-0259.txt Omit printing newline after newline van Rossum S 260 pep-0260.txt Simplify xrange() van Rossum ! Key --- 192,196 ---- SR 259 pep-0259.txt Omit printing newline after newline van Rossum S 260 pep-0260.txt Simplify xrange() van Rossum ! S 261 pep-0261.txt Support for "wide" Unicode characters Prescod Key From tim_one@users.sourceforge.net Thu Jun 28 02:52:24 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 27 Jun 2001 18:52:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv21972/python/dist/src/Lib/test Modified Files: test_generators.py Log Message: Another "if 0:" hack, this time to complain about otherwise invisible "return expr" instances in generators (which latter may be generators due to otherwise invisible "yield" stmts hiding in "if 0" blocks). This was fun the first time, but this has gotten truly ugly now. Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -r1.12 -r1.13 *** test_generators.py 2001/06/27 07:17:57 1.12 --- test_generators.py 2001/06/28 01:52:22 1.13 *************** *** 653,656 **** --- 653,667 ---- >>> def f(): + ... yield + Traceback (most recent call last): + SyntaxError: invalid syntax + + >>> def f(): + ... if 0: + ... yield + Traceback (most recent call last): + SyntaxError: invalid syntax + + >>> def f(): ... if 0: ... yield 1 *************** *** 705,708 **** --- 716,741 ---- >>> type(f()) + + >>> def f(): + ... if 0: + ... return + ... if 0: + ... yield 2 + >>> type(f()) + + + + >>> def f(): + ... if 0: + ... lambda x: x # shouldn't trigger here + ... return # or here + ... def f(i): + ... return 2*i # or here + ... if 0: + ... return 3 # but *this* sucks (line 8) + ... if 0: + ... yield 2 # because it's a generator + Traceback (most recent call last): + SyntaxError: 'return' with argument inside generator (, line 8) """ From tim_one@users.sourceforge.net Thu Jun 28 02:52:25 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 27 Jun 2001 18:52:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python compile.c,2.205,2.206 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv21972/python/dist/src/Python Modified Files: compile.c Log Message: Another "if 0:" hack, this time to complain about otherwise invisible "return expr" instances in generators (which latter may be generators due to otherwise invisible "yield" stmts hiding in "if 0" blocks). This was fun the first time, but this has gotten truly ugly now. Index: compile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v retrieving revision 2.205 retrieving revision 2.206 diff -C2 -r2.205 -r2.206 *** compile.c 2001/06/26 03:36:28 2.205 --- compile.c 2001/06/28 01:52:22 2.206 *************** *** 2877,2880 **** --- 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) *************** *** 2887,2892 **** 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); *************** *** 4841,4845 **** #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. */ static int look_for_yield(node *n) --- 4896,4903 ---- #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) *************** *** 4854,4857 **** --- 4912,4916 ---- case classdef: case funcdef: + case lambdef: /* Stuff in nested functions and classes can't make the parent a generator. */ From gvanrossum@users.sourceforge.net Thu Jun 28 17:11:37 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 28 Jun 2001 09:11:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules config.c.in,1.73,1.73.6.1 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv2073 Modified Files: Tag: descr-branch config.c.in Log Message: Disallow reload(exceptions), which breaks stuff pretty seriously, by not listing a function pointer for the initialization. The exceptions module is initialized by Py_Initialize() anyway. Index: config.c.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/config.c.in,v retrieving revision 1.73 retrieving revision 1.73.6.1 diff -C2 -r1.73 -r1.73.6.1 *** config.c.in 2001/01/23 21:46:57 1.73 --- config.c.in 2001/06/28 16:11:35 1.73.6.1 *************** *** 38,42 **** {"__builtin__", NULL}, {"sys", NULL}, ! {"exceptions", init_exceptions}, /* Sentinel */ --- 38,42 ---- {"__builtin__", NULL}, {"sys", NULL}, ! {"exceptions", NULL}, /* Sentinel */ From gvanrossum@users.sourceforge.net Thu Jun 28 17:15:40 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 28 Jun 2001 09:15:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include pythonrun.h,2.41,2.41.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv3160/Include Modified Files: Tag: descr-branch pythonrun.h Log Message: Rename init_exceptions() and fini_exceptions() to _PyExc_Init() and _PyExc_Fini(). Add some more careful error checks to the start of _PyExc_Init(). (Using PyErr_Occurred() before the exceptions have been initialized is not a good idea. :-) Index: pythonrun.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pythonrun.h,v retrieving revision 2.41 retrieving revision 2.41.4.1 diff -C2 -r2.41 -r2.41.4.1 *** pythonrun.h 2001/03/23 02:46:52 2.41 --- pythonrun.h 2001/06/28 16:15:37 2.41.4.1 *************** *** 85,92 **** DL_IMPORT(PyObject *) _PySys_Init(void); DL_IMPORT(void) _PyImport_Init(void); ! DL_IMPORT(void) init_exceptions(void); /* Various internal finalizers */ ! DL_IMPORT(void) fini_exceptions(void); DL_IMPORT(void) _PyImport_Fini(void); DL_IMPORT(void) PyMethod_Fini(void); --- 85,92 ---- DL_IMPORT(PyObject *) _PySys_Init(void); DL_IMPORT(void) _PyImport_Init(void); ! DL_IMPORT(void) _PyExc_Init(void); /* Various internal finalizers */ ! DL_IMPORT(void) _PyExc_Fini(void); DL_IMPORT(void) _PyImport_Fini(void); DL_IMPORT(void) PyMethod_Fini(void); From gvanrossum@users.sourceforge.net Thu Jun 28 17:15:40 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 28 Jun 2001 09:15:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python pythonrun.c,2.133,2.133.4.1 exceptions.c,1.24,1.24.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv3160/Python Modified Files: Tag: descr-branch pythonrun.c exceptions.c Log Message: Rename init_exceptions() and fini_exceptions() to _PyExc_Init() and _PyExc_Fini(). Add some more careful error checks to the start of _PyExc_Init(). (Using PyErr_Occurred() before the exceptions have been initialized is not a good idea. :-) Index: pythonrun.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.133 retrieving revision 2.133.4.1 diff -C2 -r2.133 -r2.133.4.1 *** pythonrun.c 2001/03/26 19:53:38 2.133 --- pythonrun.c 2001/06/28 16:15:38 2.133.4.1 *************** *** 144,148 **** /* initialize builtin exceptions */ ! init_exceptions(); /* phase 2 of builtins */ --- 144,148 ---- /* initialize builtin exceptions */ ! _PyExc_Init(); /* phase 2 of builtins */ *************** *** 238,242 **** raised. */ ! fini_exceptions(); /* Delete current thread */ --- 238,242 ---- raised. */ ! _PyExc_Fini(); /* Delete current thread */ Index: exceptions.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/exceptions.c,v retrieving revision 1.24 retrieving revision 1.24.2.1 diff -C2 -r1.24 -r1.24.2.1 *** exceptions.c 2001/04/20 19:13:02 1.24 --- exceptions.c 2001/06/28 16:15:38 1.24.2.1 *************** *** 1057,1077 **** DL_EXPORT(void) ! init_exceptions(void) { char *modulename = "exceptions"; int modnamesz = strlen(modulename); int i; ! PyObject *me = Py_InitModule(modulename, functions); ! PyObject *mydict = PyModule_GetDict(me); ! PyObject *bltinmod = PyImport_ImportModule("__builtin__"); ! PyObject *bdict = PyModule_GetDict(bltinmod); ! PyObject *doc = PyString_FromString(module__doc__); ! PyObject *args; ! PyDict_SetItemString(mydict, "__doc__", doc); Py_DECREF(doc); ! if (PyErr_Occurred()) Py_FatalError("exceptions bootstrapping error."); /* This is the base class of all exceptions, so make it first. */ --- 1057,1089 ---- DL_EXPORT(void) ! _PyExc_Init(void) { char *modulename = "exceptions"; int modnamesz = strlen(modulename); int i; + PyObject *me, *mydict, *bltinmod, *bdict, *doc, *args; ! me = Py_InitModule(modulename, functions); ! if (me == NULL) ! goto err; ! mydict = PyModule_GetDict(me); ! if (mydict == NULL) ! goto err; ! bltinmod = PyImport_ImportModule("__builtin__"); ! if (bltinmod == NULL) ! goto err; ! bdict = PyModule_GetDict(bltinmod); ! if (bdict == NULL) ! goto err; ! doc = PyString_FromString(module__doc__); ! if (doc == NULL) ! goto err; ! i = PyDict_SetItemString(mydict, "__doc__", doc); Py_DECREF(doc); ! if (i < 0) { ! err: Py_FatalError("exceptions bootstrapping error."); + } /* This is the base class of all exceptions, so make it first. */ *************** *** 1140,1144 **** DL_EXPORT(void) ! fini_exceptions(void) { int i; --- 1152,1156 ---- DL_EXPORT(void) ! _PyExc_Fini(void) { int i; From gvanrossum@users.sourceforge.net Thu Jun 28 17:21:09 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 28 Jun 2001 09:21:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python import.c,2.176,2.176.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv5321 Modified Files: Tag: descr-branch import.c Log Message: PyImport_Import(): when PyDict_GetItem() returns NULL and we treat this as an error, we must set an exception condition. Index: import.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/import.c,v retrieving revision 2.176 retrieving revision 2.176.2.1 diff -C2 -r2.176 -r2.176.2.1 *** import.c 2001/04/20 19:13:02 2.176 --- import.c 2001/06/28 16:21:07 2.176.2.1 *************** *** 1943,1948 **** /* Get the __import__ function from the builtins */ ! if (PyDict_Check(builtins)) import = PyObject_GetItem(builtins, import_str); else import = PyObject_GetAttr(builtins, import_str); --- 1943,1951 ---- /* Get the __import__ function from the builtins */ ! if (PyDict_Check(builtins)) { import = PyObject_GetItem(builtins, import_str); + if (import == NULL) + PyErr_SetObject(PyExc_KeyError, import_str); + } else import = PyObject_GetAttr(builtins, import_str); From gvanrossum@users.sourceforge.net Thu Jun 28 17:23:04 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 28 Jun 2001 09:23:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python exceptions.c,1.24.2.1,1.24.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv6056 Modified Files: Tag: descr-branch exceptions.c Log Message: _PyExc_Init(): add an unreachable return after the Py_FatalError() call so gcc won't warn about uninitialized variables. Index: exceptions.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/exceptions.c,v retrieving revision 1.24.2.1 retrieving revision 1.24.2.2 diff -C2 -r1.24.2.1 -r1.24.2.2 *** exceptions.c 2001/06/28 16:15:38 1.24.2.1 --- exceptions.c 2001/06/28 16:23:02 1.24.2.2 *************** *** 1085,1088 **** --- 1085,1089 ---- err: Py_FatalError("exceptions bootstrapping error."); + return; } From gvanrossum@users.sourceforge.net Thu Jun 28 17:36:55 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 28 Jun 2001 09:36:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include dictobject.h,2.20.8.1,2.20.8.2 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv10227/Include Modified Files: Tag: descr-branch dictobject.h Log Message: Add official API for PyDict_Update(). (This seems unrelated to this project, but in fact avoids a bootstrapping problem in typeobject.c. The previous improvements to exceptions initialization were triggered by debugging that same problem. :-) Index: dictobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/dictobject.h,v retrieving revision 2.20.8.1 retrieving revision 2.20.8.2 diff -C2 -r2.20.8.1 -r2.20.8.2 *** dictobject.h 2001/05/04 17:15:02 2.20.8.1 --- dictobject.h 2001/06/28 16:36:53 2.20.8.2 *************** *** 76,79 **** --- 76,80 ---- extern DL_IMPORT(int) PyDict_Size(PyObject *mp); extern DL_IMPORT(PyObject *) PyDict_Copy(PyObject *mp); + extern DL_IMPORT(int) PyDict_Update(PyObject *mp, PyObject *other); From gvanrossum@users.sourceforge.net Thu Jun 28 17:36:56 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 28 Jun 2001 09:36:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.80.2.13,2.80.2.14 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv10227/Objects Modified Files: Tag: descr-branch dictobject.c Log Message: Add official API for PyDict_Update(). (This seems unrelated to this project, but in fact avoids a bootstrapping problem in typeobject.c. The previous improvements to exceptions initialization were triggered by debugging that same problem. :-) Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.80.2.13 retrieving revision 2.80.2.14 diff -C2 -r2.80.2.13 -r2.80.2.14 *** dictobject.c 2001/06/17 23:18:19 2.80.2.13 --- dictobject.c 2001/06/28 16:36:53 2.80.2.14 *************** *** 826,838 **** static PyObject * ! dict_update(register dictobject *mp, PyObject *args) { ! register int i; ! dictobject *other; ! dictentry *entry; if (!PyArg_Parse(args, "O!", &PyDict_Type, &other)) return NULL; if (other == mp || other->ma_used == 0) ! goto done; /* a.update(a) or a.update({}); nothing to do */ /* Do one big resize at the start, rather than incrementally resizing as we insert new items. Expect that there will be --- 826,856 ---- static PyObject * ! dict_update(PyObject *mp, PyObject *args) { ! PyObject *other; ! if (!PyArg_Parse(args, "O!", &PyDict_Type, &other)) return NULL; + if (PyDict_Update(mp, other) < 0) + return NULL; + Py_INCREF(Py_None); + return Py_None; + } + + int + PyDict_Update(PyObject *a, PyObject *b) + { + register PyDictObject *mp, *other; + register int i; + dictentry *entry; + + if (a == NULL || !PyDict_Check(a) || b == NULL || !PyDict_Check(b)) { + PyErr_BadInternalCall(); + return -1; + } + mp = (PyDictObject *)a; + other = (PyDictObject *)b; if (other == mp || other->ma_used == 0) ! return 0; /* a.update(a) or a.update({}); nothing to do */ /* Do one big resize at the start, rather than incrementally resizing as we insert new items. Expect that there will be *************** *** 840,844 **** if ((mp->ma_fill + other->ma_used)*3 >= mp->ma_size*2) { if (dictresize(mp, (mp->ma_used + other->ma_used)*3/2) != 0) ! return NULL; } for (i = 0; i < other->ma_size; i++) { --- 858,862 ---- if ((mp->ma_fill + other->ma_used)*3 >= mp->ma_size*2) { if (dictresize(mp, (mp->ma_used + other->ma_used)*3/2) != 0) ! return -1 ; } for (i = 0; i < other->ma_size; i++) { *************** *** 851,857 **** } } ! done: ! Py_INCREF(Py_None); ! return Py_None; } --- 869,873 ---- } } ! return 0; } *************** *** 1234,1238 **** {"values", (PyCFunction)dict_values, METH_OLDARGS, values__doc__}, ! {"update", (PyCFunction)dict_update, METH_OLDARGS, update__doc__}, {"clear", (PyCFunction)dict_clear, METH_OLDARGS, --- 1250,1254 ---- {"values", (PyCFunction)dict_values, METH_OLDARGS, values__doc__}, ! {"update", dict_update, METH_OLDARGS, update__doc__}, {"clear", (PyCFunction)dict_clear, METH_OLDARGS, From gvanrossum@users.sourceforge.net Thu Jun 28 17:46:53 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 28 Jun 2001 09:46:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects classobject.c,2.127.2.5,2.127.2.6 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv14132 Modified Files: Tag: descr-branch classobject.c Log Message: instance_dealloc(): changed a couple of references to tp_free to tp_frees (the new name for this debug-only field in the type structure). Index: classobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v retrieving revision 2.127.2.5 retrieving revision 2.127.2.6 diff -C2 -r2.127.2.5 -r2.127.2.6 *** classobject.c 2001/06/16 13:59:48 2.127.2.5 --- classobject.c 2001/06/28 16:46:51 2.127.2.6 *************** *** 593,597 **** if (--inst->ob_refcnt > 0) { #ifdef COUNT_ALLOCS ! inst->ob_type->tp_free--; #endif return; /* __del__ added a reference; don't delete now */ --- 593,597 ---- if (--inst->ob_refcnt > 0) { #ifdef COUNT_ALLOCS ! inst->ob_type->tp_frees--; #endif return; /* __del__ added a reference; don't delete now */ *************** *** 601,605 **** #ifdef COUNT_ALLOCS /* compensate for increment in _Py_ForgetReference */ ! inst->ob_type->tp_free--; #endif #ifndef WITH_CYCLE_GC --- 601,605 ---- #ifdef COUNT_ALLOCS /* compensate for increment in _Py_ForgetReference */ ! inst->ob_type->tp_frees--; #endif #ifndef WITH_CYCLE_GC From gvanrossum@users.sourceforge.net Thu Jun 28 17:49:13 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 28 Jun 2001 09:49:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include object.h,2.79.2.18,2.79.2.19 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv14700 Modified Files: Tag: descr-branch object.h Log Message: Define a new flag: Py_TPFLAGS_DYNAMICTYPE, to indicate that a type should be considered dynamic, i.e. its __dict__ can be modified at run-time. Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.79.2.18 retrieving revision 2.79.2.19 diff -C2 -r2.79.2.18 -r2.79.2.19 *** object.h 2001/06/26 20:16:57 2.79.2.18 --- object.h 2001/06/28 16:49:11 2.79.2.19 *************** *** 405,408 **** --- 405,411 ---- #define Py_TPFLAGS_BASETYPE (1L<<10) + /* Set if the type's __dict__ may change */ + #define Py_TPFLAGS_DYNAMICTYPE (1L<<11) + #define Py_TPFLAGS_DEFAULT ( \ Py_TPFLAGS_HAVE_GETCHARBUFFER | \ From gvanrossum@users.sourceforge.net Thu Jun 28 17:51:29 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 28 Jun 2001 09:51:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects object.c,2.124.4.15,2.124.4.16 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv15318 Modified Files: Tag: descr-branch object.c Log Message: PyObject_GenericGetAttr(): if Py_TPFLAGS_DYNAMICTYPE is set in tp_flags, walk down the dependency chain in MRO order looking for the attribute and doing the right thing. Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.124.4.15 retrieving revision 2.124.4.16 diff -C2 -r2.124.4.15 -r2.124.4.16 *** object.c 2001/06/19 12:27:22 2.124.4.15 --- object.c 2001/06/28 16:51:27 2.124.4.16 *************** *** 1151,1154 **** --- 1151,1181 ---- } + if (tp->tp_flags & Py_TPFLAGS_DYNAMICTYPE) { + /* Look through base classes tp_defined, in MRO, + skipping first base (which should be tp) */ + int i, n; + PyObject *mro = tp->tp_mro; + PyTypeObject *t; + assert(PyTuple_Check(mro)); + n = PyTuple_GET_SIZE(mro); + assert(n > 0 && PyTuple_GET_ITEM(mro, 0) == (PyObject *)tp); + descr = NULL; + for (i = 1; i < n; i++) { + t = (PyTypeObject *) PyTuple_GET_ITEM(mro, i); + assert(PyType_Check(t)); + assert(t->tp_dict && PyDict_Check(t->tp_dict)); + descr = PyDict_GetItem(t->tp_dict, name); + if (descr != NULL) { + f = descr->ob_type->tp_descr_get; + if (f != NULL) + return f(descr, obj); + else { + Py_INCREF(descr); + return descr; + } + } + } + } + PyErr_Format(PyExc_AttributeError, "'%.50s' object has no attribute '%.400s'", From gvanrossum@users.sourceforge.net Thu Jun 28 20:52:45 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 28 Jun 2001 12:52:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.1.2.17,1.1.2.18 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv14184 Modified Files: Tag: descr-branch test_descr.py Log Message: Add an __init__() method to the Number class in complexes(), now that constructors work. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_descr.py,v retrieving revision 1.1.2.17 retrieving revision 1.1.2.18 diff -C2 -r1.1.2.17 -r1.1.2.18 *** test_descr.py 2001/06/18 22:02:29 1.1.2.17 --- test_descr.py 2001/06/28 19:52:43 1.1.2.18 *************** *** 202,207 **** class Number(complex): __slots__ = ['prec'] def __repr__(self): ! prec = self.prec or 12 if self.imag == 0.0: return "%.*g" % (prec, self.real) --- 202,209 ---- class Number(complex): __slots__ = ['prec'] + def __init__(self, *args, **kwds): + self.prec = kwds.get('prec', 12) def __repr__(self): ! prec = self.prec if self.imag == 0.0: return "%.*g" % (prec, self.real) *************** *** 210,216 **** return "(%.*g+%.*gj)" % (prec, self.real, prec, self.imag) __str__ = __repr__ ! a = Number(3.14) ! a.prec = 12 verify(`a` == "3.14") def spamlists(): --- 212,218 ---- return "(%.*g+%.*gj)" % (prec, self.real, prec, self.imag) __str__ = __repr__ ! a = Number(3.14, prec=6) verify(`a` == "3.14") + verify(a.prec == 6) def spamlists(): From gvanrossum@users.sourceforge.net Thu Jun 28 21:32:46 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 28 Jun 2001 13:32:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.241.2.3,2.241.2.4 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv27097 Modified Files: Tag: descr-branch ceval.c Log Message: Fix a surprise that botched a demo: overriding __getitem__ in a subclass of list didn't work. Turns out the inlining version in the bytecode interpreter was triggered for subclasses of list... That's what I get for redefining PyList_Check()! :-( Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.241.2.3 retrieving revision 2.241.2.4 diff -C2 -r2.241.2.3 -r2.241.2.4 *** ceval.c 2001/06/05 12:48:11 2.241.2.3 --- ceval.c 2001/06/28 20:32:44 2.241.2.4 *************** *** 1010,1014 **** w = POP(); v = POP(); ! if (PyList_Check(v) && PyInt_Check(w)) { /* INLINE: list[int] */ long i = PyInt_AsLong(w); --- 1010,1014 ---- w = POP(); v = POP(); ! if (v->ob_type == &PyList_Type && PyInt_Check(w)) { /* INLINE: list[int] */ long i = PyInt_AsLong(w); From gvanrossum@users.sourceforge.net Thu Jun 28 21:35:33 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 28 Jun 2001 13:35:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.1.2.18,1.1.2.19 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv28093 Modified Files: Tag: descr-branch test_descr.py Log Message: Add a test that overrides some list methods and verifies that they are called properly. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_descr.py,v retrieving revision 1.1.2.18 retrieving revision 1.1.2.19 diff -C2 -r1.1.2.18 -r1.1.2.19 *** test_descr.py 2001/06/28 19:52:43 1.1.2.18 --- test_descr.py 2001/06/28 20:35:31 1.1.2.19 *************** *** 328,331 **** --- 328,345 ---- verify(a[i][j] == i*j) + def pylists(): + if verbose: print "Testing Python subclass of list..." + class C(list): + def __getitem__(self, i): + return list.__getitem__(self, i) + 100 + def __getslice__(self, i, j): + return (i, j) + a = C() + a.extend([0,1,2]) + verify(a[0] == 100) + verify(a[1] == 101) + verify(a[2] == 102) + verify(a[100:200] == (100,200)) + def metaclass(): if verbose: print "Testing __metaclass__..." *************** *** 551,554 **** --- 565,569 ---- spamdicts() pydicts() + pylists() metaclass() pymods() From jackjansen@users.sourceforge.net Thu Jun 28 23:07:32 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Thu, 28 Jun 2001 15:07:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/bgen/bgen bgenObjectDefinition.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/bgen/bgen In directory usw-pr-cvs1:/tmp/cvs-serv27230/Python/Tools/bgen/bgen Modified Files: bgenObjectDefinition.py Log Message: Make basechain a class variable in stead of initializing it in __init__. That way it's more easily overridden. Index: bgenObjectDefinition.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenObjectDefinition.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -r1.10 -r1.11 *** bgenObjectDefinition.py 2001/05/19 13:59:18 1.10 --- bgenObjectDefinition.py 2001/06/28 22:07:30 1.11 *************** *** 4,7 **** --- 4,8 ---- class ObjectDefinition(GeneratorGroup): "Spit out code that together defines a new Python object type" + basechain = "NULL" def __init__(self, name, prefix, itselftype): *************** *** 22,26 **** self.argref = "" # set to "*" if arg to _New should be pointer self.static = "static " # set to "" to make _New and _Convert public - self.basechain = "NULL" # set to &_chain to chain methods def add(self, g, dupcheck=0): --- 23,26 ---- From jackjansen@users.sourceforge.net Thu Jun 28 23:08:19 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Thu, 28 Jun 2001 15:08:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/cf CFmodule.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/cf In directory usw-pr-cvs1:/tmp/cvs-serv27466/Python/Mac/Modules/cf Modified Files: CFmodule.c Log Message: Added CFURL support, and got base chaining to really work. Index: CFmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/cf/CFmodule.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** CFmodule.c 2001/06/27 22:00:46 1.2 --- CFmodule.c 2001/06/28 22:08:17 1.3 *************** *** 16,24 **** /* For now we declare them forward here. They'll go to mactoolbox later */ ! extern PyObject *CFTypeRefObj_New(CFTypeRef); ! extern int CFTypeRefObj_Convert(PyObject *, CFTypeRef *); ! extern PyObject *CFStringRefObj_New(CFStringRef); ! extern int CFStringRefObj_Convert(PyObject *, CFStringRef *); // ADD declarations #ifdef NOTYET_USE_TOOLBOX_OBJECT_GLUE --- 16,26 ---- /* For now we declare them forward here. They'll go to mactoolbox later */ ! staticforward PyObject *CFTypeRefObj_New(CFTypeRef); ! staticforward int CFTypeRefObj_Convert(PyObject *, CFTypeRef *); ! staticforward PyObject *CFStringRefObj_New(CFStringRef); ! staticforward int CFStringRefObj_Convert(PyObject *, CFStringRef *); + staticforward int CFURLRefObj_Convert(PyObject *, CFURLRef *); + // ADD declarations #ifdef NOTYET_USE_TOOLBOX_OBJECT_GLUE *************** *** 31,35 **** /* ! ** Parse/generate RGB records */ PyObject *CFRange_New(CFRange *itself) --- 33,37 ---- /* ! ** Parse/generate CFRange records */ PyObject *CFRange_New(CFRange *itself) *************** *** 50,53 **** --- 52,66 ---- } + /* Optional CFURL argument or None (passed as NULL) */ + int + OptionalCFURLRefObj_Convert(PyObject *v, CFURLRef *p_itself) + { + if ( v == Py_None ) { + p_itself = NULL; + return 1; + } + return CFURLRefObj_Convert(v, p_itself); + } + static PyObject *CF_Error; *************** *** 334,338 **** }; ! PyMethodChain CFArrayRefObj_chain = { CFArrayRefObj_methods, NULL }; static PyObject *CFArrayRefObj_getattr(CFArrayRefObject *self, char *name) --- 347,351 ---- }; ! PyMethodChain CFArrayRefObj_chain = { CFArrayRefObj_methods, &CFTypeRefObj_chain }; static PyObject *CFArrayRefObj_getattr(CFArrayRefObject *self, char *name) *************** *** 354,358 **** { char buf[100]; ! sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself); return PyString_FromString(buf); } --- 367,371 ---- { char buf[100]; ! sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself); return PyString_FromString(buf); } *************** *** 485,489 **** }; ! PyMethodChain CFMutableArrayRefObj_chain = { CFMutableArrayRefObj_methods, NULL }; static PyObject *CFMutableArrayRefObj_getattr(CFMutableArrayRefObject *self, char *name) --- 498,502 ---- }; ! PyMethodChain CFMutableArrayRefObj_chain = { CFMutableArrayRefObj_methods, &CFArrayRefObj_chain }; static PyObject *CFMutableArrayRefObj_getattr(CFMutableArrayRefObject *self, char *name) *************** *** 505,509 **** { char buf[100]; ! sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself); return PyString_FromString(buf); } --- 518,522 ---- { char buf[100]; ! sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself); return PyString_FromString(buf); } *************** *** 602,606 **** }; ! PyMethodChain CFDictionaryRefObj_chain = { CFDictionaryRefObj_methods, NULL }; static PyObject *CFDictionaryRefObj_getattr(CFDictionaryRefObject *self, char *name) --- 615,619 ---- }; ! PyMethodChain CFDictionaryRefObj_chain = { CFDictionaryRefObj_methods, &CFTypeRefObj_chain }; static PyObject *CFDictionaryRefObj_getattr(CFDictionaryRefObject *self, char *name) *************** *** 622,626 **** { char buf[100]; ! sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself); return PyString_FromString(buf); } --- 635,639 ---- { char buf[100]; ! sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself); return PyString_FromString(buf); } *************** *** 718,722 **** }; ! PyMethodChain CFMutableDictionaryRefObj_chain = { CFMutableDictionaryRefObj_methods, NULL }; static PyObject *CFMutableDictionaryRefObj_getattr(CFMutableDictionaryRefObject *self, char *name) --- 731,735 ---- }; ! PyMethodChain CFMutableDictionaryRefObj_chain = { CFMutableDictionaryRefObj_methods, &CFDictionaryRefObj_chain }; static PyObject *CFMutableDictionaryRefObj_getattr(CFMutableDictionaryRefObject *self, char *name) *************** *** 738,742 **** { char buf[100]; ! sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself); return PyString_FromString(buf); } --- 751,755 ---- { char buf[100]; ! sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself); return PyString_FromString(buf); } *************** *** 835,839 **** }; ! PyMethodChain CFDataRefObj_chain = { CFDataRefObj_methods, NULL }; static PyObject *CFDataRefObj_getattr(CFDataRefObject *self, char *name) --- 848,852 ---- }; ! PyMethodChain CFDataRefObj_chain = { CFDataRefObj_methods, &CFTypeRefObj_chain }; static PyObject *CFDataRefObj_getattr(CFDataRefObject *self, char *name) *************** *** 855,859 **** { char buf[100]; ! sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself); return PyString_FromString(buf); } --- 868,872 ---- { char buf[100]; ! sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself); return PyString_FromString(buf); } *************** *** 1029,1033 **** }; ! PyMethodChain CFMutableDataRefObj_chain = { CFMutableDataRefObj_methods, NULL }; static PyObject *CFMutableDataRefObj_getattr(CFMutableDataRefObject *self, char *name) --- 1042,1046 ---- }; ! PyMethodChain CFMutableDataRefObj_chain = { CFMutableDataRefObj_methods, &CFDataRefObj_chain }; static PyObject *CFMutableDataRefObj_getattr(CFMutableDataRefObject *self, char *name) *************** *** 1049,1053 **** { char buf[100]; ! sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself); return PyString_FromString(buf); } --- 1062,1066 ---- { char buf[100]; ! sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself); return PyString_FromString(buf); } *************** *** 1434,1438 **** }; ! PyMethodChain CFStringRefObj_chain = { CFStringRefObj_methods, NULL }; static PyObject *CFStringRefObj_getattr(CFStringRefObject *self, char *name) --- 1447,1451 ---- }; ! PyMethodChain CFStringRefObj_chain = { CFStringRefObj_methods, &CFTypeRefObj_chain }; static PyObject *CFStringRefObj_getattr(CFStringRefObject *self, char *name) *************** *** 1454,1458 **** { char buf[100]; ! sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself); return PyString_FromString(buf); } --- 1467,1471 ---- { char buf[100]; ! sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself); return PyString_FromString(buf); } *************** *** 1712,1716 **** }; ! PyMethodChain CFMutableStringRefObj_chain = { CFMutableStringRefObj_methods, NULL }; static PyObject *CFMutableStringRefObj_getattr(CFMutableStringRefObject *self, char *name) --- 1725,1729 ---- }; ! PyMethodChain CFMutableStringRefObj_chain = { CFMutableStringRefObj_methods, &CFStringRefObj_chain }; static PyObject *CFMutableStringRefObj_getattr(CFMutableStringRefObject *self, char *name) *************** *** 1732,1736 **** { char buf[100]; ! sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself); return PyString_FromString(buf); } --- 1745,1749 ---- { char buf[100]; ! sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself); return PyString_FromString(buf); } *************** *** 1764,1767 **** --- 1777,2116 ---- + /* ---------------------- Object type CFURLRef ---------------------- */ + + PyTypeObject CFURLRef_Type; + + #define CFURLRefObj_Check(x) ((x)->ob_type == &CFURLRef_Type) + + typedef struct CFURLRefObject { + PyObject_HEAD + CFURLRef ob_itself; + void (*ob_freeit)(CFTypeRef ptr); + } CFURLRefObject; + + PyObject *CFURLRefObj_New(CFURLRef itself) + { + CFURLRefObject *it; + if (itself == NULL) return PyMac_Error(resNotFound); + CFRetain(itself); + it = PyObject_NEW(CFURLRefObject, &CFURLRef_Type); + if (it == NULL) return NULL; + it->ob_itself = itself; + it->ob_freeit = CFRelease; + return (PyObject *)it; + } + CFURLRefObj_Convert(PyObject *v, CFURLRef *p_itself) + { + + if (v == Py_None) { *p_itself = NULL; return 1; } + /* Check for other CF objects here */ + + if (!CFURLRefObj_Check(v)) + { + PyErr_SetString(PyExc_TypeError, "CFURLRef required"); + return 0; + } + *p_itself = ((CFURLRefObject *)v)->ob_itself; + return 1; + } + + static void CFURLRefObj_dealloc(CFURLRefObject *self) + { + if (self->ob_freeit && self->ob_itself) + { + self->ob_freeit((CFTypeRef)self->ob_itself); + } + PyMem_DEL(self); + } + + static PyObject *CFURLRefObj_CFURLCopyAbsoluteURL(CFURLRefObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + CFURLRef _rv; + if (!PyArg_ParseTuple(_args, "")) + return NULL; + _rv = CFURLCopyAbsoluteURL(_self->ob_itself); + _res = Py_BuildValue("O&", + CFURLRefObj_New, _rv); + return _res; + } + + static PyObject *CFURLRefObj_CFURLGetString(CFURLRefObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + CFStringRef _rv; + if (!PyArg_ParseTuple(_args, "")) + return NULL; + _rv = CFURLGetString(_self->ob_itself); + _res = Py_BuildValue("O&", + CFStringRefObj_New, _rv); + return _res; + } + + static PyObject *CFURLRefObj_CFURLGetBaseURL(CFURLRefObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + CFURLRef _rv; + if (!PyArg_ParseTuple(_args, "")) + return NULL; + _rv = CFURLGetBaseURL(_self->ob_itself); + _res = Py_BuildValue("O&", + CFURLRefObj_New, _rv); + return _res; + } + + static PyObject *CFURLRefObj_CFURLCanBeDecomposed(CFURLRefObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + Boolean _rv; + if (!PyArg_ParseTuple(_args, "")) + return NULL; + _rv = CFURLCanBeDecomposed(_self->ob_itself); + _res = Py_BuildValue("l", + _rv); + return _res; + } + + static PyObject *CFURLRefObj_CFURLCopyScheme(CFURLRefObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + CFStringRef _rv; + if (!PyArg_ParseTuple(_args, "")) + return NULL; + _rv = CFURLCopyScheme(_self->ob_itself); + _res = Py_BuildValue("O&", + CFStringRefObj_New, _rv); + return _res; + } + + static PyObject *CFURLRefObj_CFURLCopyNetLocation(CFURLRefObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + CFStringRef _rv; + if (!PyArg_ParseTuple(_args, "")) + return NULL; + _rv = CFURLCopyNetLocation(_self->ob_itself); + _res = Py_BuildValue("O&", + CFStringRefObj_New, _rv); + return _res; + } + + static PyObject *CFURLRefObj_CFURLCopyPath(CFURLRefObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + CFStringRef _rv; + if (!PyArg_ParseTuple(_args, "")) + return NULL; + _rv = CFURLCopyPath(_self->ob_itself); + _res = Py_BuildValue("O&", + CFStringRefObj_New, _rv); + return _res; + } + + static PyObject *CFURLRefObj_CFURLHasDirectoryPath(CFURLRefObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + Boolean _rv; + if (!PyArg_ParseTuple(_args, "")) + return NULL; + _rv = CFURLHasDirectoryPath(_self->ob_itself); + _res = Py_BuildValue("l", + _rv); + return _res; + } + + static PyObject *CFURLRefObj_CFURLCopyResourceSpecifier(CFURLRefObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + CFStringRef _rv; + if (!PyArg_ParseTuple(_args, "")) + return NULL; + _rv = CFURLCopyResourceSpecifier(_self->ob_itself); + _res = Py_BuildValue("O&", + CFStringRefObj_New, _rv); + return _res; + } + + static PyObject *CFURLRefObj_CFURLCopyHostName(CFURLRefObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + CFStringRef _rv; + if (!PyArg_ParseTuple(_args, "")) + return NULL; + _rv = CFURLCopyHostName(_self->ob_itself); + _res = Py_BuildValue("O&", + CFStringRefObj_New, _rv); + return _res; + } + + static PyObject *CFURLRefObj_CFURLGetPortNumber(CFURLRefObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + SInt32 _rv; + if (!PyArg_ParseTuple(_args, "")) + return NULL; + _rv = CFURLGetPortNumber(_self->ob_itself); + _res = Py_BuildValue("l", + _rv); + return _res; + } + + static PyObject *CFURLRefObj_CFURLCopyUserName(CFURLRefObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + CFStringRef _rv; + if (!PyArg_ParseTuple(_args, "")) + return NULL; + _rv = CFURLCopyUserName(_self->ob_itself); + _res = Py_BuildValue("O&", + CFStringRefObj_New, _rv); + return _res; + } + + static PyObject *CFURLRefObj_CFURLCopyPassword(CFURLRefObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + CFStringRef _rv; + if (!PyArg_ParseTuple(_args, "")) + return NULL; + _rv = CFURLCopyPassword(_self->ob_itself); + _res = Py_BuildValue("O&", + CFStringRefObj_New, _rv); + return _res; + } + + static PyObject *CFURLRefObj_CFURLCopyParameterString(CFURLRefObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + CFStringRef _rv; + CFStringRef charactersToLeaveEscaped; + if (!PyArg_ParseTuple(_args, "O&", + CFStringRefObj_Convert, &charactersToLeaveEscaped)) + return NULL; + _rv = CFURLCopyParameterString(_self->ob_itself, + charactersToLeaveEscaped); + _res = Py_BuildValue("O&", + CFStringRefObj_New, _rv); + return _res; + } + + static PyObject *CFURLRefObj_CFURLCopyQueryString(CFURLRefObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + CFStringRef _rv; + CFStringRef charactersToLeaveEscaped; + if (!PyArg_ParseTuple(_args, "O&", + CFStringRefObj_Convert, &charactersToLeaveEscaped)) + return NULL; + _rv = CFURLCopyQueryString(_self->ob_itself, + charactersToLeaveEscaped); + _res = Py_BuildValue("O&", + CFStringRefObj_New, _rv); + return _res; + } + + static PyObject *CFURLRefObj_CFURLCopyFragment(CFURLRefObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + CFStringRef _rv; + CFStringRef charactersToLeaveEscaped; + if (!PyArg_ParseTuple(_args, "O&", + CFStringRefObj_Convert, &charactersToLeaveEscaped)) + return NULL; + _rv = CFURLCopyFragment(_self->ob_itself, + charactersToLeaveEscaped); + _res = Py_BuildValue("O&", + CFStringRefObj_New, _rv); + return _res; + } + + static PyMethodDef CFURLRefObj_methods[] = { + {"CFURLCopyAbsoluteURL", (PyCFunction)CFURLRefObj_CFURLCopyAbsoluteURL, 1, + "() -> (CFURLRef _rv)"}, + {"CFURLGetString", (PyCFunction)CFURLRefObj_CFURLGetString, 1, + "() -> (CFStringRef _rv)"}, + {"CFURLGetBaseURL", (PyCFunction)CFURLRefObj_CFURLGetBaseURL, 1, + "() -> (CFURLRef _rv)"}, + {"CFURLCanBeDecomposed", (PyCFunction)CFURLRefObj_CFURLCanBeDecomposed, 1, + "() -> (Boolean _rv)"}, + {"CFURLCopyScheme", (PyCFunction)CFURLRefObj_CFURLCopyScheme, 1, + "() -> (CFStringRef _rv)"}, + {"CFURLCopyNetLocation", (PyCFunction)CFURLRefObj_CFURLCopyNetLocation, 1, + "() -> (CFStringRef _rv)"}, + {"CFURLCopyPath", (PyCFunction)CFURLRefObj_CFURLCopyPath, 1, + "() -> (CFStringRef _rv)"}, + {"CFURLHasDirectoryPath", (PyCFunction)CFURLRefObj_CFURLHasDirectoryPath, 1, + "() -> (Boolean _rv)"}, + {"CFURLCopyResourceSpecifier", (PyCFunction)CFURLRefObj_CFURLCopyResourceSpecifier, 1, + "() -> (CFStringRef _rv)"}, + {"CFURLCopyHostName", (PyCFunction)CFURLRefObj_CFURLCopyHostName, 1, + "() -> (CFStringRef _rv)"}, + {"CFURLGetPortNumber", (PyCFunction)CFURLRefObj_CFURLGetPortNumber, 1, + "() -> (SInt32 _rv)"}, + {"CFURLCopyUserName", (PyCFunction)CFURLRefObj_CFURLCopyUserName, 1, + "() -> (CFStringRef _rv)"}, + {"CFURLCopyPassword", (PyCFunction)CFURLRefObj_CFURLCopyPassword, 1, + "() -> (CFStringRef _rv)"}, + {"CFURLCopyParameterString", (PyCFunction)CFURLRefObj_CFURLCopyParameterString, 1, + "(CFStringRef charactersToLeaveEscaped) -> (CFStringRef _rv)"}, + {"CFURLCopyQueryString", (PyCFunction)CFURLRefObj_CFURLCopyQueryString, 1, + "(CFStringRef charactersToLeaveEscaped) -> (CFStringRef _rv)"}, + {"CFURLCopyFragment", (PyCFunction)CFURLRefObj_CFURLCopyFragment, 1, + "(CFStringRef charactersToLeaveEscaped) -> (CFStringRef _rv)"}, + {NULL, NULL, 0} + }; + + PyMethodChain CFURLRefObj_chain = { CFURLRefObj_methods, &CFTypeRefObj_chain }; + + static PyObject *CFURLRefObj_getattr(CFURLRefObject *self, char *name) + { + return Py_FindMethodInChain(&CFURLRefObj_chain, (PyObject *)self, name); + } + + #define CFURLRefObj_setattr NULL + + static int CFURLRefObj_compare(CFURLRefObject *self, CFURLRefObject *other) + { + /* XXXX Or should we use CFEqual?? */ + if ( self->ob_itself > other->ob_itself ) return 1; + if ( self->ob_itself < other->ob_itself ) return -1; + return 0; + } + + static PyObject * CFURLRefObj_repr(CFURLRefObject *self) + { + char buf[100]; + sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself); + return PyString_FromString(buf); + } + + static int CFURLRefObj_hash(CFURLRefObject *self) + { + /* XXXX Or should we use CFHash?? */ + return (int)self->ob_itself; + } + + PyTypeObject CFURLRef_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*ob_size*/ + "CFURLRef", /*tp_name*/ + sizeof(CFURLRefObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor) CFURLRefObj_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + (getattrfunc) CFURLRefObj_getattr, /*tp_getattr*/ + (setattrfunc) CFURLRefObj_setattr, /*tp_setattr*/ + (cmpfunc) CFURLRefObj_compare, /*tp_compare*/ + (reprfunc) CFURLRefObj_repr, /*tp_repr*/ + (PyNumberMethods *)0, /* tp_as_number */ + (PySequenceMethods *)0, /* tp_as_sequence */ + (PyMappingMethods *)0, /* tp_as_mapping */ + (hashfunc) CFURLRefObj_hash, /*tp_hash*/ + }; + + /* -------------------- End object type CFURLRef -------------------- */ + + static PyObject *CF_CFAllocatorGetTypeID(PyObject *_self, PyObject *_args) { *************** *** 2447,2450 **** --- 2796,2893 ---- } + static PyObject *CF_CFURLGetTypeID(PyObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + CFTypeID _rv; + if (!PyArg_ParseTuple(_args, "")) + return NULL; + _rv = CFURLGetTypeID(); + _res = Py_BuildValue("l", + _rv); + return _res; + } + + static PyObject *CF_CFURLCreateWithBytes(PyObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + CFURLRef _rv; + unsigned char *URLBytes__in__; + long URLBytes__len__; + int URLBytes__in_len__; + CFStringEncoding encoding; + CFURLRef baseURL; + if (!PyArg_ParseTuple(_args, "s#lO&", + &URLBytes__in__, &URLBytes__in_len__, + &encoding, + OptionalCFURLRefObj_Convert, &baseURL)) + return NULL; + URLBytes__len__ = URLBytes__in_len__; + _rv = CFURLCreateWithBytes((CFAllocatorRef)NULL, + URLBytes__in__, URLBytes__len__, + encoding, + baseURL); + _res = Py_BuildValue("O&", + CFURLRefObj_New, _rv); + URLBytes__error__: ; + return _res; + } + + static PyObject *CF_CFURLCreateData(PyObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + CFDataRef _rv; + CFURLRef url; + CFStringEncoding encoding; + Boolean escapeWhitespace; + if (!PyArg_ParseTuple(_args, "O&ll", + CFURLRefObj_Convert, &url, + &encoding, + &escapeWhitespace)) + return NULL; + _rv = CFURLCreateData((CFAllocatorRef)NULL, + url, + encoding, + escapeWhitespace); + _res = Py_BuildValue("O&", + CFDataRefObj_New, _rv); + return _res; + } + + static PyObject *CF_CFURLCreateWithString(PyObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + CFURLRef _rv; + CFStringRef URLString; + CFURLRef baseURL; + if (!PyArg_ParseTuple(_args, "O&O&", + CFStringRefObj_Convert, &URLString, + OptionalCFURLRefObj_Convert, &baseURL)) + return NULL; + _rv = CFURLCreateWithString((CFAllocatorRef)NULL, + URLString, + baseURL); + _res = Py_BuildValue("O&", + CFURLRefObj_New, _rv); + return _res; + } + + static PyObject *CF_CFURLCreateStringByReplacingPercentEscapes(PyObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + CFStringRef _rv; + CFStringRef originalString; + CFStringRef charactersToLeaveEscaped; + if (!PyArg_ParseTuple(_args, "O&O&", + CFStringRefObj_Convert, &originalString, + CFStringRefObj_Convert, &charactersToLeaveEscaped)) + return NULL; + _rv = CFURLCreateStringByReplacingPercentEscapes((CFAllocatorRef)NULL, + originalString, + charactersToLeaveEscaped); + _res = Py_BuildValue("O&", + CFStringRefObj_New, _rv); + return _res; + } + static PyMethodDef CF_methods[] = { {"CFAllocatorGetTypeID", (PyCFunction)CF_CFAllocatorGetTypeID, 1, *************** *** 2532,2535 **** --- 2975,2988 ---- {"__CFStringMakeConstantString", (PyCFunction)CF___CFStringMakeConstantString, 1, "(char* cStr) -> (CFStringRef _rv)"}, + {"CFURLGetTypeID", (PyCFunction)CF_CFURLGetTypeID, 1, + "() -> (CFTypeID _rv)"}, + {"CFURLCreateWithBytes", (PyCFunction)CF_CFURLCreateWithBytes, 1, + "(Buffer URLBytes, CFStringEncoding encoding, CFURLRef baseURL) -> (CFURLRef _rv)"}, + {"CFURLCreateData", (PyCFunction)CF_CFURLCreateData, 1, + "(CFURLRef url, CFStringEncoding encoding, Boolean escapeWhitespace) -> (CFDataRef _rv)"}, + {"CFURLCreateWithString", (PyCFunction)CF_CFURLCreateWithString, 1, + "(CFStringRef URLString, CFURLRef baseURL) -> (CFURLRef _rv)"}, + {"CFURLCreateStringByReplacingPercentEscapes", (PyCFunction)CF_CFURLCreateStringByReplacingPercentEscapes, 1, + "(CFStringRef originalString, CFStringRef charactersToLeaveEscaped) -> (CFStringRef _rv)"}, {NULL, NULL, 0} }; *************** *** 2591,2594 **** --- 3044,3051 ---- if (PyDict_SetItemString(d, "CFMutableStringRefType", (PyObject *)&CFMutableStringRef_Type) != 0) Py_FatalError("can't initialize CFMutableStringRefType"); + CFURLRef_Type.ob_type = &PyType_Type; + Py_INCREF(&CFURLRef_Type); + if (PyDict_SetItemString(d, "CFURLRefType", (PyObject *)&CFURLRef_Type) != 0) + Py_FatalError("can't initialize CFURLRefType"); } From jackjansen@users.sourceforge.net Thu Jun 28 23:08:24 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Thu, 28 Jun 2001 15:08:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/cf cfscan.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/cf In directory usw-pr-cvs1:/tmp/cvs-serv27522/Python/Mac/Modules/cf Modified Files: cfscan.py Log Message: Added CFURL support, and got base chaining to really work. Index: cfscan.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/cf/cfscan.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** cfscan.py 2001/06/27 22:00:50 1.2 --- cfscan.py 2001/06/28 22:08:22 1.3 *************** *** 14,18 **** "CFDataRef", "CFMutableDataRef", "CFDictionaryRef", "CFMutableDictionaryRef", ! "CFStringRef", "CFMutableStringRef", ) # ADD object typenames here --- 14,19 ---- "CFDataRef", "CFMutableDataRef", "CFDictionaryRef", "CFMutableDictionaryRef", ! "CFStringRef", "CFMutableStringRef", ! "CFURLRef", ) # ADD object typenames here *************** *** 36,40 **** ## "CFStringEncodingExt.h", ## "CFTimeZone.h", ! ## "CFURL.h", ] output = SHORT + "gen.py" --- 37,41 ---- ## "CFStringEncodingExt.h", ## "CFTimeZone.h", ! "CFURL.h", ] output = SHORT + "gen.py" *************** *** 82,86 **** "CFStringGetPascalStringPtr", # TBD automatically "CFStringGetCStringPtr", ! "CFStringGetCharactersPtr", ] --- 83,90 ---- "CFStringGetPascalStringPtr", # TBD automatically "CFStringGetCStringPtr", ! "CFStringGetCharactersPtr", ! # OSX only, to be done ! "CFURLCreateWithFileSystemPath", ! "CFURLCreateStringWithFileSystemPath", ] *************** *** 105,112 **** --- 109,124 ---- def makerepairinstructions(self): return [ + # Buffers in CF seem to be passed as UInt8 * normally. ([("UInt8_ptr", "*", "InMode"), ("CFIndex", "*", "InMode")], [("UcharInBuffer", "*", "*")]), + + # Some functions return a const char *. Don't worry, we won't modify it. ([("const_char_ptr", "*", "ReturnMode")], [("return_stringptr", "*", "*")]), + + # base URLs are optional (pass None for NULL) + ([("CFURLRef", "baseURL", "InMode")], + [("OptionalCFURLRef", "*", "*")]), + ] From jackjansen@users.sourceforge.net Thu Jun 28 23:08:28 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Thu, 28 Jun 2001 15:08:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/cf cfsupport.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/cf In directory usw-pr-cvs1:/tmp/cvs-serv27545/Python/Mac/Modules/cf Modified Files: cfsupport.py Log Message: Added CFURL support, and got base chaining to really work. Index: cfsupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/cf/cfsupport.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** cfsupport.py 2001/06/27 22:00:55 1.2 --- cfsupport.py 2001/06/28 22:08:26 1.3 *************** *** 28,36 **** /* For now we declare them forward here. They'll go to mactoolbox later */ ! extern PyObject *CFTypeRefObj_New(CFTypeRef); ! extern int CFTypeRefObj_Convert(PyObject *, CFTypeRef *); ! extern PyObject *CFStringRefObj_New(CFStringRef); ! extern int CFStringRefObj_Convert(PyObject *, CFStringRef *); // ADD declarations #ifdef NOTYET_USE_TOOLBOX_OBJECT_GLUE --- 28,38 ---- /* For now we declare them forward here. They'll go to mactoolbox later */ ! staticforward PyObject *CFTypeRefObj_New(CFTypeRef); ! staticforward int CFTypeRefObj_Convert(PyObject *, CFTypeRef *); ! staticforward PyObject *CFStringRefObj_New(CFStringRef); ! staticforward int CFStringRefObj_Convert(PyObject *, CFStringRef *); + staticforward int CFURLRefObj_Convert(PyObject *, CFURLRef *); + // ADD declarations #ifdef NOTYET_USE_TOOLBOX_OBJECT_GLUE *************** *** 43,47 **** /* ! ** Parse/generate RGB records */ PyObject *CFRange_New(CFRange *itself) --- 45,49 ---- /* ! ** Parse/generate CFRange records */ PyObject *CFRange_New(CFRange *itself) *************** *** 62,65 **** --- 64,78 ---- } + /* Optional CFURL argument or None (passed as NULL) */ + int + OptionalCFURLRefObj_Convert(PyObject *v, CFURLRef *p_itself) + { + if ( v == Py_None ) { + p_itself = NULL; + return 1; + } + return CFURLRefObj_Convert(v, p_itself); + } + """ *************** *** 76,80 **** CFOptionFlags = Type("CFOptionFlags", "l") CFStringEncoding = Type("CFStringEncoding", "l") ! CFComparisonResult = Type("CFComparisonResult", "l") # a bit dangerous... char_ptr = stringptr --- 89,94 ---- CFOptionFlags = Type("CFOptionFlags", "l") CFStringEncoding = Type("CFStringEncoding", "l") ! CFComparisonResult = Type("CFComparisonResult", "l") # a bit dangerous, it's an enum ! CFURLPathStyle = Type("CFURLPathStyle", "l") # a bit dangerous, it's an enum char_ptr = stringptr *************** *** 97,100 **** --- 111,116 ---- CFStringRef = OpaqueByValueType("CFStringRef", "CFStringRefObj") CFMutableStringRef = OpaqueByValueType("CFMutableStringRef", "CFMutableStringRefObj") + CFURLRef = OpaqueByValueType("CFURLRef", "CFURLRefObj") + OptionalCFURLRef = OpaqueByValueType("CFURLRef", "OptionalCFURLRefObj") # ADD object type here *************** *** 161,165 **** OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() --- 177,181 ---- OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() *************** *** 173,177 **** OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() --- 189,193 ---- OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() *************** *** 185,189 **** OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() --- 201,205 ---- OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() *************** *** 197,201 **** OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() --- 213,217 ---- OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() *************** *** 209,213 **** OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() --- 225,229 ---- OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() *************** *** 221,225 **** OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() --- 237,241 ---- OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() *************** *** 233,237 **** OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() --- 249,253 ---- OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() *************** *** 244,249 **** Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype) OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() --- 260,277 ---- Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype) OutLbrace() + Output("char buf[100];") + Output("""sprintf(buf, "", self, self->ob_itself);""") + Output("return PyString_FromString(buf);") + OutRbrace() + + class CFURLRefObjectDefinition(MyGlobalObjectDefinition): + basechain = "&CFTypeRefObj_chain" + + def outputRepr(self): + Output() + Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype) + OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() *************** *** 257,268 **** module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff) CFTypeRef_object = CFTypeRefObjectDefinition('CFTypeRef', 'CFTypeRefObj', 'CFTypeRef') ! CFArrayRef_object = CFTypeRefObjectDefinition('CFArrayRef', 'CFArrayRefObj', 'CFArrayRef') ! CFMutableArrayRef_object = CFTypeRefObjectDefinition('CFMutableArrayRef', 'CFMutableArrayRefObj', 'CFMutableArrayRef') ! CFDictionaryRef_object = CFTypeRefObjectDefinition('CFDictionaryRef', 'CFDictionaryRefObj', 'CFDictionaryRef') ! CFMutableDictionaryRef_object = CFTypeRefObjectDefinition('CFMutableDictionaryRef', 'CFMutableDictionaryRefObj', 'CFMutableDictionaryRef') ! CFDataRef_object = CFTypeRefObjectDefinition('CFDataRef', 'CFDataRefObj', 'CFDataRef') ! CFMutableDataRef_object = CFTypeRefObjectDefinition('CFMutableDataRef', 'CFMutableDataRefObj', 'CFMutableDataRef') ! CFStringRef_object = CFTypeRefObjectDefinition('CFStringRef', 'CFStringRefObj', 'CFStringRef') ! CFMutableStringRef_object = CFTypeRefObjectDefinition('CFMutableStringRef', 'CFMutableStringRefObj', 'CFMutableStringRef') # ADD object here --- 285,297 ---- module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff) CFTypeRef_object = CFTypeRefObjectDefinition('CFTypeRef', 'CFTypeRefObj', 'CFTypeRef') ! CFArrayRef_object = CFArrayRefObjectDefinition('CFArrayRef', 'CFArrayRefObj', 'CFArrayRef') ! CFMutableArrayRef_object = CFMutableArrayRefObjectDefinition('CFMutableArrayRef', 'CFMutableArrayRefObj', 'CFMutableArrayRef') ! CFDictionaryRef_object = CFDictionaryRefObjectDefinition('CFDictionaryRef', 'CFDictionaryRefObj', 'CFDictionaryRef') ! CFMutableDictionaryRef_object = CFMutableDictionaryRefObjectDefinition('CFMutableDictionaryRef', 'CFMutableDictionaryRefObj', 'CFMutableDictionaryRef') ! CFDataRef_object = CFDataRefObjectDefinition('CFDataRef', 'CFDataRefObj', 'CFDataRef') ! CFMutableDataRef_object = CFMutableDataRefObjectDefinition('CFMutableDataRef', 'CFMutableDataRefObj', 'CFMutableDataRef') ! CFStringRef_object = CFStringRefObjectDefinition('CFStringRef', 'CFStringRefObj', 'CFStringRef') ! CFMutableStringRef_object = CFMutableStringRefObjectDefinition('CFMutableStringRef', 'CFMutableStringRefObj', 'CFMutableStringRef') ! CFURLRef_object = CFURLRefObjectDefinition('CFURLRef', 'CFURLRefObj', 'CFURLRef') # ADD object here *************** *** 277,280 **** --- 306,310 ---- module.addobject(CFStringRef_object) module.addobject(CFMutableStringRef_object) + module.addobject(CFURLRef_object) # ADD addobject call here *************** *** 294,297 **** --- 324,328 ---- CFStringRef_methods = [] CFMutableStringRef_methods = [] + CFURLRef_methods = [] # ADD _methods initializer here *************** *** 311,314 **** --- 342,346 ---- for f in CFStringRef_methods: CFStringRef_object.add(f) for f in CFMutableStringRef_methods: CFMutableStringRef_object.add(f) + for f in CFURLRef_methods: CFURLRef_object.add(f) # ADD add forloop here From tim_one@users.sourceforge.net Fri Jun 29 03:41:18 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 28 Jun 2001 19:41:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv3902/python/dist/src/Lib/test Modified Files: test_generators.py Log Message: Added a simple but general backtracking generator (conjoin), and a couple examples of use. These poke stuff not specifically targeted before, incl. recursive local generators relying on nested scopes, ditto but also inside class methods and rebinding instance vars, and anonymous partially-evaluated generators (the N-Queens solver creates a different column-generator for each row -- AFAIK this is my invention, and it's really pretty ). No problems, not even a new leak. Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -r1.13 -r1.14 *** test_generators.py 2001/06/28 01:52:22 1.13 --- test_generators.py 2001/06/29 02:41:16 1.14 *************** *** 1,2 **** --- 1,4 ---- + from __future__ import nested_scopes + tutorial_tests = """ Let's try a simple generator: *************** *** 740,748 **** """ __test__ = {"tut": tutorial_tests, "pep": pep_tests, "email": email_tests, "fun": fun_tests, ! "syntax": syntax_tests} # Magic test name that regrtest.py invokes *after* importing this module. --- 742,909 ---- """ + # conjoin is a simple backtracking generator, named in honor of Icon's + # "conjunction" control structure. Pass a list of no-argument functions + # that return iterable objects. Easiest to explain by example: assume the + # function list [x, y, z] is passed. Then conjoin acts like: + # + # def g(): + # values = [None] * 3 + # for values[0] in x(): + # for values[1] in y(): + # for values[2] in z(): + # yield values + # + # So some 3-lists of values *may* be generated, each time we successfully + # get into the innermost loop. If an iterator fails (is exhausted) before + # then, it "backtracks" to get the next value from the nearest enclosing + # iterator (the one "to the left"), and starts all over again at the next + # slot (pumps a fresh iterator). Of course this is most useful when the + # iterators have side-effects, so that which values *can* be generated at + # each slot depend on the values iterated at previous slots. + + def conjoin(gs): + + values = [None] * len(gs) + + def gen(i, values=values): + if i >= len(gs): + yield values + else: + for values[i] in gs[i](): + for x in gen(i+1): + yield x + + for x in gen(0): + yield x + + # A conjoin-based N-Queens solver. + + class Queens: + def __init__(self, n): + self.n = n + rangen = range(n) + + # Assign a unique int to each column and diagonal. + # columns: n of those, range(n). + # NW-SE diagonals: 2n-1 of these, i-j unique and invariant along + # each, smallest i-j is 0-(n-1) = 1-n, so add n-1 to shift to 0- + # based. + # NE-SW diagonals: 2n-1 of these, i+j unique and invariant along + # each, smallest i+j is 0, largest is 2n-2. + + # For each square, compute a bit vector of the columns and + # diagonals it covers, and for each row compute a function that + # generates the possiblities for the columns in that row. + self.rowgenerators = [] + for i in rangen: + rowuses = [(1L << j) | # column ordinal + (1L << (n + i-j + n-1)) | # NW-SE ordinal + (1L << (n + 2*n-1 + i+j)) # NE-SW ordinal + for j in rangen] + + def rowgen(rowuses=rowuses): + for j in rangen: + uses = rowuses[j] + if uses & self.used: + continue + self.used |= uses + yield j + self.used &= ~uses + + self.rowgenerators.append(rowgen) + + # Generate solutions. + def solve(self): + self.used = 0 + for row2col in conjoin(self.rowgenerators): + yield row2col + + def printsolution(self, row2col): + n = self.n + assert n == len(row2col) + sep = "+" + "-+" * n + print sep + for i in range(n): + squares = [" " for j in range(n)] + squares[row2col[i]] = "Q" + print "|" + "|".join(squares) + "|" + print sep + + conjoin_tests = """ + + Generate the 3-bit binary numbers in order. This illustrates dumbest- + possible use of conjoin, just to generate the full cross-product. + + >>> def g(): + ... return [0, 1] + + >>> for c in conjoin([g] * 3): + ... print c + [0, 0, 0] + [0, 0, 1] + [0, 1, 0] + [0, 1, 1] + [1, 0, 0] + [1, 0, 1] + [1, 1, 0] + [1, 1, 1] + + And run an 8-queens solver. + + >>> q = Queens(8) + >>> LIMIT = 2 + >>> count = 0 + >>> for row2col in q.solve(): + ... count += 1 + ... if count <= LIMIT: + ... print "Solution", count + ... q.printsolution(row2col) + Solution 1 + +-+-+-+-+-+-+-+-+ + |Q| | | | | | | | + +-+-+-+-+-+-+-+-+ + | | | | |Q| | | | + +-+-+-+-+-+-+-+-+ + | | | | | | | |Q| + +-+-+-+-+-+-+-+-+ + | | | | | |Q| | | + +-+-+-+-+-+-+-+-+ + | | |Q| | | | | | + +-+-+-+-+-+-+-+-+ + | | | | | | |Q| | + +-+-+-+-+-+-+-+-+ + | |Q| | | | | | | + +-+-+-+-+-+-+-+-+ + | | | |Q| | | | | + +-+-+-+-+-+-+-+-+ + Solution 2 + +-+-+-+-+-+-+-+-+ + |Q| | | | | | | | + +-+-+-+-+-+-+-+-+ + | | | | | |Q| | | + +-+-+-+-+-+-+-+-+ + | | | | | | | |Q| + +-+-+-+-+-+-+-+-+ + | | |Q| | | | | | + +-+-+-+-+-+-+-+-+ + | | | | | | |Q| | + +-+-+-+-+-+-+-+-+ + | | | |Q| | | | | + +-+-+-+-+-+-+-+-+ + | |Q| | | | | | | + +-+-+-+-+-+-+-+-+ + | | | | |Q| | | | + +-+-+-+-+-+-+-+-+ + + >>> print count, "solutions in all." + 92 solutions in all. + """ + __test__ = {"tut": tutorial_tests, "pep": pep_tests, "email": email_tests, "fun": fun_tests, ! "syntax": syntax_tests, ! "conjoin": conjoin_tests} # Magic test name that regrtest.py invokes *after* importing this module. From gvanrossum@users.sourceforge.net Fri Jun 29 14:06:08 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 29 Jun 2001 06:06:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib cgi.py,1.63,1.64 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv13366 Modified Files: cgi.py Log Message: Solve SF bug #231249: cgi.py opens too many (temporary) files. class FieldStorage: this patch changes read_lines() and co. to use a StringIO() instead of a real file. The write() calls are redirected to a private method that replaces it with a real, external file only when it gets too big (> 1000 bytes). This avoids problems in forms using the multipart/form-data encoding with many fields. The original code created a temporary file for *every* field (not just for file upload fields), thereby sometimes exceeding the open file limit of some systems. Note that the simpler solution "use a real file only for file uploads" can't be used because the form field parser has no way to tell which fields correspond to file uploads. It's *possible* but extremely unlikely that this would break someone's code; they would have to be stepping way outside the documented interface for FieldStorage and use f.file.fileno(), or depend on overriding make_file() to return a file-like object with additional known properties. Index: cgi.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/cgi.py,v retrieving revision 1.63 retrieving revision 1.64 diff -C2 -r1.63 -r1.64 *** cgi.py 2001/03/19 13:40:44 1.63 --- cgi.py 2001/06/29 13:06:06 1.64 *************** *** 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): From gvanrossum@users.sourceforge.net Fri Jun 29 15:03:29 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 29 Jun 2001 07:03:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python pythonrun.c,2.133.4.1,2.133.4.2 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv1103 Modified Files: Tag: descr-branch pythonrun.c Log Message: _Py_AskYesNo(): print the prompt to stderr, so it doesn't somehow disappear when running "make test". Index: pythonrun.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.133.4.1 retrieving revision 2.133.4.2 diff -C2 -r2.133.4.1 -r2.133.4.2 *** pythonrun.c 2001/06/28 16:15:38 2.133.4.1 --- pythonrun.c 2001/06/29 14:03:27 2.133.4.2 *************** *** 1315,1319 **** char buf[256]; ! printf("%s [ny] ", prompt); if (fgets(buf, sizeof buf, stdin) == NULL) return 0; --- 1315,1319 ---- char buf[256]; ! fprintf(stderr, "%s [ny] ", prompt); if (fgets(buf, sizeof buf, stdin) == NULL) return 0; From gvanrossum@users.sourceforge.net Fri Jun 29 15:19:34 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 29 Jun 2001 07:19:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects descrobject.c,1.1.2.9,1.1.2.10 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv6431 Modified Files: Tag: descr-branch descrobject.c Log Message: descr_call(): improve two error messages. Index: descrobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/Attic/descrobject.c,v retrieving revision 1.1.2.9 retrieving revision 1.1.2.10 diff -C2 -r1.1.2.9 -r1.1.2.10 *** descrobject.c 2001/06/06 14:27:54 1.1.2.9 --- descrobject.c 2001/06/29 14:19:30 1.1.2.10 *************** *** 204,217 **** if (argc < 1) { PyErr_SetString(PyExc_TypeError, ! "descriptor call needs 'self' argument"); return NULL; } self = PyTuple_GET_ITEM(args, 0); if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) { PyErr_Format(PyExc_TypeError, ! "descriptor call 'self' is type '%.100s', " ! "expected type '%.100s'", ! self->ob_type->tp_name, ! descr->d_type->tp_name); return NULL; } --- 204,222 ---- if (argc < 1) { PyErr_SetString(PyExc_TypeError, ! "descriptor call needs a self argument"); return NULL; } self = PyTuple_GET_ITEM(args, 0); if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) { + char *name = descr_name(descr); + if (name == NULL) + name = "?"; PyErr_Format(PyExc_TypeError, ! "descriptor '%.100s' " ! "requires a '%.100s', " ! "received a '%.100s'", ! name, ! descr->d_type->tp_name, ! self->ob_type->tp_name); return NULL; } From gvanrossum@users.sourceforge.net Fri Jun 29 15:31:13 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 29 Jun 2001 07:31:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects descrobject.c,1.1.2.10,1.1.2.11 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv11012 Modified Files: Tag: descr-branch descrobject.c Log Message: descr_name(): return "?" for unnamed descriptors instead of NULL, so it is safe to use this in "%s" formats. descr_call(): always report the name of the descriptor in error messages. descr_get_name(): test for "?" returned from descr_name() instead of NULL. Index: descrobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/Attic/descrobject.c,v retrieving revision 1.1.2.10 retrieving revision 1.1.2.11 diff -C2 -r1.1.2.10 -r1.1.2.11 *** descrobject.c 2001/06/29 14:19:30 1.1.2.10 --- descrobject.c 2001/06/29 14:31:11 1.1.2.11 *************** *** 48,52 **** return descr->d_union.d_wrapper.base->name; default: ! return NULL; } } --- 48,52 ---- return descr->d_union.d_wrapper.base->name; default: ! return "?"; } } *************** *** 203,220 **** argc = PyTuple_GET_SIZE(args); if (argc < 1) { ! PyErr_SetString(PyExc_TypeError, ! "descriptor call needs a self argument"); return NULL; } self = PyTuple_GET_ITEM(args, 0); if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) { - char *name = descr_name(descr); - if (name == NULL) - name = "?"; PyErr_Format(PyExc_TypeError, "descriptor '%.100s' " ! "requires a '%.100s', " ! "received a '%.100s'", ! name, descr->d_type->tp_name, self->ob_type->tp_name); --- 203,218 ---- argc = PyTuple_GET_SIZE(args); if (argc < 1) { ! PyErr_Format(PyExc_TypeError, ! "descriptor '%.100s' needs an argument", ! descr_name(descr)); return NULL; } self = PyTuple_GET_ITEM(args, 0); if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) { PyErr_Format(PyExc_TypeError, "descriptor '%.100s' " ! "requires '%.100s', " ! "received '%.100s'", ! descr_name(descr), descr->d_type->tp_name, self->ob_type->tp_name); *************** *** 245,251 **** assert(PyDict_Check(kwds)); if (PyDict_Size(kwds) > 0) { ! PyErr_SetString(PyExc_TypeError, ! "this descriptor object can't called " ! "called with keyword arguments"); return NULL; } --- 243,250 ---- assert(PyDict_Check(kwds)); if (PyDict_Size(kwds) > 0) { ! PyErr_Format(PyExc_TypeError, ! "descriptor '%.100s' can't called " ! "called with keyword arguments", ! descr_name(descr)); return NULL; } *************** *** 261,266 **** return Py_None; } ! PyErr_SetString(PyExc_TypeError, ! "too many arguments to descriptor call"); return NULL; } --- 260,266 ---- return Py_None; } ! PyErr_Format(PyExc_TypeError, ! "too many arguments to call descriptor '%.100s'", ! descr_name(descr)); return NULL; } *************** *** 303,307 **** char *s = descr_name(descr); ! if (s != NULL) return PyString_FromString(s); PyErr_SetString(PyExc_AttributeError, "unnamed descriptor"); --- 303,307 ---- char *s = descr_name(descr); ! if (*s != '?') return PyString_FromString(s); PyErr_SetString(PyExc_AttributeError, "unnamed descriptor"); From gvanrossum@users.sourceforge.net Fri Jun 29 15:58:32 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 29 Jun 2001 07:58:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.48,2.16.8.49 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv25707 Modified Files: Tag: descr-branch typeobject.c Log Message: override_slots(): cosmetic change. Pass the full operator name as a string argument to the macro argument, so instead of NBSLOT(or, nb_or) we write NBSLOT("__or__", nb_or). The reason: this is a reminder of what is going on in the macro, and also makes it easier to search for e.g. __add__ to find this function. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.48 retrieving revision 2.16.8.49 diff -C2 -r2.16.8.48 -r2.16.8.49 *** typeobject.c 2001/06/26 20:16:58 2.16.8.48 --- typeobject.c 2001/06/29 14:58:30 2.16.8.49 *************** *** 1949,2043 **** #define SQSLOT(OPNAME, SLOTNAME) \ ! if (PyDict_GetItemString(dict, "__" #OPNAME "__")) { \ sq->SLOTNAME = slot_##SLOTNAME; \ } #define MPSLOT(OPNAME, SLOTNAME) \ ! if (PyDict_GetItemString(dict, "__" #OPNAME "__")) { \ mp->SLOTNAME = slot_##SLOTNAME; \ } #define NBSLOT(OPNAME, SLOTNAME) \ ! if (PyDict_GetItemString(dict, "__" #OPNAME "__")) { \ nb->SLOTNAME = slot_##SLOTNAME; \ } #define TPSLOT(OPNAME, SLOTNAME) \ ! if (PyDict_GetItemString(dict, "__" #OPNAME "__")) { \ type->SLOTNAME = slot_##SLOTNAME; \ } ! SQSLOT(len, sq_length); ! SQSLOT(add, sq_concat); ! SQSLOT(mul, sq_repeat); ! SQSLOT(getitem, sq_item); ! SQSLOT(getslice, sq_slice); ! SQSLOT(setitem, sq_ass_item); ! SQSLOT(setslice, sq_ass_slice); ! SQSLOT(contains, sq_contains); ! SQSLOT(iadd, sq_inplace_concat); ! SQSLOT(imul, sq_inplace_repeat); ! ! MPSLOT(len, mp_length); ! MPSLOT(getitem, mp_subscript); ! MPSLOT(setitem, mp_ass_subscript); ! ! NBSLOT(add, nb_add); ! NBSLOT(sub, nb_subtract); ! NBSLOT(mul, nb_multiply); ! NBSLOT(div, nb_divide); ! NBSLOT(mod, nb_remainder); ! NBSLOT(divmod, nb_divmod); ! NBSLOT(pow, nb_power); ! NBSLOT(neg, nb_negative); ! NBSLOT(pos, nb_positive); ! NBSLOT(abs, nb_absolute); ! NBSLOT(nonzero, nb_nonzero); ! NBSLOT(invert, nb_invert); ! NBSLOT(lshift, nb_lshift); ! NBSLOT(rshift, nb_rshift); ! NBSLOT(and, nb_and); ! NBSLOT(xor, nb_xor); ! NBSLOT(or, nb_or); /* Not coerce() */ ! NBSLOT(int, nb_int); ! NBSLOT(long, nb_long); ! NBSLOT(float, nb_float); ! NBSLOT(oct, nb_oct); ! NBSLOT(hex, nb_hex); ! NBSLOT(iadd, nb_inplace_add); ! NBSLOT(isub, nb_inplace_subtract); ! NBSLOT(imul, nb_inplace_multiply); ! NBSLOT(idiv, nb_inplace_divide); ! NBSLOT(imod, nb_inplace_remainder); ! NBSLOT(ipow, nb_inplace_power); ! NBSLOT(ilshift, nb_inplace_lshift); ! NBSLOT(irshift, nb_inplace_rshift); ! NBSLOT(iand, nb_inplace_and); ! NBSLOT(ixor, nb_inplace_xor); ! NBSLOT(ior, nb_inplace_or); if (PyDict_GetItemString(dict, "__str__") || PyDict_GetItemString(dict, "__repr__")) type->tp_print = NULL; ! ! TPSLOT(cmp, tp_compare); ! TPSLOT(repr, tp_repr); ! TPSLOT(hash, tp_hash); ! TPSLOT(call, tp_call); ! TPSLOT(str, tp_str); ! TPSLOT(getattr, tp_getattro); ! TPSLOT(setattr, tp_setattro); ! TPSLOT(lt, tp_richcompare); ! TPSLOT(le, tp_richcompare); ! TPSLOT(eq, tp_richcompare); ! TPSLOT(ne, tp_richcompare); ! TPSLOT(gt, tp_richcompare); ! TPSLOT(ge, tp_richcompare); ! TPSLOT(iter, tp_iter); ! if (PyDict_GetItemString(dict, "next")) ! type->tp_iternext = slot_tp_iternext; ! TPSLOT(get, tp_descr_get); ! TPSLOT(set, tp_descr_set); ! TPSLOT(init, tp_init); } --- 1949,2042 ---- #define SQSLOT(OPNAME, SLOTNAME) \ ! if (PyDict_GetItemString(dict, OPNAME)) { \ sq->SLOTNAME = slot_##SLOTNAME; \ } #define MPSLOT(OPNAME, SLOTNAME) \ ! if (PyDict_GetItemString(dict, OPNAME)) { \ mp->SLOTNAME = slot_##SLOTNAME; \ } #define NBSLOT(OPNAME, SLOTNAME) \ ! if (PyDict_GetItemString(dict, OPNAME)) { \ nb->SLOTNAME = slot_##SLOTNAME; \ } #define TPSLOT(OPNAME, SLOTNAME) \ ! if (PyDict_GetItemString(dict, OPNAME)) { \ type->SLOTNAME = slot_##SLOTNAME; \ } ! SQSLOT("__len__", sq_length); ! SQSLOT("__add__", sq_concat); ! SQSLOT("__mul__", sq_repeat); ! SQSLOT("__getitem__", sq_item); ! SQSLOT("__getslice__", sq_slice); ! SQSLOT("__setitem__", sq_ass_item); ! SQSLOT("__setslice__", sq_ass_slice); ! SQSLOT("__contains__", sq_contains); ! SQSLOT("__iadd__", sq_inplace_concat); ! SQSLOT("__imul__", sq_inplace_repeat); ! ! MPSLOT("__len__", mp_length); ! MPSLOT("__getitem__", mp_subscript); ! MPSLOT("__setitem__", mp_ass_subscript); ! ! NBSLOT("__add__", nb_add); ! NBSLOT("__sub__", nb_subtract); ! NBSLOT("__mul__", nb_multiply); ! NBSLOT("__div__", nb_divide); ! NBSLOT("__mod__", nb_remainder); ! NBSLOT("__divmod__", nb_divmod); ! NBSLOT("__pow__", nb_power); ! NBSLOT("__neg__", nb_negative); ! NBSLOT("__pos__", nb_positive); ! NBSLOT("__abs__", nb_absolute); ! NBSLOT("__nonzero__", nb_nonzero); ! NBSLOT("__invert__", nb_invert); ! NBSLOT("__lshift__", nb_lshift); ! NBSLOT("__rshift__", nb_rshift); ! NBSLOT("__and__", nb_and); ! NBSLOT("__xor__", nb_xor); ! NBSLOT("__or__", nb_or); /* Not coerce() */ ! NBSLOT("__int__", nb_int); ! NBSLOT("__long__", nb_long); ! NBSLOT("__float__", nb_float); ! NBSLOT("__oct__", nb_oct); ! NBSLOT("__hex__", nb_hex); ! NBSLOT("__iadd__", nb_inplace_add); ! NBSLOT("__isub__", nb_inplace_subtract); ! NBSLOT("__imul__", nb_inplace_multiply); ! NBSLOT("__idiv__", nb_inplace_divide); ! NBSLOT("__imod__", nb_inplace_remainder); ! NBSLOT("__ipow__", nb_inplace_power); ! NBSLOT("__ilshift__", nb_inplace_lshift); ! NBSLOT("__irshift__", nb_inplace_rshift); ! NBSLOT("__iand__", nb_inplace_and); ! NBSLOT("__ixor__", nb_inplace_xor); ! NBSLOT("__ior__", nb_inplace_or); if (PyDict_GetItemString(dict, "__str__") || PyDict_GetItemString(dict, "__repr__")) type->tp_print = NULL; ! ! TPSLOT("__cmp__", tp_compare); ! TPSLOT("__repr__", tp_repr); ! TPSLOT("__hash__", tp_hash); ! TPSLOT("__call__", tp_call); ! TPSLOT("__str__", tp_str); ! TPSLOT("__getattr__", tp_getattro); ! TPSLOT("__setattr__", tp_setattro); ! TPSLOT("__lt__", tp_richcompare); ! TPSLOT("__le__", tp_richcompare); ! TPSLOT("__eq__", tp_richcompare); ! TPSLOT("__ne__", tp_richcompare); ! TPSLOT("__gt__", tp_richcompare); ! TPSLOT("__ge__", tp_richcompare); ! TPSLOT("__iter__", tp_iter); ! TPSLOT("next", tp_iternext); ! TPSLOT("__get__", tp_descr_get); ! TPSLOT("__set__", tp_descr_set); ! TPSLOT("__init__", tp_init); } From fdrake@users.sourceforge.net Fri Jun 29 15:59:03 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 29 Jun 2001 07:59:03 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libcgi.tex,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv25891/lib Modified Files: libcgi.tex Log Message: Simplify an example based on comment from Thomas Holenstein : Do not use an extra flag variable to test only once in one subsequent if statement. Index: libcgi.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcgi.tex,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -r1.28 -r1.29 *** libcgi.tex 2000/08/25 21:47:55 1.28 --- libcgi.tex 2001/06/29 14:59:01 1.29 *************** *** 90,97 **** \begin{verbatim} form = cgi.FieldStorage() ! form_ok = 0 ! if form.has_key("name") and form.has_key("addr"): ! form_ok = 1 ! if not form_ok: print "

Error

" print "Please fill in the name and addr fields." --- 90,94 ---- \begin{verbatim} form = cgi.FieldStorage() ! if not (form.has_key("name") and form.has_key("addr")): print "

Error

" print "Please fill in the name and addr fields." From fdrake@users.sourceforge.net Fri Jun 29 16:00:37 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 29 Jun 2001 08:00:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libcgi.tex,1.28,1.28.6.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv26689/lib Modified Files: Tag: release21-maint libcgi.tex Log Message: Simplify an example based on comment from Thomas Holenstein : Do not use an extra flag variable to test only once in one subsequent if statement. Index: libcgi.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcgi.tex,v retrieving revision 1.28 retrieving revision 1.28.6.1 diff -C2 -r1.28 -r1.28.6.1 *** libcgi.tex 2000/08/25 21:47:55 1.28 --- libcgi.tex 2001/06/29 15:00:34 1.28.6.1 *************** *** 90,97 **** \begin{verbatim} form = cgi.FieldStorage() ! form_ok = 0 ! if form.has_key("name") and form.has_key("addr"): ! form_ok = 1 ! if not form_ok: print "

Error

" print "Please fill in the name and addr fields." --- 90,94 ---- \begin{verbatim} form = cgi.FieldStorage() ! if not (form.has_key("name") and form.has_key("addr")): print "

Error

" print "Please fill in the name and addr fields." From fdrake@users.sourceforge.net Fri Jun 29 16:01:16 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 29 Jun 2001 08:01:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc ACKS,1.16,1.16.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv27003 Modified Files: Tag: release21-maint ACKS Log Message: Another name. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ACKS,v retrieving revision 1.16 retrieving revision 1.16.4.1 diff -C2 -r1.16 -r1.16.4.1 *** ACKS 2001/02/23 19:11:45 1.16 --- ACKS 2001/06/29 15:01:14 1.16.4.1 *************** *** 66,69 **** --- 66,70 ---- Gregor Hoffleit Steve Holden + Thomas Holenstein Gerrit Holl Rob Hooft From gvanrossum@users.sourceforge.net Fri Jun 29 16:03:56 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 29 Jun 2001 08:03:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include object.h,2.79.2.19,2.79.2.20 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv28096 Modified Files: Tag: descr-branch object.h Log Message: Add declaration for _PyType_Lookup(). Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.79.2.19 retrieving revision 2.79.2.20 diff -C2 -r2.79.2.19 -r2.79.2.20 *** object.h 2001/06/28 16:49:11 2.79.2.19 --- object.h 2001/06/29 15:03:54 2.79.2.20 *************** *** 302,305 **** --- 302,306 ---- extern DL_IMPORT(PyObject *) PyType_GenericNew(PyTypeObject *, PyObject *, PyObject *); + extern DL_IMPORT(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *); /* Generic operations on objects */ From gvanrossum@users.sourceforge.net Fri Jun 29 16:03:00 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 29 Jun 2001 08:03:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.49,2.16.8.50 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv27650 Modified Files: Tag: descr-branch typeobject.c Log Message: First cut at dynamic types. Too much code moved around to describe the changes in detail. Specification of what changed: If you set ``__dynamic__ = 1'' is a class statement that creates a new type, the new type is dynamic. A new type is also dynamic if at least one of its base types is dynamic and no __dynamic__ flag is set in the class statement. By setting ``__dynamic__ = 0'' in the class statement you can force a static type even if some bases are dynamic. For a dynamic type t: - t.__dict__ is t.__defined__ # they are the same object - type(t.__dict__) is dictionary # not a proxy - t. = is equivalent to t.__dict__[''] = - attribute lookup for dynamic types and their instances searches the __defined__ dict of the type and its base types, in MRO sequence (even if the base class is static) Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.49 retrieving revision 2.16.8.50 diff -C2 -r2.16.8.49 -r2.16.8.50 *** typeobject.c 2001/06/29 14:58:30 2.16.8.49 --- typeobject.c 2001/06/29 15:02:58 2.16.8.50 *************** *** 36,39 **** --- 36,43 ---- return Py_None; } + if (type->tp_flags & Py_TPFLAGS_DYNAMICTYPE) { + Py_INCREF(type->tp_dict); + return type->tp_dict; + } return PyDictProxy_New(type->tp_dict); } *************** *** 46,49 **** --- 50,57 ---- return Py_None; } + if (type->tp_flags & Py_TPFLAGS_DYNAMICTYPE) { + Py_INCREF(type->tp_defined); + return type->tp_defined; + } return PyDictProxy_New(type->tp_defined); } *************** *** 371,379 **** PyObject *name, *bases, *dict; static char *kwlist[] = {"name", "bases", "dict", 0}; ! PyObject *slots; ! PyTypeObject *type, *base; etype *et; struct memberlist *mp; ! int i, nbases, nslots, slotoffset; if (PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 && --- 379,387 ---- PyObject *name, *bases, *dict; static char *kwlist[] = {"name", "bases", "dict", 0}; ! PyObject *slots, *tmp; ! PyTypeObject *type, *base, *tmptype; etype *et; struct memberlist *mp; ! int i, nbases, nslots, slotoffset, dynamic; if (PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 && *************** *** 386,414 **** /* Check arguments */ ! if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO:type", kwlist, ! &name, &bases, &dict)) return NULL; ! if (PyTuple_Check(bases)) { ! int i, n; ! n = PyTuple_GET_SIZE(bases); ! for (i = 0; i < n; i++) { ! PyObject *base_i = PyTuple_GET_ITEM(bases, i); ! PyTypeObject *type_i = base_i->ob_type; ! if (issubtype(metatype, type_i)) ! continue; ! if (issubtype(type_i, metatype)) { ! metatype = type_i; ! continue; ! } ! PyErr_SetString(PyExc_TypeError, ! "metaclass conflict among bases"); ! return NULL; } ! if (metatype->tp_new != type_new) ! return metatype->tp_new(metatype, args, kwds); } ! /* Adjust empty bases */ ! nbases = PyTuple_GET_SIZE(bases); if (nbases == 0) { bases = Py_BuildValue("(O)", &PyBaseObject_Type); --- 394,425 ---- /* Check arguments */ ! if (!PyArg_ParseTupleAndKeywords(args, kwds, "SO!O!:type", kwlist, ! &name, ! &PyTuple_Type, &bases, ! &PyDict_Type, &dict)) return NULL; ! ! /* Determine the proper metatype to deal with this, ! and check for metatype conflicts while we're at it. ! Note that if some other metatype wins to contract, ! it's possible that its instances are not types. */ ! nbases = PyTuple_GET_SIZE(bases); ! for (i = 0; i < nbases; i++) { ! tmp = PyTuple_GET_ITEM(bases, i); ! tmptype = tmp->ob_type; ! if (issubtype(metatype, tmptype)) ! continue; ! if (issubtype(tmptype, metatype)) { ! metatype = tmptype; ! continue; } ! PyErr_SetString(PyExc_TypeError, ! "metatype conflict among bases"); ! return NULL; } + if (metatype->tp_new != type_new) /* Pass it to the winner */ + return metatype->tp_new(metatype, args, kwds); ! /* Adjust for empty tuple bases */ if (nbases == 0) { bases = Py_BuildValue("(O)", &PyBaseObject_Type); *************** *** 419,424 **** else Py_INCREF(bases); ! /* Calculate best base */ base = best_base(bases); if (base == NULL) --- 430,437 ---- else Py_INCREF(bases); + + /* XXX From here until type is allocated, "return NULL" leaks bases! */ ! /* Calculate best base, and check that all bases are type objects */ base = best_base(bases); if (base == NULL) *************** *** 431,434 **** --- 444,475 ---- } + /* Should this be a dynamic class (i.e. modifiable __dict__)? */ + tmp = PyDict_GetItemString(dict, "__dynamic__"); + if (tmp != NULL) { + /* The class author has a preference */ + dynamic = PyObject_IsTrue(tmp); + Py_DECREF(tmp); + if (dynamic < 0) + return NULL; + } + else { + /* Make a new class dynamic if any of its bases is dynamic. + This is not always the same as inheriting the __dynamic__ + class attribute! */ + dynamic = 0; + for (i = 0; i < nbases; i++) { + tmptype = (PyTypeObject *)PyTuple_GET_ITEM(bases, i); + if (tmptype->tp_flags & Py_TPFLAGS_DYNAMICTYPE) { + dynamic = 1; + break; + } + } + + /* Set the __dynamic__ attribute */ + if (PyDict_SetItemString(dict, "__dynamic__", + dynamic ? Py_True : Py_False) < 0) + return NULL; + } + /* Check for a __slots__ sequence variable in dict, and count it */ slots = PyDict_GetItemString(dict, "__slots__"); *************** *** 457,460 **** --- 498,504 ---- nslots = 1; + /* XXX From here until type is safely allocated, + "return NULL" may leak slots! */ + /* Allocate the type object */ type = (PyTypeObject *)metatype->tp_alloc(metatype, nslots); *************** *** 471,474 **** --- 515,520 ---- type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE | Py_TPFLAGS_BASETYPE; + if (dynamic) + type->tp_flags |= Py_TPFLAGS_DYNAMICTYPE; type->tp_as_number = &et->as_number; type->tp_as_sequence = &et->as_sequence; *************** *** 515,519 **** /* Special case some slots */ ! if (type->tp_dictoffset != 0) { if (base->tp_getattr == NULL && base->tp_getattro == NULL) type->tp_getattro = PyObject_GenericGetAttr; --- 561,565 ---- /* Special case some slots */ ! if (type->tp_dictoffset != 0 || nslots > 0) { if (base->tp_getattr == NULL && base->tp_getattro == NULL) type->tp_getattro = PyObject_GenericGetAttr; *************** *** 537,548 **** } static PyObject * type_getattro(PyTypeObject *type, PyObject *name) { if (type->tp_dict == NULL) { if (PyType_InitDict(type) < 0) return NULL; } ! return PyObject_GenericGetAttr((PyObject *)type, name); } --- 583,641 ---- } + /* Internal API to look for a name through the MRO. + This returns a borrowed reference, and doesn't set an exception! */ + PyObject * + _PyType_Lookup(PyTypeObject *type, PyObject *name) + { + int i, n; + PyObject *mro = type->tp_mro, *res; + + assert(PyTuple_Check(mro)); + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + type = (PyTypeObject *) PyTuple_GET_ITEM(mro, i); + assert(PyType_Check(type)); + assert(type->tp_dict && PyDict_Check(type->tp_dict)); + res = PyDict_GetItem(type->tp_dict, name); + if (res != NULL) + return res; + } + return NULL; + } + static PyObject * type_getattro(PyTypeObject *type, PyObject *name) { + PyObject *descr, *res; + descrgetfunc f; + if (type->tp_dict == NULL) { if (PyType_InitDict(type) < 0) return NULL; + } + descr = PyObject_GenericGetAttr((PyObject *)type, name); + if (descr == NULL) { + descr = _PyType_Lookup(type, name); + if (descr == NULL) + return NULL; + PyErr_Clear(); + Py_INCREF(descr); + } + f = descr->ob_type->tp_descr_get; + if (f != NULL) { + res = f(descr, NULL); + Py_DECREF(descr); + return res; } ! return descr; ! } ! ! static int ! type_setattro(PyTypeObject *type, PyObject *name, PyObject *value) ! { ! if (type->tp_flags & Py_TPFLAGS_DYNAMICTYPE) ! return PyObject_GenericSetAttr((PyObject *)type, name, value); ! PyErr_SetString(PyExc_TypeError, "can't set type attributes"); ! return -1; } *************** *** 589,593 **** 0, /* tp_str */ (getattrofunc)type_getattro, /* tp_getattro */ ! 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ --- 682,686 ---- 0, /* tp_str */ (getattrofunc)type_getattro, /* tp_getattro */ ! (setattrofunc)type_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ *************** *** 994,1008 **** } - /* Initialize tp_dict from tp_defined */ - type->tp_dict = PyDict_Copy(dict); - if (type->tp_dict == NULL) - return -1; - - /* Inherit base class slots */ - if (base) { - if (inherit_slots(type, base) < 0) - return -1; - } - /* Calculate method resolution order */ x = method_resolution_order(type); --- 1087,1090 ---- *************** *** 1015,1032 **** Py_DECREF(x); ! /* Inherit methods, updating from last base backwards */ ! bases = type->tp_mro; ! assert(bases != NULL); ! assert(PyTuple_Check(bases)); ! n = PyTuple_GET_SIZE(bases); ! for (i = n; --i >= 0; ) { ! base = (PyTypeObject *)PyTuple_GET_ITEM(bases, i); ! assert(PyType_Check(base)); ! x = base->tp_defined; ! if (x != NULL) { ! x = PyObject_CallMethod(type->tp_dict, "update","O",x); ! if (x == NULL) return -1; - Py_DECREF(x); /* throw away None */ } } --- 1097,1125 ---- Py_DECREF(x); ! /* Initialize tp_dict */ ! if (type->tp_flags & Py_TPFLAGS_DYNAMICTYPE) { ! /* For a dynamic type. tp_dict *is* tp_defined */ ! Py_INCREF(type->tp_defined); ! type->tp_dict = type->tp_defined; ! } ! else { ! /* For a static type, tp_dict is the consolidation ! of the tp_defined of its bases in MRO. Earlier ! bases override later bases; since d.update() works ! the other way, we walk the MRO sequence backwards. */ ! ! type->tp_dict = PyDict_New(); ! if (type->tp_dict == NULL) ! return -1; ! bases = type->tp_mro; ! assert(bases != NULL); ! assert(PyTuple_Check(bases)); ! n = PyTuple_GET_SIZE(bases); ! for (i = n; --i >= 0; ) { ! base = (PyTypeObject *)PyTuple_GET_ITEM(bases, i); ! assert(PyType_Check(base)); ! x = base->tp_defined; ! if (x != NULL && PyDict_Update(type->tp_dict, x) < 0) return -1; } } From gvanrossum@users.sourceforge.net Fri Jun 29 16:06:00 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 29 Jun 2001 08:06:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects object.c,2.124.4.16,2.124.4.17 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv29052 Modified Files: Tag: descr-branch object.c Log Message: PyObject_GenericGetAttr(): for dynamic types, use _PyType_Lookup() instead of coding the MRO loop directly. (This will now search the type's own __defined__ a second time unsuccessfully; this is all provisional anyway.) Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.124.4.16 retrieving revision 2.124.4.17 diff -C2 -r2.124.4.16 -r2.124.4.17 *** object.c 2001/06/28 16:51:27 2.124.4.16 --- object.c 2001/06/29 15:05:58 2.124.4.17 *************** *** 1152,1177 **** if (tp->tp_flags & Py_TPFLAGS_DYNAMICTYPE) { ! /* Look through base classes tp_defined, in MRO, ! skipping first base (which should be tp) */ ! int i, n; ! PyObject *mro = tp->tp_mro; ! PyTypeObject *t; ! assert(PyTuple_Check(mro)); ! n = PyTuple_GET_SIZE(mro); ! assert(n > 0 && PyTuple_GET_ITEM(mro, 0) == (PyObject *)tp); ! descr = NULL; ! for (i = 1; i < n; i++) { ! t = (PyTypeObject *) PyTuple_GET_ITEM(mro, i); ! assert(PyType_Check(t)); ! assert(t->tp_dict && PyDict_Check(t->tp_dict)); ! descr = PyDict_GetItem(t->tp_dict, name); ! if (descr != NULL) { ! f = descr->ob_type->tp_descr_get; ! if (f != NULL) ! return f(descr, obj); ! else { ! Py_INCREF(descr); ! return descr; ! } } } --- 1152,1164 ---- if (tp->tp_flags & Py_TPFLAGS_DYNAMICTYPE) { ! /* Look through base classes tp_defined, in MRO */ ! descr = _PyType_Lookup(tp, name); ! if (descr != NULL) { ! f = descr->ob_type->tp_descr_get; ! if (f != NULL) ! return f(descr, obj); ! else { ! Py_INCREF(descr); ! return descr; } } From gvanrossum@users.sourceforge.net Fri Jun 29 16:06:34 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 29 Jun 2001 08:06:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.1.2.19,1.1.2.20 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv29317 Modified Files: Tag: descr-branch test_descr.py Log Message: Add tests for dynamic types. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_descr.py,v retrieving revision 1.1.2.19 retrieving revision 1.1.2.20 diff -C2 -r1.1.2.19 -r1.1.2.20 *** test_descr.py 2001/06/28 20:35:31 1.1.2.19 --- test_descr.py 2001/06/29 15:06:31 1.1.2.20 *************** *** 502,505 **** --- 502,544 ---- verify(x.c == 3) + def dynamics(): + if verbose: print "Testing __dynamic__..." + class S1: + __metaclass__ = type + verify(S1.__dynamic__ == 0) + class S(object): + pass + verify(C.__dynamic__ == 0) + class D(object): + __dynamic__ = 1 + verify(D.__dynamic__ == 1) + class E(D, S): + pass + verify(E.__dynamic__ == 1) + class F(S, D): + pass + verify(F.__dynamic__ == 1) + try: + S.foo = 1 + except (AttributeError, TypeError): + pass + else: + print "Ouch: assignment to a static class attribute shouldn't work!" + D.foo = 1 + verify(D.foo == 1) + # Test that dynamic attributes are inherited + verify(E.foo == 1) + verify(F.foo == 1) + class SS(D): + __dynamic__ = 0 + verify(SS.__dynamic__ == 0) + verify(SS.foo == 1) + try: + SS.foo = 1 + except (AttributeError, TypeError): + pass + else: + print "Ouch: assignment to SS.foo shouldn't work!" + def errors(): if verbose: print "Testing errors..." *************** *** 572,575 **** --- 611,615 ---- objects() slots() + dynamics() errors() From fdrake@users.sourceforge.net Fri Jun 29 16:39:55 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 29 Jun 2001 08:39:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libtime.tex,1.38,1.39 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv7932/lib Modified Files: libtime.tex Log Message: SourceForge bug #437041: Use a portable format in the example that creates a timestamp suitable for use in email, also updating it and the footnote from RFC 822 to RFC 2822. Index: libtime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libtime.tex,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -r1.38 -r1.39 *** libtime.tex 2001/04/19 04:55:23 1.38 --- libtime.tex 2001/06/29 15:39:53 1.39 *************** *** 231,247 **** Here is an example, a format for dates compatible with that specified ! in the \rfc{822} Internet email standard. ! \footnote{The use of \%Z is now ! deprecated, but the \%z escape that expands to the preferred hour/minute offset is not supported by all ANSI C libraries. Also, a strict reading of the original 1982 \rfc{822} standard calls for a two-digit year (\%y rather than \%Y), but practice moved to ! 4-digit years long before the year 2000.} \begin{verbatim} ! >>> from time import * ! >>> strftime("%a, %d %b %Y %H:%M:%S %Z", localtime()) ! 'Sat, 27 Jan 2001 05:15:05 EST' ! >>> \end{verbatim} --- 231,247 ---- Here is an example, a format for dates compatible with that specified ! in the \rfc{2822} Internet email standard. ! \footnote{The use of \code{\%Z} is now ! deprecated, but the \code{\%z} escape that expands to the preferred hour/minute offset is not supported by all ANSI C libraries. Also, a strict reading of the original 1982 \rfc{822} standard calls for a two-digit year (\%y rather than \%Y), but practice moved to ! 4-digit years long before the year 2000. The 4-digit year has ! been mandated by \rfc{2822}, which obsoletes \rfc{822}.} \begin{verbatim} ! >>> from time import gmtime, strftime ! >>> strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime()) ! 'Thu, 28 Jun 2001 14:17:15 +0000' \end{verbatim} From fdrake@users.sourceforge.net Fri Jun 29 16:41:21 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 29 Jun 2001 08:41:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libtime.tex,1.37.4.1,1.37.4.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv8372/lib Modified Files: Tag: release21-maint libtime.tex Log Message: SourceForge bug #437041: Use a portable format in the example that creates a timestamp suitable for use in email, also updating it and the footnote from RFC 822 to RFC 2822. Index: libtime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libtime.tex,v retrieving revision 1.37.4.1 retrieving revision 1.37.4.2 diff -C2 -r1.37.4.1 -r1.37.4.2 *** libtime.tex 2001/04/19 04:55:57 1.37.4.1 --- libtime.tex 2001/06/29 15:41:19 1.37.4.2 *************** *** 231,247 **** Here is an example, a format for dates compatible with that specified ! in the \rfc{822} Internet email standard. ! \footnote{The use of \%Z is now ! deprecated, but the \%z escape that expands to the preferred hour/minute offset is not supported by all ANSI C libraries. Also, a strict reading of the original 1982 \rfc{822} standard calls for a two-digit year (\%y rather than \%Y), but practice moved to ! 4-digit years long before the year 2000.} \begin{verbatim} ! >>> from time import * ! >>> strftime("%a, %d %b %Y %H:%M:%S %Z", localtime()) ! 'Sat, 27 Jan 2001 05:15:05 EST' ! >>> \end{verbatim} --- 231,247 ---- Here is an example, a format for dates compatible with that specified ! in the \rfc{2822} Internet email standard. ! \footnote{The use of \code{\%Z} is now ! deprecated, but the \code{\%z} escape that expands to the preferred hour/minute offset is not supported by all ANSI C libraries. Also, a strict reading of the original 1982 \rfc{822} standard calls for a two-digit year (\%y rather than \%Y), but practice moved to ! 4-digit years long before the year 2000. The 4-digit year has ! been mandated by \rfc{2822}, which obsoletes \rfc{822}.} \begin{verbatim} ! >>> from time import gmtime, strftime ! >>> strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime()) ! 'Thu, 28 Jun 2001 14:17:15 +0000' \end{verbatim} From fdrake@users.sourceforge.net Fri Jun 29 16:41:47 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 29 Jun 2001 08:41:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc ACKS,1.16.4.1,1.16.4.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv8503 Modified Files: Tag: release21-maint ACKS Log Message: Another name. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ACKS,v retrieving revision 1.16.4.1 retrieving revision 1.16.4.2 diff -C2 -r1.16.4.1 -r1.16.4.2 *** ACKS 2001/06/29 15:01:14 1.16.4.1 --- ACKS 2001/06/29 15:41:45 1.16.4.2 *************** *** 42,45 **** --- 42,46 ---- Michael Ernst Blame Andy Eskilsson + Carey Evans Martijn Faassen Carl Feynman From fdrake@users.sourceforge.net Fri Jun 29 16:42:22 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 29 Jun 2001 08:42:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc ACKS,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv8779 Modified Files: ACKS Log Message: Two more names. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ACKS,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -r1.18 -r1.19 *** ACKS 2001/06/23 03:17:02 1.18 --- ACKS 2001/06/29 15:42:20 1.19 *************** *** 45,48 **** --- 45,49 ---- Michael Ernst Blame Andy Eskilsson + Carey Evans Martijn Faassen Carl Feynman *************** *** 70,73 **** --- 71,75 ---- Gregor Hoffleit Steve Holden + Thomas Holenstein Gerrit Holl Rob Hooft From gvanrossum@users.sourceforge.net Fri Jun 29 16:48:23 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 29 Jun 2001 08:48:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include objimpl.h,2.34.4.1,2.34.4.2 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv10465 Modified Files: Tag: descr-branch objimpl.h Log Message: PyType_BASICSIZE() and PyType_SET_BASICSIZE(): two macros that make calculations involving tp_basicsize easier, by automating the PyGC_HEAD_SIZE bias calculation. Index: objimpl.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/objimpl.h,v retrieving revision 2.34.4.1 retrieving revision 2.34.4.2 diff -C2 -r2.34.4.1 -r2.34.4.2 *** objimpl.h 2001/05/04 16:48:08 2.34.4.1 --- objimpl.h 2001/06/29 15:48:21 2.34.4.2 *************** *** 241,244 **** --- 241,246 ---- #define PyObject_AS_GC(o) (o) #define PyObject_FROM_GC(o) (o) + #define PyType_BASICSIZE(t) ((t)->tp_basicsize) + #define PyType_SET_BASICSIZE(t, s) ((t)->tp_basicsize = (s)) #else *************** *** 273,276 **** --- 275,285 ---- /* Get the object given the PyGC_Head */ #define PyObject_FROM_GC(g) ((PyObject *)(((PyGC_Head *)g)+1)) + + /* Calculate tp_basicsize excluding PyGC_HEAD_SIZE if applicable */ + #define PyType_BASICSIZE(t) (!PyType_IS_GC(t) ? (t)->tp_basicsize : \ + (t)->tp_basicsize - PyGC_HEAD_SIZE) + #define PyType_SET_BASICSIZE(t, s) (!PyType_IS_GC(t) ? \ + ((t)->tp_basicsize = (s)) : \ + ((t)->tp_basicsize = (s) + PyGC_HEAD_SIZE)) extern DL_IMPORT(void) _PyGC_Dump(PyGC_Head *); From gvanrossum@users.sourceforge.net Fri Jun 29 16:50:20 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 29 Jun 2001 08:50:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.50,2.16.8.51 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv11116 Modified Files: Tag: descr-branch typeobject.c Log Message: Put the new PyType_(SET_)BASICSIZE() macros to use. (This was an idea from Tim Peters that removes most of my desire to incorporate Neil's patch to the GC API.) Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.50 retrieving revision 2.16.8.51 diff -C2 -r2.16.8.50 -r2.16.8.51 *** typeobject.c 2001/06/29 15:02:58 2.16.8.50 --- typeobject.c 2001/06/29 15:50:18 2.16.8.51 *************** *** 332,344 **** extra_ivars(PyTypeObject *type, PyTypeObject *base) { ! int t_size = type->tp_basicsize; ! int b_size = base->tp_basicsize; - assert((type->tp_flags & Py_TPFLAGS_GC) >= - (base->tp_flags & Py_TPFLAGS_GC)); /* base has GC, type not! */ - if (type->tp_flags & Py_TPFLAGS_GC) - t_size -= PyGC_HEAD_SIZE; - if (base->tp_flags & Py_TPFLAGS_GC) - b_size -= PyGC_HEAD_SIZE; assert(t_size >= b_size); /* type smaller than base! */ if (type->tp_itemsize || base->tp_itemsize) { --- 332,338 ---- 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! */ if (type->tp_itemsize || base->tp_itemsize) { *************** *** 537,543 **** /* Add descriptors for custom slots from __slots__, or for __dict__ */ mp = et->members; ! slotoffset = base->tp_basicsize; ! if (base->tp_flags & Py_TPFLAGS_GC) ! slotoffset -= PyGC_HEAD_SIZE; if (slots != NULL) { for (i = 0; i < nslots; i++, mp++) { --- 531,535 ---- /* Add descriptors for custom slots from __slots__, or for __dict__ */ mp = et->members; ! slotoffset = PyType_BASICSIZE(base); if (slots != NULL) { for (i = 0; i < nslots; i++, mp++) { *************** *** 962,973 **** /* Copying basicsize is connected to the GC flags */ ! oldsize = base->tp_basicsize; ! if (base->tp_flags & Py_TPFLAGS_GC) ! oldsize -= PyGC_HEAD_SIZE; ! newsize = type->tp_basicsize; ! if (newsize && (type->tp_flags & Py_TPFLAGS_GC)) ! newsize -= PyGC_HEAD_SIZE; ! if (!newsize) ! newsize = oldsize; if (!(type->tp_flags & Py_TPFLAGS_GC) && (base->tp_flags & Py_TPFLAGS_GC) && --- 954,959 ---- /* Copying basicsize is connected to the GC flags */ ! oldsize = PyType_BASICSIZE(base); ! newsize = type->tp_basicsize ? PyType_BASICSIZE(type) : oldsize; if (!(type->tp_flags & Py_TPFLAGS_GC) && (base->tp_flags & Py_TPFLAGS_GC) && *************** *** 978,984 **** COPYSLOT(tp_clear); } ! if (type->tp_flags & Py_TPFLAGS_GC) ! newsize += PyGC_HEAD_SIZE; ! type->tp_basicsize = newsize; COPYSLOT(tp_itemsize); --- 964,968 ---- COPYSLOT(tp_clear); } ! PyType_SET_BASICSIZE(type, newsize); COPYSLOT(tp_itemsize); From gvanrossum@users.sourceforge.net Fri Jun 29 16:51:41 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 29 Jun 2001 08:51:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects object.c,2.124.4.17,2.124.4.18 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv11657 Modified Files: Tag: descr-branch object.c Log Message: Put the new PyType_BASICSIZE() macro to use. Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.124.4.17 retrieving revision 2.124.4.18 diff -C2 -r2.124.4.17 -r2.124.4.18 *** object.c 2001/06/29 15:05:58 2.124.4.17 --- object.c 2001/06/29 15:51:39 2.124.4.18 *************** *** 1090,1094 **** return NULL; if (dictoffset < 0) { ! dictoffset += tp->tp_basicsize; assert(dictoffset > 0); /* Sanity check */ if (tp->tp_itemsize > 0) { --- 1090,1094 ---- return NULL; if (dictoffset < 0) { ! dictoffset += PyType_BASICSIZE(tp); assert(dictoffset > 0); /* Sanity check */ if (tp->tp_itemsize > 0) { From gvanrossum@users.sourceforge.net Fri Jun 29 16:59:57 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 29 Jun 2001 08:59:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.1.2.20,1.1.2.21 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv14870 Modified Files: Tag: descr-branch test_descr.py Log Message: Add tests that __dynamic__ attribute is present on built-in types. Replace ``print "Ouch! ..."'' with verify(0, "..."). Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_descr.py,v retrieving revision 1.1.2.20 retrieving revision 1.1.2.21 diff -C2 -r1.1.2.20 -r1.1.2.21 *** test_descr.py 2001/06/29 15:06:31 1.1.2.20 --- test_descr.py 2001/06/29 15:59:55 1.1.2.21 *************** *** 459,463 **** pass else: ! print "Ouch: object() should not allow setting a foo attribute!" verify(not hasattr(object(), "__dict__")) --- 459,463 ---- pass else: ! verify(0, "object() should not allow setting a foo attribute") verify(not hasattr(object(), "__dict__")) *************** *** 504,507 **** --- 504,509 ---- def dynamics(): if verbose: print "Testing __dynamic__..." + verify(object.__dynamic__ == 0) + verify(list.__dynamic__ == 0) class S1: __metaclass__ = type *************** *** 524,528 **** pass else: ! print "Ouch: assignment to a static class attribute shouldn't work!" D.foo = 1 verify(D.foo == 1) --- 526,530 ---- pass else: ! verify(0, "assignment to a static class attribute should be illegal") D.foo = 1 verify(D.foo == 1) *************** *** 539,543 **** pass else: ! print "Ouch: assignment to SS.foo shouldn't work!" def errors(): --- 541,545 ---- pass else: ! verify(0, "assignment to SS.foo should be illegal") def errors(): *************** *** 550,554 **** pass else: ! print "Ouch: inheritance from both list and dict should be illegal!" try: --- 552,556 ---- pass else: ! verify(0, "inheritance from both list and dict should be illegal") try: *************** *** 558,562 **** pass else: ! print "Ouch: inheritance from non-type should be illegal!" class Classic: pass --- 560,564 ---- pass else: ! verify(0, "inheritance from non-type should be illegal") class Classic: pass *************** *** 568,572 **** pass else: ! print "Ouch: inheritance from object and Classic should be illegal!" try: --- 570,574 ---- pass else: ! verify(0, "inheritance from object and Classic should be illegal") try: *************** *** 576,580 **** pass else: ! print "Ouch: inheritance from int should be illegal!" try: --- 578,582 ---- pass else: ! verify(0, "inheritance from int should be illegal") try: *************** *** 584,588 **** pass else: ! print "Ouch: __slots__ = {} should be illegal!" try: --- 586,590 ---- pass else: ! verify(0, "__slots__ = {} should be illegal") try: *************** *** 592,596 **** pass else: ! print "Ouch: __slots__ = [1] should be illegal!" def all(): --- 594,598 ---- pass else: ! verify(0, "__slots__ = [1] should be illegal") def all(): From gvanrossum@users.sourceforge.net Fri Jun 29 17:00:57 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 29 Jun 2001 09:00:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.51,2.16.8.52 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv15243 Modified Files: Tag: descr-branch typeobject.c Log Message: Make __dynamic__ a built-in attribute rather than an entry in the type's __dict__. This makes it available for built-in types too. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.51 retrieving revision 2.16.8.52 diff -C2 -r2.16.8.51 -r2.16.8.52 *** typeobject.c 2001/06/29 15:50:18 2.16.8.51 --- typeobject.c 2001/06/29 16:00:54 2.16.8.52 *************** *** 57,64 **** --- 57,75 ---- } + static PyObject * + type_dynamic(PyTypeObject *type, void *context) + { + PyObject *res; + + res = (type->tp_flags & Py_TPFLAGS_DYNAMICTYPE) ? Py_True : Py_False; + Py_INCREF(res); + return res; + } + struct getsetlist type_getsets[] = { {"__module__", (getter)type_module, NULL, NULL}, {"__dict__", (getter)type_dict, NULL, NULL}, {"__defined__", (getter)type_defined, NULL, NULL}, + {"__dynamic__", (getter)type_dynamic, NULL, NULL}, {0} }; *************** *** 459,467 **** } } - - /* Set the __dynamic__ attribute */ - if (PyDict_SetItemString(dict, "__dynamic__", - dynamic ? Py_True : Py_False) < 0) - return NULL; } --- 470,473 ---- From fdrake@users.sourceforge.net Fri Jun 29 17:21:49 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 29 Jun 2001 09:21:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libcookie.tex,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv21986/lib Modified Files: libcookie.tex Log Message: Removed some stray periods, and fix up a number of visible markup consistency errors (mostly omitted "()" at the end of function and method names). Reported by Milan Zamazal . Index: libcookie.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcookie.tex,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** libcookie.tex 2001/01/18 07:50:17 1.5 --- libcookie.tex 2001/06/29 16:21:47 1.6 *************** *** 29,44 **** the key and the value. ! If \var{input} is given, it is passed to the \method{load} method. \end{classdesc} \begin{classdesc}{SimpleCookie}{\optional{input}} ! This class derives from \class{BaseCookie} and overrides \method{value_decode} ! and \method{value_encode} to be the identity and \function{str()} respectively. \end{classdesc} \begin{classdesc}{SerialCookie}{\optional{input}} ! This class derives from \class{BaseCookie} and overrides \method{value_decode} ! and \method{value_encode} to be the \function{pickle.loads()} and ! \function{pickle.dumps}. Do not use this class. Reading pickled values from a cookie is a --- 29,45 ---- the key and the value. ! If \var{input} is given, it is passed to the \method{load()} method. \end{classdesc} \begin{classdesc}{SimpleCookie}{\optional{input}} ! This class derives from \class{BaseCookie} and overrides ! \method{value_decode()} and \method{value_encode()} to be the identity ! and \function{str()} respectively. \end{classdesc} \begin{classdesc}{SerialCookie}{\optional{input}} ! This class derives from \class{BaseCookie} and overrides ! \method{value_decode()} and \method{value_encode()} to be the ! \function{pickle.loads()} and \function{pickle.dumps()}. Do not use this class. Reading pickled values from a cookie is a *************** *** 50,58 **** \begin{classdesc}{SmartCookie}{\optional{input}} ! This class derives from \class{BaseCookie}. It overrides \method{value_decode} ! to be \function{pickle.loads()} if it is a valid pickle, and otherwise ! the value itself. It overrides \method{value_encode} to be ! \function{pickle.dumps()} unless it is a string, in which case it returns ! the value itself. The same security warning from \class{SerialCookie} applies here. --- 51,59 ---- \begin{classdesc}{SmartCookie}{\optional{input}} ! This class derives from \class{BaseCookie}. It overrides ! \method{value_decode()} to be \function{pickle.loads()} if it is a ! valid pickle, and otherwise the value itself. It overrides ! \method{value_encode()} to be \function{pickle.dumps()} unless it is a ! string, in which case it returns the value itself. The same security warning from \class{SerialCookie} applies here. *************** *** 79,91 **** so it can be overridden ! In general, it should be the case that \method{value_encode} and ! \method{value_decode} are inverses on the range of \var{value_decode}. ! \end{methoddesc}. \begin{methoddesc}[BaseCookie]{output}{\optional{attrs\optional{, header\optional{, sep}}}} Return a string representation suitable to be sent as HTTP headers. ! \var{attrs} and \var{header} are sent to each \class{Morsel}'s \method{output} ! method. \var{sep} is used to join the headers together, and is by default ! a newline. \end{methoddesc} --- 80,92 ---- so it can be overridden ! In general, it should be the case that \method{value_encode()} and ! \method{value_decode()} are inverses on the range of \var{value_decode}. ! \end{methoddesc} \begin{methoddesc}[BaseCookie]{output}{\optional{attrs\optional{, header\optional{, sep}}}} Return a string representation suitable to be sent as HTTP headers. ! \var{attrs} and \var{header} are sent to each \class{Morsel}'s ! \method{output()} method. \var{sep} is used to join the headers ! together, and is by default a newline. \end{methoddesc} *************** *** 162,166 **** The meaning for \var{attrs} is the same as in \method{output()}. ! \end{methoddesc}. \begin{methoddesc}[Morsel]{OutputString}{\optional{attrs}} --- 163,167 ---- The meaning for \var{attrs} is the same as in \method{output()}. ! \end{methoddesc} \begin{methoddesc}[Morsel]{OutputString}{\optional{attrs}} From fdrake@users.sourceforge.net Fri Jun 29 17:22:38 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 29 Jun 2001 09:22:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libcookie.tex,1.5,1.5.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv22198/lib Modified Files: Tag: release21-maint libcookie.tex Log Message: Removed some stray periods, and fix up a number of visible markup consistency errors (mostly omitted "()" at the end of function and method names). Reported by Milan Zamazal . Index: libcookie.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcookie.tex,v retrieving revision 1.5 retrieving revision 1.5.4.1 diff -C2 -r1.5 -r1.5.4.1 *** libcookie.tex 2001/01/18 07:50:17 1.5 --- libcookie.tex 2001/06/29 16:22:36 1.5.4.1 *************** *** 29,44 **** the key and the value. ! If \var{input} is given, it is passed to the \method{load} method. \end{classdesc} \begin{classdesc}{SimpleCookie}{\optional{input}} ! This class derives from \class{BaseCookie} and overrides \method{value_decode} ! and \method{value_encode} to be the identity and \function{str()} respectively. \end{classdesc} \begin{classdesc}{SerialCookie}{\optional{input}} ! This class derives from \class{BaseCookie} and overrides \method{value_decode} ! and \method{value_encode} to be the \function{pickle.loads()} and ! \function{pickle.dumps}. Do not use this class. Reading pickled values from a cookie is a --- 29,45 ---- the key and the value. ! If \var{input} is given, it is passed to the \method{load()} method. \end{classdesc} \begin{classdesc}{SimpleCookie}{\optional{input}} ! This class derives from \class{BaseCookie} and overrides ! \method{value_decode()} and \method{value_encode()} to be the identity ! and \function{str()} respectively. \end{classdesc} \begin{classdesc}{SerialCookie}{\optional{input}} ! This class derives from \class{BaseCookie} and overrides ! \method{value_decode()} and \method{value_encode()} to be the ! \function{pickle.loads()} and \function{pickle.dumps()}. Do not use this class. Reading pickled values from a cookie is a *************** *** 50,58 **** \begin{classdesc}{SmartCookie}{\optional{input}} ! This class derives from \class{BaseCookie}. It overrides \method{value_decode} ! to be \function{pickle.loads()} if it is a valid pickle, and otherwise ! the value itself. It overrides \method{value_encode} to be ! \function{pickle.dumps()} unless it is a string, in which case it returns ! the value itself. The same security warning from \class{SerialCookie} applies here. --- 51,59 ---- \begin{classdesc}{SmartCookie}{\optional{input}} ! This class derives from \class{BaseCookie}. It overrides ! \method{value_decode()} to be \function{pickle.loads()} if it is a ! valid pickle, and otherwise the value itself. It overrides ! \method{value_encode()} to be \function{pickle.dumps()} unless it is a ! string, in which case it returns the value itself. The same security warning from \class{SerialCookie} applies here. *************** *** 76,91 **** \begin{methoddesc}[BaseCookie]{value_encode}{val} Return an encoded value. \var{val} can be any type, but return value ! must be a string. This method does nothing in \class{BaseCookie} --- it exists ! so it can be overridden ! In general, it should be the case that \method{value_encode} and ! \method{value_decode} are inverses on the range of \var{value_decode}. ! \end{methoddesc}. \begin{methoddesc}[BaseCookie]{output}{\optional{attrs\optional{, header\optional{, sep}}}} Return a string representation suitable to be sent as HTTP headers. ! \var{attrs} and \var{header} are sent to each \class{Morsel}'s \method{output} ! method. \var{sep} is used to join the headers together, and is by default ! a newline. \end{methoddesc} --- 77,93 ---- \begin{methoddesc}[BaseCookie]{value_encode}{val} Return an encoded value. \var{val} can be any type, but return value ! must be a string. This method does nothing in \class{BaseCookie} --- ! it exists so it can be overridden ! In general, it should be the case that \method{value_encode()} and ! \method{value_decode()} are inverses on the range of ! \var{value_decode}. ! \end{methoddesc} \begin{methoddesc}[BaseCookie]{output}{\optional{attrs\optional{, header\optional{, sep}}}} Return a string representation suitable to be sent as HTTP headers. ! \var{attrs} and \var{header} are sent to each \class{Morsel}'s ! \method{output()} method. \var{sep} is used to join the headers ! together, and is by default a newline. \end{methoddesc} *************** *** 162,166 **** The meaning for \var{attrs} is the same as in \method{output()}. ! \end{methoddesc}. \begin{methoddesc}[Morsel]{OutputString}{\optional{attrs}} --- 164,168 ---- The meaning for \var{attrs} is the same as in \method{output()}. ! \end{methoddesc} \begin{methoddesc}[Morsel]{OutputString}{\optional{attrs}} From fdrake@users.sourceforge.net Fri Jun 29 17:24:49 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 29 Jun 2001 09:24:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libweakref.tex,1.7.2.2,1.7.2.3 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv22828/lib Modified Files: Tag: release21-maint libweakref.tex Log Message: Correct a markup error for an accented character. Reported by Milan Zamazal . Index: libweakref.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libweakref.tex,v retrieving revision 1.7.2.2 retrieving revision 1.7.2.3 diff -C2 -r1.7.2.2 -r1.7.2.3 *** libweakref.tex 2001/06/22 17:20:05 1.7.2.2 --- libweakref.tex 2001/06/29 16:24:47 1.7.2.3 *************** *** 6,10 **** \moduleauthor{Fred L. Drake, Jr.}{fdrake@acm.org} \moduleauthor{Neil Schemenauer}{nas@arctrix.com} ! \moduleauthor{Martin von L\o"wis}{martin@loewis.home.cs.tu-berlin.de} \sectionauthor{Fred L. Drake, Jr.}{fdrake@acm.org} --- 6,10 ---- \moduleauthor{Fred L. Drake, Jr.}{fdrake@acm.org} \moduleauthor{Neil Schemenauer}{nas@arctrix.com} ! \moduleauthor{Martin von L\"owis}{martin@loewis.home.cs.tu-berlin.de} \sectionauthor{Fred L. Drake, Jr.}{fdrake@acm.org} From fdrake@users.sourceforge.net Fri Jun 29 17:25:09 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 29 Jun 2001 09:25:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libweakref.tex,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv22975/lib Modified Files: libweakref.tex Log Message: Correct a markup error for an accented character. Reported by Milan Zamazal . Index: libweakref.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libweakref.tex,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -r1.9 -r1.10 *** libweakref.tex 2001/06/22 17:20:29 1.9 --- libweakref.tex 2001/06/29 16:25:07 1.10 *************** *** 6,10 **** \moduleauthor{Fred L. Drake, Jr.}{fdrake@acm.org} \moduleauthor{Neil Schemenauer}{nas@arctrix.com} ! \moduleauthor{Martin von L\o"wis}{martin@loewis.home.cs.tu-berlin.de} \sectionauthor{Fred L. Drake, Jr.}{fdrake@acm.org} --- 6,10 ---- \moduleauthor{Fred L. Drake, Jr.}{fdrake@acm.org} \moduleauthor{Neil Schemenauer}{nas@arctrix.com} ! \moduleauthor{Martin von L\"owis}{martin@loewis.home.cs.tu-berlin.de} \sectionauthor{Fred L. Drake, Jr.}{fdrake@acm.org} From gvanrossum@users.sourceforge.net Fri Jun 29 17:32:37 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 29 Jun 2001 09:32:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules spam.c,1.1.2.6,1.1.2.7 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv25234 Modified Files: Tag: descr-branch spam.c Log Message: Simplify and change the spam API: instead of exporting a separate type object and constructor function for each type, the module now exports just the type, by its natural name (spamlist or spamdict). Index: spam.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/Attic/spam.c,v retrieving revision 1.1.2.6 retrieving revision 1.1.2.7 diff -C2 -r1.1.2.6 -r1.1.2.7 *** spam.c 2001/06/06 14:27:54 1.1.2.6 --- spam.c 2001/06/29 16:32:35 1.1.2.7 *************** *** 68,72 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ --- 68,72 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ *************** *** 89,100 **** }; ! static PyObject * ! spamlist_new(void) ! { ! return PyObject_CallObject((PyObject *) &spamlist_type, NULL); ! } - /* spamdict -- a dictf subtype */ - typedef struct { PyDictObject dict; --- 89,94 ---- }; ! /* spamdict -- a dict subtype */ typedef struct { PyDictObject dict; *************** *** 162,166 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ --- 156,160 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ *************** *** 183,213 **** }; - static PyObject * - spamdict_new(void) - { - return PyObject_CallObject((PyObject *) &spamdict_type, NULL); - } - - static PyObject * - spam_dict(PyObject *self, PyObject *args) - { - if (!PyArg_ParseTuple(args, ":dict")) - return NULL; - return spamdict_new(); - } - - /* Module spam */ - - static PyObject * - spam_list(PyObject *self, PyObject *args) - { - if (!PyArg_ParseTuple(args, ":list")) - return NULL; - return spamlist_new(); - } - static PyMethodDef spam_functions[] = { - {"list", spam_list, METH_VARARGS, "create a new spamlist object"}, - {"dict", spam_dict, METH_VARARGS, "create a new spamdict object"}, {0} }; --- 177,181 ---- *************** *** 229,237 **** return; Py_INCREF(&spamlist_type); ! if (PyDict_SetItemString(d, "SpamListType", (PyObject *) &spamlist_type) < 0) return; Py_INCREF(&spamdict_type); ! if (PyDict_SetItemString(d, "SpamDictType", (PyObject *) &spamdict_type) < 0) return; --- 197,205 ---- 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; From gvanrossum@users.sourceforge.net Fri Jun 29 17:32:47 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 29 Jun 2001 09:32:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.1.2.21,1.1.2.22 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv25274 Modified Files: Tag: descr-branch test_descr.py Log Message: Simplify and change the spam API: instead of exporting a separate type object and constructor function for each type, the module now exports just the type, by its natural name (spamlist or spamdict). Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_descr.py,v retrieving revision 1.1.2.21 retrieving revision 1.1.2.22 diff -C2 -r1.1.2.21 -r1.1.2.22 *** test_descr.py 2001/06/29 15:59:55 1.1.2.21 --- test_descr.py 2001/06/29 16:32:45 1.1.2.22 *************** *** 221,229 **** def spamlist(l, memo=None): import spam ! sl = spam.list() ! for i in l: sl.append(i) ! return sl # This is an ugly hack: ! copy._deepcopy_dispatch[spam.SpamListType] = spamlist testbinop(spamlist([1]), spamlist([2]), spamlist([1,2]), "a+b", "__add__") --- 221,227 ---- def spamlist(l, memo=None): import spam ! return spam.spamlist(l) # This is an ugly hack: ! copy._deepcopy_dispatch[spam.spamlist] = spamlist testbinop(spamlist([1]), spamlist([2]), spamlist([1,2]), "a+b", "__add__") *************** *** 249,257 **** def spamdict(d, memo=None): import spam ! sd = spam.dict() for k, v in d.items(): sd[k] = v return sd # This is an ugly hack: ! copy._deepcopy_dispatch[spam.SpamDictType] = spamdict testbinop(spamdict({1:2}), spamdict({2:1}), -1, "cmp(a,b)", "__cmp__") --- 247,255 ---- def spamdict(d, memo=None): import spam ! sd = spam.spamdict() for k, v in d.items(): sd[k] = v return sd # This is an ugly hack: ! copy._deepcopy_dispatch[spam.spamdict] = spamdict testbinop(spamdict({1:2}), spamdict({2:1}), -1, "cmp(a,b)", "__cmp__") From gvanrossum@users.sourceforge.net Fri Jun 29 17:38:40 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 29 Jun 2001 09:38:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.1.2.22,1.1.2.23 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv27651 Modified Files: Tag: descr-branch test_descr.py Log Message: Add some tests for subclassing spam.spamlist and spam.spamdict, since this ability was just added. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_descr.py,v retrieving revision 1.1.2.22 retrieving revision 1.1.2.23 diff -C2 -r1.1.2.22 -r1.1.2.23 *** test_descr.py 2001/06/29 16:32:45 1.1.2.22 --- test_descr.py 2001/06/29 16:38:38 1.1.2.23 *************** *** 241,244 **** --- 241,255 ---- testset3op(spamlist([1,2,3,4]), 1, 3, spamlist([5,6]), spamlist([1,5,6,4]), "a[b:c]=d", "__setslice__") + # Test subclassing + class C(spam.spamlist): + def foo(self): return 1 + a = C() + verify(a == []) + verify(a.foo() == 1) + a.append(100) + verify(a == [100]) + verify(a.getstate() == 0) + a.setstate(42) + verify(a.getstate() == 42) def spamdicts(): *************** *** 273,276 **** --- 284,298 ---- testset2op(spamdict({1:2,3:4}), 2, 3, spamdict({1:2,2:3,3:4}), "a[b]=c", "__setitem__") + # Test subclassing + class C(spam.spamdict): + def foo(self): return 1 + a = C() + verify(a.items() == []) + verify(a.foo() == 1) + a['foo'] = 'bar' + verify(a.items() == [('foo', 'bar')]) + verify(a.getstate() == 0) + a.setstate(100) + verify(a.getstate() == 100) def pydicts(): From fdrake@users.sourceforge.net Fri Jun 29 18:51:00 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 29 Jun 2001 10:51:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tut tut.tex,1.141,1.142 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tut In directory usw-pr-cvs1:/tmp/cvs-serv21536/tut Modified Files: tut.tex Log Message: Use the more conventional "self" as the name of the self parameter in an example. It actually confused a reader. Index: tut.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tut/tut.tex,v retrieving revision 1.141 retrieving revision 1.142 diff -C2 -r1.141 -r1.142 *** tut.tex 2001/06/20 21:37:34 1.141 --- tut.tex 2001/06/29 17:50:57 1.142 *************** *** 3430,3434 **** "A simple example class" i = 12345 ! def f(x): return 'hello world' \end{verbatim} --- 3430,3434 ---- "A simple example class" i = 12345 ! def f(self): return 'hello world' \end{verbatim} From fdrake@users.sourceforge.net Fri Jun 29 18:51:45 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 29 Jun 2001 10:51:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tut tut.tex,1.133.2.3,1.133.2.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tut In directory usw-pr-cvs1:/tmp/cvs-serv21892/tut Modified Files: Tag: release21-maint tut.tex Log Message: Use the more conventional "self" as the name of the self parameter in an example. It actually confused a reader. Index: tut.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tut/tut.tex,v retrieving revision 1.133.2.3 retrieving revision 1.133.2.4 diff -C2 -r1.133.2.3 -r1.133.2.4 *** tut.tex 2001/06/21 18:52:50 1.133.2.3 --- tut.tex 2001/06/29 17:51:42 1.133.2.4 *************** *** 3425,3429 **** "A simple example class" i = 12345 ! def f(x): return 'hello world' \end{verbatim} --- 3425,3429 ---- "A simple example class" i = 12345 ! def f(self): return 'hello world' \end{verbatim} From gvanrossum@users.sourceforge.net Fri Jun 29 19:02:37 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 29 Jun 2001 11:02:37 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,NONE,1.1.2.1 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv25568 Added Files: Tag: descr-branch PLAN.txt Log Message: Implementation plan for descr-branch. This will be deleted upon completion. --- NEW FILE: PLAN.txt --- Project: core implementation **************************** Tasks: Do binary operators properly. nb_add should try to call self.__add__ and other.__radd__. I think I'll exclude base types that define any binary operator without setting the CHECKTYPES flag. Fix comparisons. There's some nasty stuff here: when two types are not the same, and they're not instances, the fallback code doesn't account for the possibility that they might be subtypes of a common base type that defines a comparison. Fix subtype_dealloc(). This currently searches through the list of 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 are a bunch of different APIs here and not all of them do the right 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 to decide whether multiple bases have conflicting instance variables aren't strict enough. I think that sometimes two different classes adding __dict__ may be incompatible after all. Check for order conflicts. Suppose there are two base classes X and Y. Suppose class B derives from X and Y, and class C from Y and X (in that order). Now suppose class D derives from B and C. In which order should the base classes X and Y be searched? This is an order conflict, and should be disallowed; currently the test for this is not implemented. Clean up the GC interface. Currently, tp_basicsize includes the GC head size iff tp_flags includes the GC flag bit. This makes object size math a pain (e.g. to see if two object types have the same instance size, you can't just compare the tp_basicsize fields -- you have to conditionally subtract the GC head size). Neil has a patch that improves the API in this area, but it's backwards incompatible. (http://sf.net/tracker/?func=detail&aid=421893&group_id=5470&atid=305470) I think I know of a way to fix the incompatibility (by switching to a different flag bit). *** Tim proposed a better idea: macros to access tp_basicsize while hiding the nastiness. This is done now, so I think the rest of this task needn't be done. *** Make the __dict__ of types declared with Python class statements writable -- only statically declared types must have an immutable dict, because they're shared between interpreter instances. Possibly trap writes to the __dict__ to update the corresponding tp_ if an ____ name is affected. *** Done as part of the next task. *** It should be an option (maybe a different metaclass, maybe a flag) to *not* merge __dict__ with all the bases, but instead search the __dict__ (or __introduced__?) of all bases in __mro__ order. (This is needed anyway to unify classes completely.) *** Partly done. Inheritance of slots from bases is still icky. Also, I still need to think more about making sure that "special" ivars (those with descriptors classifying them as data) can't be overridden by things in the __dict__. *** Universal base class (object). How can we make the object class subclassable and define simple default methods for everything without having these inherited by built-in types that don't want these defaults? (This may be mostly fixed now.) *** Done, really. *** Add error checking to the MRO calculation. 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. Project: loose ends and follow-through ************************************** Tasks: Make more (most?) built-in types act as their own factory functions. Make more (most?) built-in types subtypable -- with or without overridable allocation. Exceptions should be types. This changes the rules, since now almost anything can be raised (as maybe it should). Or should we strive for enforcement of the convention that all exceptions should be derived from Exception? String exceptions will be another hassle, to be deprecated and eventually ruled out. Standardize a module containing names for all built-in types, and standardize on names. E.g. should the official name of the string type be 'str', 'string', or 'StringType'? Create a hierarchy of types, so that e.g. int and long are both subtypes of an abstract base type integer, which is itself a subtype of number, etc. A lot of thinking can go into this! Project: making classes use the new machinery ********************************************* Tasks: Try to get rid of all code in classobject.c by deferring to the new mechanisms. How far can we get without breaking backwards compatibility? This is underspecified because I haven't thought much about it yet. Can we lose the use of PyInstance_Check() everywhere? I would hope so! Project: backwards compatibility ******************************** Tasks: Make sure all code checks the proper tp_flags bit before accessing type object fields. Identify areas of incompatibility with Python 2.1. Design solutions. Implement and test. Some specific areas: a fair amount of code probably depends on specific types having __members__ and/or __methods__ attributes. 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 type(x) == types.InstanceType won't work any more to detect instances. Should there be a mode where this still works? Maybe this should be the default mode, with a warning, and an explicit way to get the new way to work? (Instead of a __future__ statement, I'm thinking of a module global __metaclass__ which would provide the default metaclass for baseless class statements.) Project: testing **************** Tasks: Identify new functionality that needs testing. Conceive unit tests for all new functionality. Conceive stress tests for critical features. Run the tests. Fix bugs. Repeat until satisfied. Note: this may interact with the branch integration task. Project: integration with main branch ************************************* Tasks: Merge changes in the HEAD branch into the descr-branch. Then merge the descr-branch back into the HEAD branch. The longer we wait, the more effort this will be -- the descr-branch forked off quite a long time ago, and there are changes everywhere in the HEAD branch (e.g. the dict object has been radically rewritten). On the other hand, if we do this too early, we'll have to do it again later. Project: performance tuning *************************** Tasks: Pick or create a general performance benchmark for Python. Benchmark the new system vs. the old system. Profile the new system. Improve hotspots. Repeat until satisfied. Note: this may interact with the branch integration task. Project: documentation ********************** Tasks: Update PEP 252 (descriptors). Describe more of the prototype implementation Update PEP 253 (subtyping). Complicated architectural wrangling with metaclasses. There is an interaction between implementation and description. Write PEP 254 (unification of classes). This should discuss what changes for ordinary classes, and how we can make it more b/w compatible. Other documentation. There needs to be user documentation, eventually. Project: community interaction ****************************** Tasks: Once the PEPs are written, solicit community feedback, and formulate responses to the feedback. Give the community enough time to think over this complicated proposal. Provide the community with a prototype implementation to test. Try to do this *before* casting everything in stone! From gvanrossum@users.sourceforge.net Fri Jun 29 21:03:16 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 29 Jun 2001 13:03:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.52,2.16.8.53 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv926 Modified Files: Tag: descr-branch typeobject.c Log Message: Aargh! During an innocent benchmark test I found out that a simple getattr operation on an instance of a static type was 20x slower than one on an instance of a dynamic type. It took an hour of tracing in the debugger to realize that the call override_slots(type, type->tp_dict) at the end of type_init() was wrong, and should really be override_slots(type, type->tp_defined). The tp_getattro slot had turned into a wrapper for __getattr__, which in turn was a wrapper around the base class's tp_getattro slot. (The solution isn't quite right, because slots are now inherited from the "strongest base" only, while they should be inherited from all bases; but that's a separate issue; it's no worse than before, and the speed glitch is gone.) Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.52 retrieving revision 2.16.8.53 diff -C2 -r2.16.8.52 -r2.16.8.53 *** typeobject.c 2001/06/29 16:00:54 2.16.8.52 --- typeobject.c 2001/06/29 20:03:14 2.16.8.53 *************** *** 577,581 **** /* Override slots that deserve it */ ! override_slots(type, type->tp_dict); return (PyObject *)type; } --- 577,581 ---- /* Override slots that deserve it */ ! override_slots(type, type->tp_defined); return (PyObject *)type; } From gvanrossum@users.sourceforge.net Fri Jun 29 21:46:53 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 29 Jun 2001 13:46:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects object.c,2.124.4.18,2.124.4.19 typeobject.c,2.16.8.53,2.16.8.54 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv11696 Modified Files: Tag: descr-branch object.c typeobject.c Log Message: Fix the problems with inherited "special" attributes (attributes described by a data descriptor, such as __class__ and __dict__). In typeobject.c: - _PyType_Lookup() is smarter: when used on a static type, it does just one dictionary lookup. - type_getattr() does the right thing, which involves a variation on PyObject_GenericGetAttr(), rather than calling it. In object.c: - PyObject_Generic{Get,Set}Attr() now calls _PyType_Lookup() right at the start. For static types, this is the same as the single dictionary lookup it did before. For dynamic types, this correctly gives "special" attributes priority over what might be in the instance dictionary, even if the "special" attribute is inherited from several layers deep. I was worried about the speed of all this. But not to worry: a primitive benchmark suggests that for dynamic type instances a normal attribute lookup is about as fast as that of a classic class. Static type instances are even a bit faster! Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.124.4.18 retrieving revision 2.124.4.19 diff -C2 -r2.124.4.18 -r2.124.4.19 *** object.c 2001/06/29 15:51:39 2.124.4.18 --- object.c 2001/06/29 20:46:51 2.124.4.19 *************** *** 1123,1127 **** } ! descr = PyDict_GetItem(tp->tp_dict, name); f = NULL; if (descr != NULL) { --- 1123,1127 ---- } ! descr = _PyType_Lookup(tp, name); f = NULL; if (descr != NULL) { *************** *** 1151,1168 **** } - if (tp->tp_flags & Py_TPFLAGS_DYNAMICTYPE) { - /* Look through base classes tp_defined, in MRO */ - descr = _PyType_Lookup(tp, name); - if (descr != NULL) { - f = descr->ob_type->tp_descr_get; - if (f != NULL) - return f(descr, obj); - else { - Py_INCREF(descr); - return descr; - } - } - } - PyErr_Format(PyExc_AttributeError, "'%.50s' object has no attribute '%.400s'", --- 1151,1154 ---- *************** *** 1183,1187 **** return -1; } ! descr = PyDict_GetItem(tp->tp_dict, name); f = NULL; if (descr != NULL) { --- 1169,1174 ---- return -1; } ! ! descr = _PyType_Lookup(tp, name); f = NULL; if (descr != NULL) { Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.16.8.53 retrieving revision 2.16.8.54 diff -C2 -r2.16.8.53 -r2.16.8.54 *** typeobject.c 2001/06/29 20:03:14 2.16.8.53 --- typeobject.c 2001/06/29 20:46:51 2.16.8.54 *************** *** 587,592 **** { int i, n; ! PyObject *mro = type->tp_mro, *res; assert(PyTuple_Check(mro)); n = PyTuple_GET_SIZE(mro); --- 587,601 ---- { int i, n; ! PyObject *mro, *res, *dict; + /* For static types, look in tp_dict */ + if (!(type->tp_flags & Py_TPFLAGS_DYNAMICTYPE)) { + dict = type->tp_dict; + assert(dict && PyDict_Check(dict)); + return PyDict_GetItem(dict, name); + } + + /* For dynamic types, look in tp_defined of types in MRO */ + mro = type->tp_mro; assert(PyTuple_Check(mro)); n = PyTuple_GET_SIZE(mro); *************** *** 594,599 **** type = (PyTypeObject *) PyTuple_GET_ITEM(mro, i); assert(PyType_Check(type)); ! assert(type->tp_dict && PyDict_Check(type->tp_dict)); ! res = PyDict_GetItem(type->tp_dict, name); if (res != NULL) return res; --- 603,609 ---- type = (PyTypeObject *) PyTuple_GET_ITEM(mro, i); assert(PyType_Check(type)); ! dict = type->tp_defined; ! assert(dict && PyDict_Check(dict)); ! res = PyDict_GetItem(dict, name); if (res != NULL) return res; *************** *** 602,630 **** } static PyObject * type_getattro(PyTypeObject *type, PyObject *name) { PyObject *descr, *res; descrgetfunc f; if (type->tp_dict == NULL) { if (PyType_InitDict(type) < 0) return NULL; } ! descr = PyObject_GenericGetAttr((PyObject *)type, name); ! if (descr == NULL) { ! descr = _PyType_Lookup(type, name); ! if (descr == NULL) ! return NULL; ! PyErr_Clear(); ! Py_INCREF(descr); } ! f = descr->ob_type->tp_descr_get; if (f != NULL) { res = f(descr, NULL); - Py_DECREF(descr); return res; } ! return descr; } --- 612,661 ---- } + /* This is similar to PyObject_GenericGetAttr(), + but uses _PyType_Lookup() instead of just looking in type->tp_dict. */ static PyObject * type_getattro(PyTypeObject *type, PyObject *name) { + PyTypeObject *metatype = type->ob_type; PyObject *descr, *res; descrgetfunc f; + /* Initialize this type (we'll assume the metatype is initialized) */ if (type->tp_dict == NULL) { if (PyType_InitDict(type) < 0) return NULL; } ! ! /* Get a descriptor from the metatype */ ! descr = _PyType_Lookup(metatype, name); ! f = NULL; ! if (descr != NULL) { ! f = descr->ob_type->tp_descr_get; ! if (f != NULL && PyDescr_IsData(descr)) ! return f(descr, (PyObject *)type); } ! ! /* Look in tp_defined of this type and its bases */ ! res = _PyType_Lookup(type, name); ! if (res != NULL) { ! Py_INCREF(res); ! return res; ! } ! ! /* Use the descriptor from the metatype */ if (f != NULL) { res = f(descr, NULL); return res; + } + if (descr != NULL) { + Py_INCREF(descr); + return descr; } ! ! /* Give up */ ! PyErr_Format(PyExc_AttributeError, ! "type object '%.50s' has no attribute '%.400s'", ! type->tp_name, PyString_AS_STRING(name)); ! return NULL; } From gvanrossum@users.sourceforge.net Fri Jun 29 21:57:14 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 29 Jun 2001 13:57:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules spam.c,1.1.2.7,1.1.2.8 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv18131 Modified Files: Tag: descr-branch spam.c Log Message: Add a little benchmark function, spam.bench(obj, "name", n) which returns the clock time (in seconds, as a float) it takes to compute obj.name n times. Index: spam.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/Attic/spam.c,v retrieving revision 1.1.2.7 retrieving revision 1.1.2.8 diff -C2 -r1.1.2.7 -r1.1.2.8 *** spam.c 2001/06/29 16:32:35 1.1.2.7 --- spam.c 2001/06/29 20:57:12 1.1.2.8 *************** *** 177,182 **** }; static PyMethodDef spam_functions[] = { ! {0} }; --- 177,202 ---- }; + 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 spam_functions[] = { ! {"bench", spam_bench, 1} }; From gvanrossum@users.sourceforge.net Fri Jun 29 22:06:18 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 29 Jun 2001 14:06:18 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.1.2.1,1.1.2.2 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv21049 Modified Files: Tag: descr-branch PLAN.txt Log Message: Slight status update: no more need to store special ivars in a separate directory. _PyType_Lookup() is fast enough. Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Attic/PLAN.txt,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -r1.1.2.1 -r1.1.2.2 *** PLAN.txt 2001/06/29 18:02:35 1.1.2.1 --- PLAN.txt 2001/06/29 21:06:16 1.1.2.2 *************** *** 58,70 **** __dict__ (or __introduced__?) of all bases in __mro__ order. (This is needed anyway to unify classes completely.) *** Partly done. ! Inheritance of slots from bases is still icky. Also, I still need to ! think more about making sure that "special" ivars (those with ! descriptors classifying them as data) can't be overridden by things in ! the __dict__. *** Universal base class (object). How can we make the object class subclassable and define simple default methods for everything without having these inherited by built-in types that don't want these ! defaults? (This may be mostly fixed now.) *** Done, really. *** Add error checking to the MRO calculation. --- 58,67 ---- __dict__ (or __introduced__?) of all bases in __mro__ order. (This is needed anyway to unify classes completely.) *** Partly done. ! Inheritance of slots from bases is still icky. *** Universal base class (object). How can we make the object class subclassable and define simple default methods for everything without having these inherited by built-in types that don't want these ! defaults? *** Done, really. *** Add error checking to the MRO calculation. From tim_one@users.sourceforge.net Sat Jun 30 00:51:10 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 29 Jun 2001 16:51:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libtokenize.tex,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv5587/python/dist/src/Doc/lib Modified Files: libtokenize.tex Log Message: Turns out Neil didn't intend for *all* of his gen-branch work to get committed. tokenize.py: I like these changes, and have tested them extensively without even realizing it, so I just updated the docstring and the docs. tabnanny.py: Also liked this, but did a little code fiddling. I should really rewrite this to *exploit* generators, but that's near the bottom of my effort/benefit scale so doubt I'll get to it anytime soon (it would be most useful as a non-trivial example of ideal use of generators; but test_generators.py has already grown plenty of food-for-thought examples). inspect.py: I'm sure Ping intended for this to continue running even under 1.5.2, so I reverted this to the last pre-gen-branch version. The "bugfix" I checked in in-between was actually repairing a bug *introduced* by the conversion to generators, so it's OK that the reverted version doesn't reflect that checkin. Index: libtokenize.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libtokenize.tex,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** libtokenize.tex 2001/03/23 05:22:12 1.4 --- libtokenize.tex 2001/06/29 23:51:07 1.5 *************** *** 13,22 **** ``pretty-printers,'' including colorizers for on-screen displays. ! The scanner is exposed by a single function: \begin{funcdesc}{tokenize}{readline\optional{, tokeneater}} The \function{tokenize()} function accepts two parameters: one ! representing the input stream, and one providing an output mechanism for \function{tokenize()}. --- 13,43 ---- ``pretty-printers,'' including colorizers for on-screen displays. ! The primary entry point is a generator: + \begin{funcdesc}{generate_tokens}{readline} + The \function{generate_tokens()} generator requires one argment, + \var{readline}, which must be a callable object which + provides the same interface as the \method{readline()} method of + built-in file objects (see section~\ref{bltin-file-objects}). Each + call to the function should return one line of input as a string. + + The generator produces 5-tuples with these members: + the token type; + the token string; + a 2-tuple \code{(\var{srow}, \var{scol})} of ints specifying the + row and column where the token begins in the source; + a 2-tuple \code{(\var{erow}, \var{ecol})} of ints specifying the + row and column where the token ends in the source; + and the line on which the token was found. + The line passed is the \emph{logical} line; + continuation lines are included. + \versionadded{2.2} + \end{funcdesc} + + An older entry point is retained for backward compatibility: \begin{funcdesc}{tokenize}{readline\optional{, tokeneater}} The \function{tokenize()} function accepts two parameters: one ! representing the input stream, and one providing an output mechanism for \function{tokenize()}. *************** *** 27,41 **** The second parameter, \var{tokeneater}, must also be a callable ! object. It is called with five parameters: the token type, the ! token string, a tuple \code{(\var{srow}, \var{scol})} specifying the ! row and column where the token begins in the source, a tuple ! \code{(\var{erow}, \var{ecol})} giving the ending position of the ! token, and the line on which the token was found. The line passed ! is the \emph{logical} line; continuation lines are included. \end{funcdesc} ! All constants from the \refmodule{token} module are also exported from ! \module{tokenize}, as are two additional token type values that might be passed to the \var{tokeneater} function by \function{tokenize()}: --- 48,58 ---- The second parameter, \var{tokeneater}, must also be a callable ! object. It is called once for each token, with five arguments, ! corresponding to the tuples generated by \function{generate_tokens()}. \end{funcdesc} ! All constants from the \refmodule{token} module are also exported from ! \module{tokenize}, as are two additional token type values that might be passed to the \var{tokeneater} function by \function{tokenize()}: From tim_one@users.sourceforge.net Sat Jun 30 00:51:10 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 29 Jun 2001 16:51:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib inspect.py,1.17,1.18 tabnanny.py,1.14,1.15 tokenize.py,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv5587/python/dist/src/Lib Modified Files: inspect.py tabnanny.py tokenize.py Log Message: Turns out Neil didn't intend for *all* of his gen-branch work to get committed. tokenize.py: I like these changes, and have tested them extensively without even realizing it, so I just updated the docstring and the docs. tabnanny.py: Also liked this, but did a little code fiddling. I should really rewrite this to *exploit* generators, but that's near the bottom of my effort/benefit scale so doubt I'll get to it anytime soon (it would be most useful as a non-trivial example of ideal use of generators; but test_generators.py has already grown plenty of food-for-thought examples). inspect.py: I'm sure Ping intended for this to continue running even under 1.5.2, so I reverted this to the last pre-gen-branch version. The "bugfix" I checked in in-between was actually repairing a bug *introduced* by the conversion to generators, so it's OK that the reverted version doesn't reflect that checkin. Index: inspect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/inspect.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -r1.17 -r1.18 *** inspect.py 2001/06/18 22:08:13 1.17 --- inspect.py 2001/06/29 23:51:08 1.18 *************** *** 350,375 **** else: return '' ! def getblock(lines): ! """Extract the block of code at the top of the given list of lines.""" ! indent = 0 ! started = 0 ! last = 0 ! tokens = tokenize.generate_tokens(ListReader(lines).readline) ! for (type, token, (srow, scol), (erow, ecol), line) in tokens: ! if not started: ! if type == tokenize.NAME: ! started = 1 elif type == tokenize.NEWLINE: ! last = srow elif type == tokenize.INDENT: ! indent = indent + 1 elif type == tokenize.DEDENT: ! indent = indent - 1 ! if indent == 0: ! return lines[:last] ! else: ! raise ValueError, "unable to find block" def getsourcelines(object): --- 350,379 ---- else: return '' ! class EndOfBlock(Exception): pass ! class BlockFinder: ! """Provide a tokeneater() method to detect the end of a code block.""" ! def __init__(self): ! self.indent = 0 ! self.started = 0 ! self.last = 0 ! def tokeneater(self, type, token, (srow, scol), (erow, ecol), line): ! if not self.started: ! if type == tokenize.NAME: self.started = 1 elif type == tokenize.NEWLINE: ! self.last = srow elif type == tokenize.INDENT: ! self.indent = self.indent + 1 elif type == tokenize.DEDENT: ! self.indent = self.indent - 1 ! if self.indent == 0: raise EndOfBlock, self.last ! ! def getblock(lines): ! """Extract the block of code at the top of the given list of lines.""" ! try: ! tokenize.tokenize(ListReader(lines).readline, BlockFinder().tokeneater) ! except EndOfBlock, eob: ! return lines[:eob.args[0]] def getsourcelines(object): Index: tabnanny.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/tabnanny.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -r1.14 -r1.15 *** tabnanny.py 2001/06/18 22:08:13 1.14 --- tabnanny.py 2001/06/29 23:51:08 1.15 *************** *** 15,18 **** --- 15,20 ---- import getopt import tokenize + if not hasattr(tokenize, 'NL'): + raise ValueError("tokenize.NL doesn't exist -- tokenize module too old") __all__ = ["check"] *************** *** 244,256 **** return prefix + " " + string.join(firsts, ', ') ! # Need Guido's enhancement ! assert hasattr(tokenize, 'NL'), "tokenize module too old" ! ! def process_tokens(tokens, ! INDENT=tokenize.INDENT, ! DEDENT=tokenize.DEDENT, ! NEWLINE=tokenize.NEWLINE, ! JUNK=(tokenize.COMMENT, tokenize.NL)): ! indents = [Whitespace("")] check_equal = 0 --- 246,254 ---- return prefix + " " + string.join(firsts, ', ') ! def process_tokens(tokens): ! INDENT = tokenize.INDENT ! DEDENT = tokenize.DEDENT ! NEWLINE = tokenize.NEWLINE ! JUNK = tokenize.COMMENT, tokenize.NL indents = [Whitespace("")] check_equal = 0 Index: tokenize.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/tokenize.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -r1.23 -r1.24 *** tokenize.py 2001/06/18 22:08:13 1.23 --- tokenize.py 2001/06/29 23:51:08 1.24 *************** *** 1,13 **** """Tokenization help for Python programs. ! This module exports a function called 'tokenize()' that breaks a stream of text into Python tokens. It accepts a readline-like method which is called ! repeatedly to get the next line of input (or "" for EOF) and a "token-eater" ! function which is called once for each token found. The latter function is ! passed the token type, a string containing the token, the starting and ! ending (row, column) coordinates of the token, and the original line. It is ! designed to match the working of the Python tokenizer exactly, except that ! it produces COMMENT tokens for comments and gives type OP for all operators.""" __author__ = 'Ka-Ping Yee ' __credits__ = \ --- 1,26 ---- """Tokenization help for Python programs. ! generate_tokens(readline) is a generator that breaks a stream of text into Python tokens. It accepts a readline-like method which is called ! repeatedly to get the next line of input (or "" for EOF). It generates ! 5-tuples with these members: + the token type (see token.py) + the token (a string) + the starting (row, column) indices of the token (a 2-tuple of ints) + the ending (row, column) indices of the token (a 2-tuple of ints) + the original line (string) + + It is designed to match the working of the Python tokenizer exactly, except + that it produces COMMENT tokens for comments and gives type OP for all + operators + + Older entry points + tokenize_loop(readline, tokeneater) + tokenize(readline, tokeneater=printtoken) + are the same, except instead of generating tokens, tokeneater is a callback + function to which the 5 fields described above are passed as 5 arguments, + each time a new token is found.""" + __author__ = 'Ka-Ping Yee ' __credits__ = \ *************** *** 112,116 **** pass ! # backwards compatible interface, probably not used def tokenize_loop(readline, tokeneater): for token_info in generate_tokens(readline): --- 125,129 ---- pass ! # backwards compatible interface def tokenize_loop(readline, tokeneater): for token_info in generate_tokens(readline): From tim_one@users.sourceforge.net Sat Jun 30 08:29:46 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 30 Jun 2001 00:29:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_generators.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv20431/python/dist/src/Lib/test Modified Files: test_generators.py Log Message: Derive an industrial-strength conjoin() via cross-recursion loop unrolling, and fiddle the conjoin tests to exercise all the new possible paths. Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -r1.14 -r1.15 *** test_generators.py 2001/06/29 02:41:16 1.14 --- test_generators.py 2001/06/30 07:29:44 1.15 *************** *** 777,780 **** --- 777,836 ---- yield x + # That works fine, but recursing a level and checking i against len(gs) for + # each item produced is inefficient. By doing manual loop unrolling across + # generator boundaries, it's possible to eliminate most of that overhead. + # This isn't worth the bother *in general* for generators, but conjoin() is + # a core building block for some CPU-intensive generator applications. + + def conjoin(gs): + + n = len(gs) + values = [None] * n + + # Do one loop nest at time recursively, until the # of loop nests + # remaining is divisible by 3. + + def gen(i, values=values): + if i >= n: + yield values + + elif (n-i) % 3: + ip1 = i+1 + for values[i] in gs[i](): + for x in gen(ip1): + yield x + + else: + for x in _gen3(i): + yield x + + # Do three loop nests at a time, recursing only if at least three more + # remain. Don't call directly: this is an internal optimization for + # gen's use. + + def _gen3(i, values=values): + assert i < n and (n-i) % 3 == 0 + ip1, ip2, ip3 = i+1, i+2, i+3 + g, g1, g2 = gs[i : ip3] + + if ip3 >= n: + # These are the last three, so we can yield values directly. + for values[i] in g(): + for values[ip1] in g1(): + for values[ip2] in g2(): + yield values + + else: + # At least 6 loop nests remain; peel off 3 and recurse for the + # rest. + for values[i] in g(): + for values[ip1] in g1(): + for values[ip2] in g2(): + for x in _gen3(ip3): + yield x + + for x in gen(0): + yield x + # A conjoin-based N-Queens solver. *************** *** 805,813 **** for j in rangen: uses = rowuses[j] ! if uses & self.used: ! continue ! self.used |= uses ! yield j ! self.used &= ~uses self.rowgenerators.append(rowgen) --- 861,868 ---- for j in rangen: uses = rowuses[j] ! if uses & self.used == 0: ! self.used |= uses ! yield j ! self.used &= ~uses self.rowgenerators.append(rowgen) *************** *** 835,842 **** possible use of conjoin, just to generate the full cross-product. ! >>> def g(): ! ... return [0, 1] ! ! >>> for c in conjoin([g] * 3): ... print c [0, 0, 0] --- 890,894 ---- possible use of conjoin, just to generate the full cross-product. ! >>> for c in conjoin([lambda: (0, 1)] * 3): ... print c [0, 0, 0] *************** *** 848,851 **** --- 900,925 ---- [1, 1, 0] [1, 1, 1] + + For efficiency in typical backtracking apps, conjoin() yields the same list + object each time. So if you want to save away a full account of its + generated sequence, you need to copy its results. + + >>> def gencopy(iterator): + ... for x in iterator: + ... yield x[:] + + >>> for n in range(10): + ... all = list(gencopy(conjoin([lambda: (0, 1)] * n))) + ... print n, len(all), all[0] == [0] * n, all[-1] == [1] * n + 0 1 1 1 + 1 2 1 1 + 2 4 1 1 + 3 8 1 1 + 4 16 1 1 + 5 32 1 1 + 6 64 1 1 + 7 128 1 1 + 8 256 1 1 + 9 512 1 1 And run an 8-queens solver. From gvanrossum@users.sourceforge.net Sat Jun 30 13:25:26 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 30 Jun 2001 05:25:26 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.1.2.2,1.1.2.3 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv6612 Modified Files: Tag: descr-branch PLAN.txt Log Message: Exaplin what's wrong with slot inheritance. Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Attic/PLAN.txt,v retrieving revision 1.1.2.2 retrieving revision 1.1.2.3 diff -C2 -r1.1.2.2 -r1.1.2.3 *** PLAN.txt 2001/06/29 21:06:16 1.1.2.2 --- PLAN.txt 2001/06/30 12:25:24 1.1.2.3 *************** *** 58,62 **** __dict__ (or __introduced__?) of all bases in __mro__ order. (This is needed anyway to unify classes completely.) *** Partly done. ! Inheritance of slots from bases is still icky. *** Universal base class (object). How can we make the object class --- 58,65 ---- __dict__ (or __introduced__?) of all bases in __mro__ order. (This is needed anyway to unify classes completely.) *** Partly done. ! Inheritance of slots from bases is still icky: (1) MRO is not always ! respected when inheriting slots; (2) dynamic classes can't add slot ! implementations in Python after creation (e.g., setting C.__hash__ ! doesn't set the tp_hash slot). *** Universal base class (object). How can we make the object class