[Python-checkins] r46212 - in python/branches/blais-bytebuf: Doc/ACKS Doc/texinputs/python.sty Doc/whatsnew/whatsnew25.tex Grammar/Grammar Lib/hotbuf.py Lib/struct.py Lib/test/string_tests.py Lib/test/test_builtin.py Lib/test/test_hotbuf.py Lib/test/test_importhooks.py Misc/NEWS Misc/developers.txt Modules/_hotbuf.c Objects/longobject.c Python/errors.c Python/graminit.c

martin.blais python-checkins at python.org
Thu May 25 16:25:42 CEST 2006


Author: martin.blais
Date: Thu May 25 16:25:38 2006
New Revision: 46212

Modified:
   python/branches/blais-bytebuf/Doc/ACKS
   python/branches/blais-bytebuf/Doc/texinputs/python.sty
   python/branches/blais-bytebuf/Doc/whatsnew/whatsnew25.tex
   python/branches/blais-bytebuf/Grammar/Grammar
   python/branches/blais-bytebuf/Lib/hotbuf.py
   python/branches/blais-bytebuf/Lib/struct.py
   python/branches/blais-bytebuf/Lib/test/string_tests.py
   python/branches/blais-bytebuf/Lib/test/test_builtin.py
   python/branches/blais-bytebuf/Lib/test/test_hotbuf.py
   python/branches/blais-bytebuf/Lib/test/test_importhooks.py
   python/branches/blais-bytebuf/Misc/NEWS
   python/branches/blais-bytebuf/Misc/developers.txt
   python/branches/blais-bytebuf/Modules/_hotbuf.c
   python/branches/blais-bytebuf/Objects/longobject.c
   python/branches/blais-bytebuf/Python/errors.c
   python/branches/blais-bytebuf/Python/graminit.c
Log:
Update bytebuf branch to 46211

Modified: python/branches/blais-bytebuf/Doc/ACKS
==============================================================================
--- python/branches/blais-bytebuf/Doc/ACKS	(original)
+++ python/branches/blais-bytebuf/Doc/ACKS	Thu May 25 16:25:38 2006
@@ -195,6 +195,7 @@
 Steven Work
 Thomas Wouters
 Ka-Ping Yee
+Rory Yorke
 Moshe Zadka
 Milan Zamazal
 Cheng Zhang

Modified: python/branches/blais-bytebuf/Doc/texinputs/python.sty
==============================================================================
--- python/branches/blais-bytebuf/Doc/texinputs/python.sty	(original)
+++ python/branches/blais-bytebuf/Doc/texinputs/python.sty	Thu May 25 16:25:38 2006
@@ -848,8 +848,17 @@
 % but only if we actually used hyperref:
 \ifpdf
   \newcommand{\url}[1]{{%
-    \py at pdfstartlink attr{/Border [0 0 0]} user{/S /URI /URI (#1)}%
-    \py at LinkColor%                              color of the link text
+    \py at pdfstartlink%
+    attr{ /Border [0 0 0] }%
+    user{%
+      /Subtype/Link%
+      /A<<%
+      /Type/Action%
+      /S/URI%
+      /URI(#1)%
+      >>%
+    }%
+    \py at LinkColor%                      color of the link text
     \py at smallsize\sf #1%
     \py at NormalColor%                    Turn it back off; these are declarative
     \pdfendlink}%                       and don't appear bound to the current
@@ -925,7 +934,16 @@
 \ifpdf
   \newcommand{\ulink}[2]{{%
     % For PDF, we *should* only generate a link when the URL is absolute.
-    \py at pdfstartlink attr{/Border [0 0 0]} user{/S /URI /URI (#2)}%
+    \py at pdfstartlink%
+    attr{ /Border [0 0 0] }%
+    user{%
+      /Subtype/Link%
+      /A<<%
+      /Type/Action%
+      /S/URI%
+      /URI(#2)%
+      >>%
+    }%
     \py at LinkColor%                              color of the link text
     #1%
     \py at NormalColor%                    Turn it back off; these are declarative

Modified: python/branches/blais-bytebuf/Doc/whatsnew/whatsnew25.tex
==============================================================================
--- python/branches/blais-bytebuf/Doc/whatsnew/whatsnew25.tex	(original)
+++ python/branches/blais-bytebuf/Doc/whatsnew/whatsnew25.tex	Thu May 25 16:25:38 2006
@@ -512,9 +512,9 @@
   \exception{GeneratorExit} or \exception{StopIteration}; catching the 
   exception and doing anything else is illegal and will trigger
   a \exception{RuntimeError}.  \method{close()} will also be called by 
-  Python's garbage collection when the generator is garbage-collected.
+  Python's garbage collector when the generator is garbage-collected.
 
-  If you need to run cleanup code in case of a \exception{GeneratorExit},
+  If you need to run cleanup code when a \exception{GeneratorExit} occurs,
   I suggest using a \code{try: ... finally:} suite instead of 
   catching \exception{GeneratorExit}.
 
@@ -1143,6 +1143,13 @@
 sprint. Character map decoding was improved by Walter D\"orwald.)
 % Patch 1313939
 
+\item The \function{long(\var{str}, \var{base})} function is now
+faster on long digit strings because fewer intermediate results are
+calculated.  The peak is for strings of around 800--1000 digits where 
+the function is 6 times faster.
+(Contributed by Alan McIntyre and committed at the NeedForSpeed sprint.)
+% Patch 1442927
+
 \item The \module{struct} module now compiles structure format 
 strings into an internal representation and caches this
 representation, yielding a 20\% speedup.  (Contributed by Bob Ippolito

Modified: python/branches/blais-bytebuf/Grammar/Grammar
==============================================================================
--- python/branches/blais-bytebuf/Grammar/Grammar	(original)
+++ python/branches/blais-bytebuf/Grammar/Grammar	Thu May 25 16:25:38 2006
@@ -62,7 +62,7 @@
 raise_stmt: 'raise' [test [',' test [',' test]]]
 import_stmt: import_name | import_from
 import_name: 'import' dotted_as_names
-import_from: ('from' ('.'* dotted_name | '.')
+import_from: ('from' ('.'* dotted_name | '.'+)
               'import' ('*' | '(' import_as_names ')' | import_as_names))
 import_as_name: NAME [('as' | NAME) NAME]
 dotted_as_name: dotted_name [('as' | NAME) NAME]

Modified: python/branches/blais-bytebuf/Lib/hotbuf.py
==============================================================================
--- python/branches/blais-bytebuf/Lib/hotbuf.py	(original)
+++ python/branches/blais-bytebuf/Lib/hotbuf.py	Thu May 25 16:25:38 2006
@@ -5,8 +5,20 @@
 """
 
 from _hotbuf import _hotbuf
+from struct import Struct
+
+_long = Struct('l')
 
 class hotbuf(_hotbuf):
-    pass
+
+    def getlong( self ):
+        r = _long.unpack_from(self, 0)
+        self.setposition(self.position + _long.size)
+        return r
+
+##     def putlong( self ):
+##         s = _long.pack(0)
+##         self.setposition(self.position + _long.size)
+##         return 
 
 

Modified: python/branches/blais-bytebuf/Lib/struct.py
==============================================================================
--- python/branches/blais-bytebuf/Lib/struct.py	(original)
+++ python/branches/blais-bytebuf/Lib/struct.py	Thu May 25 16:25:38 2006
@@ -73,7 +73,7 @@
     except KeyError:
         o = _compile(fmt)
     return o.unpack(s)
-    
+
 def unpack_from(fmt, buf, offset=0):
     """
     Unpack the buffer, containing packed C structure data, according to
@@ -84,4 +84,4 @@
         o = _cache[fmt]
     except KeyError:
         o = _compile(fmt)
-    return o.unpack_from(buf, offset)
\ No newline at end of file
+    return o.unpack_from(buf, offset)

Modified: python/branches/blais-bytebuf/Lib/test/string_tests.py
==============================================================================
--- python/branches/blais-bytebuf/Lib/test/string_tests.py	(original)
+++ python/branches/blais-bytebuf/Lib/test/string_tests.py	Thu May 25 16:25:38 2006
@@ -376,6 +376,158 @@
         self.checkraises(TypeError, 'hello', 'swapcase', 42)
 
     def test_replace(self):
+        EQ = self.checkequal
+
+        # Operations on the empty string
+        EQ("", "", "replace", "", "")
+
+        #EQ("A", "", "replace", "", "A")
+        # That was the correct result; this is the result we actually get
+        # now (for str, but not for unicode):
+        #EQ("", "", "replace", "", "A")
+
+        EQ("", "", "replace", "A", "")
+        EQ("", "", "replace", "A", "A")
+        EQ("", "", "replace", "", "", 100)
+        EQ("", "", "replace", "", "", sys.maxint)
+
+        # interleave (from=="", 'to' gets inserted everywhere)
+        EQ("A", "A", "replace", "", "")
+        EQ("*A*", "A", "replace", "", "*")
+        EQ("*1A*1", "A", "replace", "", "*1")
+        EQ("*-#A*-#", "A", "replace", "", "*-#")
+        EQ("*-A*-A*-", "AA", "replace", "", "*-")
+        EQ("*-A*-A*-", "AA", "replace", "", "*-", -1)
+        EQ("*-A*-A*-", "AA", "replace", "", "*-", sys.maxint)
+        EQ("*-A*-A*-", "AA", "replace", "", "*-", 4)
+        EQ("*-A*-A*-", "AA", "replace", "", "*-", 3)
+        EQ("*-A*-A", "AA", "replace", "", "*-", 2)
+        EQ("*-AA", "AA", "replace", "", "*-", 1)
+        EQ("AA", "AA", "replace", "", "*-", 0)
+
+        # single character deletion (from=="A", to=="")
+        EQ("", "A", "replace", "A", "")
+        EQ("", "AAA", "replace", "A", "")
+        EQ("", "AAA", "replace", "A", "", -1)
+        EQ("", "AAA", "replace", "A", "", sys.maxint)
+        EQ("", "AAA", "replace", "A", "", 4)
+        EQ("", "AAA", "replace", "A", "", 3)
+        EQ("A", "AAA", "replace", "A", "", 2)
+        EQ("AA", "AAA", "replace", "A", "", 1)
+        EQ("AAA", "AAA", "replace", "A", "", 0)
+        EQ("", "AAAAAAAAAA", "replace", "A", "")
+        EQ("BCD", "ABACADA", "replace", "A", "")
+        EQ("BCD", "ABACADA", "replace", "A", "", -1)
+        EQ("BCD", "ABACADA", "replace", "A", "", sys.maxint)
+        EQ("BCD", "ABACADA", "replace", "A", "", 5)
+        EQ("BCD", "ABACADA", "replace", "A", "", 4)
+        EQ("BCDA", "ABACADA", "replace", "A", "", 3)
+        EQ("BCADA", "ABACADA", "replace", "A", "", 2)
+        EQ("BACADA", "ABACADA", "replace", "A", "", 1)
+        EQ("ABACADA", "ABACADA", "replace", "A", "", 0)
+        EQ("BCD", "ABCAD", "replace", "A", "")
+        EQ("BCD", "ABCADAA", "replace", "A", "")
+        EQ("BCD", "BCD", "replace", "A", "")
+        EQ("*************", "*************", "replace", "A", "")
+        EQ("^A^", "^"+"A"*1000+"^", "replace", "A", "", 999)
+
+        # substring deletion (from=="the", to=="")
+        EQ("", "the", "replace", "the", "")
+        EQ("ater", "theater", "replace", "the", "")
+        EQ("", "thethe", "replace", "the", "")
+        EQ("", "thethethethe", "replace", "the", "")
+        EQ("aaaa", "theatheatheathea", "replace", "the", "")
+        EQ("that", "that", "replace", "the", "")
+        EQ("thaet", "thaet", "replace", "the", "")
+        EQ("here and re", "here and there", "replace", "the", "")
+        EQ("here and re and re", "here and there and there",
+           "replace", "the", "", sys.maxint)
+        EQ("here and re and re", "here and there and there",
+           "replace", "the", "", -1)
+        EQ("here and re and re", "here and there and there",
+           "replace", "the", "", 3)
+        EQ("here and re and re", "here and there and there",
+           "replace", "the", "", 2)
+        EQ("here and re and there", "here and there and there",
+           "replace", "the", "", 1)
+        EQ("here and there and there", "here and there and there",
+           "replace", "the", "", 0)
+        EQ("here and re and re", "here and there and there", "replace", "the", "")
+
+        EQ("abc", "abc", "replace", "the", "")
+        EQ("abcdefg", "abcdefg", "replace", "the", "")
+
+        # substring deletion (from=="bob", to=="")
+        EQ("bob", "bbobob", "replace", "bob", "")
+        EQ("bobXbob", "bbobobXbbobob", "replace", "bob", "")
+        EQ("aaaaaaa", "aaaaaaabob", "replace", "bob", "")
+        EQ("aaaaaaa", "aaaaaaa", "replace", "bob", "")
+
+        # single character replace in place (len(from)==len(to)==1)
+        EQ("Who goes there?", "Who goes there?", "replace", "o", "o")
+        EQ("WhO gOes there?", "Who goes there?", "replace", "o", "O")
+        EQ("WhO gOes there?", "Who goes there?", "replace", "o", "O", sys.maxint)
+        EQ("WhO gOes there?", "Who goes there?", "replace", "o", "O", -1)
+        EQ("WhO gOes there?", "Who goes there?", "replace", "o", "O", 3)
+        EQ("WhO gOes there?", "Who goes there?", "replace", "o", "O", 2)
+        EQ("WhO goes there?", "Who goes there?", "replace", "o", "O", 1)
+        EQ("Who goes there?", "Who goes there?", "replace", "o", "O", 0)
+
+        EQ("Who goes there?", "Who goes there?", "replace", "a", "q")
+        EQ("who goes there?", "Who goes there?", "replace", "W", "w")
+        EQ("wwho goes there?ww", "WWho goes there?WW", "replace", "W", "w")
+        EQ("Who goes there!", "Who goes there?", "replace", "?", "!")
+        EQ("Who goes there!!", "Who goes there??", "replace", "?", "!")
+
+        EQ("Who goes there?", "Who goes there?", "replace", ".", "!")
+
+        # substring replace in place (len(from)==len(to) > 1)
+        EQ("Th** ** a t**sue", "This is a tissue", "replace", "is", "**")
+        EQ("Th** ** a t**sue", "This is a tissue", "replace", "is", "**", sys.maxint)
+        EQ("Th** ** a t**sue", "This is a tissue", "replace", "is", "**", -1)
+        EQ("Th** ** a t**sue", "This is a tissue", "replace", "is", "**", 4)
+        EQ("Th** ** a t**sue", "This is a tissue", "replace", "is", "**", 3)
+        EQ("Th** ** a tissue", "This is a tissue", "replace", "is", "**", 2)
+        EQ("Th** is a tissue", "This is a tissue", "replace", "is", "**", 1)
+        EQ("This is a tissue", "This is a tissue", "replace", "is", "**", 0)
+        EQ("cobob", "bobob", "replace", "bob", "cob")
+        EQ("cobobXcobocob", "bobobXbobobob", "replace", "bob", "cob")
+        EQ("bobob", "bobob", "replace", "bot", "bot")
+
+        # replace single character (len(from)==1, len(to)>1)
+        EQ("ReyKKjaviKK", "Reykjavik", "replace", "k", "KK")
+        EQ("ReyKKjaviKK", "Reykjavik", "replace", "k", "KK", -1)
+        EQ("ReyKKjaviKK", "Reykjavik", "replace", "k", "KK", sys.maxint)
+        EQ("ReyKKjaviKK", "Reykjavik", "replace", "k", "KK", 2)
+        EQ("ReyKKjavik", "Reykjavik", "replace", "k", "KK", 1)
+        EQ("Reykjavik", "Reykjavik", "replace", "k", "KK", 0)
+        EQ("A----B----C----", "A.B.C.", "replace", ".", "----")
+
+        EQ("Reykjavik", "Reykjavik", "replace", "q", "KK")
+
+        # replace substring (len(from)>1, len(to)!=len(from))
+        EQ("ham, ham, eggs and ham", "spam, spam, eggs and spam",
+           "replace", "spam", "ham")
+        EQ("ham, ham, eggs and ham", "spam, spam, eggs and spam",
+           "replace", "spam", "ham", sys.maxint)
+        EQ("ham, ham, eggs and ham", "spam, spam, eggs and spam",
+           "replace", "spam", "ham", -1)
+        EQ("ham, ham, eggs and ham", "spam, spam, eggs and spam",
+           "replace", "spam", "ham", 4)
+        EQ("ham, ham, eggs and ham", "spam, spam, eggs and spam",
+           "replace", "spam", "ham", 3)
+        EQ("ham, ham, eggs and spam", "spam, spam, eggs and spam",
+           "replace", "spam", "ham", 2)
+        EQ("ham, spam, eggs and spam", "spam, spam, eggs and spam",
+           "replace", "spam", "ham", 1)
+        EQ("spam, spam, eggs and spam", "spam, spam, eggs and spam",
+           "replace", "spam", "ham", 0)
+
+        EQ("bobob", "bobobob", "replace", "bobob", "bob")
+        EQ("bobobXbobob", "bobobobXbobobob", "replace", "bobob", "bob")
+        EQ("BOBOBOB", "BOBOBOB", "replace", "bob", "bobby")
+
+        #
         self.checkequal('one at two!three!', 'one!two!three!', 'replace', '!', '@', 1)
         self.checkequal('onetwothree', 'one!two!three!', 'replace', '!', '')
         self.checkequal('one at two@three!', 'one!two!three!', 'replace', '!', '@', 2)
@@ -403,6 +555,16 @@
         self.checkraises(TypeError, 'hello', 'replace', 42, 'h')
         self.checkraises(TypeError, 'hello', 'replace', 'h', 42)
 
+### Commented out until the underlying libraries are fixed
+##    def test_replace_overflow(self):
+##        # Check for overflow checking on 32 bit machines
+##        if sys.maxint != 2147483647:
+##            return
+##        A2_16 = "A" * (2**16)
+##        self.checkraises(OverflowError, A2_16, "replace", "", A2_16)
+##        self.checkraises(OverflowError, A2_16, "replace", "A", A2_16)
+##        self.checkraises(OverflowError, A2_16, "replace", "AA", A2_16+A2_16)
+
     def test_zfill(self):
         self.checkequal('123', '123', 'zfill', 2)
         self.checkequal('123', '123', 'zfill', 3)

Modified: python/branches/blais-bytebuf/Lib/test/test_builtin.py
==============================================================================
--- python/branches/blais-bytebuf/Lib/test/test_builtin.py	(original)
+++ python/branches/blais-bytebuf/Lib/test/test_builtin.py	Thu May 25 16:25:38 2006
@@ -980,6 +980,81 @@
         self.assertRaises(ValueError, long, '53', 40)
         self.assertRaises(TypeError, long, 1, 12)
 
+        self.assertEqual(long('100000000000000000000000000000000', 2),
+                         4294967296)
+        self.assertEqual(long('102002022201221111211', 3), 4294967296)
+        self.assertEqual(long('10000000000000000', 4), 4294967296)
+        self.assertEqual(long('32244002423141', 5), 4294967296)
+        self.assertEqual(long('1550104015504', 6), 4294967296)
+        self.assertEqual(long('211301422354', 7), 4294967296)
+        self.assertEqual(long('40000000000', 8), 4294967296)
+        self.assertEqual(long('12068657454', 9), 4294967296)
+        self.assertEqual(long('4294967296', 10), 4294967296)
+        self.assertEqual(long('1904440554', 11), 4294967296)
+        self.assertEqual(long('9ba461594', 12), 4294967296)
+        self.assertEqual(long('535a79889', 13), 4294967296)
+        self.assertEqual(long('2ca5b7464', 14), 4294967296)
+        self.assertEqual(long('1a20dcd81', 15), 4294967296)
+        self.assertEqual(long('100000000', 16), 4294967296)
+        self.assertEqual(long('a7ffda91', 17), 4294967296)
+        self.assertEqual(long('704he7g4', 18), 4294967296)
+        self.assertEqual(long('4f5aff66', 19), 4294967296)
+        self.assertEqual(long('3723ai4g', 20), 4294967296)
+        self.assertEqual(long('281d55i4', 21), 4294967296)
+        self.assertEqual(long('1fj8b184', 22), 4294967296)
+        self.assertEqual(long('1606k7ic', 23), 4294967296)
+        self.assertEqual(long('mb994ag', 24), 4294967296)
+        self.assertEqual(long('hek2mgl', 25), 4294967296)
+        self.assertEqual(long('dnchbnm', 26), 4294967296)
+        self.assertEqual(long('b28jpdm', 27), 4294967296)
+        self.assertEqual(long('8pfgih4', 28), 4294967296)
+        self.assertEqual(long('76beigg', 29), 4294967296)
+        self.assertEqual(long('5qmcpqg', 30), 4294967296)
+        self.assertEqual(long('4q0jto4', 31), 4294967296)
+        self.assertEqual(long('4000000', 32), 4294967296)
+        self.assertEqual(long('3aokq94', 33), 4294967296)
+        self.assertEqual(long('2qhxjli', 34), 4294967296)
+        self.assertEqual(long('2br45qb', 35), 4294967296)
+        self.assertEqual(long('1z141z4', 36), 4294967296)
+
+        self.assertEqual(long('100000000000000000000000000000001', 2),
+                         4294967297)
+        self.assertEqual(long('102002022201221111212', 3), 4294967297)
+        self.assertEqual(long('10000000000000001', 4), 4294967297)
+        self.assertEqual(long('32244002423142', 5), 4294967297)
+        self.assertEqual(long('1550104015505', 6), 4294967297)
+        self.assertEqual(long('211301422355', 7), 4294967297)
+        self.assertEqual(long('40000000001', 8), 4294967297)
+        self.assertEqual(long('12068657455', 9), 4294967297)
+        self.assertEqual(long('4294967297', 10), 4294967297)
+        self.assertEqual(long('1904440555', 11), 4294967297)
+        self.assertEqual(long('9ba461595', 12), 4294967297)
+        self.assertEqual(long('535a7988a', 13), 4294967297)
+        self.assertEqual(long('2ca5b7465', 14), 4294967297)
+        self.assertEqual(long('1a20dcd82', 15), 4294967297)
+        self.assertEqual(long('100000001', 16), 4294967297)
+        self.assertEqual(long('a7ffda92', 17), 4294967297)
+        self.assertEqual(long('704he7g5', 18), 4294967297)
+        self.assertEqual(long('4f5aff67', 19), 4294967297)
+        self.assertEqual(long('3723ai4h', 20), 4294967297)
+        self.assertEqual(long('281d55i5', 21), 4294967297)
+        self.assertEqual(long('1fj8b185', 22), 4294967297)
+        self.assertEqual(long('1606k7id', 23), 4294967297)
+        self.assertEqual(long('mb994ah', 24), 4294967297)
+        self.assertEqual(long('hek2mgm', 25), 4294967297)
+        self.assertEqual(long('dnchbnn', 26), 4294967297)
+        self.assertEqual(long('b28jpdn', 27), 4294967297)
+        self.assertEqual(long('8pfgih5', 28), 4294967297)
+        self.assertEqual(long('76beigh', 29), 4294967297)
+        self.assertEqual(long('5qmcpqh', 30), 4294967297)
+        self.assertEqual(long('4q0jto5', 31), 4294967297)
+        self.assertEqual(long('4000001', 32), 4294967297)
+        self.assertEqual(long('3aokq95', 33), 4294967297)
+        self.assertEqual(long('2qhxjlj', 34), 4294967297)
+        self.assertEqual(long('2br45qc', 35), 4294967297)
+        self.assertEqual(long('1z141z5', 36), 4294967297)
+
+
     def test_longconversion(self):
         # Test __long__()
         class Foo0:

Modified: python/branches/blais-bytebuf/Lib/test/test_hotbuf.py
==============================================================================
--- python/branches/blais-bytebuf/Lib/test/test_hotbuf.py	(original)
+++ python/branches/blais-bytebuf/Lib/test/test_hotbuf.py	Thu May 25 16:25:38 2006
@@ -21,21 +21,21 @@
         self.assertRaises(ValueError, hotbuf, 0)
         b = hotbuf(CAPACITY)
         self.assertEquals(len(b), CAPACITY)
-        self.assertEquals(b.capacity(), CAPACITY)
+        self.assertEquals(b.capacity, CAPACITY)
 
         # Play with the position
-        assert b.position() == 0
+        assert b.position == 0
         b.setposition(10)
-        self.assertEquals(b.position(), 10)
+        self.assertEquals(b.position, 10)
         self.assertRaises(IndexError, b.setposition, CAPACITY + 1)
 
         # Play with the limit
-        assert b.limit() == CAPACITY
+        assert b.limit == CAPACITY
         b.setlimit(CAPACITY - 10)
-        self.assertEquals(b.limit(), CAPACITY - 10)
+        self.assertEquals(b.limit, CAPACITY - 10)
         self.assertRaises(IndexError, b.setlimit, CAPACITY + 1)
-        b.setlimit(b.position() - 1)
-        self.assertEquals(b.position(), b.limit())
+        b.setlimit(b.position - 1)
+        self.assertEquals(b.position, b.limit)
 
         # Play with reset before the mark has been set.
         self.assertRaises(IndexError, b.setlimit, CAPACITY + 1)
@@ -45,11 +45,11 @@
         b.setlimit(100)
         b.setmark()
         b.setposition(15)
-        self.assertEquals(b.mark(), 10)
+        self.assertEquals(b.mark, 10)
 
         # Play with clear
         b.clear()
-        self.assertEquals((b.position(), b.limit(), b.mark()),
+        self.assertEquals((b.position, b.limit, b.mark),
                           (0, CAPACITY, -1))
 
         # Play with flip.
@@ -57,7 +57,7 @@
         b.setlimit(104)
         b.setmark()
         b.flip()
-        self.assertEquals((b.position(), b.limit(), b.mark()),
+        self.assertEquals((b.position, b.limit, b.mark),
                           (0, 42, -1))
 
         # Play with rewind.
@@ -65,7 +65,7 @@
         b.setlimit(104)
         b.setmark()
         b.rewind()
-        self.assertEquals((b.position(), b.limit(), b.mark()),
+        self.assertEquals((b.position, b.limit, b.mark),
                           (0, 104, -1))
 
         # Play with remaining.
@@ -78,9 +78,9 @@
 
         b.setposition(100)
         b.setlimit(200)
-        b.mark()
+        m = b.mark
         b.compact()
-        self.assertEquals((b.position(), b.limit(), b.mark()),
+        self.assertEquals((b.position, b.limit, b.mark),
                           (100, CAPACITY, -1))
 
     def test_byte( self ):
@@ -102,6 +102,26 @@
         # Test underflow.
         self.assertRaises(IndexError, b.putbyte, 42)
 
+    def test_conversion( self ):
+        b = hotbuf(CAPACITY)
+
+        b.setposition(100)
+        b.setlimit(132)
+
+        self.assertEquals(len(b), 32)
+        s = str(b)
+        self.assertEquals(len(s), 32)
+
+        r = repr(b)
+        self.assert_(r.startswith('<hotbuf '))
+        
+    def test_compare( self ):
+        b = hotbuf(CAPACITY)
+
+## FIXME we need a few methods to be able to write strings into and out of it
+
+
+
 
 def test_main():
     test_support.run_unittest(HotbufTestCase)

Modified: python/branches/blais-bytebuf/Lib/test/test_importhooks.py
==============================================================================
--- python/branches/blais-bytebuf/Lib/test/test_importhooks.py	(original)
+++ python/branches/blais-bytebuf/Lib/test/test_importhooks.py	Thu May 25 16:25:38 2006
@@ -14,6 +14,7 @@
 
 absimp = "import sub\n"
 relimp = "from . import sub\n"
+deeprelimp = "from .... import sub\n"
 futimp = "from __future__ import absolute_import\n"
 
 reload_src = test_src+"""\
@@ -26,6 +27,7 @@
 test2_oldabs_co = compile(absimp + test_src, "<???>", "exec")
 test2_newabs_co = compile(futimp + absimp + test_src, "<???>", "exec")
 test2_newrel_co = compile(relimp + test_src, "<???>", "exec")
+test2_deeprel_co = compile(deeprelimp + test_src, "<???>", "exec")
 test2_futrel_co = compile(futimp + relimp + test_src, "<???>", "exec")
 
 test_path = "!!!_test_!!!"
@@ -46,10 +48,11 @@
         "hooktestmodule": (False, test_co),
         "hooktestpackage": (True, test_co),
         "hooktestpackage.sub": (True, test_co),
-        "hooktestpackage.sub.subber": (False, test_co),
+        "hooktestpackage.sub.subber": (True, test_co),
         "hooktestpackage.oldabs": (False, test2_oldabs_co),
         "hooktestpackage.newabs": (False, test2_newabs_co),
         "hooktestpackage.newrel": (False, test2_newrel_co),
+        "hooktestpackage.sub.subber.subest": (True, test2_deeprel_co),
         "hooktestpackage.futrel": (False, test2_futrel_co),
         "sub": (False, test_co),
         "reloadmodule": (False, test_co),
@@ -203,6 +206,12 @@
         self.assertEqual(hooktestpackage.newrel.sub,
                          hooktestpackage.sub)
 
+        import hooktestpackage.sub.subber.subest as subest
+        self.assertEqual(subest.get_name(),
+                         "hooktestpackage.sub.subber.subest")
+        self.assertEqual(subest.sub,
+                         hooktestpackage.sub)
+
         import hooktestpackage.futrel
         self.assertEqual(hooktestpackage.futrel.get_name(),
                          "hooktestpackage.futrel")

Modified: python/branches/blais-bytebuf/Misc/NEWS
==============================================================================
--- python/branches/blais-bytebuf/Misc/NEWS	(original)
+++ python/branches/blais-bytebuf/Misc/NEWS	Thu May 25 16:25:38 2006
@@ -12,6 +12,12 @@
 Core and builtins
 -----------------
 
+- Patch #1442927: ``long(str, base)`` is now up to 6x faster for non-power-
+  of-2 bases.  The largest speedup is for inputs with about 1000 decimal
+  digits.  Conversion from non-power-of-2 bases remains quadratic-time in
+  the number of input digits (it was and remains linear-time for bases
+  2, 4, 8, 16 and 32).
+
 - Bug #1334662: ``int(string, base)`` could deliver a wrong answer
   when ``base`` was not 2, 4, 8, 10, 16 or 32, and ``string`` represented
   an integer close to ``sys.maxint``.  This was repaired by patch

Modified: python/branches/blais-bytebuf/Misc/developers.txt
==============================================================================
--- python/branches/blais-bytebuf/Misc/developers.txt	(original)
+++ python/branches/blais-bytebuf/Misc/developers.txt	Thu May 25 16:25:38 2006
@@ -17,6 +17,12 @@
 Permissions History
 -------------------
 
+- 2006 Summer of Code entries: Matt Fleming was added on 25 May 2006
+  by AMK; he'll be working on enhancing the Python debugger.  SoC
+  developers are expected to work primarily in nondist/sandbox or on a
+  branch of their own, and will have their work reviewed before
+  changes are accepted into the trunk.
+
 - Steven Bethard was given SVN access on 27 Apr 2006 by DJG, for PEP
   update access.
 
@@ -40,7 +46,7 @@
 
 - Added two new developers for the Summer of Code project. 8 July 2005
   by RDH.  Andrew Kuchling will be mentoring Gregory K Johnson for a
-  project to enchance mailbox.  Brett Cannon requested access for Flovis
+  project to enhance mailbox.  Brett Cannon requested access for Flovis
   Bruynooghe (sirolf) to work on pstats, profile, and hotshot.  Both users
   are expected to work primarily in nondist/sandbox and have their work
   reviewed before making updates to active code.

Modified: python/branches/blais-bytebuf/Modules/_hotbuf.c
==============================================================================
--- python/branches/blais-bytebuf/Modules/_hotbuf.c	(original)
+++ python/branches/blais-bytebuf/Modules/_hotbuf.c	Thu May 25 16:25:38 2006
@@ -4,6 +4,7 @@
  */
 
 #include "Python.h"
+#include "structmember.h"
 #include <string.h> /* for memmove */
 
 PyAPI_DATA(PyTypeObject) PyHotbuf_Type;
@@ -163,18 +164,21 @@
 static int
 hotbuf_compare(PyHotbufObject *self, PyHotbufObject *other)
 {
-    Py_ssize_t min_len;
+    Py_ssize_t len_self, len_other, min_len;
     int cmp;
 
-    min_len = ((self->b_capacity < other->b_capacity) ?
-               self->b_capacity : other->b_capacity);
+    len_self = self->b_limit - self->b_position;
+    len_other = other->b_limit - other->b_position;
+
+    min_len = ((len_self < len_other) ? len_self : len_other);
     if (min_len > 0) {
-        cmp = memcmp(self->b_ptr, other->b_ptr, min_len);
+        cmp = memcmp(self->b_ptr + self->b_position, 
+                     other->b_ptr + other->b_position, min_len);
         if (cmp != 0)
             return cmp;
     }
-    return ((self->b_capacity < other->b_capacity) ?
-            -1 : (self->b_capacity > other->b_capacity) ? 1 : 0);
+
+    return ((len_self < len_other) ? -1 : (len_self > len_other) ? 1 : 0);
 }
 
 
@@ -196,7 +200,12 @@
 static PyObject *
 hotbuf_str(PyHotbufObject *self)
 {
-    return PyString_FromStringAndSize((const char *)self->b_ptr, self->b_capacity);
+    if ( self->b_position == self->b_limit ) {
+        return Py_None;
+    }
+    return PyString_FromStringAndSize(
+        (const char *)(self->b_ptr + self->b_position), 
+        self->b_limit - self->b_position);
 }
 
 
@@ -205,31 +214,6 @@
  * Object Methods (basic interface)
  */
 
-PyDoc_STRVAR(capacity__doc__,
-"B.capacity() -> int\n\
-\n\
-Returns this buffer's capacity. \n\
-(the entire size of the allocated buffer.)");
-
-static PyObject*
-hotbuf_capacity(PyHotbufObject *self)
-{
-    return PyInt_FromLong(self->b_capacity);
-}
-
-
-PyDoc_STRVAR(position__doc__,
-"B.position() -> int\n\
-\n\
-Returns this buffer's position.");
-
-static PyObject*
-hotbuf_position(PyHotbufObject *self)
-{
-    return PyInt_FromLong(self->b_position);
-}
-
-
 PyDoc_STRVAR(setposition__doc__,
 "B.setposition(int)\n\
 \n\
@@ -263,18 +247,6 @@
 }
 
 
-PyDoc_STRVAR(limit__doc__,
-"B.limit() -> int\n\
-\n\
-Returns this buffer's limit.");
-
-static PyObject*
-hotbuf_limit(PyHotbufObject *self)
-{
-    return PyInt_FromLong(self->b_limit);
-}
-
-
 PyDoc_STRVAR(setlimit__doc__,
 "B.setlimit(int)\n\
 \n\
@@ -313,19 +285,6 @@
 }
 
 
-PyDoc_STRVAR(mark__doc__,
-"B.mark() -> int\n\
-\n\
-Returns this buffer's mark. \n\
-Return -1 if the mark is not set.");
-
-static PyObject*
-hotbuf_mark(PyHotbufObject *self)
-{
-    return PyInt_FromLong(self->b_mark);
-}
-
-
 PyDoc_STRVAR(setmark__doc__,
 "B.setmark()\n\
 \n\
@@ -571,6 +530,57 @@
 }
 
 
+static PyObject*
+hotbuf_getstring(PyHotbufObject *self, PyObject* arg)
+{
+    int len;
+    CHECK_LIMIT_ERROR(sizeof(byte));
+
+    len = PyInt_AsLong(arg);
+    if (len == -1 && PyErr_Occurred())
+        return NULL;
+
+    if (len > (self->b_limit - self->b_position)) {
+        PyErr_SetString(PyExc_IndexError,
+                        "cannot read beyond limit");
+        return NULL;
+    }
+
+FIXME continue here
+
+    return PyString_FromStringAndSize(
+        (const char *)(self->b_ptr + self->b_position), len);
+}
+
+FIXME continue here
+
+FIXME we need to find a way to automatically advance position without doing it in Python
+
+
+static PyObject*
+hotbuf_putstring(PyHotbufObject *self, PyObject* arg)
+{
+    int byte_i;
+    unsigned char byte;
+
+    byte_i = PyInt_AsLong(arg);
+    if (byte_i == -1 && PyErr_Occurred())
+        return NULL;
+
+    if ( byte_i > 255 ) {
+        PyErr_SetString(PyExc_ValueError,
+                        "overflow for byte");
+        return NULL;
+    }
+    byte = (unsigned char)byte_i;
+
+    CHECK_LIMIT_ERROR(sizeof(byte));
+    *(unsigned char*)(self->b_ptr + self->b_position) = byte;
+    self->b_position += sizeof(byte);
+    return Py_None;
+}
+
+
 
 
 /* ===========================================================================
@@ -649,35 +659,45 @@
 ByteBuffer class.");
 
 
+
+#define OFF(x) offsetof(PyHotbufObject, x)
+
+static PyMemberDef hotbuf_members[] = {
+    {"capacity", T_INT, OFF(b_capacity), RO,
+     "buffer's capacity, it's total allocated size"},
+    {"position", T_INT, OFF(b_position), RO,
+     "buffer's position"},
+    {"limit", T_INT, OFF(b_limit), RO,
+     "buffer's limit"},
+    {"mark", T_INT, OFF(b_mark), RO,
+     "buffer's mark, -1 if not set"},
+    {NULL} /* Sentinel */
+};
+
 static PyMethodDef
 hotbuf_methods[] = {
-        {"clear", (PyCFunction)hotbuf_clear, METH_NOARGS, clear__doc__},
-        {"capacity", (PyCFunction)hotbuf_capacity, METH_NOARGS, capacity__doc__},
-        {"position", (PyCFunction)hotbuf_position, METH_NOARGS, position__doc__},
-        {"setposition", (PyCFunction)hotbuf_setposition, METH_O, setposition__doc__},
-        {"limit", (PyCFunction)hotbuf_limit, METH_NOARGS, limit__doc__},
-        {"setlimit", (PyCFunction)hotbuf_setlimit, METH_O, setlimit__doc__},
-        {"mark", (PyCFunction)hotbuf_mark, METH_NOARGS, mark__doc__},
-        {"setmark", (PyCFunction)hotbuf_setmark, METH_NOARGS, setmark__doc__},
-        {"reset", (PyCFunction)hotbuf_reset, METH_NOARGS, reset__doc__},
-        {"flip", (PyCFunction)hotbuf_flip, METH_NOARGS, flip__doc__},
-        {"rewind", (PyCFunction)hotbuf_rewind, METH_NOARGS, rewind__doc__},
-        {"remaining", (PyCFunction)hotbuf_remaining, METH_NOARGS, remaining__doc__},
-        {"compact", (PyCFunction)hotbuf_compact, METH_NOARGS, compact__doc__},
-
-        {"getbyte", (PyCFunction)hotbuf_getbyte, METH_NOARGS, relative_get__doc__},
-        {"putbyte", (PyCFunction)hotbuf_putbyte, METH_O, relative_put__doc__},
-        {NULL, NULL} /* sentinel */
+    {"clear", (PyCFunction)hotbuf_clear, METH_NOARGS, clear__doc__},
+    {"setposition", (PyCFunction)hotbuf_setposition, METH_O, setposition__doc__},
+    {"setlimit", (PyCFunction)hotbuf_setlimit, METH_O, setlimit__doc__},
+    {"setmark", (PyCFunction)hotbuf_setmark, METH_NOARGS, setmark__doc__},
+    {"reset", (PyCFunction)hotbuf_reset, METH_NOARGS, reset__doc__},
+    {"flip", (PyCFunction)hotbuf_flip, METH_NOARGS, flip__doc__},
+    {"rewind", (PyCFunction)hotbuf_rewind, METH_NOARGS, rewind__doc__},
+    {"remaining", (PyCFunction)hotbuf_remaining, METH_NOARGS, remaining__doc__},
+    {"compact", (PyCFunction)hotbuf_compact, METH_NOARGS, compact__doc__},
+    {"getbyte", (PyCFunction)hotbuf_getbyte, METH_NOARGS, relative_get__doc__},
+    {"putbyte", (PyCFunction)hotbuf_putbyte, METH_O, relative_put__doc__},
+    {NULL, NULL} /* sentinel */
 };
 
 static PySequenceMethods hotbuf_as_sequence = {
-        (lenfunc)hotbuf_length,                 /*sq_length*/
-        0 /* (binaryfunc)hotbuf_concat */,              /*sq_concat*/
-        0 /* (ssizeargfunc)hotbuf_repeat */,            /*sq_repeat*/
-        0 /* (ssizeargfunc)hotbuf_item */,              /*sq_item*/
-        0 /*(ssizessizeargfunc)hotbuf_slice*/,        /*sq_slice*/
-        0 /*(ssizeobjargproc)hotbuf_ass_item*/,       /*sq_ass_item*/
-        0 /*(ssizessizeobjargproc)hotbuf_ass_slice*/, /*sq_ass_slice*/
+    (lenfunc)hotbuf_length,                 /*sq_length*/
+    0 /* (binaryfunc)hotbuf_concat */,              /*sq_concat*/
+    0 /* (ssizeargfunc)hotbuf_repeat */,            /*sq_repeat*/
+    0 /* (ssizeargfunc)hotbuf_item */,              /*sq_item*/
+    0 /*(ssizessizeargfunc)hotbuf_slice*/,        /*sq_slice*/
+    0 /*(ssizeobjargproc)hotbuf_ass_item*/,       /*sq_ass_item*/
+    0 /*(ssizessizeobjargproc)hotbuf_ass_slice*/, /*sq_ass_slice*/
 };
 
 static PyBufferProcs hotbuf_as_buffer = {
@@ -717,7 +737,7 @@
     0,                                          /* tp_iter */
     0,                                          /* tp_iternext */
     hotbuf_methods,                             /* tp_methods */
-    0,                                          /* tp_members */
+    hotbuf_members,                             /* tp_members */
     0,                                          /* tp_getset */
     0,                                          /* tp_base */
     0,                                          /* tp_dict */

Modified: python/branches/blais-bytebuf/Objects/longobject.c
==============================================================================
--- python/branches/blais-bytebuf/Objects/longobject.c	(original)
+++ python/branches/blais-bytebuf/Objects/longobject.c	Thu May 25 16:25:38 2006
@@ -277,9 +277,9 @@
  overflow:
 	PyErr_SetString(PyExc_OverflowError,
 			"long int too large to convert to int");
-	if (sign > 0) 
+	if (sign > 0)
 		return PY_SSIZE_T_MAX;
-	else 
+	else
 		return PY_SSIZE_T_MIN;
 }
 
@@ -1304,7 +1304,34 @@
 	return (PyObject *)str;
 }
 
-/* *str points to the first digit in a string of base base digits.  base
+static int digval[] = {
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  37, 37, 37, 37, 37, 37,
+	37, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+	25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 37, 37, 37, 37,
+	37, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+	25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37
+};
+
+/* *str points to the first digit in a string of base `base` digits.  base
  * is a power of 2 (2, 4, 8, 16, or 32).  *str is set to point to the first
  * non-digit (which may be *str!).  A normalized long is returned.
  * The point to this routine is that it takes time linear in the number of
@@ -1328,20 +1355,8 @@
 		n >>= 1;
 	/* n <- total # of bits needed, while setting p to end-of-string */
 	n = 0;
-	for (;;) {
-		int k = -1;
-		char ch = *p;
-
-		if (ch <= '9')
-			k = ch - '0';
-		else if (ch >= 'a')
-			k = ch - 'a' + 10;
-		else if (ch >= 'A')
-			k = ch - 'A' + 10;
-		if (k < 0 || k >= base)
-			break;
+	while (digval[Py_CHARMASK(*p)] < base)
 		++p;
-	}
 	*str = p;
 	n = (p - start) * bits_per_char;
 	if (n / bits_per_char != p - start) {
@@ -1361,17 +1376,7 @@
 	bits_in_accum = 0;
 	pdigit = z->ob_digit;
 	while (--p >= start) {
-		int k;
-		char ch = *p;
-
-		if (ch <= '9')
-			k = ch - '0';
-		else if (ch >= 'a')
-			k = ch - 'a' + 10;
-		else {
-			assert(ch >= 'A');
-			k = ch - 'A' + 10;
-		}
+		int k = digval[Py_CHARMASK(*p)];
 		assert(k >= 0 && k < base);
 		accum |= (twodigits)(k << bits_in_accum);
 		bits_in_accum += bits_per_char;
@@ -1427,33 +1432,140 @@
 	}
 	if (base == 16 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
 		str += 2;
+
 	start = str;
 	if ((base & (base - 1)) == 0)
 		z = long_from_binary_base(&str, base);
 	else {
-		z = _PyLong_New(0);
-		for ( ; z != NULL; ++str) {
-			int k = -1;
-			PyLongObject *temp;
-
-			if (*str <= '9')
-				k = *str - '0';
-			else if (*str >= 'a')
-				k = *str - 'a' + 10;
-			else if (*str >= 'A')
-				k = *str - 'A' + 10;
-			if (k < 0 || k >= base)
-				break;
-			temp = muladd1(z, (digit)base, (digit)k);
-			Py_DECREF(z);
-			z = temp;
+/***
+Binary bases can be converted in time linear in the number of digits, because
+Python's representation base is binary.  Other bases (including decimal!) use
+the simple quadratic-time algorithm below, complicated by some speed tricks.
+
+First some math:  the largest integer that can be expressed in N base-B digits
+is B**N-1.  Consequently, if we have an N-digit input in base B, the worst-
+case number of Python digits needed to hold it is the smallest integer n s.t.
+
+    BASE**n-1 >= B**N-1  [or, adding 1 to both sides]
+    BASE**n >= B**N      [taking logs to base BASE]
+    n >= log(B**N)/log(BASE) = N * log(B)/log(BASE)
+
+The static array log_base_BASE[base] == log(base)/log(BASE) so we can compute
+this quickly.  A Python long with that much space is reserved near the start,
+and the result is computed into it.
+
+The input string is actually treated as being in base base**i (i.e., i digits
+are processed at a time), where two more static arrays hold:
+
+    convwidth_base[base] = the largest integer i such that base**i <= BASE
+    convmultmax_base[base] = base ** convwidth_base[base]
+
+The first of these is the largest i such that i consecutive input digits
+must fit in a single Python digit.  The second is effectively the input
+base we're really using.
+
+Viewing the input as a sequence <c0, c1, ..., c_n-1> of digits in base
+convmultmax_base[base], the result is "simply"
+
+   (((c0*B + c1)*B + c2)*B + c3)*B + ... ))) + c_n-1
+
+where B = convmultmax_base[base].
+***/
+		register twodigits c;	/* current input character */
+		Py_ssize_t size_z;
+		int i;
+		int convwidth;
+		twodigits convmultmax, convmult;
+		digit *pz, *pzstop;
+		char* scan;
+
+		static double log_base_BASE[37] = {0.0e0,};
+		static int convwidth_base[37] = {0,};
+		static twodigits convmultmax_base[37] = {0,};
+
+		if (log_base_BASE[base] == 0.0) {
+			twodigits convmax = base;
+			int i = 1;
+
+			log_base_BASE[base] = log((double)base) /
+						log((double)BASE);
+			for (;;) {
+				twodigits next = convmax * base;
+				if (next > BASE)
+					break;
+				convmax = next;
+				++i;
+			}
+			convmultmax_base[base] = convmax;
+			assert(i > 0);
+			convwidth_base[base] = i;
+		}
+
+		/* Find length of the string of numeric characters. */
+		scan = str;
+		while (digval[Py_CHARMASK(*scan)] < base)
+			++scan;
+
+		/* Create a long object that can contain the largest possible
+		 * integer with this base and length.  Note that there's no
+		 * need to initialize z->ob_digit -- no slot is read up before
+		 * being stored into.
+		 */
+		size_z = (Py_ssize_t)((scan - str) * log_base_BASE[base]) + 1;
+		assert(size_z > 0);
+		z = _PyLong_New(size_z);
+		if (z == NULL)
+			return NULL;
+		z->ob_size = 0;
+
+		/* `convwidth` consecutive input digits are treated as a single
+		 * digit in base `convmultmax`.
+		 */
+		convwidth = convwidth_base[base];
+		convmultmax = convmultmax_base[base];
+
+		/* Work ;-) */
+		while (str < scan) {
+			/* grab up to convwidth digits from the input string */
+			c = (digit)digval[Py_CHARMASK(*str++)];
+			for (i = 1; i < convwidth && str != scan; ++i, ++str) {
+				c = (twodigits)(c *  base +
+					digval[Py_CHARMASK(*str)]);
+				assert(c < BASE);
+			}
+
+			convmult = convmultmax;
+			/* Calculate the shift only if we couldn't get
+			 * convwidth digits.
+			 */
+			if (i != convwidth) {
+				convmult = base;
+				for ( ; i > 1; --i)
+					convmult *= base;
+			}
+
+			/* Multiply z by convmult, and add c. */
+			pz = z->ob_digit;
+			pzstop = pz + z->ob_size;
+			for (; pz < pzstop; ++pz) {
+				c += (twodigits)*pz * convmult;
+				*pz = (digit)(c & MASK);
+				c >>= SHIFT;
+			}
+			/* carry off the current end? */
+			if (c) {
+				assert(c < BASE);
+				assert(z->ob_size < size_z);
+				*pz = (digit)c;
+				++z->ob_size;
+			}
 		}
 	}
 	if (z == NULL)
 		return NULL;
 	if (str == start)
 		goto onError;
-	if (sign < 0 && z != NULL && z->ob_size != 0)
+	if (sign < 0)
 		z->ob_size = -(z->ob_size);
 	if (*str == 'L' || *str == 'l')
 		str++;

Modified: python/branches/blais-bytebuf/Python/errors.c
==============================================================================
--- python/branches/blais-bytebuf/Python/errors.c	(original)
+++ python/branches/blais-bytebuf/Python/errors.c	Thu May 25 16:25:38 2006
@@ -785,7 +785,7 @@
 				break;
 			/* fgets read *something*; if it didn't get as
 			   far as pLastChar, it must have found a newline
-			   or hit the end of the file;	if pLastChar is \n,
+			   or hit the end of the file; if pLastChar is \n,
 			   it obviously found a newline; else we haven't
 			   yet seen a newline, so must continue */
 		} while (*pLastChar != '\0' && *pLastChar != '\n');

Modified: python/branches/blais-bytebuf/Python/graminit.c
==============================================================================
--- python/branches/blais-bytebuf/Python/graminit.c	(original)
+++ python/branches/blais-bytebuf/Python/graminit.c	Thu May 25 16:25:38 2006
@@ -517,41 +517,36 @@
 	{12, 3},
 };
 static arc arcs_26_2[3] = {
-	{75, 4},
+	{75, 2},
 	{12, 3},
-	{72, 5},
+	{72, 4},
 };
 static arc arcs_26_3[1] = {
-	{72, 5},
+	{72, 4},
 };
-static arc arcs_26_4[2] = {
-	{75, 4},
-	{12, 3},
+static arc arcs_26_4[3] = {
+	{28, 5},
+	{13, 6},
+	{76, 5},
 };
-static arc arcs_26_5[3] = {
-	{28, 6},
-	{13, 7},
-	{76, 6},
+static arc arcs_26_5[1] = {
+	{0, 5},
 };
 static arc arcs_26_6[1] = {
-	{0, 6},
+	{76, 7},
 };
 static arc arcs_26_7[1] = {
-	{76, 8},
-};
-static arc arcs_26_8[1] = {
-	{15, 6},
+	{15, 5},
 };
-static state states_26[9] = {
+static state states_26[8] = {
 	{1, arcs_26_0},
 	{2, arcs_26_1},
 	{3, arcs_26_2},
 	{1, arcs_26_3},
-	{2, arcs_26_4},
-	{3, arcs_26_5},
+	{3, arcs_26_4},
+	{1, arcs_26_5},
 	{1, arcs_26_6},
 	{1, arcs_26_7},
-	{1, arcs_26_8},
 };
 static arc arcs_27_0[1] = {
 	{19, 1},
@@ -1839,7 +1834,7 @@
 	 "\000\000\000\000\000\000\000\000\000\005\000\000\000\000\000\000\000\000\000\000\000"},
 	{281, "import_name", 0, 3, states_25,
 	 "\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000"},
-	{282, "import_from", 0, 9, states_26,
+	{282, "import_from", 0, 8, states_26,
 	 "\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000"},
 	{283, "import_as_name", 0, 4, states_27,
 	 "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},


More information about the Python-checkins mailing list