[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