Python-checkins
Threads by month
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
August 2006
- 23 participants
- 662 discussions
Author: neal.norwitz
Date: Tue Aug 29 07:40:58 2006
New Revision: 51642
Modified:
python/trunk/Lib/doctest.py
Log:
Fix a couple of typos.
Modified: python/trunk/Lib/doctest.py
==============================================================================
--- python/trunk/Lib/doctest.py (original)
+++ python/trunk/Lib/doctest.py Tue Aug 29 07:40:58 2006
@@ -1561,7 +1561,7 @@
- test: the DocTest object being run
- - excample: the Example object that failed
+ - example: the Example object that failed
- got: the actual output
"""
@@ -1580,7 +1580,7 @@
- test: the DocTest object being run
- - excample: the Example object that failed
+ - example: the Example object that failed
- exc_info: the exception info
"""
1
0
Author: brett.cannon
Date: Mon Aug 28 23:49:36 2006
New Revision: 51638
Modified:
python/branches/bcannon-objcap/Lib/distutils/sysconfig.py
python/branches/bcannon-objcap/Lib/idlelib/ColorDelegator.py
python/branches/bcannon-objcap/Lib/pstats.py
python/branches/bcannon-objcap/Lib/site.py
python/branches/bcannon-objcap/Lib/tarfile.py
python/branches/bcannon-objcap/Lib/test/test_bool.py
python/branches/bcannon-objcap/Lib/test/test_bz2.py
python/branches/bcannon-objcap/Lib/test/test_descr.py
python/branches/bcannon-objcap/Lib/test/test_inspect.py
python/branches/bcannon-objcap/Lib/test/test_iter.py
python/branches/bcannon-objcap/Lib/test/test_marshal.py
python/branches/bcannon-objcap/Lib/test/test_os.py
python/branches/bcannon-objcap/Lib/test/test_tarfile.py
python/branches/bcannon-objcap/Lib/test/test_unicode_file.py
python/branches/bcannon-objcap/Lib/test/test_urllib.py
python/branches/bcannon-objcap/Lib/test/test_urllibnet.py
python/branches/bcannon-objcap/Lib/webbrowser.py
Log:
Backport rev. 51537 and 51539 from p3yk branch (replace usage of 'file()' with 'open()'). Will eventually turn off the 'file' constructor in this branch.
Modified: python/branches/bcannon-objcap/Lib/distutils/sysconfig.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/distutils/sysconfig.py (original)
+++ python/branches/bcannon-objcap/Lib/distutils/sysconfig.py Mon Aug 28 23:49:36 2006
@@ -354,7 +354,7 @@
# load the installed pyconfig.h:
try:
filename = get_config_h_filename()
- parse_config_h(file(filename), g)
+ parse_config_h(open(filename), g)
except IOError, msg:
my_msg = "invalid Python installation: unable to open %s" % filename
if hasattr(msg, "strerror"):
Modified: python/branches/bcannon-objcap/Lib/idlelib/ColorDelegator.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/idlelib/ColorDelegator.py (original)
+++ python/branches/bcannon-objcap/Lib/idlelib/ColorDelegator.py Mon Aug 28 23:49:36 2006
@@ -16,7 +16,7 @@
kw = r"\b" + any("KEYWORD", keyword.kwlist) + r"\b"
builtinlist = [str(name) for name in dir(__builtin__)
if not name.startswith('_')]
- # self.file = file("file") :
+ # self.file = open("file") :
# 1st 'file' colorized normal, 2nd as builtin, 3rd as string
builtin = r"([^.'\"\\#]\b|^)" + any("BUILTIN", builtinlist) + r"\b"
comment = any("COMMENT", [r"#[^\n]*"])
Modified: python/branches/bcannon-objcap/Lib/pstats.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/pstats.py (original)
+++ python/branches/bcannon-objcap/Lib/pstats.py Mon Aug 28 23:49:36 2006
@@ -173,7 +173,7 @@
def dump_stats(self, filename):
"""Write the profile data to a file we know how to load back."""
- f = file(filename, 'wb')
+ f = open(filename, 'wb')
try:
marshal.dump(self.stats, f)
finally:
Modified: python/branches/bcannon-objcap/Lib/site.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/site.py (original)
+++ python/branches/bcannon-objcap/Lib/site.py Mon Aug 28 23:49:36 2006
@@ -274,7 +274,7 @@
for filename in self.__files:
filename = os.path.join(dir, filename)
try:
- fp = file(filename, "rU")
+ fp = open(filename, "rU")
data = fp.read()
fp.close()
break
Modified: python/branches/bcannon-objcap/Lib/tarfile.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/tarfile.py (original)
+++ python/branches/bcannon-objcap/Lib/tarfile.py Mon Aug 28 23:49:36 2006
@@ -65,6 +65,8 @@
# from tarfile import *
__all__ = ["TarFile", "TarInfo", "is_tarfile", "TarError"]
+from __builtin__ import open as _open # Since 'open' is TarFile.open
+
#---------------------------------------------------------
# tar constants
#---------------------------------------------------------
@@ -934,7 +936,7 @@
self.mode = {"r": "rb", "a": "r+b", "w": "wb"}[mode]
if not fileobj:
- fileobj = file(self.name, self.mode)
+ fileobj = _open(self.name, self.mode)
self._extfileobj = False
else:
if self.name is None and hasattr(fileobj, "name"):
@@ -1083,7 +1085,7 @@
tarname = pre + ext
if fileobj is None:
- fileobj = file(name, mode + "b")
+ fileobj = _open(name, mode + "b")
if mode != "r":
name = tarname
@@ -1355,7 +1357,7 @@
# Append the tar header and data to the archive.
if tarinfo.isreg():
- f = file(name, "rb")
+ f = _open(name, "rb")
self.addfile(tarinfo, f)
f.close()
@@ -1617,7 +1619,7 @@
"""Make a file called targetpath.
"""
source = self.extractfile(tarinfo)
- target = file(targetpath, "wb")
+ target = _open(targetpath, "wb")
copyfileobj(source, target)
source.close()
target.close()
Modified: python/branches/bcannon-objcap/Lib/test/test_bool.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_bool.py (original)
+++ python/branches/bcannon-objcap/Lib/test/test_bool.py Mon Aug 28 23:49:36 2006
@@ -246,7 +246,7 @@
def test_fileclosed(self):
try:
- f = file(test_support.TESTFN, "w")
+ f = open(test_support.TESTFN, "w")
self.assertIs(f.closed, False)
f.close()
self.assertIs(f.closed, True)
Modified: python/branches/bcannon-objcap/Lib/test/test_bz2.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_bz2.py (original)
+++ python/branches/bcannon-objcap/Lib/test/test_bz2.py Mon Aug 28 23:49:36 2006
@@ -251,7 +251,7 @@
self.createTempFile()
bz2f = BZ2File(self.filename, "U")
bz2f.close()
- f = file(self.filename)
+ f = open(self.filename)
f.seek(0, 2)
self.assertEqual(f.tell(), len(self.DATA))
f.close()
Modified: python/branches/bcannon-objcap/Lib/test/test_descr.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_descr.py (original)
+++ python/branches/bcannon-objcap/Lib/test/test_descr.py Mon Aug 28 23:49:36 2006
@@ -2463,7 +2463,7 @@
self.ateof = 1
return s
- f = file(name=TESTFN, mode='w')
+ f = open(name=TESTFN, mode='w')
lines = ['a\n', 'b\n', 'c\n']
try:
f.writelines(lines)
@@ -2519,7 +2519,7 @@
sandbox = rexec.RExec()
code1 = """f = open(%r, 'w')""" % TESTFN
- code2 = """f = file(%r, 'w')""" % TESTFN
+ code2 = """f = open(%r, 'w')""" % TESTFN
code3 = """\
f = open(%r)
t = type(f) # a sneaky way to get the file() constructor
Modified: python/branches/bcannon-objcap/Lib/test/test_inspect.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_inspect.py (original)
+++ python/branches/bcannon-objcap/Lib/test/test_inspect.py Mon Aug 28 23:49:36 2006
@@ -130,7 +130,7 @@
def __init__(self, *args, **kwargs):
unittest.TestCase.__init__(self, *args, **kwargs)
- self.source = file(inspect.getsourcefile(self.fodderFile)).read()
+ self.source = open(inspect.getsourcefile(self.fodderFile)).read()
def sourcerange(self, top, bottom):
lines = self.source.split("\n")
Modified: python/branches/bcannon-objcap/Lib/test/test_iter.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_iter.py (original)
+++ python/branches/bcannon-objcap/Lib/test/test_iter.py Mon Aug 28 23:49:36 2006
@@ -674,7 +674,7 @@
# Test iterators with file.writelines().
def test_writelines(self):
- f = file(TESTFN, "w")
+ f = open(TESTFN, "w")
try:
self.assertRaises(TypeError, f.writelines, None)
@@ -713,7 +713,7 @@
f.writelines(Whatever(6, 6+2000))
f.close()
- f = file(TESTFN)
+ f = open(TESTFN)
expected = [str(i) + "\n" for i in range(1, 2006)]
self.assertEqual(list(f), expected)
Modified: python/branches/bcannon-objcap/Lib/test/test_marshal.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_marshal.py (original)
+++ python/branches/bcannon-objcap/Lib/test/test_marshal.py Mon Aug 28 23:49:36 2006
@@ -16,8 +16,8 @@
s = marshal.dumps(expected)
got = marshal.loads(s)
self.assertEqual(expected, got)
- marshal.dump(expected, file(test_support.TESTFN, "wb"))
- got = marshal.load(file(test_support.TESTFN, "rb"))
+ marshal.dump(expected, open(test_support.TESTFN, "wb"))
+ got = marshal.load( open(test_support.TESTFN, "rb"))
self.assertEqual(expected, got)
n = n >> 1
os.unlink(test_support.TESTFN)
@@ -51,8 +51,8 @@
new = marshal.loads(marshal.dumps(b))
self.assertEqual(b, new)
self.assertEqual(type(b), type(new))
- marshal.dump(b, file(test_support.TESTFN, "wb"))
- new = marshal.load(file(test_support.TESTFN, "rb"))
+ marshal.dump(b, open(test_support.TESTFN, "wb"))
+ new = marshal.load(open(test_support.TESTFN, "rb"))
self.assertEqual(b, new)
self.assertEqual(type(b), type(new))
@@ -67,8 +67,8 @@
s = marshal.dumps(f)
got = marshal.loads(s)
self.assertEqual(f, got)
- marshal.dump(f, file(test_support.TESTFN, "wb"))
- got = marshal.load(file(test_support.TESTFN, "rb"))
+ marshal.dump(f, open(test_support.TESTFN, "wb"))
+ got = marshal.load(open(test_support.TESTFN, "rb"))
self.assertEqual(f, got)
n /= 123.4567
@@ -94,12 +94,12 @@
got = marshal.loads(s)
self.assertEqual(f, got)
- marshal.dump(f, file(test_support.TESTFN, "wb"))
- got = marshal.load(file(test_support.TESTFN, "rb"))
+ marshal.dump(f, open(test_support.TESTFN, "wb"))
+ got = marshal.load(open(test_support.TESTFN, "rb"))
self.assertEqual(f, got)
- marshal.dump(f, file(test_support.TESTFN, "wb"), 1)
- got = marshal.load(file(test_support.TESTFN, "rb"))
+ marshal.dump(f, open(test_support.TESTFN, "wb"), 1)
+ got = marshal.load(open(test_support.TESTFN, "rb"))
self.assertEqual(f, got)
n *= 123.4567
os.unlink(test_support.TESTFN)
@@ -110,8 +110,8 @@
new = marshal.loads(marshal.dumps(s))
self.assertEqual(s, new)
self.assertEqual(type(s), type(new))
- marshal.dump(s, file(test_support.TESTFN, "wb"))
- new = marshal.load(file(test_support.TESTFN, "rb"))
+ marshal.dump(s, open(test_support.TESTFN, "wb"))
+ new = marshal.load(open(test_support.TESTFN, "rb"))
self.assertEqual(s, new)
self.assertEqual(type(s), type(new))
os.unlink(test_support.TESTFN)
@@ -121,8 +121,8 @@
new = marshal.loads(marshal.dumps(s))
self.assertEqual(s, new)
self.assertEqual(type(s), type(new))
- marshal.dump(s, file(test_support.TESTFN, "wb"))
- new = marshal.load(file(test_support.TESTFN, "rb"))
+ marshal.dump(s, open(test_support.TESTFN, "wb"))
+ new = marshal.load(open(test_support.TESTFN, "rb"))
self.assertEqual(s, new)
self.assertEqual(type(s), type(new))
os.unlink(test_support.TESTFN)
@@ -132,8 +132,8 @@
b = buffer(s)
new = marshal.loads(marshal.dumps(b))
self.assertEqual(s, new)
- marshal.dump(b, file(test_support.TESTFN, "wb"))
- new = marshal.load(file(test_support.TESTFN, "rb"))
+ marshal.dump(b, open(test_support.TESTFN, "wb"))
+ new = marshal.load(open(test_support.TESTFN, "rb"))
self.assertEqual(s, new)
os.unlink(test_support.TESTFN)
@@ -161,8 +161,8 @@
def test_dict(self):
new = marshal.loads(marshal.dumps(self.d))
self.assertEqual(self.d, new)
- marshal.dump(self.d, file(test_support.TESTFN, "wb"))
- new = marshal.load(file(test_support.TESTFN, "rb"))
+ marshal.dump(self.d, open(test_support.TESTFN, "wb"))
+ new = marshal.load(open(test_support.TESTFN, "rb"))
self.assertEqual(self.d, new)
os.unlink(test_support.TESTFN)
@@ -170,8 +170,8 @@
lst = self.d.items()
new = marshal.loads(marshal.dumps(lst))
self.assertEqual(lst, new)
- marshal.dump(lst, file(test_support.TESTFN, "wb"))
- new = marshal.load(file(test_support.TESTFN, "rb"))
+ marshal.dump(lst, open(test_support.TESTFN, "wb"))
+ new = marshal.load(open(test_support.TESTFN, "rb"))
self.assertEqual(lst, new)
os.unlink(test_support.TESTFN)
@@ -179,8 +179,8 @@
t = tuple(self.d.keys())
new = marshal.loads(marshal.dumps(t))
self.assertEqual(t, new)
- marshal.dump(t, file(test_support.TESTFN, "wb"))
- new = marshal.load(file(test_support.TESTFN, "rb"))
+ marshal.dump(t, open(test_support.TESTFN, "wb"))
+ new = marshal.load(open(test_support.TESTFN, "rb"))
self.assertEqual(t, new)
os.unlink(test_support.TESTFN)
@@ -191,8 +191,8 @@
self.assertEqual(t, new)
self.assert_(isinstance(new, constructor))
self.assertNotEqual(id(t), id(new))
- marshal.dump(t, file(test_support.TESTFN, "wb"))
- new = marshal.load(file(test_support.TESTFN, "rb"))
+ marshal.dump(t, open(test_support.TESTFN, "wb"))
+ new = marshal.load(open(test_support.TESTFN, "rb"))
self.assertEqual(t, new)
os.unlink(test_support.TESTFN)
Modified: python/branches/bcannon-objcap/Lib/test/test_os.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_os.py (original)
+++ python/branches/bcannon-objcap/Lib/test/test_os.py Mon Aug 28 23:49:36 2006
@@ -273,7 +273,7 @@
os.makedirs(sub11_path)
os.makedirs(sub2_path)
for path in tmp1_path, tmp2_path, tmp3_path:
- f = file(path, "w")
+ f = open(path, "w")
f.write("I'm " + path + " and proud of it. Blame test_os.\n")
f.close()
@@ -361,10 +361,10 @@
class DevNullTests (unittest.TestCase):
def test_devnull(self):
- f = file(os.devnull, 'w')
+ f = open(os.devnull, 'w')
f.write('hello')
f.close()
- f = file(os.devnull, 'r')
+ f = open(os.devnull, 'r')
self.assertEqual(f.read(), '')
f.close()
Modified: python/branches/bcannon-objcap/Lib/test/test_tarfile.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_tarfile.py (original)
+++ python/branches/bcannon-objcap/Lib/test/test_tarfile.py Mon Aug 28 23:49:36 2006
@@ -333,11 +333,11 @@
f.close()
elif self.comp == "bz2":
f = bz2.BZ2Decompressor()
- s = file(self.dstname).read()
+ s = open(self.dstname).read()
s = f.decompress(s)
self.assertEqual(len(f.unused_data), 0, "trailing data")
else:
- f = file(self.dstname)
+ f = open(self.dstname)
s = f.read()
f.close()
Modified: python/branches/bcannon-objcap/Lib/test/test_unicode_file.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_unicode_file.py (original)
+++ python/branches/bcannon-objcap/Lib/test/test_unicode_file.py Mon Aug 28 23:49:36 2006
@@ -152,7 +152,7 @@
# top-level 'test' functions would be if they could take params
def _test_single(self, filename):
remove_if_exists(filename)
- f = file(filename, "w")
+ f = open(filename, "w")
f.close()
try:
self._do_single(filename)
@@ -170,7 +170,7 @@
def _test_equivalent(self, filename1, filename2):
remove_if_exists(filename1)
self.failUnless(not os.path.exists(filename2))
- f = file(filename1, "w")
+ f = open(filename1, "w")
f.close()
try:
self._do_equivilent(filename1, filename2)
Modified: python/branches/bcannon-objcap/Lib/test/test_urllib.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_urllib.py (original)
+++ python/branches/bcannon-objcap/Lib/test/test_urllib.py Mon Aug 28 23:49:36 2006
@@ -27,7 +27,7 @@
def setUp(self):
"""Setup of a temp file to use for testing"""
self.text = "test_urllib: %s\n" % self.__class__.__name__
- FILE = file(test_support.TESTFN, 'wb')
+ FILE = open(test_support.TESTFN, 'wb')
try:
FILE.write(self.text)
finally:
@@ -139,7 +139,7 @@
self.registerFileForCleanUp(test_support.TESTFN)
self.text = 'testing urllib.urlretrieve'
try:
- FILE = file(test_support.TESTFN, 'wb')
+ FILE = open(test_support.TESTFN, 'wb')
FILE.write(self.text)
FILE.close()
finally:
@@ -192,7 +192,7 @@
self.assertEqual(second_temp, result[0])
self.assert_(os.path.exists(second_temp), "copy of the file was not "
"made")
- FILE = file(second_temp, 'rb')
+ FILE = open(second_temp, 'rb')
try:
text = FILE.read()
FILE.close()
Modified: python/branches/bcannon-objcap/Lib/test/test_urllibnet.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_urllibnet.py (original)
+++ python/branches/bcannon-objcap/Lib/test/test_urllibnet.py Mon Aug 28 23:49:36 2006
@@ -120,7 +120,7 @@
file_location,info = urllib.urlretrieve("http://www.python.org/")
self.assert_(os.path.exists(file_location), "file location returned by"
" urlretrieve is not a valid path")
- FILE = file(file_location)
+ FILE = open(file_location)
try:
self.assert_(FILE.read(), "reading from the file location returned"
" by urlretrieve failed")
@@ -134,7 +134,7 @@
test_support.TESTFN)
self.assertEqual(file_location, test_support.TESTFN)
self.assert_(os.path.exists(file_location))
- FILE = file(file_location)
+ FILE = open(file_location)
try:
self.assert_(FILE.read(), "reading from temporary file failed")
finally:
Modified: python/branches/bcannon-objcap/Lib/webbrowser.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/webbrowser.py (original)
+++ python/branches/bcannon-objcap/Lib/webbrowser.py Mon Aug 28 23:49:36 2006
@@ -210,7 +210,7 @@
cmdline = [self.name] + raise_opt + args
if remote or self.background:
- inout = file(os.devnull, "r+")
+ inout = open(os.devnull, "r+")
else:
# for TTY browsers, we need stdin/out
inout = None
@@ -334,7 +334,7 @@
else:
action = "openURL"
- devnull = file(os.devnull, "r+")
+ devnull = open(os.devnull, "r+")
# if possible, put browser in separate process group, so
# keyboard interrupts don't affect browser as well as Python
setsid = getattr(os, 'setsid', None)
1
0
Author: brett.cannon
Date: Mon Aug 28 22:07:25 2006
New Revision: 51637
Modified:
python/branches/bcannon-objcap/securing_python.txt
Log:
Add a Status section, starting with __subclasses__ handled.
Modified: python/branches/bcannon-objcap/securing_python.txt
==============================================================================
--- python/branches/bcannon-objcap/securing_python.txt (original)
+++ python/branches/bcannon-objcap/securing_python.txt Mon Aug 28 22:07:25 2006
@@ -1,6 +1,26 @@
Securing Python
#####################################################################
+Status
+///////////////////////////////////////
+
++ Remove object.__subclasses__ [done]
++ Dangerous constructors
+ - file
+ - code
++ Sandboxed built-ins
+ - open()
+ - __import__() / PEP 302 importer
++ Filesystem path hiding
++ mini 'sys' module
++ Create sandboxed interpreters
+ - Be able to specify built-ins
+ - Set 'sys' module settings
+ - API
+ * Python
+ * C
+
+
Introduction
///////////////////////////////////////
1
0
r51636 - in python/branches: bcannon-objcap/securing_python.txt bcannon-sandboxing/securing_python.txt
by brett.cannon 28 Aug '06
by brett.cannon 28 Aug '06
28 Aug '06
Author: brett.cannon
Date: Mon Aug 28 21:55:57 2006
New Revision: 51636
Added:
python/branches/bcannon-objcap/securing_python.txt
- copied unchanged from r51635, python/branches/bcannon-sandboxing/securing_python.txt
Removed:
python/branches/bcannon-sandboxing/securing_python.txt
Log:
Moving securing_python.txt to a more proper home.
Deleted: /python/branches/bcannon-sandboxing/securing_python.txt
==============================================================================
--- /python/branches/bcannon-sandboxing/securing_python.txt Mon Aug 28 21:55:57 2006
+++ (empty file)
@@ -1,701 +0,0 @@
-Securing Python
-#####################################################################
-
-Introduction
-///////////////////////////////////////
-
-As of Python 2.5, the Python does not support any form of security
-model for
-executing arbitrary Python code in some form of protected interpreter.
-While one can use such things as ``exec`` and ``eval`` to garner a
-very weak form of sandboxing, it does not provide any thorough
-protections from malicious code.
-
-This should be rectified. This document attempts to lay out what
-would be needed to secure Python in such a way as to allow arbitrary
-Python code to execute in a sandboxed interpreter without worries of
-that interpreter providing access to any resource of the operating
-system without being given explicit authority to do so.
-
-Throughout this document several terms are going to be used. A
-"sandboxed interpreter" is one where the built-in namespace is not the
-same as that of an interpreter whose built-ins were unaltered, which
-is called an "unprotected interpreter".
-
-A "bare interpreter" is one where the built-in namespace has been
-stripped down the bare minimum needed to run any form of basic Python
-program. This means that all atomic types (i.e., syntactically
-supported types), ``object``, and the exceptions provided by the
-``exceptions`` module are considered in the built-in namespace. There
-have also been no imports executed in the interpreter.
-
-The "security domain" is the boundary at which security is cared
-about. For this dicussion, it is the interpreter. Anything that
-happens within a security domain is considered open and unprotected.
-But any action that tries to cross the boundary of the security domain
-is where the security model and protection comes in.
-
-The "powerbox" is the thing that possesses the ultimate power in the
-system for giving out abilities. In our case it is the Python
-process. No interpreter can possess any ability that the overall
-process does not have. It is up to the Python process to initially
-hand out abilities to interpreters to use either for themselves or to
-give to interpreters they create themselves. This means that we care
-about interpreter<->interpreter interaction along with
-interpreter<->process interactions.
-
-
-Rationale
-///////////////////////////////////////
-
-Python is used extensively as an embedded language within existing
-programs. These applications often times need to provide the
-functionality of allowing users to run Python code written by someone
-else where they can trust that no unintentional harm will come to
-their system regardless of their trust of the code they are executing.
-
-For instance, think of an application that supports a plug-in system
-with Python as the language used for writing plug-ins. You do not
-want to have to examine every plug-in you download to make sure that
-it does not alter your filesystem if you can help it. With a proper
-security model and implementation in place this hinderance of having
-to examine all code you execute should be alleviated.
-
-
-Approaches to Security
-///////////////////////////////////////
-
-There are essentially two types of security: who-I-am
-security and what-I-have security.
-
-Who-I-Am Security
-========================
-
-With who-I-am security (a.k.a., permissions-based security), the
-ability to use a resource requires providing who you are, validating
-you are allowed to access the resource you are requesting, and then
-performing the requested action on the resource.
-
-The ACL security system on most UNIX filesystems is who-I-am security.
-When you want to open a file, say ``/etc/passwd``, you make the
-function call to open the file. Within that function, it fetchs
-the ACL for the file, finds out who the caller is, checks to see if
-the caller is on the ACL for opening the file, and then proceeds to
-either deny access or return an open file object.
-
-
-What-I-Have Security
-========================
-
-A contrast to who-I-am security, what-I-have security never requires
-knowing who is requesting a resource. If you know what resources are
-allowed or needed when you begin a security domain, you can just have
-the powerbox pass in those resources to begin with and not provide a
-function to retrieve them. This alleviates the worry of providing a
-function that can wield more power than the security domain should
-ever have if security is breached on that function.
-
-But if you don't know the exact resources needed ahead of time, you
-pass in a proxy to the resource that checks its arguments to make sure
-they are valid in terms of allowed usage of the protected resource.
-With this approach, you are only doing argument validation, where the
-validation happens to be related to security. No identity check is
-needed at any point.
-
-Using our file example, the program trying to open a file is given the
-open file object directly at time of creation that it will need to
-work with. A proxy to the full-powered open function can be used if
-you need more of a wildcard support for opening files. But
-it works just as well, if not better, to pass in all needed file
-objects at the beginning when the allowed files to work with is known
-so as to not even risk exposing the file opening function.
-
-This illustrates a subtle, but key difference between who-I-am and
-what-I-have security. For who-I-am, you must know who the caller is
-and check that the arguments are valid for the person calling. For
-what-I-have security, you only have to validate the arguments.
-
-
-Object-Capabilities
-///////////////////////////////////////
-
-What-I-have security is a super-set of the object-capabilities
-security model. The belief here is in POLA (Principle Of Least
-Authority): you give a program exactly what it needs, and no more. By
-providing a function that can open any file that relies on identity to
-decide if to open something, you are still providing a fully capable
-function that just requires faking one's identity to circumvent
-security. It also means that if you accidentally run code that
-performs actions that you did not expect (e.g., deleting all your
-files), there is no way to stop it since it operates with *your*
-permissions.
-
-Using POLA and object-capabilities, you only give access to resources
-to the extent that someone needs. This means if a program only needs
-access to a single file, you only give them a function that can open
-that single file. If you accidentally run code that tries to delete
-all of your files, it can only delete the one file you authorized the
-program to open.
-
-Object-capabilities use the reference graph of objects to provide the
-security of accessing resources. If you do not have a reference to a
-resource (or a reference to an object that can references a resource),
-you cannot access it, period. You can provide conditional access by
-using a proxy between code and a resource, but that still requires a
-reference to the resource by the proxy. This means that your security
-model can be viewed simply by using a whiteboard to draw out the
-interactions between your security domains where by any connection
-between domains is a possible security issue if you do not put in a
-proxy to mediate between the two domains.
-
-This leads to a much cleaner implementation of security. By not
-having to change internal code in the interpreter to perform identity
-checks, you can instead shift the burden of security to proxies
-which are much more flexible and have less of an adverse affect on the
-interpreter directly (assuming you have the basic requirements for
-object-capabilities met).
-
-
-Difficulties in Python for Object-Capabilities
-//////////////////////////////////////////////
-
-In order to provide the proper protection of references that
-object-capabilities require, you must set up a secure perimeter
-defense around your security domain. The domain can be anthing:
-objects, interpreters, processes, etc. The point is that the domain
-is where you draw the line for allowing arbitrary access to resources.
-This means that with the interpreter is the security domain, then
-anything within an interpreter can be expected to be freely shared,
-but beyond that, reference access is strictly controlled.
-
-Three key requirements for providing a proper perimeter defence is
-private namespaces, immutable shared state across domains, and
-unforgeable references. Unfortunately Python only has one of the
-three requirements by default (you cannot forge a reference in Python
-code).
-
-
-Problem of No Private Namespace
-===============================
-
-Typically, in languages that are statically typed (like C++), you have
-public and private attributes on objects. Those private attributes
-provide a private namespace for the class and instances that are not
-accessible by other objects.
-
-The Python language has no such thing as a private namespace. The
-language has the philosophy that if exposing something to the
-programmer could provide some use, then it is exposed. This has led
-to Python having a wonderful amount of introspection abilities.
-Unfortunately this makes the possibility of a private namespace
-non-existent. This poses an issue for providing proxies for resources
-since there is no way in Python code to hide the reference to a
-resource. It also makes providing security at the object level using
-object-capabilities non-existent in pure Python code.
-
-Luckily, the Python virtual machine *does* provide a private namespace,
-albeit not for pure Python source code. If you use the Python/C
-language barrier in extension modules, you can provide a private
-namespace by using the struct allocated for each instance of an
-object. This provides a way to create proxies, written in C, that can
-protect resources properly. Throughout this document, when mentioning
-proxies, it is assumed they have been implemented in C.
-
-
-Problem of Mutable Shared State
-===============================
-
-Another problem that Python's introspection abilties cause is that of
-mutable shared state. At the interpreter level, there has never been
-a concerted effort to isolate state shared between all interpreters
-running in the same Python process. Sometimes this is for performance
-reasons, sometimes because it is just easier to implement this way.
-Regardless, sharing of state that can be influenced by another
-interpreter is not safe for object-capabilities.
-
-To rectify the situation, some changes will be needed to some built-in
-objects in Python. It should mostly consist of abstracting or
-refactoring certain abilities out to an extension module so that
-access can be protected using import guards. For instance, as it
-stands now, ``object.__subclasses__()`` will return a tuple of all of
-its subclasses, regardless of what interpreter the subclass was
-defined in.
-
-
-Threat Model
-///////////////////////////////////////
-
-The threat that this security model is attempting to handle is the
-execution of arbitrary Python code in a sandboxed interpreter such
-that the code in that interpreter is not able to harm anything outside
-of itself unless explicitly allowed to. This means that:
-
-* An interpreter cannot gain abilties the Python process possesses
- without explicitly being given those abilities.
- + With the Python process being the powerbox, if an interpreter
- could gain whatever abilities it wanted to then the security
- domain would be completely breached.
-* An interpreter cannot influence another interpreter directly at the
- Python level without explicitly allowing it.
- + This includes preventing communicating with another interpreter.
- + Mutable objects cannot be shared between interpreters without
- explicit allowance for it.
- + "Explicit allowance" includes the importation of C extension
- modules because a technical detail requires that these modules
- not be re-initialized per interpreter, meaning that all
- interpreters in a single Python process share the same C
- extension modules.
-* An interpreter cannot use operating system resources without being
- explicitly given those resources.
- + This includes importing modules since that requires the ability
- to use the resource of the filesystem.
- + This is mediated by having to go through the process to gain the
- abilities in the OS that the process possesses.
-
-In order to accomplish these goals, certain things must be made true.
-
-* The Python process is the powerbox.
- + It controls the initial granting of abilties to interpreters.
-* A bare Python interpreter is always trusted.
- + Python source code that can be created in a bare interpreter is
- always trusted.
- + Python source code created within a bare interpreter cannot
- crash the interpreter.
-* Python bytecode is always distrusted.
- + Malicious bytecode can bring down an interpreter.
-* Pure Python source code is always safe on its own.
- + Malicious abilities are derived from C extension modules,
- built-in modules, and unsafe types implemented in C, not from
- pure Python source.
-* A sub-interpreter started by another interpreter does not inherit
- any state.
- + The sub-interpreter starts out with a fresh global namespace and
- whatever built-ins it was initially given.
-
-
-Implementation
-///////////////////////////////////////
-
-Guiding Principles
-========================
-
-To begin, the Python process garners all power as the powerbox. It is
-up to the process to initially hand out access to resources and
-abilities to interpreters. This might take the form of an interpreter
-with all abilities granted (i.e., a standard interpreter as launched
-when you execute Python), which then creates sub-interpreters with
-sandboxed abilities. Another alternative is only creating
-interpreters with sandboxed abilities (i.e., Python being embedded in
-an application that only uses sandboxed interpreters).
-
-All security measures should never have to ask who an interpreter is.
-This means that what abilities an interpreter has should not be stored
-at the interpreter level when the security can be provided at the
-Python level. This means that while supporting a memory cap can
-have a per-interpreter setting that is checked (because access to the
-operating system's memory allocator is not supported at the program
-level), protecting files and imports should not such a per-interpreter
-protection at such a low level (because those can have extension
-module proxies to provide the security). This means that security is
-based on possessing the authority to do something through a reference
-to an object that can perform the action. And that object will most
-likely decide whether to carry out its action based on the arguments
-passed in (whether that is an opaque token, file path allowed to be
-opened, etc.).
-
-For common case security measures, the Python standard library
-(stdlib) should provide a simple way to provide those measures. Most
-commonly this will take the form of providing factory functions that
-create instances of proxies for providing protection of key resources.
-
-Backwards-compatibility will not be a hindrance upon the design or
-implementation of the security model. Because the security model will
-inherently remove resources and abilities that existing code expects,
-it is not reasonable to expect existing code to work in a sandboxed
-interpreter.
-
-Keeping Python "pythonic" is required for all design decisions.
-In general, being pythonic means that something fits the general
-design guidelines of the Python programming language (run
-``import this`` from a Python interpreter to see the basic ones).
-If removing an ability leads to something being unpythonic, it will not
-be done unless there is an extremely compelling reason to do so.
-This does not mean existing pythonic code must continue to work, but
-the spirit of being pythonic will not be compromised in the name of the
-security model. While this might lead to a weaker security model, this
-is a price that must be paid in order for Python to continue to be the
-language that it is.
-
-Restricting what is in the built-in namespace and the safe-guarding
-the interpreter (which includes safe-guarding the built-in types) is
-where the majority of security will come from. Imports and the
-``file`` type are both part of the standard namespace and must be
-restricted in order for any security implementation to be effective.
-The built-in types which are needed for basic Python usage (e.g.,
-``object`` code objects, etc.) must be made safe to use in a sandboxed
-interpreter since they are easily accessbile and yet required for
-Python to function.
-
-The rest of the security for Python will come in the form of
-protecting physical resources. For those resources that can be denied
-in a Denial of Service (DoS) attack but protected in a
-platform-agnositc fashion, they should. This means, for instance,
-that memory should be protected but CPU usage can't.
-
-
-Abilities of a Standard Sandboxed Interpreter
-=============================================
-
-In the end, a standard sandboxed interpreter should (not)
-allow certain things to be doable by code running within itself.
-Below is a list of abilities that will (not) be allowed in the default
-instance of a sandboxed interpreter comparative to an unprotected
-interpreter that has not imported any modules. These protections can
-be tweaked by using proxies to allow for certain extended abilities to
-be accessible.
-
-* You cannot open any files directly.
-* Importation
- + You can import any pure Python module.
- + You cannot import any Python bytecode module.
- + You cannot import any C extension module.
- + You cannot import any built-in module.
-* You cannot find out any information about the operating system you
- are running on.
-* Only safe built-ins are provided.
-
-
-Implementation Details
-========================
-
-An important point to keep in mind when reading about the
-implementation details for the security model is that these are
-general changes and are not special to any type of interpreter,
-sandboxed or otherwise. That means if a change to a built-in type is
-suggested and it does not involve a proxy, that change is meant
-Python-wide for *all* interpreters.
-
-
-Imports
--------
-
-A proxy for protecting imports will be provided. This is done by
-setting the ``__import__()`` function in the built-in namespace of the
-sandboxed interpreter to a proxied version of the function.
-
-The planned proxy will take in a passed-in function to use for the
-import and a whitelist of C extension modules and built-in modules to
-allow importation of. If an import would lead to loading an extension
-or built-in module, it is checked against the whitelist and allowed
-to be imported based on that list. All .pyc and .pyo file will not
-be imported. All .py files will be imported.
-
-XXX perhaps augment 'sys' so that you list the extension of files that
-can be used for importing? Thought this was controlled somewhere
-already but can't find it. It is returned by ``imp.get_suffixes()``,
-but I can't find where to set it from Python code.
-
-It must be warned that importing any C extension module is dangerous.
-Not only are they able to circumvent security measures by executing C
-code, but they share state across interpreters. Because an extension
-module's init function is only called once for the Python *process*,
-its initial state is set only once. This means that if some mutable
-object is exposed at the module level, a sandboxed interpreter could
-mutate that object, return, and then if the creating interpreter
-accesses that mutated object it is essentially communicating and/or
-acting on behalf of the sandboxed interpreter. This violates the
-perimeter defence. No one should import extension modules blindly.
-
-Implementing Import in Python
-+++++++++++++++++++++++++++++
-
-To help facilitate in the exposure of more of what importation
-requires (and thus make implementing a proxy easier), the import
-machinery should be rewritten in Python. This will require some
-bootstrapping in order for the code to be loaded into the process
-without itself requiring importation, but that should be doable. Plus
-some care must be taken to not lead to circular dependency on
-importing modules needed to handle importing (e.g. importing sys but
-having that import call the import call, etc.).
-
-Interaction with another interpreter that might provide an import
-function must also be dealt with. One cannot expose the importation
-of a needed module for the import machinery as it might not be allowed
-by a proxy. This can be handled by allowing the powerbox's import
-function to have modules directly injected into its global namespace.
-But there is also the issue of using the proper ``sys.modules`` for
-storing the modules already imported. You do not want to inject the
-``sys`` module of the powerbox and have all imports end up in its
-``sys.modules`` but in the interpreter making the call. This must be
-dealt with in some fashion (injecting per-call, having a factory
-function create a new import function based on an interpreter passed
-in, etc.).
-
-
-Sanitizing Built-In Types
--------------------------
-
-Python contains a wealth of bulit-in types. These are used at a basic
-level so that they are easily accessible to any Python code. They are
-also shared amongst all interpreters in a Python process. This means
-all built-in types need to be made safe (e.g., immutable shared
-state) so that they can be used by any and all interpreters in a
-single Python process. Several aspects of built-in types need to be
-examined.
-
-
-Constructors
-++++++++++++
-
-Almost all of Python's built-in types contain a constructor that allows
-code to create a new instance of a type as long as you have the type
-itself. Unfortunately this does not work well in an object-capabilities
-system without either providing a proxy to the constructor or just
-removing it when access to such a constructor should be controlled.
-
-The plan is to remove select constructors of the types that are
-dangerous and either relocate them to an extension module as factory
-functions or create a new built-in that acts a generic factory
-function for all types, missing constructor or not. The former approach
-will allow for protections to be enforced by import proxy; just don't
-allow the extension module to be imported. The latter approach would
-allow either a unique constructor per type, or more generic built-in(s)
-for construction (e.g., introducing a ``construct()`` function that
-takes in a type and any arguments desired to be passed in for
-constructing an instance of the type) and allowing using proxies to
-provide security.
-
-Some might consider this unpythonic. Python very rarely separates the
-constructor of an object from the class/type and require that you go
-through a function. But there is some precedent for not using a
-type's constructor to get an instance of a type. The ``file`` type,
-for instance, typically has its instances created through the
-``open()`` function. This slight shift for certain types to have their
-(dangerous) constructor not on the type but in a function is
-considered an acceptable compromise.
-
-Types whose constructors are considered dangerous are:
-
-* ``file``
- + Will definitely use the ``open()`` built-in.
-* code objects
-* XXX sockets?
-* XXX type?
-* XXX
-
-
-Filesystem Information
-++++++++++++++++++++++
-
-When running code in a sandboxed interpreter, POLA suggests that you
-do not want to expose information about your environment on top of
-protecting its use. This means that filesystem paths typically should
-not be exposed. Unfortunately, Python exposes file paths all over the
-place that will need to be hidden:
-
-* Modules
- + ``__file__`` attribute
-* Code objects
- + ``co_filename`` attribute
-* Packages
- + ``__path__`` attribute
-* XXX
-
-XXX how to expose safely? ``path()`` built-in?
-
-
-Mutable Shared State
-++++++++++++++++++++
-
-Because built-in types are shared between interpreters, they cannot
-expose any mutable shared state. Unfortunately, as it stands, some
-do. Below is a list of types that share some form of dangerous state,
-how they share it, and how to fix the problem:
-
-* ``object``
- + ``__subclasses__()`` function
- - Remove the function; never seen used in real-world code.
-* XXX
-
-
-Perimeter Defences Between a Created Interpreter and Its Creator
-----------------------------------------------------------------
-
-The plan is to allow interpreters to instantiate sandboxed
-interpreters safely. By using the creating interpreter's abilities to
-provide abilities to the created interpreter, you make sure there is
-no escalation in abilities.
-
-But by creating a sandboxed interpreter and passing in any code into
-it, you open up the chance of possible ways of getting back to the
-creating interpreter or escalating privileges. Those ways are:
-
-* ``__del__`` created in sandboxed interpreter but object is cleaned
- up in unprotected interpreter.
-* Using frames to walk the frame stack back to another interpreter.
-* XXX
-
-
-Making the ``sys`` Module Safe
-------------------------------
-
-The ``sys`` module is an odd mix of both information and settings for
-the interpreter. Because of this dichotomy, some very useful, but
-innocuous information is stored in the module along with things that
-should not be exposed to sandboxed interpreters.
-
-This means that the ``sys`` module needs to have its safe information
-separated out from the unsafe settings. This will allow an import
-proxy to let through safe information but block out the ability to set
-values.
-
-XXX separate modules, ``sys.settings`` and ``sys.info``, or strip
-``sys`` to settings and put info somewhere else? Or provide a method
-that will create a faked sys module that has the safe values copied
-into it?
-
-The safe information values are:
-
-* builtin_module_names
- Information about what might be blocked from importation.
-* byteorder
- Needed for networking.
-* copyright
- Set to a string about the interpreter.
-* displayhook (?)
-* excepthook (?)
-* __displayhook__ (?)
-* __excepthook__ (?)
-* exc_info() (?)
-* exc_clear()
-* exit()
-* exitfunc
-* getcheckinterval()
- Returns an int.
-* getdefaultencoding()
- Returns a string about interpreter.
-* getrefcount()
- Returns an int about the passed-in object.
-* getrecursionlimit()
- Returns an int about the interpreter.
-* hexversion
- Set to an int about the interpreter.
-* last_type
-* last_value
-* last_traceback (?)
-* maxint
- Set to an int that exposes ambiguous information about the
- computer.
-* maxunicode
- Returns a string about the interpreter.
-* meta_path (?)
-* path_hooks (?)
-* path_importer_cache (?)
-* ps1
-* ps2
-* stdin
-* stdout
-* stderr
-* traceback (?)
-* version
-* api_version
-* version_info
-* warnoptions (?)
-
-The dangerous settings are:
-
-* argv
-* subversion
-* _current_frames()
-* dllhandle
-* exc_type
- Deprecated since 1.5 .
-* exc_value
- Deprecated since 1.5 .
-* exc_traceback
- Deprecated since 1.5 .
-* exc_prefix
- Exposes filesystem information.
-* executable
- Exposes filesystem information.
-* _getframe()
-* getwindowsversion()
- Exposes OS information.
-* modules
-* path
-* platform
- Exposes OS information.
-* prefix
- Exposes filesystem information.
-* setcheckinterval()
-* setdefaultencoding()
-* setdlopenflags()
-* setprofile()
-* setrecursionlimit()
-* settrace()
-* settcsdump()
-* __stdin__
-* __stdout__
-* __stderr__
-* winver
- Exposes OS information.
-
-
-Protecting I/O
-++++++++++++++
-
-The ``print`` keyword and the built-ins ``raw_input()`` and
-``input()`` use the values stored in ``sys.stdout`` and ``sys.stdin``.
-By exposing these attributes to the creating interpreter, one can set
-them to safe objects, such as instances of ``StringIO``.
-
-
-Safe Networking
----------------
-
-XXX proxy on socket module, modify open() to be the constructor, etc.
-
-
-Protecting Memory Usage
------------------------
-
-To protect memory, low-level hooks into the memory allocator for
-Python is needed. By hooking into the C API for memory allocation and
-deallocation a *very* rough running count of used memory can be kept.
-This can be used to compare against the set memory cap to prevent
-sandboxed interpreters from using so much memory that it impacts the
-overall performance of the system.
-
-Because this has no direct connection with object-capabilities or has
-any form of exposure at the Python level, this feature can be safely
-implemented separately from the rest of the security model.
-
-Existing APIs to protect are:
-
-- _PyObject_New() : PyObject_New()
-- _PyObject_NewVar() : PyObject_NewVar()
-- _PyObject_Del()
- remove macro that uses PyObject_Free() and protect directly
-- PyObject_Del()
- redefine macro to use _PyObject_Del() instead of PyObject_Free()
-- PyMem_Malloc() : PyMem_New()
-- PyMem_Realloc() : PyMem_Resize()
-- PyMem_Free() : PyMem_Del()
-- PyMem_MALLOC() : PyMem_NEW()
- redefine macro to use PyMem_Malloc()
-- PyMem_REALLOC() : PyMem_RESIZE()
- redefine macro to use PyMem_Realloc()
-- PyMem_FREE() : PyMem_DEL()
- redefine macro to use PyMem_Free()
-- PyObject_Malloc()
- XXX
-- PyObject_Realloc()
- XXX
-- PyObject_Free()
- XXX
-- PyObject_MALLOC()
- XXX
-- PyObject_REALLOC()
- XXX
-- PyObject_FREE()
- XXX
1
0
Author: brett.cannon
Date: Mon Aug 28 21:49:46 2006
New Revision: 51635
Added:
python/branches/bcannon-objcap/Doc/howto/functional.rst
- copied unchanged from r51624, python/trunk/Doc/howto/functional.rst
python/branches/bcannon-objcap/Lib/genericpath.py
- copied unchanged from r51624, python/trunk/Lib/genericpath.py
python/branches/bcannon-objcap/Lib/test/crashers/bogus_sre_bytecode.py
- copied unchanged from r51624, python/trunk/Lib/test/crashers/bogus_sre_bytecode.py
python/branches/bcannon-objcap/Lib/test/test_genericpath.py
- copied unchanged from r51624, python/trunk/Lib/test/test_genericpath.py
python/branches/bcannon-objcap/Misc/RPM/python-2.6.spec
- copied unchanged from r51624, python/trunk/Misc/RPM/python-2.6.spec
python/branches/bcannon-objcap/Modules/_ctypes/libffi_msvc/win64.asm
- copied unchanged from r51624, python/trunk/Modules/_ctypes/libffi_msvc/win64.asm
python/branches/bcannon-objcap/PCbuild/amd64_ml64.bat
- copied unchanged from r51624, python/trunk/PCbuild/amd64_ml64.bat
python/branches/bcannon-objcap/Python/peephole.c
- copied unchanged from r51624, python/trunk/Python/peephole.c
Removed:
python/branches/bcannon-objcap/Misc/RPM/python-2.5.spec
Modified:
python/branches/bcannon-objcap/ (props changed)
python/branches/bcannon-objcap/Doc/api/abstract.tex
python/branches/bcannon-objcap/Doc/api/concrete.tex
python/branches/bcannon-objcap/Doc/api/intro.tex
python/branches/bcannon-objcap/Doc/api/newtypes.tex
python/branches/bcannon-objcap/Doc/commontex/boilerplate.tex
python/branches/bcannon-objcap/Doc/lib/libctypes.tex
python/branches/bcannon-objcap/Doc/lib/libuuid.tex
python/branches/bcannon-objcap/Doc/whatsnew/whatsnew25.tex
python/branches/bcannon-objcap/Include/code.h
python/branches/bcannon-objcap/Include/import.h
python/branches/bcannon-objcap/Include/patchlevel.h
python/branches/bcannon-objcap/Lib/compiler/ast.py
python/branches/bcannon-objcap/Lib/compiler/pycodegen.py
python/branches/bcannon-objcap/Lib/compiler/symbols.py
python/branches/bcannon-objcap/Lib/ctypes/__init__.py
python/branches/bcannon-objcap/Lib/ctypes/test/test_as_parameter.py
python/branches/bcannon-objcap/Lib/ctypes/test/test_functions.py
python/branches/bcannon-objcap/Lib/ctypes/test/test_python_api.py
python/branches/bcannon-objcap/Lib/ctypes/test/test_win32.py
python/branches/bcannon-objcap/Lib/distutils/__init__.py
python/branches/bcannon-objcap/Lib/encodings/__init__.py
python/branches/bcannon-objcap/Lib/idlelib/Bindings.py
python/branches/bcannon-objcap/Lib/idlelib/CREDITS.txt
python/branches/bcannon-objcap/Lib/idlelib/CodeContext.py
python/branches/bcannon-objcap/Lib/idlelib/NEWS.txt
python/branches/bcannon-objcap/Lib/idlelib/PyShell.py
python/branches/bcannon-objcap/Lib/idlelib/idlever.py
python/branches/bcannon-objcap/Lib/macpath.py
python/branches/bcannon-objcap/Lib/ntpath.py
python/branches/bcannon-objcap/Lib/os2emxpath.py
python/branches/bcannon-objcap/Lib/posixpath.py
python/branches/bcannon-objcap/Lib/site.py
python/branches/bcannon-objcap/Lib/tarfile.py
python/branches/bcannon-objcap/Lib/test/output/test_tokenize
python/branches/bcannon-objcap/Lib/test/test_array.py
python/branches/bcannon-objcap/Lib/test/test_compiler.py
python/branches/bcannon-objcap/Lib/test/test_parser.py
python/branches/bcannon-objcap/Lib/test/test_syntax.py
python/branches/bcannon-objcap/Lib/test/test_tarfile.py
python/branches/bcannon-objcap/Lib/test/test_tokenize.py
python/branches/bcannon-objcap/Lib/test/test_unicode.py
python/branches/bcannon-objcap/Lib/test/test_urllib2.py
python/branches/bcannon-objcap/Lib/test/test_uuid.py
python/branches/bcannon-objcap/Lib/test/test_xml_etree_c.py
python/branches/bcannon-objcap/Lib/tokenize.py
python/branches/bcannon-objcap/Lib/urllib2.py
python/branches/bcannon-objcap/Lib/uuid.py
python/branches/bcannon-objcap/Makefile.pre.in
python/branches/bcannon-objcap/Misc/ACKS
python/branches/bcannon-objcap/Misc/NEWS
python/branches/bcannon-objcap/Misc/build.sh
python/branches/bcannon-objcap/Modules/_ctypes/_ctypes.c
python/branches/bcannon-objcap/Modules/_ctypes/_ctypes_test.c
python/branches/bcannon-objcap/Modules/_ctypes/callbacks.c
python/branches/bcannon-objcap/Modules/_ctypes/callproc.c
python/branches/bcannon-objcap/Modules/_ctypes/cfield.c
python/branches/bcannon-objcap/Modules/_ctypes/libffi_msvc/ffi.c
python/branches/bcannon-objcap/Modules/_ctypes/libffi_msvc/ffi.h
python/branches/bcannon-objcap/Modules/_ctypes/libffi_msvc/ffitarget.h
python/branches/bcannon-objcap/Modules/_ctypes/stgdict.c
python/branches/bcannon-objcap/Modules/_elementtree.c
python/branches/bcannon-objcap/Modules/arraymodule.c
python/branches/bcannon-objcap/Modules/mmapmodule.c
python/branches/bcannon-objcap/Modules/parsermodule.c
python/branches/bcannon-objcap/Objects/classobject.c
python/branches/bcannon-objcap/Objects/fileobject.c
python/branches/bcannon-objcap/Objects/listobject.c
python/branches/bcannon-objcap/Objects/unicodeobject.c
python/branches/bcannon-objcap/PC/pyconfig.h
python/branches/bcannon-objcap/PCbuild/_ctypes.vcproj
python/branches/bcannon-objcap/PCbuild/_ssl.mak
python/branches/bcannon-objcap/PCbuild/_ssl.vcproj
python/branches/bcannon-objcap/PCbuild/build_ssl.py
python/branches/bcannon-objcap/PCbuild/pythoncore.vcproj
python/branches/bcannon-objcap/PCbuild/readme.txt
python/branches/bcannon-objcap/Python/compile.c
python/branches/bcannon-objcap/Python/pythonrun.c
python/branches/bcannon-objcap/Python/symtable.c
python/branches/bcannon-objcap/README
python/branches/bcannon-objcap/Tools/buildbot/external.bat
python/branches/bcannon-objcap/Tools/msi/msi.py
python/branches/bcannon-objcap/configure
python/branches/bcannon-objcap/configure.in
Log:
Merged revisions 51301-51633 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
Modified: python/branches/bcannon-objcap/Doc/api/abstract.tex
==============================================================================
--- python/branches/bcannon-objcap/Doc/api/abstract.tex (original)
+++ python/branches/bcannon-objcap/Doc/api/abstract.tex Mon Aug 28 21:49:46 2006
@@ -5,6 +5,10 @@
numerical types, or all sequence types). When used on object types
for which they do not apply, they will raise a Python exception.
+It is not possible to use these functions on objects that are not properly
+initialized, such as a list object that has been created by
+\cfunction{PyList_New()}, but whose items have not been set to some
+non-\code{NULL} value yet.
\section{Object Protocol \label{object}}
Modified: python/branches/bcannon-objcap/Doc/api/concrete.tex
==============================================================================
--- python/branches/bcannon-objcap/Doc/api/concrete.tex (original)
+++ python/branches/bcannon-objcap/Doc/api/concrete.tex Mon Aug 28 21:49:46 2006
@@ -1840,6 +1840,11 @@
\begin{cfuncdesc}{PyObject*}{PyList_New}{Py_ssize_t len}
Return a new list of length \var{len} on success, or \NULL{} on
failure.
+ \note{If \var{length} is greater than zero, the returned list object's
+ items are set to \code{NULL}. Thus you cannot use abstract
+ API functions such as \cfunction{PySequence_SetItem()}
+ or expose the object to Python code before setting all items to a
+ real object with \cfunction{PyList_SetItem()}.}
\end{cfuncdesc}
\begin{cfuncdesc}{Py_ssize_t}{PyList_Size}{PyObject *list}
Modified: python/branches/bcannon-objcap/Doc/api/intro.tex
==============================================================================
--- python/branches/bcannon-objcap/Doc/api/intro.tex (original)
+++ python/branches/bcannon-objcap/Doc/api/intro.tex Mon Aug 28 21:49:46 2006
@@ -225,25 +225,10 @@
\cfunction{PyTuple_SetItem()} for tuples that you are creating
yourself.
-Equivalent code for populating a list can be written using
-\cfunction{PyList_New()} and \cfunction{PyList_SetItem()}. Such code
-can also use \cfunction{PySequence_SetItem()}; this illustrates the
-difference between the two (the extra \cfunction{Py_DECREF()} calls):
+Equivalent code for populating a list can be written using
+\cfunction{PyList_New()} and \cfunction{PyList_SetItem()}.
-\begin{verbatim}
-PyObject *l, *x;
-
-l = PyList_New(3);
-x = PyInt_FromLong(1L);
-PySequence_SetItem(l, 0, x); Py_DECREF(x);
-x = PyInt_FromLong(2L);
-PySequence_SetItem(l, 1, x); Py_DECREF(x);
-x = PyString_FromString("three");
-PySequence_SetItem(l, 2, x); Py_DECREF(x);
-\end{verbatim}
-
-You might find it strange that the ``recommended'' approach takes more
-code. However, in practice, you will rarely use these ways of
+However, in practice, you will rarely use these ways of
creating and populating a tuple or list. There's a generic function,
\cfunction{Py_BuildValue()}, that can create most common objects from
C values, directed by a \dfn{format string}. For example, the
@@ -251,10 +236,10 @@
also takes care of the error checking):
\begin{verbatim}
-PyObject *t, *l;
+PyObject *tuple, *list;
-t = Py_BuildValue("(iis)", 1, 2, "three");
-l = Py_BuildValue("[iis]", 1, 2, "three");
+tuple = Py_BuildValue("(iis)", 1, 2, "three");
+list = Py_BuildValue("[iis]", 1, 2, "three");
\end{verbatim}
It is much more common to use \cfunction{PyObject_SetItem()} and
@@ -276,8 +261,12 @@
if (n < 0)
return -1;
for (i = 0; i < n; i++) {
- if (PyObject_SetItem(target, i, item) < 0)
+ PyObject *index = PyInt_FromLong(i);
+ if (!index)
+ return -1;
+ if (PyObject_SetItem(target, index, item) < 0)
return -1;
+ Py_DECREF(index);
}
return 0;
}
Modified: python/branches/bcannon-objcap/Doc/api/newtypes.tex
==============================================================================
--- python/branches/bcannon-objcap/Doc/api/newtypes.tex (original)
+++ python/branches/bcannon-objcap/Doc/api/newtypes.tex Mon Aug 28 21:49:46 2006
@@ -979,7 +979,7 @@
More information about Python's garbage collection
scheme can be found in section \ref{supporting-cycle-detection}.
- This field is inherited by subtypes together with \member{tp_clear}
+ This field is inherited by subtypes together with \member{tp_traverse}
and the \constant{Py_TPFLAGS_HAVE_GC} flag bit: the flag bit,
\member{tp_traverse}, and \member{tp_clear} are all inherited from
the base type if they are all zero in the subtype \emph{and} the
Modified: python/branches/bcannon-objcap/Doc/commontex/boilerplate.tex
==============================================================================
--- python/branches/bcannon-objcap/Doc/commontex/boilerplate.tex (original)
+++ python/branches/bcannon-objcap/Doc/commontex/boilerplate.tex Mon Aug 28 21:49:46 2006
@@ -5,5 +5,5 @@
Email: \email{docs(a)python.org}
}
-\date{3rd August, 2006} % XXX update before final release!
+\date{\today} % XXX update before final release!
\input{patchlevel} % include Python version information
Modified: python/branches/bcannon-objcap/Doc/lib/libctypes.tex
==============================================================================
--- python/branches/bcannon-objcap/Doc/lib/libctypes.tex (original)
+++ python/branches/bcannon-objcap/Doc/lib/libctypes.tex Mon Aug 28 21:49:46 2006
@@ -199,8 +199,13 @@
There are, however, enough ways to crash Python with \code{ctypes}, so
you should be careful anyway.
-Python integers, strings and unicode strings are the only objects that
-can directly be used as parameters in these function calls.
+\code{None}, integers, longs, byte strings and unicode strings are the
+only native Python objects that can directly be used as parameters in
+these function calls. \code{None} is passed as a C \code{NULL} pointer,
+byte strings and unicode strings are passed as pointer to the memory
+block that contains their data (\code{char *} or \code{wchar{\_}t *}). Python
+integers and Python longs are passed as the platforms default C
+\code{int} type, their value is masked to fit into the C type.
Before we move on calling functions with other parameter types, we
have to learn more about \code{ctypes} data types.
@@ -227,7 +232,18 @@
\code{char}
}
{
-character
+1-character
+string
+}
+\lineiii{
+\class{c{\_}wchar}
+}
+{
+\code{wchar{\_}t}
+}
+{
+1-character
+unicode string
}
\lineiii{
\class{c{\_}byte}
@@ -236,7 +252,7 @@
\code{char}
}
{
-integer
+int/long
}
\lineiii{
\class{c{\_}ubyte}
@@ -245,7 +261,7 @@
\code{unsigned char}
}
{
-integer
+int/long
}
\lineiii{
\class{c{\_}short}
@@ -254,7 +270,7 @@
\code{short}
}
{
-integer
+int/long
}
\lineiii{
\class{c{\_}ushort}
@@ -263,7 +279,7 @@
\code{unsigned short}
}
{
-integer
+int/long
}
\lineiii{
\class{c{\_}int}
@@ -272,7 +288,7 @@
\code{int}
}
{
-integer
+int/long
}
\lineiii{
\class{c{\_}uint}
@@ -281,7 +297,7 @@
\code{unsigned int}
}
{
-integer
+int/long
}
\lineiii{
\class{c{\_}long}
@@ -290,7 +306,7 @@
\code{long}
}
{
-integer
+int/long
}
\lineiii{
\class{c{\_}ulong}
@@ -299,7 +315,7 @@
\code{unsigned long}
}
{
-long
+int/long
}
\lineiii{
\class{c{\_}longlong}
@@ -309,7 +325,7 @@
\code{long long}
}
{
-long
+int/long
}
\lineiii{
\class{c{\_}ulonglong}
@@ -319,7 +335,7 @@
\code{unsigned long long}
}
{
-long
+int/long
}
\lineiii{
\class{c{\_}float}
@@ -368,8 +384,8 @@
\code{void *}
}
{
-integer or
-\code{None}
+int/long
+or \code{None}
}
\end{tableiii}
\end{quote}
@@ -554,11 +570,11 @@
\subsubsection{Return types\label{ctypes-return-types}}
-By default functions are assumed to return integers. Other return
-types can be specified by setting the \member{restype} attribute of the
-function object.
+By default functions are assumed to return the C \code{int} type. Other
+return types can be specified by setting the \member{restype} attribute of
+the function object.
-Here is a more advanced example, it uses the strchr function, which
+Here is a more advanced example, it uses the \code{strchr} function, which
expects a string pointer and a char, and returns a pointer to a
string:
\begin{verbatim}
@@ -1611,8 +1627,8 @@
\begin{datadescni}{pythonapi}
An instance of \class{PyDLL} that exposes Python C api functions as
-attributes. Note that all these functions are assumed to return
-integers, which is of course not always the truth, so you have to
+attributes. Note that all these functions are assumed to return C
+\code{int}, which is of course not always the truth, so you have to
assign the correct \member{restype} attribute to use these functions.
\end{datadescni}
@@ -1642,8 +1658,8 @@
anything.
It is possible to assign a callable Python object that is not a
-ctypes type, in this case the function is assumed to return an
-integer, and the callable will be called with this integer,
+ctypes type, in this case the function is assumed to return a
+C \code{int}, and the callable will be called with this integer,
allowing to do further processing or error checking. Using this
is deprecated, for more flexible postprocessing or error checking
use a ctypes data type as \member{restype} and assign a callable to the
@@ -2283,9 +2299,12 @@
or error information for a function or method call.
\end{classdesc*}
-\begin{classdesc*}{py_object}
-Represents the C \code{PyObject *} datatype.
-\end{classdesc*}
+\code{py{\_}object} : classdesc*
+\begin{quote}
+
+Represents the C \code{PyObject *} datatype. Calling this with an
+without an argument creates a \code{NULL} \code{PyObject *} pointer.
+\end{quote}
The \code{ctypes.wintypes} module provides quite some other Windows
specific data types, for example \code{HWND}, \code{WPARAM}, or \code{DWORD}.
@@ -2324,9 +2343,9 @@
the second item specifies the type of the field; it can be any
ctypes data type.
-For integer type fields, a third optional item can be given. It
-must be a small positive integer defining the bit width of the
-field.
+For integer type fields like \class{c{\_}int}, a third optional item can
+be given. It must be a small positive integer defining the bit
+width of the field.
Field names must be unique within one structure or union. This is
not checked, only one field can be accessed when names are
Modified: python/branches/bcannon-objcap/Doc/lib/libuuid.tex
==============================================================================
--- python/branches/bcannon-objcap/Doc/lib/libuuid.tex (original)
+++ python/branches/bcannon-objcap/Doc/lib/libuuid.tex Mon Aug 28 21:49:46 2006
@@ -18,20 +18,11 @@
network address. \function{uuid4()} creates a random UUID.
\begin{classdesc}{UUID}{\optional{hex\optional{, bytes\optional{,
-fields\optional{, int\optional{, version}}}}}}
-
-%Instances of the UUID class represent UUIDs as specified in RFC 4122.
-%UUID objects are immutable, hashable, and usable as dictionary keys.
-%Converting a UUID to a string with str() yields something in the form
-%'12345678-1234-1234-1234-123456789abc'. The UUID constructor accepts
-%four possible forms: a similar string of hexadecimal digits, or a
-%string of 16 raw bytes as an argument named 'bytes', or a tuple of
-%six integer fields (with 32-bit, 16-bit, 16-bit, 8-bit, 8-bit, and
-%48-bit values respectively) as an argument named 'fields', or a single
-%128-bit integer as an argument named 'int'.
+bytes_le\optional{, fields\optional{, int\optional{, version}}}}}}}
Create a UUID from either a string of 32 hexadecimal digits,
-a string of 16 bytes as the \var{bytes} argument, a tuple of six
+a string of 16 bytes as the \var{bytes} argument, a string of 16 bytes
+in little-endian order as the \var{bytes_le} argument, a tuple of six
integers (32-bit \var{time_low}, 16-bit \var{time_mid},
16-bit \var{time_hi_version},
8-bit \var{clock_seq_hi_variant}, 8-bit \var{clock_seq_low}, 48-bit \var{node})
@@ -45,22 +36,31 @@
UUID('12345678123456781234567812345678')
UUID('urn:uuid:12345678-1234-5678-1234-567812345678')
UUID(bytes='\x12\x34\x56\x78'*4)
+UUID(bytes_le='\x78\x56\x34\x12\x34\x12\x78\x56' +
+ '\x12\x34\x56\x78\x12\x34\x56\x78')
UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678))
UUID(int=0x12345678123456781234567812345678)
\end{verbatim}
-Exactly one of \var{hex}, \var{bytes}, \var{fields}, or \var{int} must
+Exactly one of \var{hex}, \var{bytes}, \var{bytes_le}, \var{fields},
+or \var{int} must
be given. The \var{version} argument is optional; if given, the
resulting UUID will have its variant and version number set according to
RFC 4122, overriding bits in the given \var{hex}, \var{bytes},
-\var{fields}, or \var{int}.
+\var{bytes_le}, \var{fields}, or \var{int}.
\end{classdesc}
\class{UUID} instances have these read-only attributes:
\begin{memberdesc}{bytes}
-The UUID as a 16-byte string.
+The UUID as a 16-byte string (containing the six
+integer fields in big-endian byte order).
+\end{memberdesc}
+
+\begin{memberdesc}{bytes_le}
+The UUID as a 16-byte string (with \var{time_low}, \var{time_mid},
+and \var{time_hi_version} in little-endian byte order).
\end{memberdesc}
\begin{memberdesc}{fields}
Modified: python/branches/bcannon-objcap/Doc/whatsnew/whatsnew25.tex
==============================================================================
--- python/branches/bcannon-objcap/Doc/whatsnew/whatsnew25.tex (original)
+++ python/branches/bcannon-objcap/Doc/whatsnew/whatsnew25.tex Mon Aug 28 21:49:46 2006
@@ -5,7 +5,7 @@
% Fix XXX comments
\title{What's New in Python 2.5}
-\release{0.9}
+\release{1.0}
\author{A.M. Kuchling}
\authoraddress{\email{amk(a)amk.ca}}
@@ -40,15 +40,14 @@
As well as the language and library additions, other improvements and
bugfixes were made throughout the source tree. A search through the
-SVN change logs finds there were 334 patches applied and 443 bugs
+SVN change logs finds there were 353 patches applied and 458 bugs
fixed between Python 2.4 and 2.5. (Both figures are likely to be
underestimates.)
This article doesn't try to be a complete specification of the new
features; instead changes are briefly introduced using helpful
examples. For full details, you should always refer to the
-documentation for Python 2.5.
-% XXX add hyperlink when the documentation becomes available online.
+documentation for Python 2.5 at \url{http://docs.python.org}.
If you want to understand the complete implementation and design
rationale, refer to the PEP for a particular new feature.
@@ -751,7 +750,6 @@
database, or rolled back, meaning that the changes are all discarded
and the database is unchanged. See any database textbook for more
information.)
-% XXX find a shorter reference?
Let's assume there's an object representing a database connection.
Our goal will be to let the user write code like this:
@@ -1184,6 +1182,35 @@
# -*- coding: latin1 -*-
\end{verbatim}
+\item A new warning, \class{UnicodeWarning}, is triggered when
+you attempt to compare a Unicode string and an 8-bit string
+that can't be converted to Unicode using the default ASCII encoding.
+The result of the comparison is false:
+
+\begin{verbatim}
+>>> chr(128) == unichr(128) # Can't convert chr(128) to Unicode
+__main__:1: UnicodeWarning: Unicode equal comparison failed
+ to convert both arguments to Unicode - interpreting them
+ as being unequal
+False
+>>> chr(127) == unichr(127) # chr(127) can be converted
+True
+\end{verbatim}
+
+Previously this would raise a \class{UnicodeDecodeError} exception,
+but in 2.5 this could result in puzzling problems when accessing a
+dictionary. If you looked up \code{unichr(128)} and \code{chr(128)}
+was being used as a key, you'd get a \class{UnicodeDecodeError}
+exception. Other changes in 2.5 resulted in this exception being
+raised instead of suppressed by the code in \file{dictobject.c} that
+implements dictionaries.
+
+Raising an exception for such a comparison is strictly correct, but
+the change might have broken code, so instead
+\class{UnicodeWarning} was introduced.
+
+(Implemented by Marc-Andr\'e Lemburg.)
+
\item One error that Python programmers sometimes make is forgetting
to include an \file{__init__.py} module in a package directory.
Debugging this mistake can be confusing, and usually requires running
@@ -1305,9 +1332,6 @@
\end{itemize}
-The net result of the 2.5 optimizations is that Python 2.5 runs the
-pystone benchmark around XXX\% faster than Python 2.4.
-
%======================================================================
\section{New, Improved, and Removed Modules\label{modules}}
@@ -2423,6 +2447,11 @@
described in section~\ref{pep-342}, it's now possible
for \member{gi_frame} to be \code{None}.
+\item A new warning, \class{UnicodeWarning}, is triggered when
+you attempt to compare a Unicode string and an 8-bit string that can't
+be converted to Unicode using the default ASCII encoding. Previously
+such comparisons would raise a \class{UnicodeDecodeError} exception.
+
\item Library: the \module{csv} module is now stricter about multi-line quoted
fields. If your files contain newlines embedded within fields, the
input should be split into lines in a manner which preserves the
Modified: python/branches/bcannon-objcap/Include/code.h
==============================================================================
--- python/branches/bcannon-objcap/Include/code.h (original)
+++ python/branches/bcannon-objcap/Include/code.h Mon Aug 28 21:49:46 2006
@@ -88,6 +88,9 @@
PyAPI_FUNC(int) PyCode_CheckLineNumber(PyCodeObject* co,
int lasti, PyAddrPair *bounds);
+PyAPI_FUNC(PyObject*) PyCode_Optimize(PyObject *code, PyObject* consts,
+ PyObject *names, PyObject *lineno_obj);
+
#ifdef __cplusplus
}
#endif
Modified: python/branches/bcannon-objcap/Include/import.h
==============================================================================
--- python/branches/bcannon-objcap/Include/import.h (original)
+++ python/branches/bcannon-objcap/Include/import.h Mon Aug 28 21:49:46 2006
@@ -22,7 +22,7 @@
PyAPI_FUNC(PyObject *) PyImport_ImportModuleEx(
char *name, PyObject *globals, PyObject *locals, PyObject *fromlist);
#define PyImport_ImportModuleEx(n, g, l, f) \
- PyImport_ImportModuleLevel(n, g, l, f, -1);
+ PyImport_ImportModuleLevel(n, g, l, f, -1)
PyAPI_FUNC(PyObject *) PyImport_Import(PyObject *name);
PyAPI_FUNC(PyObject *) PyImport_ReloadModule(PyObject *m);
Modified: python/branches/bcannon-objcap/Include/patchlevel.h
==============================================================================
--- python/branches/bcannon-objcap/Include/patchlevel.h (original)
+++ python/branches/bcannon-objcap/Include/patchlevel.h Mon Aug 28 21:49:46 2006
@@ -20,13 +20,13 @@
/* Version parsed out into numeric values */
#define PY_MAJOR_VERSION 2
-#define PY_MINOR_VERSION 5
+#define PY_MINOR_VERSION 6
#define PY_MICRO_VERSION 0
-#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_BETA
-#define PY_RELEASE_SERIAL 3
+#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA
+#define PY_RELEASE_SERIAL 0
/* Version as a string */
-#define PY_VERSION "2.5b3"
+#define PY_VERSION "2.6a0"
/* Subversion Revision number of this file (not of the repository) */
#define PY_PATCHLEVEL_REVISION "$Revision$"
Modified: python/branches/bcannon-objcap/Lib/compiler/ast.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/compiler/ast.py (original)
+++ python/branches/bcannon-objcap/Lib/compiler/ast.py Mon Aug 28 21:49:46 2006
@@ -583,11 +583,9 @@
def __init__(self, code, lineno=None):
self.code = code
self.lineno = lineno
- self.argnames = ['[outmost-iterable]']
+ self.argnames = ['.0']
self.varargs = self.kwargs = None
-
-
def getChildren(self):
return self.code,
Modified: python/branches/bcannon-objcap/Lib/compiler/pycodegen.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/compiler/pycodegen.py (original)
+++ python/branches/bcannon-objcap/Lib/compiler/pycodegen.py Mon Aug 28 21:49:46 2006
@@ -658,18 +658,19 @@
stack = []
for i, for_ in zip(range(len(node.quals)), node.quals):
- start, anchor = self.visit(for_)
+ start, anchor, end = self.visit(for_)
cont = None
for if_ in for_.ifs:
if cont is None:
cont = self.newBlock()
self.visit(if_, cont)
- stack.insert(0, (start, cont, anchor))
+ stack.insert(0, (start, cont, anchor, end))
self.visit(node.expr)
self.emit('YIELD_VALUE')
+ self.emit('POP_TOP')
- for start, cont, anchor in stack:
+ for start, cont, anchor, end in stack:
if cont:
skip_one = self.newBlock()
self.emit('JUMP_FORWARD', skip_one)
@@ -678,14 +679,22 @@
self.nextBlock(skip_one)
self.emit('JUMP_ABSOLUTE', start)
self.startBlock(anchor)
+ self.emit('POP_BLOCK')
+ self.setups.pop()
+ self.startBlock(end)
+
self.emit('LOAD_CONST', None)
def visitGenExprFor(self, node):
start = self.newBlock()
anchor = self.newBlock()
+ end = self.newBlock()
+
+ self.setups.push((LOOP, start))
+ self.emit('SETUP_LOOP', end)
if node.is_outmost:
- self.loadName('[outmost-iterable]')
+ self.loadName('.0')
else:
self.visit(node.iter)
self.emit('GET_ITER')
@@ -695,7 +704,7 @@
self.emit('FOR_ITER', anchor)
self.nextBlock()
self.visit(node.assign)
- return start, anchor
+ return start, anchor, end
def visitGenExprIf(self, node, branch):
self.set_lineno(node, force=True)
Modified: python/branches/bcannon-objcap/Lib/compiler/symbols.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/compiler/symbols.py (original)
+++ python/branches/bcannon-objcap/Lib/compiler/symbols.py Mon Aug 28 21:49:46 2006
@@ -188,7 +188,7 @@
i = self.__counter
self.__counter += 1
self.__super_init("generator expression<%d>"%i, module, klass)
- self.add_param('[outmost-iterable]')
+ self.add_param('.0')
def get_names(self):
keys = Scope.get_names(self)
Modified: python/branches/bcannon-objcap/Lib/ctypes/__init__.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/ctypes/__init__.py (original)
+++ python/branches/bcannon-objcap/Lib/ctypes/__init__.py Mon Aug 28 21:49:46 2006
@@ -135,6 +135,11 @@
class py_object(_SimpleCData):
_type_ = "O"
+ def __repr__(self):
+ try:
+ return super(py_object, self).__repr__()
+ except ValueError:
+ return "%s(<NULL>)" % type(self).__name__
class c_short(_SimpleCData):
_type_ = "h"
@@ -422,6 +427,8 @@
c_size_t = c_uint
elif sizeof(c_ulong) == sizeof(c_void_p):
c_size_t = c_ulong
+elif sizeof(c_ulonglong) == sizeof(c_void_p):
+ c_size_t = c_ulonglong
# functions
Modified: python/branches/bcannon-objcap/Lib/ctypes/test/test_as_parameter.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/ctypes/test/test_as_parameter.py (original)
+++ python/branches/bcannon-objcap/Lib/ctypes/test/test_as_parameter.py Mon Aug 28 21:49:46 2006
@@ -61,6 +61,7 @@
def callback(v):
args.append(v)
+ return v
CallBack = CFUNCTYPE(c_int, c_int)
Modified: python/branches/bcannon-objcap/Lib/ctypes/test/test_functions.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/ctypes/test/test_functions.py (original)
+++ python/branches/bcannon-objcap/Lib/ctypes/test/test_functions.py Mon Aug 28 21:49:46 2006
@@ -222,6 +222,7 @@
def callback(v):
args.append(v)
+ return v
CallBack = CFUNCTYPE(c_int, c_int)
Modified: python/branches/bcannon-objcap/Lib/ctypes/test/test_python_api.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/ctypes/test/test_python_api.py (original)
+++ python/branches/bcannon-objcap/Lib/ctypes/test/test_python_api.py Mon Aug 28 21:49:46 2006
@@ -78,5 +78,10 @@
# not enough arguments
self.failUnlessRaises(TypeError, PyOS_snprintf, buf)
+ def test_pyobject_repr(self):
+ self.failUnlessEqual(repr(py_object()), "py_object(<NULL>)")
+ self.failUnlessEqual(repr(py_object(42)), "py_object(42)")
+ self.failUnlessEqual(repr(py_object(object)), "py_object(%r)" % object)
+
if __name__ == "__main__":
unittest.main()
Modified: python/branches/bcannon-objcap/Lib/ctypes/test/test_win32.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/ctypes/test/test_win32.py (original)
+++ python/branches/bcannon-objcap/Lib/ctypes/test/test_win32.py Mon Aug 28 21:49:46 2006
@@ -6,7 +6,8 @@
import _ctypes_test
-if sys.platform == "win32":
+if sys.platform == "win32" and sizeof(c_void_p) == sizeof(c_int):
+ # Only windows 32-bit has different calling conventions.
class WindowsTestCase(unittest.TestCase):
def test_callconv_1(self):
Modified: python/branches/bcannon-objcap/Lib/distutils/__init__.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/distutils/__init__.py (original)
+++ python/branches/bcannon-objcap/Lib/distutils/__init__.py Mon Aug 28 21:49:46 2006
@@ -12,6 +12,12 @@
__revision__ = "$Id$"
-import sys
-__version__ = "%d.%d.%d" % sys.version_info[:3]
-del sys
+# Distutils version
+#
+# Please coordinate with Marc-Andre Lemburg <mal(a)egenix.com> when adding
+# new features to distutils that would warrant bumping the version number.
+#
+# In general, major and minor version should loosely follow the Python
+# version number the distutils code was shipped with.
+#
+__version__ = "2.5.0"
Modified: python/branches/bcannon-objcap/Lib/encodings/__init__.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/encodings/__init__.py (original)
+++ python/branches/bcannon-objcap/Lib/encodings/__init__.py Mon Aug 28 21:49:46 2006
@@ -28,7 +28,7 @@
"""#"
-import codecs, types
+import codecs
from encodings import aliases
_cache = {}
@@ -60,7 +60,7 @@
"""
# Make sure we have an 8-bit string, because .translate() works
# differently for Unicode strings.
- if type(encoding) is types.UnicodeType:
+ if isinstance(encoding, unicode):
# Note that .encode('latin-1') does *not* use the codec
# registry, so this call doesn't recurse. (See unicodeobject.c
# PyUnicode_AsEncodedString() for details)
Modified: python/branches/bcannon-objcap/Lib/idlelib/Bindings.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/idlelib/Bindings.py (original)
+++ python/branches/bcannon-objcap/Lib/idlelib/Bindings.py Mon Aug 28 21:49:46 2006
@@ -22,9 +22,9 @@
None,
('_Save', '<<save-window>>'),
('Save _As...', '<<save-window-as-file>>'),
- ('Save Co_py As...', '<<save-copy-of-window-as-file>>'),
+ ('Save Cop_y As...', '<<save-copy-of-window-as-file>>'),
None,
- ('_Print Window', '<<print-window>>'),
+ ('Prin_t Window', '<<print-window>>'),
None,
('_Close', '<<close-window>>'),
('E_xit', '<<close-all-windows>>'),
Modified: python/branches/bcannon-objcap/Lib/idlelib/CREDITS.txt
==============================================================================
--- python/branches/bcannon-objcap/Lib/idlelib/CREDITS.txt (original)
+++ python/branches/bcannon-objcap/Lib/idlelib/CREDITS.txt Mon Aug 28 21:49:46 2006
@@ -24,8 +24,8 @@
integration, debugger integration and persistent breakpoints).
Scott David Daniels, Tal Einat, Hernan Foffani, Christos Georgiou,
-Martin v. L�wis, Jason Orendorff, Josh Robb, Nigel Rowe, Bruce Sherwood,
-and Jeff Shute have submitted useful patches. Thanks, guys!
+Jim Jewett, Martin v. L�wis, Jason Orendorff, Josh Robb, Nigel Rowe,
+Bruce Sherwood, and Jeff Shute have submitted useful patches. Thanks, guys!
For additional details refer to NEWS.txt and Changelog.
Modified: python/branches/bcannon-objcap/Lib/idlelib/CodeContext.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/idlelib/CodeContext.py (original)
+++ python/branches/bcannon-objcap/Lib/idlelib/CodeContext.py Mon Aug 28 21:49:46 2006
@@ -15,7 +15,7 @@
from sys import maxint as INFINITY
BLOCKOPENERS = set(["class", "def", "elif", "else", "except", "finally", "for",
- "if", "try", "while"])
+ "if", "try", "while", "with"])
UPDATEINTERVAL = 100 # millisec
FONTUPDATEINTERVAL = 1000 # millisec
Modified: python/branches/bcannon-objcap/Lib/idlelib/NEWS.txt
==============================================================================
--- python/branches/bcannon-objcap/Lib/idlelib/NEWS.txt (original)
+++ python/branches/bcannon-objcap/Lib/idlelib/NEWS.txt Mon Aug 28 21:49:46 2006
@@ -1,7 +1,26 @@
+What's New in IDLE 2.6a1?
+=========================
+
+*Release date: XX-XXX-200X*
+
+- IDLE's version number takes a big jump to match the version number of
+ the Python release of which it's a part.
+
+
What's New in IDLE 1.2c1?
=========================
-*Release date: XX-AUG-2006*
+*Release date: 17-AUG-2006*
+
+- File menu hotkeys: there were three 'p' assignments. Reassign the
+ 'Save Copy As' and 'Print' hotkeys to 'y' and 't'. Change the
+ Shell hotkey from 's' to 'l'.
+
+- IDLE honors new quit() and exit() commands from site.py Quitter() object.
+ Patch 1540892, Jim Jewett
+
+- The 'with' statement is now a Code Context block opener.
+ Patch 1540851, Jim Jewett
- Retrieval of previous shell command was not always preserving indentation
(since 1.2a1) Patch 1528468 Tal Einat.
Modified: python/branches/bcannon-objcap/Lib/idlelib/PyShell.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/idlelib/PyShell.py (original)
+++ python/branches/bcannon-objcap/Lib/idlelib/PyShell.py Mon Aug 28 21:49:46 2006
@@ -478,9 +478,6 @@
import sys as _sys
_sys.path = %r
del _sys
- _msg = 'Use File/Exit or your end-of-file key to quit IDLE'
- __builtins__.quit = __builtins__.exit = _msg
- del _msg
\n""" % (sys.path,))
active_seq = None
@@ -514,7 +511,10 @@
print >>sys.__stderr__, errmsg, what
print >>console, errmsg, what
# we received a response to the currently active seq number:
- self.tkconsole.endexecuting()
+ try:
+ self.tkconsole.endexecuting()
+ except AttributeError: # shell may have closed
+ pass
# Reschedule myself
if not self.tkconsole.closing:
self.tkconsole.text.after(self.tkconsole.pollinterval,
@@ -713,14 +713,17 @@
else:
exec code in self.locals
except SystemExit:
- if tkMessageBox.askyesno(
- "Exit?",
- "Do you want to exit altogether?",
- default="yes",
- master=self.tkconsole.text):
- raise
+ if not self.tkconsole.closing:
+ if tkMessageBox.askyesno(
+ "Exit?",
+ "Do you want to exit altogether?",
+ default="yes",
+ master=self.tkconsole.text):
+ raise
+ else:
+ self.showtraceback()
else:
- self.showtraceback()
+ raise
except:
if use_subprocess:
print >> self.tkconsole.stderr, \
@@ -730,7 +733,10 @@
self.tkconsole.endexecuting()
finally:
if not use_subprocess:
- self.tkconsole.endexecuting()
+ try:
+ self.tkconsole.endexecuting()
+ except AttributeError: # shell may have closed
+ pass
def write(self, s):
"Override base class method"
@@ -794,7 +800,7 @@
if use_subprocess:
ms = self.menu_specs
if ms[2][0] != "shell":
- ms.insert(2, ("shell", "_Shell"))
+ ms.insert(2, ("shell", "She_ll"))
self.interp = ModifiedInterpreter(self)
if flist is None:
root = Tk()
@@ -804,9 +810,6 @@
#
OutputWindow.__init__(self, flist, None, None)
#
- import __builtin__
- __builtin__.quit = __builtin__.exit = "To exit, type Ctrl-D."
- #
## self.config(usetabs=1, indentwidth=8, context_use_ps1=1)
self.usetabs = True
# indentwidth must be 8 when using tabs. See note in EditorWindow:
Modified: python/branches/bcannon-objcap/Lib/idlelib/idlever.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/idlelib/idlever.py (original)
+++ python/branches/bcannon-objcap/Lib/idlelib/idlever.py Mon Aug 28 21:49:46 2006
@@ -1 +1 @@
-IDLE_VERSION = "1.2b3"
+IDLE_VERSION = "2.6a0"
Modified: python/branches/bcannon-objcap/Lib/macpath.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/macpath.py (original)
+++ python/branches/bcannon-objcap/Lib/macpath.py Mon Aug 28 21:49:46 2006
@@ -2,6 +2,7 @@
import os
from stat import *
+from genericpath import *
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
"basename","dirname","commonprefix","getsize","getmtime",
@@ -101,31 +102,6 @@
components = split(s)
return len(components) == 2 and components[1] == ''
-def isdir(s):
- """Return true if the pathname refers to an existing directory."""
-
- try:
- st = os.stat(s)
- except os.error:
- return 0
- return S_ISDIR(st.st_mode)
-
-
-# Get size, mtime, atime of files.
-
-def getsize(filename):
- """Return the size of a file, reported by os.stat()."""
- return os.stat(filename).st_size
-
-def getmtime(filename):
- """Return the last modification time of a file, reported by os.stat()."""
- return os.stat(filename).st_mtime
-
-def getatime(filename):
- """Return the last access time of a file, reported by os.stat()."""
- return os.stat(filename).st_atime
-
-
def islink(s):
"""Return true if the pathname refers to a symbolic link."""
@@ -135,29 +111,6 @@
except:
return False
-
-def isfile(s):
- """Return true if the pathname refers to an existing regular file."""
-
- try:
- st = os.stat(s)
- except os.error:
- return False
- return S_ISREG(st.st_mode)
-
-def getctime(filename):
- """Return the creation time of a file, reported by os.stat()."""
- return os.stat(filename).st_ctime
-
-def exists(s):
- """Test whether a path exists. Returns False for broken symbolic links"""
-
- try:
- st = os.stat(s)
- except os.error:
- return False
- return True
-
# Is `stat`/`lstat` a meaningful difference on the Mac? This is safe in any
# case.
@@ -170,20 +123,6 @@
return False
return True
-# Return the longest prefix of all list elements.
-
-def commonprefix(m):
- "Given a list of pathnames, returns the longest common leading component"
- if not m: return ''
- s1 = min(m)
- s2 = max(m)
- n = min(len(s1), len(s2))
- for i in xrange(n):
- if s1[i] != s2[i]:
- return s1[:i]
- return s1[:n]
-
-
def expandvars(path):
"""Dummy to retain interface-compatibility with other operating systems."""
return path
Modified: python/branches/bcannon-objcap/Lib/ntpath.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/ntpath.py (original)
+++ python/branches/bcannon-objcap/Lib/ntpath.py Mon Aug 28 21:49:46 2006
@@ -8,6 +8,7 @@
import os
import stat
import sys
+from genericpath import *
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
"basename","dirname","commonprefix","getsize","getmtime",
@@ -206,86 +207,18 @@
"""Returns the directory component of a pathname"""
return split(p)[0]
-
-# Return the longest prefix of all list elements.
-
-def commonprefix(m):
- "Given a list of pathnames, returns the longest common leading component"
- if not m: return ''
- s1 = min(m)
- s2 = max(m)
- n = min(len(s1), len(s2))
- for i in xrange(n):
- if s1[i] != s2[i]:
- return s1[:i]
- return s1[:n]
-
-
-# Get size, mtime, atime of files.
-
-def getsize(filename):
- """Return the size of a file, reported by os.stat()"""
- return os.stat(filename).st_size
-
-def getmtime(filename):
- """Return the last modification time of a file, reported by os.stat()"""
- return os.stat(filename).st_mtime
-
-def getatime(filename):
- """Return the last access time of a file, reported by os.stat()"""
- return os.stat(filename).st_atime
-
-def getctime(filename):
- """Return the creation time of a file, reported by os.stat()."""
- return os.stat(filename).st_ctime
-
# Is a path a symbolic link?
# This will always return false on systems where posix.lstat doesn't exist.
def islink(path):
- """Test for symbolic link. On WindowsNT/95 always returns false"""
+ """Test for symbolic link.
+ On WindowsNT/95 and OS/2 always returns false
+ """
return False
-
-# Does a path exist?
-
-def exists(path):
- """Test whether a path exists"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return True
-
+# alias exists to lexists
lexists = exists
-
-# Is a path a dos directory?
-# This follows symbolic links, so both islink() and isdir() can be true
-# for the same path.
-
-def isdir(path):
- """Test whether a path is a directory"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return stat.S_ISDIR(st.st_mode)
-
-
-# Is a path a regular file?
-# This follows symbolic links, so both islink() and isdir() can be true
-# for the same path.
-
-def isfile(path):
- """Test whether a path is a regular file"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return stat.S_ISREG(st.st_mode)
-
-
# Is a path a mount point? Either a root (with or without drive letter)
# or an UNC path with at most a / or \ after the mount point.
Modified: python/branches/bcannon-objcap/Lib/os2emxpath.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/os2emxpath.py (original)
+++ python/branches/bcannon-objcap/Lib/os2emxpath.py Mon Aug 28 21:49:46 2006
@@ -7,6 +7,9 @@
import os
import stat
+from genericpath import *
+from ntpath import (expanduser, expandvars, isabs, islink, splitdrive,
+ splitext, split, walk)
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
"basename","dirname","commonprefix","getsize","getmtime",
@@ -36,18 +39,6 @@
return s.replace('\\', '/').lower()
-# Return whether a path is absolute.
-# Trivial in Posix, harder on the Mac or MS-DOS.
-# For DOS it is absolute if it starts with a slash or backslash (current
-# volume), or if a pathname after the volume letter and colon / UNC resource
-# starts with a slash or backslash.
-
-def isabs(s):
- """Test whether a path is absolute"""
- s = splitdrive(s)[1]
- return s != '' and s[:1] in '/\\'
-
-
# Join two (or more) paths.
def join(a, *p):
@@ -63,17 +54,6 @@
return path
-# Split a path in a drive specification (a drive letter followed by a
-# colon) and the path specification.
-# It is always true that drivespec + pathspec == p
-def splitdrive(p):
- """Split a pathname into drive and path specifiers. Returns a 2-tuple
-"(drive,path)"; either part may be empty"""
- if p[1:2] == ':':
- return p[0:2], p[2:]
- return '', p
-
-
# Parse UNC paths
def splitunc(p):
"""Split a pathname into UNC mount point and relative path specifiers.
@@ -103,57 +83,6 @@
return '', p
-# Split a path in head (everything up to the last '/') and tail (the
-# rest). After the trailing '/' is stripped, the invariant
-# join(head, tail) == p holds.
-# The resulting head won't end in '/' unless it is the root.
-
-def split(p):
- """Split a pathname.
-
- Return tuple (head, tail) where tail is everything after the final slash.
- Either part may be empty."""
-
- d, p = splitdrive(p)
- # set i to index beyond p's last slash
- i = len(p)
- while i and p[i-1] not in '/\\':
- i = i - 1
- head, tail = p[:i], p[i:] # now tail has no slashes
- # remove trailing slashes from head, unless it's all slashes
- head2 = head
- while head2 and head2[-1] in '/\\':
- head2 = head2[:-1]
- head = head2 or head
- return d + head, tail
-
-
-# Split a path in root and extension.
-# The extension is everything starting at the last dot in the last
-# pathname component; the root is everything before that.
-# It is always true that root + ext == p.
-
-def splitext(p):
- """Split the extension from a pathname.
-
- Extension is everything from the last dot to the end.
- Return (root, ext), either part may be empty."""
- root, ext = '', ''
- for c in p:
- if c in ['/','\\']:
- root, ext = root + ext + c, ''
- elif c == '.':
- if ext:
- root, ext = root + ext, c
- else:
- ext = c
- elif ext:
- ext = ext + c
- else:
- root = root + c
- return root, ext
-
-
# Return the tail (basename) part of a path.
def basename(p):
@@ -168,84 +97,12 @@
return split(p)[0]
-# Return the longest prefix of all list elements.
-
-def commonprefix(m):
- "Given a list of pathnames, returns the longest common leading component"
- if not m: return ''
- s1 = min(m)
- s2 = max(m)
- n = min(len(s1), len(s2))
- for i in xrange(n):
- if s1[i] != s2[i]:
- return s1[:i]
- return s1[:n]
-
-
-# Get size, mtime, atime of files.
-
-def getsize(filename):
- """Return the size of a file, reported by os.stat()"""
- return os.stat(filename).st_size
-
-def getmtime(filename):
- """Return the last modification time of a file, reported by os.stat()"""
- return os.stat(filename).st_mtime
-
-def getatime(filename):
- """Return the last access time of a file, reported by os.stat()"""
- return os.stat(filename).st_atime
-
-def getctime(filename):
- """Return the creation time of a file, reported by os.stat()."""
- return os.stat(filename).st_ctime
-
-# Is a path a symbolic link?
-# This will always return false on systems where posix.lstat doesn't exist.
-
-def islink(path):
- """Test for symbolic link. On OS/2 always returns false"""
- return False
-
-
-# Does a path exist?
-# This is false for dangling symbolic links.
-
-def exists(path):
- """Test whether a path exists"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return True
-
+# alias exists to lexists
lexists = exists
# Is a path a directory?
-def isdir(path):
- """Test whether a path is a directory"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return stat.S_ISDIR(st.st_mode)
-
-
-# Is a path a regular file?
-# This follows symbolic links, so both islink() and isdir() can be true
-# for the same path.
-
-def isfile(path):
- """Test whether a path is a regular file"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return stat.S_ISREG(st.st_mode)
-
-
# Is a path a mount point? Either a root (with or without drive letter)
# or an UNC path with at most a / or \ after the mount point.
@@ -258,131 +115,6 @@
return len(p) == 1 and p[0] in '/\\'
-# Directory tree walk.
-# For each directory under top (including top itself, but excluding
-# '.' and '..'), func(arg, dirname, filenames) is called, where
-# dirname is the name of the directory and filenames is the list
-# of files (and subdirectories etc.) in the directory.
-# The func may modify the filenames list, to implement a filter,
-# or to impose a different order of visiting.
-
-def walk(top, func, arg):
- """Directory tree walk whth callback function.
-
- walk(top, func, arg) calls func(arg, d, files) for each directory d
- in the tree rooted at top (including top itself); files is a list
- of all the files and subdirs in directory d."""
- try:
- names = os.listdir(top)
- except os.error:
- return
- func(arg, top, names)
- exceptions = ('.', '..')
- for name in names:
- if name not in exceptions:
- name = join(top, name)
- if isdir(name):
- walk(name, func, arg)
-
-
-# Expand paths beginning with '~' or '~user'.
-# '~' means $HOME; '~user' means that user's home directory.
-# If the path doesn't begin with '~', or if the user or $HOME is unknown,
-# the path is returned unchanged (leaving error reporting to whatever
-# function is called with the expanded path as argument).
-# See also module 'glob' for expansion of *, ? and [...] in pathnames.
-# (A function should also be defined to do full *sh-style environment
-# variable expansion.)
-
-def expanduser(path):
- """Expand ~ and ~user constructs.
-
- If user or $HOME is unknown, do nothing."""
- if path[:1] != '~':
- return path
- i, n = 1, len(path)
- while i < n and path[i] not in '/\\':
- i = i + 1
- if i == 1:
- if 'HOME' in os.environ:
- userhome = os.environ['HOME']
- elif not 'HOMEPATH' in os.environ:
- return path
- else:
- try:
- drive = os.environ['HOMEDRIVE']
- except KeyError:
- drive = ''
- userhome = join(drive, os.environ['HOMEPATH'])
- else:
- return path
- return userhome + path[i:]
-
-
-# Expand paths containing shell variable substitutions.
-# The following rules apply:
-# - no expansion within single quotes
-# - no escape character, except for '$$' which is translated into '$'
-# - ${varname} is accepted.
-# - varnames can be made out of letters, digits and the character '_'
-# XXX With COMMAND.COM you can use any characters in a variable name,
-# XXX except '^|<>='.
-
-def expandvars(path):
- """Expand shell variables of form $var and ${var}.
-
- Unknown variables are left unchanged."""
- if '$' not in path:
- return path
- import string
- varchars = string.letters + string.digits + '_-'
- res = ''
- index = 0
- pathlen = len(path)
- while index < pathlen:
- c = path[index]
- if c == '\'': # no expansion within single quotes
- path = path[index + 1:]
- pathlen = len(path)
- try:
- index = path.index('\'')
- res = res + '\'' + path[:index + 1]
- except ValueError:
- res = res + path
- index = pathlen - 1
- elif c == '$': # variable or '$$'
- if path[index + 1:index + 2] == '$':
- res = res + c
- index = index + 1
- elif path[index + 1:index + 2] == '{':
- path = path[index+2:]
- pathlen = len(path)
- try:
- index = path.index('}')
- var = path[:index]
- if var in os.environ:
- res = res + os.environ[var]
- except ValueError:
- res = res + path
- index = pathlen - 1
- else:
- var = ''
- index = index + 1
- c = path[index:index + 1]
- while c != '' and c in varchars:
- var = var + c
- index = index + 1
- c = path[index:index + 1]
- if var in os.environ:
- res = res + os.environ[var]
- if c != '':
- res = res + c
- else:
- res = res + c
- index = index + 1
- return res
-
-
# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B.
def normpath(path):
Modified: python/branches/bcannon-objcap/Lib/posixpath.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/posixpath.py (original)
+++ python/branches/bcannon-objcap/Lib/posixpath.py Mon Aug 28 21:49:46 2006
@@ -12,6 +12,7 @@
import os
import stat
+from genericpath import *
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
"basename","dirname","commonprefix","getsize","getmtime",
@@ -119,37 +120,6 @@
return split(p)[0]
-# Return the longest prefix of all list elements.
-
-def commonprefix(m):
- "Given a list of pathnames, returns the longest common leading component"
- if not m: return ''
- s1 = min(m)
- s2 = max(m)
- n = min(len(s1), len(s2))
- for i in xrange(n):
- if s1[i] != s2[i]:
- return s1[:i]
- return s1[:n]
-
-# Get size, mtime, atime of files.
-
-def getsize(filename):
- """Return the size of a file, reported by os.stat()."""
- return os.stat(filename).st_size
-
-def getmtime(filename):
- """Return the last modification time of a file, reported by os.stat()."""
- return os.stat(filename).st_mtime
-
-def getatime(filename):
- """Return the last access time of a file, reported by os.stat()."""
- return os.stat(filename).st_atime
-
-def getctime(filename):
- """Return the metadata change time of a file, reported by os.stat()."""
- return os.stat(filename).st_ctime
-
# Is a path a symbolic link?
# This will always return false on systems where os.lstat doesn't exist.
@@ -161,19 +131,6 @@
return False
return stat.S_ISLNK(st.st_mode)
-
-# Does a path exist?
-# This is false for dangling symbolic links.
-
-def exists(path):
- """Test whether a path exists. Returns False for broken symbolic links"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return True
-
-
# Being true for dangling symbolic links is also useful.
def lexists(path):
@@ -185,32 +142,6 @@
return True
-# Is a path a directory?
-# This follows symbolic links, so both islink() and isdir() can be true
-# for the same path.
-
-def isdir(path):
- """Test whether a path is a directory"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return stat.S_ISDIR(st.st_mode)
-
-
-# Is a path a regular file?
-# This follows symbolic links, so both islink() and isfile() can be true
-# for the same path.
-
-def isfile(path):
- """Test whether a path is a regular file"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return stat.S_ISREG(st.st_mode)
-
-
# Are two filenames really pointing to the same file?
def samefile(f1, f2):
Modified: python/branches/bcannon-objcap/Lib/site.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/site.py (original)
+++ python/branches/bcannon-objcap/Lib/site.py Mon Aug 28 21:49:46 2006
@@ -242,6 +242,12 @@
def __repr__(self):
return 'Use %s() or %s to exit' % (self.name, eof)
def __call__(self, code=None):
+ # Shells like IDLE catch the SystemExit, but listen when their
+ # stdin wrapper is closed.
+ try:
+ sys.stdin.close()
+ except:
+ pass
raise SystemExit(code)
__builtin__.quit = Quitter('quit')
__builtin__.exit = Quitter('exit')
Modified: python/branches/bcannon-objcap/Lib/tarfile.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/tarfile.py (original)
+++ python/branches/bcannon-objcap/Lib/tarfile.py Mon Aug 28 21:49:46 2006
@@ -411,9 +411,6 @@
self.buf += self.cmp.flush()
if self.mode == "w" and self.buf:
- blocks, remainder = divmod(len(self.buf), self.bufsize)
- if remainder > 0:
- self.buf += NUL * (self.bufsize - remainder)
self.fileobj.write(self.buf)
self.buf = ""
if self.comptype == "gz":
Modified: python/branches/bcannon-objcap/Lib/test/output/test_tokenize
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/output/test_tokenize (original)
+++ python/branches/bcannon-objcap/Lib/test/output/test_tokenize Mon Aug 28 21:49:46 2006
@@ -1,15 +1,23 @@
test_tokenize
-1,0-1,35: COMMENT "# Tests for the 'tokenize' module.\n"
-2,0-2,43: COMMENT '# Large bits stolen from test_grammar.py. \n'
+1,0-1,34: COMMENT "# Tests for the 'tokenize' module."
+1,34-1,35: NL '\n'
+2,0-2,42: COMMENT '# Large bits stolen from test_grammar.py. '
+2,42-2,43: NL '\n'
3,0-3,1: NL '\n'
-4,0-4,11: COMMENT '# Comments\n'
+4,0-4,10: COMMENT '# Comments'
+4,10-4,11: NL '\n'
5,0-5,3: STRING '"#"'
5,3-5,4: NEWLINE '\n'
-6,0-6,3: COMMENT "#'\n"
-7,0-7,3: COMMENT '#"\n'
-8,0-8,3: COMMENT '#\\\n'
-9,7-9,9: COMMENT '#\n'
-10,4-10,10: COMMENT '# abc\n'
+6,0-6,2: COMMENT "#'"
+6,2-6,3: NL '\n'
+7,0-7,2: COMMENT '#"'
+7,2-7,3: NL '\n'
+8,0-8,2: COMMENT '#\\'
+8,2-8,3: NL '\n'
+9,7-9,8: COMMENT '#'
+9,8-9,9: NL '\n'
+10,4-10,9: COMMENT '# abc'
+10,9-10,10: NL '\n'
11,0-12,4: STRING "'''#\n#'''"
12,4-12,5: NEWLINE '\n'
13,0-13,1: NL '\n'
@@ -19,7 +27,8 @@
14,7-14,8: COMMENT '#'
14,8-14,9: NEWLINE '\n'
15,0-15,1: NL '\n'
-16,0-16,25: COMMENT '# Balancing continuation\n'
+16,0-16,24: COMMENT '# Balancing continuation'
+16,24-16,25: NL '\n'
17,0-17,1: NL '\n'
18,0-18,1: NAME 'a'
18,2-18,3: OP '='
@@ -92,7 +101,8 @@
29,2-29,3: OP ')'
29,3-29,4: NEWLINE '\n'
30,0-30,1: NL '\n'
-31,0-31,37: COMMENT '# Backslash means line continuation:\n'
+31,0-31,36: COMMENT '# Backslash means line continuation:'
+31,36-31,37: NL '\n'
32,0-32,1: NAME 'x'
32,2-32,3: OP '='
32,4-32,5: NUMBER '1'
@@ -100,13 +110,15 @@
33,2-33,3: NUMBER '1'
33,3-33,4: NEWLINE '\n'
34,0-34,1: NL '\n'
-35,0-35,55: COMMENT '# Backslash does not means continuation in comments :\\\n'
+35,0-35,54: COMMENT '# Backslash does not means continuation in comments :\\'
+35,54-35,55: NL '\n'
36,0-36,1: NAME 'x'
36,2-36,3: OP '='
36,4-36,5: NUMBER '0'
36,5-36,6: NEWLINE '\n'
37,0-37,1: NL '\n'
-38,0-38,20: COMMENT '# Ordinary integers\n'
+38,0-38,19: COMMENT '# Ordinary integers'
+38,19-38,20: NL '\n'
39,0-39,4: NUMBER '0xff'
39,5-39,7: OP '<>'
39,8-39,11: NUMBER '255'
@@ -137,7 +149,8 @@
44,15-44,16: NUMBER '1'
44,16-44,17: NEWLINE '\n'
45,0-45,1: NL '\n'
-46,0-46,16: COMMENT '# Long integers\n'
+46,0-46,15: COMMENT '# Long integers'
+46,15-46,16: NL '\n'
47,0-47,1: NAME 'x'
47,2-47,3: OP '='
47,4-47,6: NUMBER '0L'
@@ -171,7 +184,8 @@
54,4-54,35: NUMBER '123456789012345678901234567890l'
54,35-54,36: NEWLINE '\n'
55,0-55,1: NL '\n'
-56,0-56,25: COMMENT '# Floating-point numbers\n'
+56,0-56,24: COMMENT '# Floating-point numbers'
+56,24-56,25: NL '\n'
57,0-57,1: NAME 'x'
57,2-57,3: OP '='
57,4-57,8: NUMBER '3.14'
@@ -184,7 +198,8 @@
59,2-59,3: OP '='
59,4-59,9: NUMBER '0.314'
59,9-59,10: NEWLINE '\n'
-60,0-60,18: COMMENT '# XXX x = 000.314\n'
+60,0-60,17: COMMENT '# XXX x = 000.314'
+60,17-60,18: NL '\n'
61,0-61,1: NAME 'x'
61,2-61,3: OP '='
61,4-61,8: NUMBER '.314'
@@ -218,7 +233,8 @@
68,4-68,9: NUMBER '3.1e4'
68,9-68,10: NEWLINE '\n'
69,0-69,1: NL '\n'
-70,0-70,18: COMMENT '# String literals\n'
+70,0-70,17: COMMENT '# String literals'
+70,17-70,18: NL '\n'
71,0-71,1: NAME 'x'
71,2-71,3: OP '='
71,4-71,6: STRING "''"
@@ -366,7 +382,8 @@
125,6-126,3: STRING "uR'''spam\n'''"
126,3-126,4: NEWLINE '\n'
127,0-127,1: NL '\n'
-128,0-128,14: COMMENT '# Indentation\n'
+128,0-128,13: COMMENT '# Indentation'
+128,13-128,14: NL '\n'
129,0-129,2: NAME 'if'
129,3-129,4: NUMBER '1'
129,4-129,5: OP ':'
@@ -438,7 +455,8 @@
142,14-142,15: NUMBER '2'
142,15-142,16: NEWLINE '\n'
143,0-143,1: NL '\n'
-144,0-144,12: COMMENT '# Operators\n'
+144,0-144,11: COMMENT '# Operators'
+144,11-144,12: NL '\n'
145,0-145,1: NL '\n'
146,0-146,0: DEDENT ''
146,0-146,0: DEDENT ''
@@ -500,7 +518,8 @@
149,27-149,28: OP ')'
149,28-149,29: NEWLINE '\n'
150,0-150,1: NL '\n'
-151,0-151,13: COMMENT '# comparison\n'
+151,0-151,12: COMMENT '# comparison'
+151,12-151,13: NL '\n'
152,0-152,2: NAME 'if'
152,3-152,4: NUMBER '1'
152,5-152,6: OP '<'
@@ -531,7 +550,8 @@
152,67-152,71: NAME 'pass'
152,71-152,72: NEWLINE '\n'
153,0-153,1: NL '\n'
-154,0-154,9: COMMENT '# binary\n'
+154,0-154,8: COMMENT '# binary'
+154,8-154,9: NL '\n'
155,0-155,1: NAME 'x'
155,2-155,3: OP '='
155,4-155,5: NUMBER '1'
@@ -551,7 +571,8 @@
157,8-157,9: NUMBER '1'
157,9-157,10: NEWLINE '\n'
158,0-158,1: NL '\n'
-159,0-159,8: COMMENT '# shift\n'
+159,0-159,7: COMMENT '# shift'
+159,7-159,8: NL '\n'
160,0-160,1: NAME 'x'
160,2-160,3: OP '='
160,4-160,5: NUMBER '1'
@@ -561,7 +582,8 @@
160,14-160,15: NUMBER '1'
160,15-160,16: NEWLINE '\n'
161,0-161,1: NL '\n'
-162,0-162,11: COMMENT '# additive\n'
+162,0-162,10: COMMENT '# additive'
+162,10-162,11: NL '\n'
163,0-163,1: NAME 'x'
163,2-163,3: OP '='
163,4-163,5: NUMBER '1'
@@ -575,7 +597,8 @@
163,20-163,21: NUMBER '1'
163,21-163,22: NEWLINE '\n'
164,0-164,1: NL '\n'
-165,0-165,17: COMMENT '# multiplicative\n'
+165,0-165,16: COMMENT '# multiplicative'
+165,16-165,17: NL '\n'
166,0-166,1: NAME 'x'
166,2-166,3: OP '='
166,4-166,5: NUMBER '1'
@@ -587,7 +610,8 @@
166,16-166,17: NUMBER '1'
166,17-166,18: NEWLINE '\n'
167,0-167,1: NL '\n'
-168,0-168,8: COMMENT '# unary\n'
+168,0-168,7: COMMENT '# unary'
+168,7-168,8: NL '\n'
169,0-169,1: NAME 'x'
169,2-169,3: OP '='
169,4-169,5: OP '~'
@@ -625,7 +649,8 @@
170,24-170,25: NUMBER '1'
170,25-170,26: NEWLINE '\n'
171,0-171,1: NL '\n'
-172,0-172,11: COMMENT '# selector\n'
+172,0-172,10: COMMENT '# selector'
+172,10-172,11: NL '\n'
173,0-173,6: NAME 'import'
173,7-173,10: NAME 'sys'
173,10-173,11: OP ','
Modified: python/branches/bcannon-objcap/Lib/test/test_array.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_array.py (original)
+++ python/branches/bcannon-objcap/Lib/test/test_array.py Mon Aug 28 21:49:46 2006
@@ -85,6 +85,13 @@
self.assertNotEqual(id(a), id(b))
self.assertEqual(a, b)
+ def test_deepcopy(self):
+ import copy
+ a = array.array(self.typecode, self.example)
+ b = copy.deepcopy(a)
+ self.assertNotEqual(id(a), id(b))
+ self.assertEqual(a, b)
+
def test_pickle(self):
for protocol in (0, 1, 2):
a = array.array(self.typecode, self.example)
Modified: python/branches/bcannon-objcap/Lib/test/test_compiler.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_compiler.py (original)
+++ python/branches/bcannon-objcap/Lib/test/test_compiler.py Mon Aug 28 21:49:46 2006
@@ -116,6 +116,13 @@
exec c in dct
self.assertEquals(dct.get('result'), 3)
+ def testGenExp(self):
+ c = compiler.compile('list((i,j) for i in range(3) if i < 3'
+ ' for j in range(4) if j > 2)',
+ '<string>',
+ 'eval')
+ self.assertEquals(eval(c), [(0, 3), (1, 3), (2, 3)])
+
NOLINENO = (compiler.ast.Module, compiler.ast.Stmt, compiler.ast.Discard)
Modified: python/branches/bcannon-objcap/Lib/test/test_parser.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_parser.py (original)
+++ python/branches/bcannon-objcap/Lib/test/test_parser.py Mon Aug 28 21:49:46 2006
@@ -183,6 +183,44 @@
def test_assert(self):
self.check_suite("assert alo < ahi and blo < bhi\n")
+ def test_position(self):
+ # An absolutely minimal test of position information. Better
+ # tests would be a big project.
+ code = "def f(x):\n return x + 1\n"
+ st1 = parser.suite(code)
+ st2 = st1.totuple(line_info=1, col_info=1)
+
+ def walk(tree):
+ node_type = tree[0]
+ next = tree[1]
+ if isinstance(next, tuple):
+ for elt in tree[1:]:
+ for x in walk(elt):
+ yield x
+ else:
+ yield tree
+
+ terminals = list(walk(st2))
+ self.assertEqual([
+ (1, 'def', 1, 0),
+ (1, 'f', 1, 4),
+ (7, '(', 1, 5),
+ (1, 'x', 1, 6),
+ (8, ')', 1, 7),
+ (11, ':', 1, 8),
+ (4, '', 1, 9),
+ (5, '', 2, -1),
+ (1, 'return', 2, 4),
+ (1, 'x', 2, 11),
+ (14, '+', 2, 13),
+ (2, '1', 2, 15),
+ (4, '', 2, 16),
+ (6, '', 2, -1),
+ (4, '', 2, -1),
+ (0, '', 2, -1)],
+ terminals)
+
+
#
# Second, we take *invalid* trees and make sure we get ParserError
# rejections for them.
Modified: python/branches/bcannon-objcap/Lib/test/test_syntax.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_syntax.py (original)
+++ python/branches/bcannon-objcap/Lib/test/test_syntax.py Mon Aug 28 21:49:46 2006
@@ -235,6 +235,93 @@
>>> f() += 1
Traceback (most recent call last):
SyntaxError: illegal expression for augmented assignment (<doctest test.test_syntax[33]>, line 1)
+
+
+Test continue in finally in weird combinations.
+
+continue in for loop under finally shouuld be ok.
+
+ >>> def test():
+ ... try:
+ ... pass
+ ... finally:
+ ... for abc in range(10):
+ ... continue
+ ... print abc
+ >>> test()
+ 9
+
+Start simple, a continue in a finally should not be allowed.
+
+ >>> def test():
+ ... for abc in range(10):
+ ... try:
+ ... pass
+ ... finally:
+ ... continue
+ Traceback (most recent call last):
+ ...
+ SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[36]>, line 6)
+
+This is essentially a continue in a finally which should not be allowed.
+
+ >>> def test():
+ ... for abc in range(10):
+ ... try:
+ ... pass
+ ... finally:
+ ... try:
+ ... continue
+ ... except:
+ ... pass
+ Traceback (most recent call last):
+ ...
+ SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[37]>, line 7)
+
+ >>> def foo():
+ ... try:
+ ... pass
+ ... finally:
+ ... continue
+ Traceback (most recent call last):
+ ...
+ SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[38]>, line 5)
+
+ >>> def foo():
+ ... for a in ():
+ ... try:
+ ... pass
+ ... finally:
+ ... continue
+ Traceback (most recent call last):
+ ...
+ SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[39]>, line 6)
+
+ >>> def foo():
+ ... for a in ():
+ ... try:
+ ... pass
+ ... finally:
+ ... try:
+ ... continue
+ ... finally:
+ ... pass
+ Traceback (most recent call last):
+ ...
+ SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[40]>, line 7)
+
+ >>> def foo():
+ ... for a in ():
+ ... try: pass
+ ... finally:
+ ... try:
+ ... pass
+ ... except:
+ ... continue
+ Traceback (most recent call last):
+ ...
+ SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[41]>, line 8)
+
"""
import re
Modified: python/branches/bcannon-objcap/Lib/test/test_tarfile.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_tarfile.py (original)
+++ python/branches/bcannon-objcap/Lib/test/test_tarfile.py Mon Aug 28 21:49:46 2006
@@ -324,6 +324,27 @@
class WriteStreamTest(WriteTest):
sep = '|'
+ def test_padding(self):
+ self.dst.close()
+
+ if self.comp == "gz":
+ f = gzip.GzipFile(self.dstname)
+ s = f.read()
+ f.close()
+ elif self.comp == "bz2":
+ f = bz2.BZ2Decompressor()
+ s = file(self.dstname).read()
+ s = f.decompress(s)
+ self.assertEqual(len(f.unused_data), 0, "trailing data")
+ else:
+ f = file(self.dstname)
+ s = f.read()
+ f.close()
+
+ self.assertEqual(s.count("\0"), tarfile.RECORDSIZE,
+ "incorrect zero padding")
+
+
class WriteGNULongTest(unittest.TestCase):
"""This testcase checks for correct creation of GNU Longname
and Longlink extensions.
Modified: python/branches/bcannon-objcap/Lib/test/test_tokenize.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_tokenize.py (original)
+++ python/branches/bcannon-objcap/Lib/test/test_tokenize.py Mon Aug 28 21:49:46 2006
@@ -1,9 +1,90 @@
+"""Tests for the tokenize module.
+
+The tests were originally written in the old Python style, where the
+test output was compared to a golden file. This docstring represents
+the first steps towards rewriting the entire test as a doctest.
+
+The tests can be really simple. Given a small fragment of source
+code, print out a table with the tokens. The ENDMARK is omitted for
+brevity.
+
+>>> dump_tokens("1 + 1")
+NUMBER '1' (1, 0) (1, 1)
+OP '+' (1, 2) (1, 3)
+NUMBER '1' (1, 4) (1, 5)
+
+A comment generates a token here, unlike in the parser module. The
+comment token is followed by an NL or a NEWLINE token, depending on
+whether the line contains the completion of a statement.
+
+>>> dump_tokens("if False:\\n"
+... " # NL\\n"
+... " True = False # NEWLINE\\n")
+NAME 'if' (1, 0) (1, 2)
+NAME 'False' (1, 3) (1, 8)
+OP ':' (1, 8) (1, 9)
+NEWLINE '\\n' (1, 9) (1, 10)
+COMMENT '# NL' (2, 4) (2, 8)
+NL '\\n' (2, 8) (2, 9)
+INDENT ' ' (3, 0) (3, 4)
+NAME 'True' (3, 4) (3, 8)
+OP '=' (3, 9) (3, 10)
+NAME 'False' (3, 11) (3, 16)
+COMMENT '# NEWLINE' (3, 17) (3, 26)
+NEWLINE '\\n' (3, 26) (3, 27)
+DEDENT '' (4, 0) (4, 0)
+
+
+There will be a bunch more tests of specific source patterns.
+
+The tokenize module also defines an untokenize function that should
+regenerate the original program text from the tokens.
+
+There are some standard formatting practices that are easy to get right.
+
+>>> roundtrip("if x == 1:\\n"
+... " print x\\n")
+if x == 1:
+ print x
+
+Some people use different formatting conventions, which makes
+untokenize a little trickier. Note that this test involves trailing
+whitespace after the colon. Note that we use hex escapes to make the
+two trailing blanks apparent in the expected output.
+
+>>> roundtrip("if x == 1 : \\n"
+... " print x\\n")
+if x == 1 :\x20\x20
+ print x
+
+Comments need to go in the right place.
+
+>>> roundtrip("if x == 1:\\n"
+... " # A comment by itself.\\n"
+... " print x # Comment here, too.\\n"
+... " # Another comment.\\n"
+... "after_if = True\\n")
+if x == 1:
+ # A comment by itself.
+ print x # Comment here, too.
+ # Another comment.
+after_if = True
+
+>>> roundtrip("if (x # The comments need to go in the right place\\n"
+... " == 1):\\n"
+... " print 'x == 1'\\n")
+if (x # The comments need to go in the right place
+ == 1):
+ print 'x == 1'
+
+"""
+
import os, glob, random
from cStringIO import StringIO
from test.test_support import (verbose, findfile, is_resource_enabled,
TestFailed)
-from tokenize import (tokenize, generate_tokens, untokenize,
- NUMBER, NAME, OP, STRING)
+from tokenize import (tokenize, generate_tokens, untokenize, tok_name,
+ ENDMARKER, NUMBER, NAME, OP, STRING, COMMENT)
# Test roundtrip for `untokenize`. `f` is a file path. The source code in f
# is tokenized, converted back to source code via tokenize.untokenize(),
@@ -24,6 +105,23 @@
if t1 != t2:
raise TestFailed("untokenize() roundtrip failed for %r" % f)
+def dump_tokens(s):
+ """Print out the tokens in s in a table format.
+
+ The ENDMARKER is omitted.
+ """
+ f = StringIO(s)
+ for type, token, start, end, line in generate_tokens(f.readline):
+ if type == ENDMARKER:
+ break
+ type = tok_name[type]
+ print "%(type)-10.10s %(token)-13.13r %(start)s %(end)s" % locals()
+
+def roundtrip(s):
+ f = StringIO(s)
+ source = untokenize(generate_tokens(f.readline))
+ print source,
+
# This is an example from the docs, set up as a doctest.
def decistmt(s):
"""Substitute Decimals for floats in a string of statements.
@@ -105,7 +203,7 @@
# Run the doctests in this module.
from test import test_tokenize # i.e., this module
from test.test_support import run_doctest
- run_doctest(test_tokenize)
+ run_doctest(test_tokenize, verbose)
if verbose:
print 'finished'
Modified: python/branches/bcannon-objcap/Lib/test/test_unicode.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_unicode.py (original)
+++ python/branches/bcannon-objcap/Lib/test/test_unicode.py Mon Aug 28 21:49:46 2006
@@ -92,6 +92,10 @@
"\\xfe\\xff'")
testrepr = repr(u''.join(map(unichr, xrange(256))))
self.assertEqual(testrepr, latin1repr)
+ # Test repr works on wide unicode escapes without overflow.
+ self.assertEqual(repr(u"\U00010000" * 39 + u"\uffff" * 4096),
+ repr(u"\U00010000" * 39 + u"\uffff" * 4096))
+
def test_count(self):
string_tests.CommonTest.test_count(self)
Modified: python/branches/bcannon-objcap/Lib/test/test_urllib2.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_urllib2.py (original)
+++ python/branches/bcannon-objcap/Lib/test/test_urllib2.py Mon Aug 28 21:49:46 2006
@@ -46,6 +46,69 @@
self.assertEquals(urllib2.parse_http_list(string), list)
+def test_request_headers_dict():
+ """
+ The Request.headers dictionary is not a documented interface. It should
+ stay that way, because the complete set of headers are only accessible
+ through the .get_header(), .has_header(), .header_items() interface.
+ However, .headers pre-dates those methods, and so real code will be using
+ the dictionary.
+
+ The introduction in 2.4 of those methods was a mistake for the same reason:
+ code that previously saw all (urllib2 user)-provided headers in .headers
+ now sees only a subset (and the function interface is ugly and incomplete).
+ A better change would have been to replace .headers dict with a dict
+ subclass (or UserDict.DictMixin instance?) that preserved the .headers
+ interface and also provided access to the "unredirected" headers. It's
+ probably too late to fix that, though.
+
+
+ Check .capitalize() case normalization:
+
+ >>> url = "http://example.com"
+ >>> Request(url, headers={"Spam-eggs": "blah"}).headers["Spam-eggs"]
+ 'blah'
+ >>> Request(url, headers={"spam-EggS": "blah"}).headers["Spam-eggs"]
+ 'blah'
+
+ Currently, Request(url, "Spam-eggs").headers["Spam-Eggs"] raises KeyError,
+ but that could be changed in future.
+
+ """
+
+def test_request_headers_methods():
+ """
+ Note the case normalization of header names here, to .capitalize()-case.
+ This should be preserved for backwards-compatibility. (In the HTTP case,
+ normalization to .title()-case is done by urllib2 before sending headers to
+ httplib).
+
+ >>> url = "http://example.com"
+ >>> r = Request(url, headers={"Spam-eggs": "blah"})
+ >>> r.has_header("Spam-eggs")
+ True
+ >>> r.header_items()
+ [('Spam-eggs', 'blah')]
+ >>> r.add_header("Foo-Bar", "baz")
+ >>> items = r.header_items()
+ >>> items.sort()
+ >>> items
+ [('Foo-bar', 'baz'), ('Spam-eggs', 'blah')]
+
+ Note that e.g. r.has_header("spam-EggS") is currently False, and
+ r.get_header("spam-EggS") returns None, but that could be changed in
+ future.
+
+ >>> r.has_header("Not-there")
+ False
+ >>> print r.get_header("Not-there")
+ None
+ >>> r.get_header("Not-there", "default")
+ 'default'
+
+ """
+
+
def test_password_manager(self):
"""
>>> mgr = urllib2.HTTPPasswordMgr()
@@ -676,11 +739,11 @@
r = MockResponse(200, "OK", {}, "")
newreq = h.do_request_(req)
if data is None: # GET
- self.assert_("Content-Length" not in req.unredirected_hdrs)
- self.assert_("Content-Type" not in req.unredirected_hdrs)
+ self.assert_("Content-length" not in req.unredirected_hdrs)
+ self.assert_("Content-type" not in req.unredirected_hdrs)
else: # POST
- self.assertEqual(req.unredirected_hdrs["Content-Length"], "0")
- self.assertEqual(req.unredirected_hdrs["Content-Type"],
+ self.assertEqual(req.unredirected_hdrs["Content-length"], "0")
+ self.assertEqual(req.unredirected_hdrs["Content-type"],
"application/x-www-form-urlencoded")
# XXX the details of Host could be better tested
self.assertEqual(req.unredirected_hdrs["Host"], "example.com")
@@ -692,8 +755,8 @@
req.add_unredirected_header("Host", "baz")
req.add_unredirected_header("Spam", "foo")
newreq = h.do_request_(req)
- self.assertEqual(req.unredirected_hdrs["Content-Length"], "foo")
- self.assertEqual(req.unredirected_hdrs["Content-Type"], "bar")
+ self.assertEqual(req.unredirected_hdrs["Content-length"], "foo")
+ self.assertEqual(req.unredirected_hdrs["Content-type"], "bar")
self.assertEqual(req.unredirected_hdrs["Host"], "baz")
self.assertEqual(req.unredirected_hdrs["Spam"], "foo")
@@ -847,7 +910,7 @@
407, 'Proxy-Authenticate: Basic realm="%s"\r\n\r\n' % realm)
opener.add_handler(auth_handler)
opener.add_handler(http_handler)
- self._test_basic_auth(opener, auth_handler, "Proxy-Authorization",
+ self._test_basic_auth(opener, auth_handler, "Proxy-authorization",
realm, http_handler, password_manager,
"http://acme.example.com:3128/protected",
"proxy.example.com:3128",
Modified: python/branches/bcannon-objcap/Lib/test/test_uuid.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_uuid.py (original)
+++ python/branches/bcannon-objcap/Lib/test/test_uuid.py Mon Aug 28 21:49:46 2006
@@ -16,12 +16,13 @@
def test_UUID(self):
equal = self.assertEqual
ascending = []
- for (string, curly, hex, bytes, fields, integer, urn,
+ for (string, curly, hex, bytes, bytes_le, fields, integer, urn,
time, clock_seq, variant, version) in [
('00000000-0000-0000-0000-000000000000',
'{00000000-0000-0000-0000-000000000000}',
'00000000000000000000000000000000',
'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0',
+ '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0',
(0, 0, 0, 0, 0, 0),
0,
'urn:uuid:00000000-0000-0000-0000-000000000000',
@@ -30,6 +31,7 @@
'{00010203-0405-0607-0809-0a0b0c0d0e0f}',
'000102030405060708090a0b0c0d0e0f',
'\0\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\x0d\x0e\x0f',
+ '\x03\x02\x01\0\x05\x04\x07\x06\x08\t\n\x0b\x0c\x0d\x0e\x0f',
(0x00010203L, 0x0405, 0x0607, 8, 9, 0x0a0b0c0d0e0fL),
0x000102030405060708090a0b0c0d0e0fL,
'urn:uuid:00010203-0405-0607-0809-0a0b0c0d0e0f',
@@ -38,6 +40,7 @@
'{02d9e6d5-9467-382e-8f9b-9300a64ac3cd}',
'02d9e6d59467382e8f9b9300a64ac3cd',
'\x02\xd9\xe6\xd5\x94\x67\x38\x2e\x8f\x9b\x93\x00\xa6\x4a\xc3\xcd',
+ '\xd5\xe6\xd9\x02\x67\x94\x2e\x38\x8f\x9b\x93\x00\xa6\x4a\xc3\xcd',
(0x02d9e6d5L, 0x9467, 0x382e, 0x8f, 0x9b, 0x9300a64ac3cdL),
0x02d9e6d59467382e8f9b9300a64ac3cdL,
'urn:uuid:02d9e6d5-9467-382e-8f9b-9300a64ac3cd',
@@ -46,6 +49,7 @@
'{12345678-1234-5678-1234-567812345678}',
'12345678123456781234567812345678',
'\x12\x34\x56\x78'*4,
+ '\x78\x56\x34\x12\x34\x12\x78\x56\x12\x34\x56\x78\x12\x34\x56\x78',
(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678),
0x12345678123456781234567812345678,
'urn:uuid:12345678-1234-5678-1234-567812345678',
@@ -54,6 +58,7 @@
'{6ba7b810-9dad-11d1-80b4-00c04fd430c8}',
'6ba7b8109dad11d180b400c04fd430c8',
'\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8',
+ '\x10\xb8\xa7\x6b\xad\x9d\xd1\x11\x80\xb4\x00\xc0\x4f\xd4\x30\xc8',
(0x6ba7b810L, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00c04fd430c8L),
0x6ba7b8109dad11d180b400c04fd430c8L,
'urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8',
@@ -62,6 +67,7 @@
'{6ba7b811-9dad-11d1-80b4-00c04fd430c8}',
'6ba7b8119dad11d180b400c04fd430c8',
'\x6b\xa7\xb8\x11\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8',
+ '\x11\xb8\xa7\x6b\xad\x9d\xd1\x11\x80\xb4\x00\xc0\x4f\xd4\x30\xc8',
(0x6ba7b811L, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00c04fd430c8L),
0x6ba7b8119dad11d180b400c04fd430c8L,
'urn:uuid:6ba7b811-9dad-11d1-80b4-00c04fd430c8',
@@ -70,6 +76,7 @@
'{6ba7b812-9dad-11d1-80b4-00c04fd430c8}',
'6ba7b8129dad11d180b400c04fd430c8',
'\x6b\xa7\xb8\x12\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8',
+ '\x12\xb8\xa7\x6b\xad\x9d\xd1\x11\x80\xb4\x00\xc0\x4f\xd4\x30\xc8',
(0x6ba7b812L, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00c04fd430c8L),
0x6ba7b8129dad11d180b400c04fd430c8L,
'urn:uuid:6ba7b812-9dad-11d1-80b4-00c04fd430c8',
@@ -78,6 +85,7 @@
'{6ba7b814-9dad-11d1-80b4-00c04fd430c8}',
'6ba7b8149dad11d180b400c04fd430c8',
'\x6b\xa7\xb8\x14\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8',
+ '\x14\xb8\xa7\x6b\xad\x9d\xd1\x11\x80\xb4\x00\xc0\x4f\xd4\x30\xc8',
(0x6ba7b814L, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00c04fd430c8L),
0x6ba7b8149dad11d180b400c04fd430c8L,
'urn:uuid:6ba7b814-9dad-11d1-80b4-00c04fd430c8',
@@ -86,6 +94,7 @@
'{7d444840-9dc0-11d1-b245-5ffdce74fad2}',
'7d4448409dc011d1b2455ffdce74fad2',
'\x7d\x44\x48\x40\x9d\xc0\x11\xd1\xb2\x45\x5f\xfd\xce\x74\xfa\xd2',
+ '\x40\x48\x44\x7d\xc0\x9d\xd1\x11\xb2\x45\x5f\xfd\xce\x74\xfa\xd2',
(0x7d444840L, 0x9dc0, 0x11d1, 0xb2, 0x45, 0x5ffdce74fad2L),
0x7d4448409dc011d1b2455ffdce74fad2L,
'urn:uuid:7d444840-9dc0-11d1-b245-5ffdce74fad2',
@@ -94,6 +103,7 @@
'{e902893a-9d22-3c7e-a7b8-d6e313b71d9f}',
'e902893a9d223c7ea7b8d6e313b71d9f',
'\xe9\x02\x89\x3a\x9d\x22\x3c\x7e\xa7\xb8\xd6\xe3\x13\xb7\x1d\x9f',
+ '\x3a\x89\x02\xe9\x22\x9d\x7e\x3c\xa7\xb8\xd6\xe3\x13\xb7\x1d\x9f',
(0xe902893aL, 0x9d22, 0x3c7e, 0xa7, 0xb8, 0xd6e313b71d9fL),
0xe902893a9d223c7ea7b8d6e313b71d9fL,
'urn:uuid:e902893a-9d22-3c7e-a7b8-d6e313b71d9f',
@@ -102,6 +112,7 @@
'{eb424026-6f54-4ef8-a4d0-bb658a1fc6cf}',
'eb4240266f544ef8a4d0bb658a1fc6cf',
'\xeb\x42\x40\x26\x6f\x54\x4e\xf8\xa4\xd0\xbb\x65\x8a\x1f\xc6\xcf',
+ '\x26\x40\x42\xeb\x54\x6f\xf8\x4e\xa4\xd0\xbb\x65\x8a\x1f\xc6\xcf',
(0xeb424026L, 0x6f54, 0x4ef8, 0xa4, 0xd0, 0xbb658a1fc6cfL),
0xeb4240266f544ef8a4d0bb658a1fc6cfL,
'urn:uuid:eb424026-6f54-4ef8-a4d0-bb658a1fc6cf',
@@ -110,6 +121,7 @@
'{f81d4fae-7dec-11d0-a765-00a0c91e6bf6}',
'f81d4fae7dec11d0a76500a0c91e6bf6',
'\xf8\x1d\x4f\xae\x7d\xec\x11\xd0\xa7\x65\x00\xa0\xc9\x1e\x6b\xf6',
+ '\xae\x4f\x1d\xf8\xec\x7d\xd0\x11\xa7\x65\x00\xa0\xc9\x1e\x6b\xf6',
(0xf81d4faeL, 0x7dec, 0x11d0, 0xa7, 0x65, 0x00a0c91e6bf6L),
0xf81d4fae7dec11d0a76500a0c91e6bf6L,
'urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6',
@@ -118,6 +130,7 @@
'{fffefdfc-fffe-fffe-fffe-fffefdfcfbfa}',
'fffefdfcfffefffefffefffefdfcfbfa',
'\xff\xfe\xfd\xfc\xff\xfe\xff\xfe\xff\xfe\xff\xfe\xfd\xfc\xfb\xfa',
+ '\xfc\xfd\xfe\xff\xfe\xff\xfe\xff\xff\xfe\xff\xfe\xfd\xfc\xfb\xfa',
(0xfffefdfcL, 0xfffe, 0xfffe, 0xff, 0xfe, 0xfffefdfcfbfaL),
0xfffefdfcfffefffefffefffefdfcfbfaL,
'urn:uuid:fffefdfc-fffe-fffe-fffe-fffefdfcfbfa',
@@ -126,6 +139,7 @@
'{ffffffff-ffff-ffff-ffff-ffffffffffff}',
'ffffffffffffffffffffffffffffffff',
'\xff'*16,
+ '\xff'*16,
(0xffffffffL, 0xffffL, 0xffffL, 0xff, 0xff, 0xffffffffffffL),
0xffffffffffffffffffffffffffffffffL,
'urn:uuid:ffffffff-ffff-ffff-ffff-ffffffffffff',
@@ -134,12 +148,14 @@
equivalents = []
# Construct each UUID in several different ways.
for u in [uuid.UUID(string), uuid.UUID(curly), uuid.UUID(hex),
- uuid.UUID(bytes=bytes), uuid.UUID(fields=fields),
- uuid.UUID(int=integer), uuid.UUID(urn)]:
+ uuid.UUID(bytes=bytes), uuid.UUID(bytes_le=bytes_le),
+ uuid.UUID(fields=fields), uuid.UUID(int=integer),
+ uuid.UUID(urn)]:
# Test all conversions and properties of the UUID object.
equal(str(u), string)
equal(int(u), integer)
equal(u.bytes, bytes)
+ equal(u.bytes_le, bytes_le)
equal(u.fields, fields)
equal(u.time_low, fields[0])
equal(u.time_mid, fields[1])
@@ -189,6 +205,11 @@
badvalue(lambda: uuid.UUID(bytes='\0'*15))
badvalue(lambda: uuid.UUID(bytes='\0'*17))
+ # Badly formed bytes_le.
+ badvalue(lambda: uuid.UUID(bytes_le='abc'))
+ badvalue(lambda: uuid.UUID(bytes_le='\0'*15))
+ badvalue(lambda: uuid.UUID(bytes_le='\0'*17))
+
# Badly formed fields.
badvalue(lambda: uuid.UUID(fields=(1,)))
badvalue(lambda: uuid.UUID(fields=(1, 2, 3, 4, 5)))
@@ -221,51 +242,43 @@
uuid.UUID(h)
uuid.UUID(hex=h)
uuid.UUID(bytes=b)
+ uuid.UUID(bytes_le=b)
uuid.UUID(fields=f)
uuid.UUID(int=i)
# Wrong number of arguments (positional).
badtype(lambda: uuid.UUID())
badtype(lambda: uuid.UUID(h, b))
- badtype(lambda: uuid.UUID(h, b, f))
- badtype(lambda: uuid.UUID(h, b, f, i))
-
- # Duplicate arguments (named).
- badtype(lambda: uuid.UUID(hex=h, bytes=b))
- badtype(lambda: uuid.UUID(hex=h, fields=f))
- badtype(lambda: uuid.UUID(hex=h, int=i))
- badtype(lambda: uuid.UUID(bytes=b, fields=f))
- badtype(lambda: uuid.UUID(bytes=b, int=i))
- badtype(lambda: uuid.UUID(fields=f, int=i))
- badtype(lambda: uuid.UUID(hex=h, bytes=b, fields=f))
- badtype(lambda: uuid.UUID(hex=h, bytes=b, int=i))
- badtype(lambda: uuid.UUID(hex=h, fields=f, int=i))
- badtype(lambda: uuid.UUID(bytes=b, int=i, fields=f))
- badtype(lambda: uuid.UUID(hex=h, bytes=b, int=i, fields=f))
-
- # Duplicate arguments (positional and named).
- badtype(lambda: uuid.UUID(h, hex=h))
- badtype(lambda: uuid.UUID(h, bytes=b))
- badtype(lambda: uuid.UUID(h, fields=f))
- badtype(lambda: uuid.UUID(h, int=i))
- badtype(lambda: uuid.UUID(h, hex=h, bytes=b))
- badtype(lambda: uuid.UUID(h, hex=h, fields=f))
- badtype(lambda: uuid.UUID(h, hex=h, int=i))
- badtype(lambda: uuid.UUID(h, bytes=b, fields=f))
- badtype(lambda: uuid.UUID(h, bytes=b, int=i))
- badtype(lambda: uuid.UUID(h, fields=f, int=i))
- badtype(lambda: uuid.UUID(h, hex=h, bytes=b, fields=f))
- badtype(lambda: uuid.UUID(h, hex=h, bytes=b, int=i))
- badtype(lambda: uuid.UUID(h, hex=h, fields=f, int=i))
- badtype(lambda: uuid.UUID(h, bytes=b, int=i, fields=f))
- badtype(lambda: uuid.UUID(h, hex=h, bytes=b, int=i, fields=f))
+ badtype(lambda: uuid.UUID(h, b, b))
+ badtype(lambda: uuid.UUID(h, b, b, f))
+ badtype(lambda: uuid.UUID(h, b, b, f, i))
+
+ # Duplicate arguments.
+ for hh in [[], [('hex', h)]]:
+ for bb in [[], [('bytes', b)]]:
+ for bble in [[], [('bytes_le', b)]]:
+ for ii in [[], [('int', i)]]:
+ for ff in [[], [('fields', f)]]:
+ args = dict(hh + bb + bble + ii + ff)
+ if len(args) != 0:
+ badtype(lambda: uuid.UUID(h, **args))
+ if len(args) != 1:
+ badtype(lambda: uuid.UUID(**args))
# Immutability.
u = uuid.UUID(h)
badtype(lambda: setattr(u, 'hex', h))
badtype(lambda: setattr(u, 'bytes', b))
+ badtype(lambda: setattr(u, 'bytes_le', b))
badtype(lambda: setattr(u, 'fields', f))
badtype(lambda: setattr(u, 'int', i))
+ badtype(lambda: setattr(u, 'time_low', 0))
+ badtype(lambda: setattr(u, 'time_mid', 0))
+ badtype(lambda: setattr(u, 'time_hi_version', 0))
+ badtype(lambda: setattr(u, 'time_hi_version', 0))
+ badtype(lambda: setattr(u, 'clock_seq_hi_variant', 0))
+ badtype(lambda: setattr(u, 'clock_seq_low', 0))
+ badtype(lambda: setattr(u, 'node', 0))
def check_node(self, node, source):
individual_group_bit = (node >> 40L) & 1
@@ -356,11 +369,17 @@
def test_uuid1(self):
equal = self.assertEqual
- # Make sure uuid4() generates UUIDs that are actually version 1.
+ # Make sure uuid1() generates UUIDs that are actually version 1.
for u in [uuid.uuid1() for i in range(10)]:
equal(u.variant, uuid.RFC_4122)
equal(u.version, 1)
+ # Make sure the generated UUIDs are actually unique.
+ uuids = {}
+ for u in [uuid.uuid1() for i in range(1000)]:
+ uuids[u] = 1
+ equal(len(uuids.keys()), 1000)
+
# Make sure the supplied node ID appears in the UUID.
u = uuid.uuid1(0)
equal(u.node, 0)
@@ -408,6 +427,12 @@
equal(u.variant, uuid.RFC_4122)
equal(u.version, 4)
+ # Make sure the generated UUIDs are actually unique.
+ uuids = {}
+ for u in [uuid.uuid4() for i in range(1000)]:
+ uuids[u] = 1
+ equal(len(uuids.keys()), 1000)
+
def test_uuid5(self):
equal = self.assertEqual
Modified: python/branches/bcannon-objcap/Lib/test/test_xml_etree_c.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_xml_etree_c.py (original)
+++ python/branches/bcannon-objcap/Lib/test/test_xml_etree_c.py Mon Aug 28 21:49:46 2006
@@ -204,6 +204,17 @@
"<?xml version='1.0' encoding='%s'?><xml />" % encoding
)
+def bug_1534630():
+ """
+ >>> bob = ET.TreeBuilder()
+ >>> e = bob.data("data")
+ >>> e = bob.start("tag", {})
+ >>> e = bob.end("tag")
+ >>> e = bob.close()
+ >>> serialize(ET, e)
+ '<tag />'
+ """
+
def test_main():
from test import test_xml_etree_c
test_support.run_doctest(test_xml_etree_c, verbosity=True)
Modified: python/branches/bcannon-objcap/Lib/tokenize.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/tokenize.py (original)
+++ python/branches/bcannon-objcap/Lib/tokenize.py Mon Aug 28 21:49:46 2006
@@ -159,14 +159,73 @@
for token_info in generate_tokens(readline):
tokeneater(*token_info)
+class Untokenizer:
+
+ def __init__(self):
+ self.tokens = []
+ self.prev_row = 1
+ self.prev_col = 0
+
+ def add_whitespace(self, start):
+ row, col = start
+ assert row <= self.prev_row
+ col_offset = col - self.prev_col
+ if col_offset:
+ self.tokens.append(" " * col_offset)
+
+ def untokenize(self, iterable):
+ for t in iterable:
+ if len(t) == 2:
+ self.compat(t, iterable)
+ break
+ tok_type, token, start, end, line = t
+ self.add_whitespace(start)
+ self.tokens.append(token)
+ self.prev_row, self.prev_col = end
+ if tok_type in (NEWLINE, NL):
+ self.prev_row += 1
+ self.prev_col = 0
+ return "".join(self.tokens)
+
+ def compat(self, token, iterable):
+ startline = False
+ indents = []
+ toks_append = self.tokens.append
+ toknum, tokval = token
+ if toknum in (NAME, NUMBER):
+ tokval += ' '
+ if toknum in (NEWLINE, NL):
+ startline = True
+ for tok in iterable:
+ toknum, tokval = tok[:2]
+
+ if toknum in (NAME, NUMBER):
+ tokval += ' '
+
+ if toknum == INDENT:
+ indents.append(tokval)
+ continue
+ elif toknum == DEDENT:
+ indents.pop()
+ continue
+ elif toknum in (NEWLINE, NL):
+ startline = True
+ elif startline and indents:
+ toks_append(indents[-1])
+ startline = False
+ toks_append(tokval)
def untokenize(iterable):
"""Transform tokens back into Python source code.
Each element returned by the iterable must be a token sequence
- with at least two elements, a token number and token value.
+ with at least two elements, a token number and token value. If
+ only two tokens are passed, the resulting output is poor.
+
+ Round-trip invariant for full input:
+ Untokenized source will match input source exactly
- Round-trip invariant:
+ Round-trip invariant for limited intput:
# Output text will tokenize the back to the input
t1 = [tok[:2] for tok in generate_tokens(f.readline)]
newcode = untokenize(t1)
@@ -174,31 +233,8 @@
t2 = [tok[:2] for tokin generate_tokens(readline)]
assert t1 == t2
"""
-
- startline = False
- indents = []
- toks = []
- toks_append = toks.append
- for tok in iterable:
- toknum, tokval = tok[:2]
-
- if toknum in (NAME, NUMBER):
- tokval += ' '
-
- if toknum == INDENT:
- indents.append(tokval)
- continue
- elif toknum == DEDENT:
- indents.pop()
- continue
- elif toknum in (NEWLINE, COMMENT, NL):
- startline = True
- elif startline and indents:
- toks_append(indents[-1])
- startline = False
- toks_append(tokval)
- return ''.join(toks)
-
+ ut = Untokenizer()
+ return ut.untokenize(iterable)
def generate_tokens(readline):
"""
@@ -237,7 +273,7 @@
if endmatch:
pos = end = endmatch.end(0)
yield (STRING, contstr + line[:end],
- strstart, (lnum, end), contline + line)
+ strstart, (lnum, end), contline + line)
contstr, needcont = '', 0
contline = None
elif needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n':
@@ -263,7 +299,15 @@
if pos == max: break
if line[pos] in '#\r\n': # skip comments or blank lines
- yield ((NL, COMMENT)[line[pos] == '#'], line[pos:],
+ if line[pos] == '#':
+ comment_token = line[pos:].rstrip('\r\n')
+ nl_pos = pos + len(comment_token)
+ yield (COMMENT, comment_token,
+ (lnum, pos), (lnum, pos + len(comment_token)), line)
+ yield (NL, line[nl_pos:],
+ (lnum, nl_pos), (lnum, len(line)), line)
+ else:
+ yield ((NL, COMMENT)[line[pos] == '#'], line[pos:],
(lnum, pos), (lnum, len(line)), line)
continue
@@ -294,9 +338,10 @@
(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)
+ yield (NL if parenlev > 0 else NEWLINE,
+ token, spos, epos, line)
elif initial == '#':
+ assert not token.endswith("\n")
yield (COMMENT, token, spos, epos, line)
elif token in triple_quoted:
endprog = endprogs[token]
Modified: python/branches/bcannon-objcap/Lib/urllib2.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/urllib2.py (original)
+++ python/branches/bcannon-objcap/Lib/urllib2.py Mon Aug 28 21:49:46 2006
@@ -263,11 +263,11 @@
def add_header(self, key, val):
# useful for something like authentication
- self.headers[key.title()] = val
+ self.headers[key.capitalize()] = val
def add_unredirected_header(self, key, val):
# will not be added to a redirected request
- self.unredirected_hdrs[key.title()] = val
+ self.unredirected_hdrs[key.capitalize()] = val
def has_header(self, header_name):
return (header_name in self.headers or
@@ -286,7 +286,7 @@
class OpenerDirector:
def __init__(self):
client_version = "Python-urllib/%s" % __version__
- self.addheaders = [('User-Agent', client_version)]
+ self.addheaders = [('User-agent', client_version)]
# manage the individual handlers
self.handlers = []
self.handle_open = {}
@@ -675,7 +675,7 @@
if user and password:
user_pass = '%s:%s' % (unquote(user), unquote(password))
creds = base64.encodestring(user_pass).strip()
- req.add_header('Proxy-Authorization', 'Basic ' + creds)
+ req.add_header('Proxy-authorization', 'Basic ' + creds)
hostport = unquote(hostport)
req.set_proxy(hostport, proxy_type)
if orig_type == proxy_type:
@@ -819,7 +819,7 @@
class ProxyBasicAuthHandler(AbstractBasicAuthHandler, BaseHandler):
- auth_header = 'Proxy-Authorization'
+ auth_header = 'Proxy-authorization'
def http_error_407(self, req, fp, code, msg, headers):
# http_error_auth_reqed requires that there is no userinfo component in
@@ -1022,20 +1022,20 @@
if request.has_data(): # POST
data = request.get_data()
- if not request.has_header('Content-Type'):
+ if not request.has_header('Content-type'):
request.add_unredirected_header(
- 'Content-Type',
+ 'Content-type',
'application/x-www-form-urlencoded')
- if not request.has_header('Content-Length'):
+ if not request.has_header('Content-length'):
request.add_unredirected_header(
- 'Content-Length', '%d' % len(data))
+ 'Content-length', '%d' % len(data))
scheme, sel = splittype(request.get_selector())
sel_host, sel_path = splithost(sel)
if not request.has_header('Host'):
request.add_unredirected_header('Host', sel_host or host)
for name, value in self.parent.addheaders:
- name = name.title()
+ name = name.capitalize()
if not request.has_header(name):
request.add_unredirected_header(name, value)
@@ -1067,6 +1067,8 @@
# So make sure the connection gets closed after the (only)
# request.
headers["Connection"] = "close"
+ headers = dict(
+ (name.title(), val) for name, val in headers.items())
try:
h.request(req.get_method(), req.get_selector(), req.data, headers)
r = h.getresponse()
@@ -1217,7 +1219,7 @@
modified = email.Utils.formatdate(stats.st_mtime, usegmt=True)
mtype = mimetypes.guess_type(file)[0]
headers = mimetools.Message(StringIO(
- 'Content-Type: %s\nContent-Length: %d\nLast-Modified: %s\n' %
+ 'Content-type: %s\nContent-length: %d\nLast-modified: %s\n' %
(mtype or 'text/plain', size, modified)))
if host:
host, port = splitport(host)
@@ -1272,9 +1274,9 @@
headers = ""
mtype = mimetypes.guess_type(req.get_full_url())[0]
if mtype:
- headers += "Content-Type: %s\n" % mtype
+ headers += "Content-type: %s\n" % mtype
if retrlen is not None and retrlen >= 0:
- headers += "Content-Length: %d\n" % retrlen
+ headers += "Content-length: %d\n" % retrlen
sf = StringIO(headers)
headers = mimetools.Message(sf)
return addinfourl(fp, headers, req.get_full_url())
Modified: python/branches/bcannon-objcap/Lib/uuid.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/uuid.py (original)
+++ python/branches/bcannon-objcap/Lib/uuid.py Mon Aug 28 21:49:46 2006
@@ -45,8 +45,6 @@
"""
__author__ = 'Ka-Ping Yee <ping(a)zesty.ca>'
-__date__ = '$Date: 2006/06/12 23:15:40 $'.split()[1].replace('/', '-')
-__version__ = '$Revision: 1.30 $'.split()[1]
RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [
'reserved for NCS compatibility', 'specified in RFC 4122',
@@ -57,15 +55,21 @@
UUID objects are immutable, hashable, and usable as dictionary keys.
Converting a UUID to a string with str() yields something in the form
'12345678-1234-1234-1234-123456789abc'. The UUID constructor accepts
- four possible forms: a similar string of hexadecimal digits, or a
- string of 16 raw bytes as an argument named 'bytes', or a tuple of
- six integer fields (with 32-bit, 16-bit, 16-bit, 8-bit, 8-bit, and
- 48-bit values respectively) as an argument named 'fields', or a single
- 128-bit integer as an argument named 'int'.
+ five possible forms: a similar string of hexadecimal digits, or a tuple
+ of six integer fields (with 32-bit, 16-bit, 16-bit, 8-bit, 8-bit, and
+ 48-bit values respectively) as an argument named 'fields', or a string
+ of 16 bytes (with all the integer fields in big-endian order) as an
+ argument named 'bytes', or a string of 16 bytes (with the first three
+ fields in little-endian order) as an argument named 'bytes_le', or a
+ single 128-bit integer as an argument named 'int'.
UUIDs have these read-only attributes:
- bytes the UUID as a 16-byte string
+ bytes the UUID as a 16-byte string (containing the six
+ integer fields in big-endian byte order)
+
+ bytes_le the UUID as a 16-byte string (with time_low, time_mid,
+ and time_hi_version in little-endian byte order)
fields a tuple of the six integer fields of the UUID,
which are also available as six individual attributes
@@ -94,10 +98,11 @@
when the variant is RFC_4122)
"""
- def __init__(self, hex=None, bytes=None, fields=None, int=None,
- version=None):
+ def __init__(self, hex=None, bytes=None, bytes_le=None, fields=None,
+ int=None, version=None):
r"""Create a UUID from either a string of 32 hexadecimal digits,
- a string of 16 bytes as the 'bytes' argument, a tuple of six
+ a string of 16 bytes as the 'bytes' argument, a string of 16 bytes
+ in little-endian order as the 'bytes_le' argument, a tuple of six
integers (32-bit time_low, 16-bit time_mid, 16-bit time_hi_version,
8-bit clock_seq_hi_variant, 8-bit clock_seq_low, 48-bit node) as
the 'fields' argument, or a single 128-bit integer as the 'int'
@@ -109,23 +114,31 @@
UUID('12345678123456781234567812345678')
UUID('urn:uuid:12345678-1234-5678-1234-567812345678')
UUID(bytes='\x12\x34\x56\x78'*4)
+ UUID(bytes_le='\x78\x56\x34\x12\x34\x12\x78\x56' +
+ '\x12\x34\x56\x78\x12\x34\x56\x78')
UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678))
UUID(int=0x12345678123456781234567812345678)
- Exactly one of 'hex', 'bytes', 'fields', or 'int' must be given.
- The 'version' argument is optional; if given, the resulting UUID
- will have its variant and version number set according to RFC 4122,
- overriding bits in the given 'hex', 'bytes', 'fields', or 'int'.
+ Exactly one of 'hex', 'bytes', 'bytes_le', 'fields', or 'int' must
+ be given. The 'version' argument is optional; if given, the resulting
+ UUID will have its variant and version set according to RFC 4122,
+ overriding the given 'hex', 'bytes', 'bytes_le', 'fields', or 'int'.
"""
- if [hex, bytes, fields, int].count(None) != 3:
- raise TypeError('need just one of hex, bytes, fields, or int')
+ if [hex, bytes, bytes_le, fields, int].count(None) != 4:
+ raise TypeError('need one of hex, bytes, bytes_le, fields, or int')
if hex is not None:
hex = hex.replace('urn:', '').replace('uuid:', '')
hex = hex.strip('{}').replace('-', '')
if len(hex) != 32:
raise ValueError('badly formed hexadecimal UUID string')
int = long(hex, 16)
+ if bytes_le is not None:
+ if len(bytes_le) != 16:
+ raise ValueError('bytes_le is not a 16-char string')
+ bytes = (bytes_le[3] + bytes_le[2] + bytes_le[1] + bytes_le[0] +
+ bytes_le[5] + bytes_le[4] + bytes_le[7] + bytes_le[6] +
+ bytes_le[8:])
if bytes is not None:
if len(bytes) != 16:
raise ValueError('bytes is not a 16-char string')
@@ -194,6 +207,13 @@
bytes = property(get_bytes)
+ def get_bytes_le(self):
+ bytes = self.bytes
+ return (bytes[3] + bytes[2] + bytes[1] + bytes[0] +
+ bytes[5] + bytes[4] + bytes[7] + bytes[6] + bytes[8:])
+
+ bytes_le = property(get_bytes_le)
+
def get_fields(self):
return (self.time_low, self.time_mid, self.time_hi_version,
self.clock_seq_hi_variant, self.clock_seq_low, self.node)
@@ -448,6 +468,8 @@
if _node is not None:
return _node
+_last_timestamp = None
+
def uuid1(node=None, clock_seq=None):
"""Generate a UUID from a host ID, sequence number, and the current time.
If 'node' is not given, getnode() is used to obtain the hardware
@@ -460,11 +482,15 @@
_uuid_generate_time(_buffer)
return UUID(bytes=_buffer.raw)
+ global _last_timestamp
import time
nanoseconds = int(time.time() * 1e9)
# 0x01b21dd213814000 is the number of 100-ns intervals between the
# UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00.
timestamp = int(nanoseconds/100) + 0x01b21dd213814000L
+ if timestamp <= _last_timestamp:
+ timestamp = _last_timestamp + 1
+ _last_timestamp = timestamp
if clock_seq is None:
import random
clock_seq = random.randrange(1<<14L) # instead of stable storage
Modified: python/branches/bcannon-objcap/Makefile.pre.in
==============================================================================
--- python/branches/bcannon-objcap/Makefile.pre.in (original)
+++ python/branches/bcannon-objcap/Makefile.pre.in Mon Aug 28 21:49:46 2006
@@ -260,6 +260,7 @@
Python/modsupport.o \
Python/mystrtoul.o \
Python/mysnprintf.o \
+ Python/peephole.o \
Python/pyarena.o \
Python/pyfpe.o \
Python/pystate.o \
Modified: python/branches/bcannon-objcap/Misc/ACKS
==============================================================================
--- python/branches/bcannon-objcap/Misc/ACKS (original)
+++ python/branches/bcannon-objcap/Misc/ACKS Mon Aug 28 21:49:46 2006
@@ -242,6 +242,7 @@
Michael Guravage
Lars Gust�bel
Barry Haddow
+V�clav Haisman
Paul ten Hagen
Rasmus Hahn
Peter Haight
@@ -365,6 +366,7 @@
Soren Larsen
Piers Lauder
Ben Laurie
+Simon Law
Chris Lawrence
Christopher Lee
Inyeol Lee
Modified: python/branches/bcannon-objcap/Misc/NEWS
==============================================================================
--- python/branches/bcannon-objcap/Misc/NEWS (original)
+++ python/branches/bcannon-objcap/Misc/NEWS Mon Aug 28 21:49:46 2006
@@ -4,17 +4,66 @@
(editors: check NEWS.help for information about editing NEWS using ReST.)
+What's New in Python 2.6?
+=========================
+
+*Release date: XX-XXX-200X*
+
+Core and builtins
+-----------------
+
+- Patch #1542451: disallow continue anywhere under a finally.
+
+
+Library
+-------
+
+- Bug #1541863: uuid.uuid1 failed to generate unique identifiers
+ on systems with low clock resolution.
+
+
+Extension Modules
+-----------------
+
+
+Tests
+-----
+
+
+Documentation
+-------------
+
+- Bug #1541682: Fix example in the "Refcount details" API docs.
+ Additionally, remove a faulty example showing PySequence_SetItem applied
+ to a newly created list object and add notes that this isn't a good idea.
+
+
+Build
+-----
+
+
+C API
+-----
+
+- Bug #1542693: remove semi-colon at end of PyImport_ImportModuleEx macro
+ so it can be used as an expression.
+
+
+Mac
+---
+
+
What's New in Python 2.5 release candidate 1?
=============================================
-*Release date: 18-AUG-2006*
+*Release date: 17-AUG-2006*
Core and builtins
-----------------
- Unicode objects will no longer raise an exception when being
- compared equal or unequal to a string and causing a
- UnicodeDecodeError exception, e.g. as result of a decoding failure.
+ compared equal or unequal to a string and a UnicodeDecodeError
+ exception occurs, e.g. as result of a decoding failure.
Instead, the equal (==) and unequal (!=) comparison operators will
now issue a UnicodeWarning and interpret the two objects as
@@ -64,6 +113,30 @@
Library
-------
+- Fix a bug in the ``compiler`` package that caused invalid code to be
+ generated for generator expressions.
+
+- The distutils version has been changed to 2.5.0. The change to
+ keep it programmatically in sync with the Python version running
+ the code (introduced in 2.5b3) has been reverted. It will continue
+ to be maintained manually as static string literal.
+
+- If the Python part of a ctypes callback function returns None,
+ and this cannot be converted to the required C type, an exception is
+ printed with PyErr_WriteUnraisable. Before this change, the C
+ callback returned arbitrary values to the calling code.
+
+- The __repr__ method of a NULL ctypes.py_object() no longer raises
+ an exception.
+
+- uuid.UUID now has a bytes_le attribute. This returns the UUID in
+ little-endian byte order for Windows. In addition, uuid.py gained some
+ workarounds for clocks with low resolution, to stop the code yielding
+ duplicate UUIDs.
+
+- Patch #1540892: site.py Quitter() class attempts to close sys.stdin
+ before raising SystemExit, allowing IDLE to honor quit() and exit().
+
- Bug #1224621: make tabnanny recognize IndentationErrors raised by tokenize.
- Patch #1536071: trace.py should now find the full module name of a
@@ -72,7 +145,7 @@
- logging's atexit hook now runs even if the rest of the module has
already been cleaned up.
-- Bug #1112549, DoS attack on cgi.FieldStorage.
+- Bug #1112549, fix DoS attack on cgi.FieldStorage.
- Bug #1531405, format_exception no longer raises an exception if
str(exception) raised an exception.
@@ -124,9 +197,12 @@
Build
-----
+- Bug #1535502, build _hashlib on Windows, and use masm assembler
+ code in OpenSSL.
+
- Bug #1534738, win32 debug version of _msi should be _msi_d.pyd.
-- Bug #1530448, ctypes buld failure on Solaris 10 was fixed.
+- Bug #1530448, ctypes build failure on Solaris 10 was fixed.
C API
@@ -140,10 +216,6 @@
is always 1 (normal) or 0 (if the specified thread wasn't found).
-Mac
----
-
-
What's New in Python 2.5 beta 3?
================================
@@ -152,7 +224,7 @@
Core and builtins
-----------------
-- _PyWeakref_GetWeakrefCount() now returns a Py_ssize_t, it previously
+- _PyWeakref_GetWeakrefCount() now returns a Py_ssize_t; it previously
returned a long (see PEP 353).
- Bug #1515471: string.replace() accepts character buffers again.
@@ -194,7 +266,7 @@
This means that .pyc files generated before 2.5b3 will be regenerated.
- Bug #1524317: Compiling Python ``--without-threads`` failed.
- The Python core compiles again then, and, in a build without threads, the
+ The Python core compiles again, and, in a build without threads, the
new ``sys._current_frames()`` returns a dictionary with one entry,
mapping the faux "thread id" 0 to the current frame.
@@ -216,8 +288,8 @@
- Bug #1002398: The documentation for os.path.sameopenfile now correctly
refers to file descriptors, not file objects.
-- Rename of the xml package to xmlcore, and the import hackery done to
- make it appear at both names, has been removed. Bug #1511497,
+- The renaming of the xml package to xmlcore, and the import hackery done
+ to make it appear at both names, has been removed. Bug #1511497,
#1513611, and probably others.
- Bug #1441397: The compiler module now recognizes module and function
@@ -229,13 +301,13 @@
side effects from one test to the next affect outcomes. ``DocTestFinder``
has been changed to sort the list of tests it returns.
-- The distutils version has been changed to 2.5.0, and are now kept
+- The distutils version has been changed to 2.5.0, and is now kept
in sync with sys.version_info[:3].
- Bug #978833: Really close underlying socket in _socketobject.close.
-- Bug #1459963: urllib and urllib2 now normalize HTTP header names correctly
- with title().
+- Bug #1459963: urllib and urllib2 now normalize HTTP header names with
+ title().
- Patch #1525766: In pkgutil.walk_packages, correctly pass the onerror callback
to recursive calls and call it with the failing package name.
Deleted: /python/branches/bcannon-objcap/Misc/RPM/python-2.5.spec
==============================================================================
--- /python/branches/bcannon-objcap/Misc/RPM/python-2.5.spec Mon Aug 28 21:49:46 2006
+++ (empty file)
@@ -1,385 +0,0 @@
-##########################
-# User-modifiable configs
-##########################
-
-# Is the resulting package and the installed binary named "python" or
-# "python2"?
-#WARNING: Commenting out doesn't work. Last line is what's used.
-%define config_binsuffix none
-%define config_binsuffix 2.5
-
-# Build tkinter? "auto" enables it if /usr/bin/wish exists.
-#WARNING: Commenting out doesn't work. Last line is what's used.
-%define config_tkinter no
-%define config_tkinter yes
-%define config_tkinter auto
-
-# Use pymalloc? The last line (commented or not) determines wether
-# pymalloc is used.
-#WARNING: Commenting out doesn't work. Last line is what's used.
-%define config_pymalloc no
-%define config_pymalloc yes
-
-# Enable IPV6?
-#WARNING: Commenting out doesn't work. Last line is what's used.
-%define config_ipv6 yes
-%define config_ipv6 no
-
-# Location of the HTML directory.
-%define config_htmldir /var/www/html/python
-
-#################################
-# End of user-modifiable configs
-#################################
-
-%define name python
-%define version 2.5b3
-%define libvers 2.5
-%define release 1pydotorg
-%define __prefix /usr
-
-# kludge to get around rpm <percent>define weirdness
-%define ipv6 %(if [ "%{config_ipv6}" = yes ]; then echo --enable-ipv6; else echo --disable-ipv6; fi)
-%define pymalloc %(if [ "%{config_pymalloc}" = yes ]; then echo --with-pymalloc; else echo --without-pymalloc; fi)
-%define binsuffix %(if [ "%{config_binsuffix}" = none ]; then echo ; else echo "%{config_binsuffix}"; fi)
-%define include_tkinter %(if [ \\( "%{config_tkinter}" = auto -a -f /usr/bin/wish \\) -o "%{config_tkinter}" = yes ]; then echo 1; else echo 0; fi)
-%define libdirname %(( uname -m | egrep -q '_64$' && [ -d /usr/lib64 ] && echo lib64 ) || echo lib)
-
-# detect if documentation is available
-%define include_docs %(if [ -f "%{_sourcedir}/html-%{version}.tar.bz2" ]; then echo 1; else echo 0; fi)
-
-Summary: An interpreted, interactive, object-oriented programming language.
-Name: %{name}%{binsuffix}
-Version: %{version}
-Release: %{release}
-Copyright: Modified CNRI Open Source License
-Group: Development/Languages
-Source: Python-%{version}.tar.bz2
-%if %{include_docs}
-Source1: html-%{version}.tar.bz2
-%endif
-BuildRoot: %{_tmppath}/%{name}-%{version}-root
-BuildPrereq: expat-devel
-BuildPrereq: db4-devel
-BuildPrereq: gdbm-devel
-BuildPrereq: sqlite-devel
-Prefix: %{__prefix}
-Packager: Sean Reifschneider <jafo-rpms(a)tummy.com>
-
-%description
-Python is an interpreted, interactive, object-oriented programming
-language. It incorporates modules, exceptions, dynamic typing, very high
-level dynamic data types, and classes. Python combines remarkable power
-with very clear syntax. It has interfaces to many system calls and
-libraries, as well as to various window systems, and is extensible in C or
-C++. It is also usable as an extension language for applications that need
-a programmable interface. Finally, Python is portable: it runs on many
-brands of UNIX, on PCs under Windows, MS-DOS, and OS/2, and on the
-Mac.
-
-%package devel
-Summary: The libraries and header files needed for Python extension development.
-Prereq: python%{binsuffix} = %{PACKAGE_VERSION}
-Group: Development/Libraries
-
-%description devel
-The Python programming language's interpreter can be extended with
-dynamically loaded extensions and can be embedded in other programs.
-This package contains the header files and libraries needed to do
-these types of tasks.
-
-Install python-devel if you want to develop Python extensions. The
-python package will also need to be installed. You'll probably also
-want to install the python-docs package, which contains Python
-documentation.
-
-%if %{include_tkinter}
-%package tkinter
-Summary: A graphical user interface for the Python scripting language.
-Group: Development/Languages
-Prereq: python%{binsuffix} = %{PACKAGE_VERSION}-%{release}
-
-%description tkinter
-The Tkinter (Tk interface) program is an graphical user interface for
-the Python scripting language.
-
-You should install the tkinter package if you'd like to use a graphical
-user interface for Python programming.
-%endif
-
-%package tools
-Summary: A collection of development tools included with Python.
-Group: Development/Tools
-Prereq: python%{binsuffix} = %{PACKAGE_VERSION}-%{release}
-
-%description tools
-The Python package includes several development tools that are used
-to build python programs. This package contains a selection of those
-tools, including the IDLE Python IDE.
-
-Install python-tools if you want to use these tools to develop
-Python programs. You will also need to install the python and
-tkinter packages.
-
-%if %{include_docs}
-%package docs
-Summary: Python-related documentation.
-Group: Development/Documentation
-
-%description docs
-Documentation relating to the Python programming language in HTML and info
-formats.
-%endif
-
-%changelog
-* Mon Dec 20 2004 Sean Reifschneider <jafo-rpms(a)tummy.com> [2.4-2pydotorg]
-- Changing the idle wrapper so that it passes arguments to idle.
-
-* Tue Oct 19 2004 Sean Reifschneider <jafo-rpms(a)tummy.com> [2.4b1-1pydotorg]
-- Updating to 2.4.
-
-* Thu Jul 22 2004 Sean Reifschneider <jafo-rpms(a)tummy.com> [2.3.4-3pydotorg]
-- Paul Tiemann fixes for %{prefix}.
-- Adding permission changes for directory as suggested by reimeika.ca
-- Adding code to detect when it should be using lib64.
-- Adding a define for the location of /var/www/html for docs.
-
-* Thu May 27 2004 Sean Reifschneider <jafo-rpms(a)tummy.com> [2.3.4-2pydotorg]
-- Including changes from Ian Holsman to build under Red Hat 7.3.
-- Fixing some problems with the /usr/local path change.
-
-* Sat Mar 27 2004 Sean Reifschneider <jafo-rpms(a)tummy.com> [2.3.2-3pydotorg]
-- Being more agressive about finding the paths to fix for
- #!/usr/local/bin/python.
-
-* Sat Feb 07 2004 Sean Reifschneider <jafo-rpms(a)tummy.com> [2.3.3-2pydotorg]
-- Adding code to remove "#!/usr/local/bin/python" from particular files and
- causing the RPM build to terminate if there are any unexpected files
- which have that line in them.
-
-* Mon Oct 13 2003 Sean Reifschneider <jafo-rpms(a)tummy.com> [2.3.2-1pydotorg]
-- Adding code to detect wether documentation is available to build.
-
-* Fri Sep 19 2003 Sean Reifschneider <jafo-rpms(a)tummy.com> [2.3.1-1pydotorg]
-- Updating to the 2.3.1 release.
-
-* Mon Feb 24 2003 Sean Reifschneider <jafo-rpms(a)tummy.com> [2.3b1-1pydotorg]
-- Updating to 2.3b1 release.
-
-* Mon Feb 17 2003 Sean Reifschneider <jafo-rpms(a)tummy.com> [2.3a1-1]
-- Updating to 2.3 release.
-
-* Sun Dec 23 2001 Sean Reifschneider <jafo-rpms(a)tummy.com>
-[Release 2.2-2]
-- Added -docs package.
-- Added "auto" config_tkinter setting which only enables tk if
- /usr/bin/wish exists.
-
-* Sat Dec 22 2001 Sean Reifschneider <jafo-rpms(a)tummy.com>
-[Release 2.2-1]
-- Updated to 2.2.
-- Changed the extension to "2" from "2.2".
-
-* Tue Nov 18 2001 Sean Reifschneider <jafo-rpms(a)tummy.com>
-[Release 2.2c1-1]
-- Updated to 2.2c1.
-
-* Thu Nov 1 2001 Sean Reifschneider <jafo-rpms(a)tummy.com>
-[Release 2.2b1-3]
-- Changed the way the sed for fixing the #! in pydoc works.
-
-* Wed Oct 24 2001 Sean Reifschneider <jafo-rpms(a)tummy.com>
-[Release 2.2b1-2]
-- Fixed missing "email" package, thanks to anonymous report on sourceforge.
-- Fixed missing "compiler" package.
-
-* Mon Oct 22 2001 Sean Reifschneider <jafo-rpms(a)tummy.com>
-[Release 2.2b1-1]
-- Updated to 2.2b1.
-
-* Mon Oct 9 2001 Sean Reifschneider <jafo-rpms(a)tummy.com>
-[Release 2.2a4-4]
-- otto(a)balinor.mat.unimi.it mentioned that the license file is missing.
-
-* Sun Sep 30 2001 Sean Reifschneider <jafo-rpms(a)tummy.com>
-[Release 2.2a4-3]
-- Ignacio Vazquez-Abrams pointed out that I had a spruious double-quote in
- the spec files. Thanks.
-
-* Wed Jul 25 2001 Sean Reifschneider <jafo-rpms(a)tummy.com>
-[Release 2.2a1-1]
-- Updated to 2.2a1 release.
-- Changed idle and pydoc to use binsuffix macro
-
-#######
-# PREP
-#######
-%prep
-%setup -n Python-%{version}
-
-########
-# BUILD
-########
-%build
-./configure --enable-unicode=ucs4 %{ipv6} %{pymalloc} --prefix=%{__prefix}
-make
-
-##########
-# INSTALL
-##########
-%install
-# set the install path
-echo '[install_scripts]' >setup.cfg
-echo 'install_dir='"${RPM_BUILD_ROOT}%{__prefix}/bin" >>setup.cfg
-
-[ -d "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
-mkdir -p $RPM_BUILD_ROOT%{__prefix}/%{libdirname}/python%{libvers}/lib-dynload
-make prefix=$RPM_BUILD_ROOT%{__prefix} install
-
-# REPLACE PATH IN PYDOC
-if [ ! -z "%{binsuffix}" ]
-then
- (
- cd $RPM_BUILD_ROOT%{__prefix}/bin
- mv pydoc pydoc.old
- sed 's|#!.*|#!%{__prefix}/bin/env python'%{binsuffix}'|' \
- pydoc.old >pydoc
- chmod 755 pydoc
- rm -f pydoc.old
- )
-fi
-
-# add the binsuffix
-if [ ! -z "%{binsuffix}" ]
-then
- ( cd $RPM_BUILD_ROOT%{__prefix}/bin; rm -f python[0-9a-zA-Z]*;
- mv -f python python"%{binsuffix}" )
- ( cd $RPM_BUILD_ROOT%{__prefix}/man/man1; mv python.1 python%{binsuffix}.1 )
- ( cd $RPM_BUILD_ROOT%{__prefix}/bin; mv -f pydoc pydoc"%{binsuffix}" )
- ( cd $RPM_BUILD_ROOT%{__prefix}/bin; mv -f idle idle"%{binsuffix}" )
-fi
-
-########
-# Tools
-echo '#!%{__prefix}/bin/env python%{binsuffix}' >${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix}
-echo 'import os, sys' >>${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix}
-echo 'os.execvp("%{__prefix}/bin/python%{binsuffix}", ["%{__prefix}/bin/python%{binsuffix}", "%{__prefix}/lib/python%{libvers}/idlelib/idle.py"] + sys.argv[1:])' >>${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix}
-echo 'print "Failed to exec Idle"' >>${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix}
-echo 'sys.exit(1)' >>${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix}
-chmod 755 $RPM_BUILD_ROOT%{__prefix}/bin/idle%{binsuffix}
-cp -a Tools $RPM_BUILD_ROOT%{__prefix}/%{libdirname}/python%{libvers}
-
-# MAKE FILE LISTS
-rm -f mainpkg.files
-find "$RPM_BUILD_ROOT""%{__prefix}"/%{libdirname}/python%{libvers}/lib-dynload -type f |
- sed "s|^${RPM_BUILD_ROOT}|/|" |
- grep -v -e '_tkinter.so$' >mainpkg.files
-find "$RPM_BUILD_ROOT""%{__prefix}"/bin -type f |
- sed "s|^${RPM_BUILD_ROOT}|/|" |
- grep -v -e '/bin/idle%{binsuffix}$' >>mainpkg.files
-
-rm -f tools.files
-find "$RPM_BUILD_ROOT""%{__prefix}"/%{libdirname}/python%{libvers}/idlelib \
- "$RPM_BUILD_ROOT""%{__prefix}"/%{libdirname}/python%{libvers}/Tools -type f |
- sed "s|^${RPM_BUILD_ROOT}|/|" >tools.files
-echo "%{__prefix}"/bin/idle%{binsuffix} >>tools.files
-
-######
-# Docs
-%if %{include_docs}
-mkdir -p "$RPM_BUILD_ROOT"%{config_htmldir}
-(
- cd "$RPM_BUILD_ROOT"%{config_htmldir}
- bunzip2 < %{SOURCE1} | tar x
-)
-%endif
-
-# fix the #! line in installed files
-find "$RPM_BUILD_ROOT" -type f -print0 |
- xargs -0 grep -l /usr/local/bin/python | while read file
-do
- FIXFILE="$file"
- sed 's|^#!.*python|#!%{__prefix}/bin/env python'"%{binsuffix}"'|' \
- "$FIXFILE" >/tmp/fix-python-path.$$
- cat /tmp/fix-python-path.$$ >"$FIXFILE"
- rm -f /tmp/fix-python-path.$$
-done
-
-# check to see if there are any straggling #! lines
-find "$RPM_BUILD_ROOT" -type f | xargs egrep -n '^#! */usr/local/bin/python' \
- | grep ':1:#!' >/tmp/python-rpm-files.$$ || true
-if [ -s /tmp/python-rpm-files.$$ ]
-then
- echo '*****************************************************'
- cat /tmp/python-rpm-files.$$
- cat <<@EOF
- *****************************************************
- There are still files referencing /usr/local/bin/python in the
- install directory. They are listed above. Please fix the .spec
- file and try again. If you are an end-user, you probably want
- to report this to jafo-rpms(a)tummy.com as well.
- *****************************************************
-@EOF
- rm -f /tmp/python-rpm-files.$$
- exit 1
-fi
-rm -f /tmp/python-rpm-files.$$
-
-########
-# CLEAN
-########
-%clean
-[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf $RPM_BUILD_ROOT
-rm -f mainpkg.files tools.files
-
-########
-# FILES
-########
-%files -f mainpkg.files
-%defattr(-,root,root)
-%doc Misc/README Misc/cheatsheet Misc/Porting
-%doc LICENSE Misc/ACKS Misc/HISTORY Misc/NEWS
-%{__prefix}/man/man1/python%{binsuffix}.1*
-
-%attr(755,root,root) %dir %{__prefix}/include/python%{libvers}
-%attr(755,root,root) %dir %{__prefix}/%{libdirname}/python%{libvers}/
-%{__prefix}/%{libdirname}/python%{libvers}/*.txt
-%{__prefix}/%{libdirname}/python%{libvers}/*.py*
-%{__prefix}/%{libdirname}/python%{libvers}/pdb.doc
-%{__prefix}/%{libdirname}/python%{libvers}/profile.doc
-%{__prefix}/%{libdirname}/python%{libvers}/curses
-%{__prefix}/%{libdirname}/python%{libvers}/distutils
-%{__prefix}/%{libdirname}/python%{libvers}/encodings
-%{__prefix}/%{libdirname}/python%{libvers}/plat-linux2
-%{__prefix}/%{libdirname}/python%{libvers}/site-packages
-%{__prefix}/%{libdirname}/python%{libvers}/test
-%{__prefix}/%{libdirname}/python%{libvers}/xml
-%{__prefix}/%{libdirname}/python%{libvers}/email
-%{__prefix}/%{libdirname}/python%{libvers}/email/mime
-%{__prefix}/%{libdirname}/python%{libvers}/sqlite3
-%{__prefix}/%{libdirname}/python%{libvers}/compiler
-%{__prefix}/%{libdirname}/python%{libvers}/bsddb
-%{__prefix}/%{libdirname}/python%{libvers}/hotshot
-%{__prefix}/%{libdirname}/python%{libvers}/logging
-%{__prefix}/%{libdirname}/python%{libvers}/lib-old
-
-%files devel
-%defattr(-,root,root)
-%{__prefix}/include/python%{libvers}/*.h
-%{__prefix}/%{libdirname}/python%{libvers}/config
-
-%files -f tools.files tools
-%defattr(-,root,root)
-
-%if %{include_tkinter}
-%files tkinter
-%defattr(-,root,root)
-%{__prefix}/%{libdirname}/python%{libvers}/lib-tk
-%{__prefix}/%{libdirname}/python%{libvers}/lib-dynload/_tkinter.so*
-%endif
-
-%if %{include_docs}
-%files docs
-%defattr(-,root,root)
-%{config_htmldir}/*
-%endif
Modified: python/branches/bcannon-objcap/Misc/build.sh
==============================================================================
--- python/branches/bcannon-objcap/Misc/build.sh (original)
+++ python/branches/bcannon-objcap/Misc/build.sh Mon Aug 28 21:49:46 2006
@@ -58,7 +58,7 @@
PYTHON=$INSTALL_DIR/bin/python
# Python options and regression test program that should always be run.
-REGRTEST_ARGS="-E -tt $INSTALL_DIR/lib/python2.5/test/regrtest.py"
+REGRTEST_ARGS="-E -tt $INSTALL_DIR/lib/python2.6/test/regrtest.py"
REFLOG="build/reflog.txt.out"
# These tests are not stable and falsely report leaks sometimes.
Modified: python/branches/bcannon-objcap/Modules/_ctypes/_ctypes.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_ctypes/_ctypes.c (original)
+++ python/branches/bcannon-objcap/Modules/_ctypes/_ctypes.c Mon Aug 28 21:49:46 2006
@@ -152,7 +152,7 @@
parg->tag = 'V';
stgdict = PyObject_stgdict((PyObject *)self);
- assert(stgdict);
+ assert(stgdict); /* Cannot be NULL for structure/union instances */
parg->pffi_type = &stgdict->ffi_type_pointer;
/* For structure parameters (by value), parg->value doesn't contain the structure
data itself, instead parg->value.p *points* to the structure's data
@@ -328,7 +328,6 @@
/* If we got a PyCArgObject, we must check if the object packed in it
is an instance of the type's dict->proto */
-// if(dict && ob && dict->proto == (PyObject *)ob->ob_type){
if(dict && ob
&& PyObject_IsInstance(ob, dict->proto)) {
Py_INCREF(value);
@@ -673,6 +672,7 @@
return PyInt_FromLong(0); /* NULL pointer */
typedict = PyType_stgdict(type);
+ assert(typedict); /* Cannot be NULL for pointer types */
/* If we expect POINTER(<type>), but receive a <type> instance, accept
it by calling byref(<type>).
@@ -693,6 +693,7 @@
the item types are the same.
*/
StgDictObject *v = PyObject_stgdict(value);
+ assert(v); /* Cannot be NULL for pointer or array objects */
if (PyObject_IsSubclass(v->proto, typedict->proto)) {
Py_INCREF(value);
return value;
@@ -1154,7 +1155,9 @@
if (ArrayObject_Check(value) || PointerObject_Check(value)) {
/* c_wchar array instance or pointer(c_wchar(...)) */
StgDictObject *dt = PyObject_stgdict(value);
- StgDictObject *dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
+ StgDictObject *dict;
+ assert(dt); /* Cannot be NULL for pointer or array objects */
+ dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
if (dict && (dict->setfunc == getentry("u")->setfunc)) {
Py_INCREF(value);
return value;
@@ -1216,7 +1219,9 @@
if (ArrayObject_Check(value) || PointerObject_Check(value)) {
/* c_char array instance or pointer(c_char(...)) */
StgDictObject *dt = PyObject_stgdict(value);
- StgDictObject *dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
+ StgDictObject *dict;
+ assert(dt); /* Cannot be NULL for pointer or array objects */
+ dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
if (dict && (dict->setfunc == getentry("c")->setfunc)) {
Py_INCREF(value);
return value;
@@ -1468,7 +1473,7 @@
struct fielddesc *fd;
dict = PyObject_stgdict((PyObject *)self);
- assert(dict);
+ assert(dict); /* Cannot be NULL for CDataObject instances */
fmt = PyString_AsString(dict->proto);
assert(fmt);
@@ -2066,6 +2071,7 @@
CData_clear(CDataObject *self)
{
StgDictObject *dict = PyObject_stgdict((PyObject *)self);
+ assert(dict); /* Cannot be NULL for CDataObject instances */
Py_CLEAR(self->b_objects);
if ((self->b_needsfree)
&& ((size_t)dict->size > sizeof(self->b_value)))
@@ -2363,7 +2369,9 @@
StgDictObject *p1, *p2;
PyObject *keep;
p1 = PyObject_stgdict(value);
+ assert(p1); /* Cannot be NULL for array instances */
p2 = PyType_stgdict(type);
+ assert(p2); /* Cannot be NULL for pointer types */
if (p1->proto != p2->proto) {
PyErr_Format(PyExc_TypeError,
@@ -2512,7 +2520,7 @@
return self->restype;
}
dict = PyObject_stgdict((PyObject *)self);
- assert(dict);
+ assert(dict); /* Cannot be NULL for CFuncPtrObject instances */
if (dict->restype) {
Py_INCREF(dict->restype);
return dict->restype;
@@ -2554,7 +2562,7 @@
return self->argtypes;
}
dict = PyObject_stgdict((PyObject *)self);
- assert(dict);
+ assert(dict); /* Cannot be NULL for CFuncPtrObject instances */
if (dict->argtypes) {
Py_INCREF(dict->argtypes);
return dict->argtypes;
@@ -2581,16 +2589,22 @@
PPROC address;
char *mangled_name;
int i;
- StgDictObject *dict = PyType_stgdict((PyObject *)type);
+ StgDictObject *dict;
address = (PPROC)GetProcAddress(handle, name);
+#ifdef _WIN64
+ /* win64 has no stdcall calling conv, so it should
+ also not have the name mangling of it.
+ */
+ return address;
+#else
if (address)
return address;
-
if (((size_t)name & ~0xFFFF) == 0) {
return NULL;
}
+ dict = PyType_stgdict((PyObject *)type);
/* It should not happen that dict is NULL, but better be safe */
if (dict==NULL || dict->flags & FUNCFLAG_CDECL)
return address;
@@ -2609,6 +2623,7 @@
return address;
}
return NULL;
+#endif
}
#endif
@@ -2647,8 +2662,12 @@
_validate_paramflags(PyTypeObject *type, PyObject *paramflags)
{
int i, len;
- StgDictObject *dict = PyType_stgdict((PyObject *)type);
- PyObject *argtypes = dict->argtypes;
+ StgDictObject *dict;
+ PyObject *argtypes;
+
+ dict = PyType_stgdict((PyObject *)type);
+ assert(dict); /* Cannot be NULL. 'type' is a CFuncPtr type. */
+ argtypes = dict->argtypes;
if (paramflags == NULL || dict->argtypes == NULL)
return 1;
@@ -3118,6 +3137,13 @@
}
ob = PyTuple_GET_ITEM(argtypes, i);
dict = PyType_stgdict(ob);
+ if (dict == NULL) {
+ /* Cannot happen: _validate_paramflags()
+ would not accept such an object */
+ PyErr_Format(PyExc_RuntimeError,
+ "NULL stgdict unexpected");
+ goto error;
+ }
if (PyString_Check(dict->proto)) {
PyErr_Format(
PyExc_TypeError,
@@ -3260,7 +3286,7 @@
int outmask;
unsigned int numretvals;
- assert(dict); /* if not, it's a bug */
+ assert(dict); /* Cannot be NULL for CFuncPtrObject instances */
restype = self->restype ? self->restype : dict->restype;
converters = self->converters ? self->converters : dict->converters;
checker = self->checker ? self->checker : dict->checker;
@@ -3681,7 +3707,7 @@
}
stgdict = PyObject_stgdict((PyObject *)self);
- assert(stgdict);
+ assert(stgdict); /* Cannot be NULL for array instances */
/* Would it be clearer if we got the item size from
stgdict->proto's stgdict?
*/
@@ -3712,8 +3738,11 @@
len = ihigh - ilow;
stgdict = PyObject_stgdict((PyObject *)self);
+ assert(stgdict); /* Cannot be NULL for array object instances */
proto = stgdict->proto;
itemdict = PyType_stgdict(proto);
+ assert(itemdict); /* proto is the item type of the array, a ctypes
+ type, so this cannot be NULL */
if (itemdict->getfunc == getentry("c")->getfunc) {
char *ptr = (char *)self->b_ptr;
return PyString_FromStringAndSize(ptr + ilow, len);
@@ -3750,6 +3779,7 @@
}
stgdict = PyObject_stgdict((PyObject *)self);
+ assert(stgdict); /* Cannot be NULL for array object instances */
if (index < 0 || index >= stgdict->length) {
PyErr_SetString(PyExc_IndexError,
"invalid index");
@@ -3941,6 +3971,7 @@
PyObject *result;
StgDictObject *dict = PyObject_stgdict((PyObject *)self);
+ assert(dict); /* Cannot be NULL for CDataObject instances */
assert(dict->setfunc);
result = dict->setfunc(self->b_ptr, value, dict->size);
if (!result)
@@ -3966,8 +3997,8 @@
{
StgDictObject *dict;
dict = PyObject_stgdict((PyObject *)self);
+ assert(dict); /* Cannot be NULL for CDataObject instances */
assert(dict->getfunc);
- dict = PyObject_stgdict((PyObject *)self);
return dict->getfunc(self->b_ptr, self->b_size);
}
@@ -4140,12 +4171,14 @@
}
stgdict = PyObject_stgdict((PyObject *)self);
- assert(stgdict);
- assert(stgdict->proto);
+ assert(stgdict); /* Cannot be NULL for pointer object instances */
proto = stgdict->proto;
- /* XXXXXX MAKE SURE PROTO IS NOT NULL! */
+ assert(proto);
itemdict = PyType_stgdict(proto);
+ assert(itemdict); /* proto is the item type of the pointer, a ctypes
+ type, so this cannot be NULL */
+
size = itemdict->size;
offset = index * itemdict->size;
@@ -4175,12 +4208,15 @@
}
stgdict = PyObject_stgdict((PyObject *)self);
- assert(stgdict);
- assert(stgdict->proto);
+ assert(stgdict); /* Cannot be NULL fr pointer instances */
proto = stgdict->proto;
- /* XXXXXX MAKE SURE PROTO IS NOT NULL! */
+ assert(proto);
+
itemdict = PyType_stgdict(proto);
+ assert(itemdict); /* Cannot be NULL because the itemtype of a pointer
+ is always a ctypes type */
+
size = itemdict->size;
offset = index * itemdict->size;
@@ -4200,7 +4236,7 @@
}
stgdict = PyObject_stgdict((PyObject *)self);
- assert(stgdict);
+ assert(stgdict); /* Cannot be NULL fr pointer instances */
return CData_FromBaseObj(stgdict->proto,
(PyObject *)self, 0,
*(void **)self->b_ptr);
@@ -4219,7 +4255,7 @@
return -1;
}
stgdict = PyObject_stgdict((PyObject *)self);
- /* should have been catched in Pointer_new() */
+ assert(stgdict); /* Cannot be NULL fr pointer instances */
assert(stgdict->proto);
if (!CDataObject_Check(value)
|| 0 == PyObject_IsInstance(value, stgdict->proto)) {
@@ -4295,8 +4331,11 @@
len = ihigh - ilow;
stgdict = PyObject_stgdict((PyObject *)self);
+ assert(stgdict); /* Cannot be NULL fr pointer instances */
proto = stgdict->proto;
+ assert(proto);
itemdict = PyType_stgdict(proto);
+ assert(itemdict);
if (itemdict->getfunc == getentry("c")->getfunc) {
char *ptr = *(char **)self->b_ptr;
return PyString_FromStringAndSize(ptr + ilow, len);
Modified: python/branches/bcannon-objcap/Modules/_ctypes/_ctypes_test.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_ctypes/_ctypes_test.c (original)
+++ python/branches/bcannon-objcap/Modules/_ctypes/_ctypes_test.c Mon Aug 28 21:49:46 2006
@@ -25,6 +25,16 @@
/* some functions handy for testing */
+EXPORT(int)myprintf(char *fmt, ...)
+{
+ int result;
+ va_list argptr;
+ va_start(argptr, fmt);
+ result = vprintf(fmt, argptr);
+ va_end(argptr);
+ return result;
+}
+
EXPORT(char *)my_strtok(char *token, const char *delim)
{
return strtok(token, delim);
Modified: python/branches/bcannon-objcap/Modules/_ctypes/callbacks.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_ctypes/callbacks.c (original)
+++ python/branches/bcannon-objcap/Modules/_ctypes/callbacks.c Mon Aug 28 21:49:46 2006
@@ -205,7 +205,7 @@
result = PyObject_CallObject(callable, arglist);
CHECK("'calling callback function'", result);
- if ((restype != &ffi_type_void) && result && result != Py_None) {
+ if ((restype != &ffi_type_void) && result) {
PyObject *keep;
assert(setfunc);
#ifdef WORDS_BIGENDIAN
@@ -300,7 +300,7 @@
}
cc = FFI_DEFAULT_ABI;
-#if defined(MS_WIN32) && !defined(_WIN32_WCE)
+#if defined(MS_WIN32) && !defined(_WIN32_WCE) && !defined(MS_WIN64)
if (is_cdecl == 0)
cc = FFI_STDCALL;
#endif
Modified: python/branches/bcannon-objcap/Modules/_ctypes/callproc.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_ctypes/callproc.c (original)
+++ python/branches/bcannon-objcap/Modules/_ctypes/callproc.c Mon Aug 28 21:49:46 2006
@@ -638,7 +638,7 @@
}
cc = FFI_DEFAULT_ABI;
-#if defined(MS_WIN32) && !defined(_WIN32_WCE)
+#if defined(MS_WIN32) && !defined(MS_WIN64) && !defined(_WIN32_WCE)
if ((flags & FUNCFLAG_CDECL) == 0)
cc = FFI_STDCALL;
#endif
@@ -683,6 +683,14 @@
return -1;
}
#endif
+#ifdef MS_WIN64
+ if (delta != 0) {
+ PyErr_Format(PyExc_RuntimeError,
+ "ffi_call failed with code %d",
+ delta);
+ return -1;
+ }
+#else
if (delta < 0) {
if (flags & FUNCFLAG_CDECL)
PyErr_Format(PyExc_ValueError,
@@ -704,6 +712,7 @@
return -1;
}
#endif
+#endif
if ((flags & FUNCFLAG_PYTHONAPI) && PyErr_Occurred())
return -1;
return 0;
@@ -979,7 +988,11 @@
}
for (i = 0; i < argcount; ++i) {
atypes[i] = args[i].ffi_type;
- if (atypes[i]->type == FFI_TYPE_STRUCT)
+ if (atypes[i]->type == FFI_TYPE_STRUCT
+#ifdef _WIN64
+ && atypes[i]->size <= sizeof(void *)
+#endif
+ )
avalues[i] = (void *)args[i].value.p;
else
avalues[i] = (void *)&args[i].value;
@@ -1099,7 +1112,11 @@
hMod = LoadLibrary(name);
if (!hMod)
return PyErr_SetFromWindowsErr(GetLastError());
+#ifdef _WIN64
+ return PyLong_FromVoidPtr(hMod);
+#else
return Py_BuildValue("i", hMod);
+#endif
}
static char free_library_doc[] =
Modified: python/branches/bcannon-objcap/Modules/_ctypes/cfield.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_ctypes/cfield.c (original)
+++ python/branches/bcannon-objcap/Modules/_ctypes/cfield.c Mon Aug 28 21:49:46 2006
@@ -1100,7 +1100,7 @@
if (!PyErr_Occurred())
/* Set an error if not yet set */
PyErr_SetString(PyExc_ValueError,
- "PyObject is NULL?");
+ "PyObject is NULL");
return NULL;
}
Py_INCREF(ob);
@@ -1315,7 +1315,11 @@
*(char **)ptr = PyString_AS_STRING(str);
return str;
} else if (PyInt_Check(value) || PyLong_Check(value)) {
+#if SIZEOF_VOID_P == SIZEOF_LONG_LONG
+ *(char **)ptr = (char *)PyInt_AsUnsignedLongLongMask(value);
+#else
*(char **)ptr = (char *)PyInt_AsUnsignedLongMask(value);
+#endif
_RET(value);
}
PyErr_Format(PyExc_TypeError,
@@ -1360,7 +1364,11 @@
if (!value)
return NULL;
} else if (PyInt_Check(value) || PyLong_Check(value)) {
+#if SIZEOF_VOID_P == SIZEOF_LONG_LONG
+ *(wchar_t **)ptr = (wchar_t *)PyInt_AsUnsignedLongLongMask(value);
+#else
*(wchar_t **)ptr = (wchar_t *)PyInt_AsUnsignedLongMask(value);
+#endif
Py_INCREF(Py_None);
return Py_None;
} else if (!PyUnicode_Check(value)) {
Modified: python/branches/bcannon-objcap/Modules/_ctypes/libffi_msvc/ffi.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_ctypes/libffi_msvc/ffi.c (original)
+++ python/branches/bcannon-objcap/Modules/_ctypes/libffi_msvc/ffi.c Mon Aug 28 21:49:46 2006
@@ -34,6 +34,8 @@
/* ffi_prep_args is called by the assembly routine once stack space
has been allocated for the function's arguments */
+extern void Py_FatalError(char *msg);
+
/*@-exportheader@*/
void ffi_prep_args(char *stack, extended_cif *ecif)
/*@=exportheader@*/
@@ -44,11 +46,10 @@
register ffi_type **p_arg;
argp = stack;
-
if (ecif->cif->rtype->type == FFI_TYPE_STRUCT)
{
*(void **) argp = ecif->rvalue;
- argp += 4;
+ argp += sizeof(void *);
}
p_argv = ecif->avalue;
@@ -60,8 +61,8 @@
size_t z;
/* Align if necessary */
- if ((sizeof(int) - 1) & (unsigned) argp)
- argp = (char *) ALIGN(argp, sizeof(int));
+ if ((sizeof(void *) - 1) & (size_t) argp)
+ argp = (char *) ALIGN(argp, sizeof(void *));
z = (*p_arg)->size;
if (z < sizeof(int))
@@ -108,7 +109,11 @@
p_argv++;
argp += z;
}
-
+
+ if (argp - stack > ecif->cif->bytes)
+ {
+ Py_FatalError("FFI BUG: not enough stack space for arguments");
+ }
return;
}
@@ -128,6 +133,9 @@
break;
case FFI_TYPE_UINT64:
+#ifdef _WIN64
+ case FFI_TYPE_POINTER:
+#endif
cif->flags = FFI_TYPE_SINT64;
break;
@@ -139,6 +147,7 @@
return FFI_OK;
}
+#ifdef _WIN32
/*@-declundef@*/
/*@-exportheader@*/
extern int
@@ -160,6 +169,16 @@
void (*fn)());
/*@=declundef@*/
/*@=exportheader@*/
+#endif
+
+#ifdef _WIN64
+extern int
+ffi_call_AMD64(void (*)(char *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)());
+#endif
int
ffi_call(/*@dependent@*/ ffi_cif *cif,
@@ -188,6 +207,7 @@
switch (cif->abi)
{
+#if !defined(_WIN64)
case FFI_SYSV:
/*@-usedef@*/
return ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes,
@@ -201,6 +221,14 @@
cif->flags, ecif.rvalue, fn);
/*@=usedef@*/
break;
+#else
+ case FFI_SYSV:
+ /*@-usedef@*/
+ return ffi_call_AMD64(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+#endif
default:
FFI_ASSERT(0);
@@ -213,10 +241,14 @@
/** private members **/
static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
- void** args, ffi_cif* cif);
+ void** args, ffi_cif* cif);
/* This function is jumped to by the trampoline */
+#ifdef _WIN64
+void *
+#else
static void __fastcall
+#endif
ffi_closure_SYSV (ffi_closure *closure, int *argp)
{
// this is our return value storage
@@ -244,6 +276,7 @@
rtype = cif->flags;
+#if defined(_WIN32) && !defined(_WIN64)
#ifdef _MSC_VER
/* now, do a generic return based on the value of rtype */
if (rtype == FFI_TYPE_INT)
@@ -303,6 +336,15 @@
: "eax", "edx");
}
#endif
+#endif
+
+#ifdef _WIN64
+ /* The result is returned in rax. This does the right thing for
+ result types except for floats; we have to 'mov xmm0, rax' in the
+ caller to correct this.
+ */
+ return *(void **)resp;
+#endif
}
/*@-exportheader@*/
@@ -330,8 +372,8 @@
size_t z;
/* Align if necessary */
- if ((sizeof(int) - 1) & (unsigned) argp) {
- argp = (char *) ALIGN(argp, sizeof(int));
+ if ((sizeof(char *) - 1) & (size_t) argp) {
+ argp = (char *) ALIGN(argp, sizeof(char*));
}
z = (*p_arg)->size;
@@ -347,24 +389,8 @@
return;
}
-/* How to make a trampoline. Derived from gcc/config/i386/i386.c. */
-
-#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX,BYTES) \
-{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
- unsigned int __fun = (unsigned int)(FUN); \
- unsigned int __ctx = (unsigned int)(CTX); \
- unsigned int __dis = __fun - ((unsigned int) __tramp + 8 + 4); \
- *(unsigned char*) &__tramp[0] = 0xb9; \
- *(unsigned int*) &__tramp[1] = __ctx; /* mov ecx, __ctx */ \
- *(unsigned char*) &__tramp[5] = 0x8b; \
- *(unsigned char*) &__tramp[6] = 0xd4; /* mov edx, esp */ \
- *(unsigned char*) &__tramp[7] = 0xe8; \
- *(unsigned int*) &__tramp[8] = __dis; /* call __fun */ \
- *(unsigned char*) &__tramp[12] = 0xC2; /* ret BYTES */ \
- *(unsigned short*) &__tramp[13] = BYTES; \
- }
-
/* the cif must already be prep'ed */
+extern void ffi_closure_OUTER();
ffi_status
ffi_prep_closure (ffi_closure* closure,
@@ -373,19 +399,78 @@
void *user_data)
{
short bytes;
+ char *tramp;
+#ifdef _WIN64
+ int mask;
+#endif
FFI_ASSERT (cif->abi == FFI_SYSV);
if (cif->abi == FFI_SYSV)
bytes = 0;
+#if !defined(_WIN64)
else if (cif->abi == FFI_STDCALL)
bytes = cif->bytes;
+#endif
else
return FFI_BAD_ABI;
- FFI_INIT_TRAMPOLINE (&closure->tramp[0],
- &ffi_closure_SYSV,
- (void*)closure,
- bytes);
+ tramp = &closure->tramp[0];
+
+#define BYTES(text) memcpy(tramp, text, sizeof(text)), tramp += sizeof(text)-1
+#define POINTER(x) *(void**)tramp = (void*)(x), tramp += sizeof(void*)
+#define SHORT(x) *(short*)tramp = x, tramp += sizeof(short)
+#define INT(x) *(int*)tramp = x, tramp += sizeof(int)
+
+#ifdef _WIN64
+ if (cif->nargs >= 1 &&
+ (cif->arg_types[0]->type == FFI_TYPE_FLOAT
+ || cif->arg_types[0]->type == FFI_TYPE_DOUBLE))
+ mask |= 1;
+ if (cif->nargs >= 2 &&
+ (cif->arg_types[1]->type == FFI_TYPE_FLOAT
+ || cif->arg_types[1]->type == FFI_TYPE_DOUBLE))
+ mask |= 2;
+ if (cif->nargs >= 3 &&
+ (cif->arg_types[2]->type == FFI_TYPE_FLOAT
+ || cif->arg_types[2]->type == FFI_TYPE_DOUBLE))
+ mask |= 4;
+ if (cif->nargs >= 4 &&
+ (cif->arg_types[3]->type == FFI_TYPE_FLOAT
+ || cif->arg_types[3]->type == FFI_TYPE_DOUBLE))
+ mask |= 8;
+
+ /* 41 BB ---- mov r11d,mask */
+ BYTES("\x41\xBB"); INT(mask);
+
+ /* 48 B8 -------- mov rax, closure */
+ BYTES("\x48\xB8"); POINTER(closure);
+
+ /* 49 BA -------- mov r10, ffi_closure_OUTER */
+ BYTES("\x49\xBA"); POINTER(ffi_closure_OUTER);
+
+ /* 41 FF E2 jmp r10 */
+ BYTES("\x41\xFF\xE2");
+
+#else
+
+ /* mov ecx, closure */
+ BYTES("\xb9"); POINTER(closure);
+
+ /* mov edx, esp */
+ BYTES("\x8b\xd4");
+
+ /* call ffi_closure_SYSV */
+ BYTES("\xe8"); POINTER((char*)&ffi_closure_SYSV - (tramp + 4));
+
+ /* ret bytes */
+ BYTES("\xc2");
+ SHORT(bytes);
+
+#endif
+
+ if (tramp - &closure->tramp[0] > FFI_TRAMPOLINE_SIZE)
+ Py_FatalError("FFI_TRAMPOLINE_SIZE too small in " __FILE__);
+
closure->cif = cif;
closure->user_data = user_data;
closure->fun = fun;
Modified: python/branches/bcannon-objcap/Modules/_ctypes/libffi_msvc/ffi.h
==============================================================================
--- python/branches/bcannon-objcap/Modules/_ctypes/libffi_msvc/ffi.h (original)
+++ python/branches/bcannon-objcap/Modules/_ctypes/libffi_msvc/ffi.h Mon Aug 28 21:49:46 2006
@@ -174,12 +174,10 @@
/* ---- Definitions for the raw API -------------------------------------- */
-#ifndef FFI_SIZEOF_ARG
-# if LONG_MAX == 2147483647
-# define FFI_SIZEOF_ARG 4
-# elif LONG_MAX == 9223372036854775807
-# define FFI_SIZEOF_ARG 8
-# endif
+#ifdef _WIN64
+#define FFI_SIZEOF_ARG 8
+#else
+#define FFI_SIZEOF_ARG 4
#endif
typedef union {
Modified: python/branches/bcannon-objcap/Modules/_ctypes/libffi_msvc/ffitarget.h
==============================================================================
--- python/branches/bcannon-objcap/Modules/_ctypes/libffi_msvc/ffitarget.h (original)
+++ python/branches/bcannon-objcap/Modules/_ctypes/libffi_msvc/ffitarget.h Mon Aug 28 21:49:46 2006
@@ -44,7 +44,9 @@
/* ---- Intel x86 Win32 ---------- */
FFI_SYSV,
+#ifndef _WIN64
FFI_STDCALL,
+#endif
/* TODO: Add fastcall support for the sake of completeness */
FFI_DEFAULT_ABI = FFI_SYSV,
@@ -67,8 +69,8 @@
#define FFI_CLOSURES 1
-#ifdef X86_64
-#define FFI_TRAMPOLINE_SIZE 24
+#ifdef _WIN64
+#define FFI_TRAMPOLINE_SIZE 29
#define FFI_NATIVE_RAW_API 0
#else
#define FFI_TRAMPOLINE_SIZE 15
Modified: python/branches/bcannon-objcap/Modules/_ctypes/stgdict.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_ctypes/stgdict.c (original)
+++ python/branches/bcannon-objcap/Modules/_ctypes/stgdict.c Mon Aug 28 21:49:46 2006
@@ -208,12 +208,12 @@
continue;
}
new_descr = (CFieldObject *)PyObject_CallObject((PyObject *)&CField_Type, NULL);
- assert(new_descr->ob_type == &CField_Type);
if (new_descr == NULL) {
Py_DECREF(fdescr);
Py_DECREF(fieldlist);
return -1;
}
+ assert(new_descr->ob_type == &CField_Type);
new_descr->size = fdescr->size;
new_descr->offset = fdescr->offset + offset;
new_descr->index = fdescr->index + index;
Modified: python/branches/bcannon-objcap/Modules/_elementtree.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_elementtree.c (original)
+++ python/branches/bcannon-objcap/Modules/_elementtree.c Mon Aug 28 21:49:46 2006
@@ -48,7 +48,7 @@
#include "Python.h"
-#define VERSION "1.0.6-snapshot"
+#define VERSION "1.0.6"
/* -------------------------------------------------------------------- */
/* configuration */
@@ -1599,6 +1599,10 @@
treebuilder_handle_data(TreeBuilderObject* self, PyObject* data)
{
if (!self->data) {
+ if (self->last == (ElementObject*) Py_None) {
+ /* ignore calls to data before the first call to start */
+ Py_RETURN_NONE;
+ }
/* store the first item as is */
Py_INCREF(data); self->data = data;
} else {
Modified: python/branches/bcannon-objcap/Modules/arraymodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/arraymodule.c (original)
+++ python/branches/bcannon-objcap/Modules/arraymodule.c Mon Aug 28 21:49:46 2006
@@ -1495,7 +1495,7 @@
copy_doc},
{"count", (PyCFunction)array_count, METH_O,
count_doc},
- {"__deepcopy__",(PyCFunction)array_copy, METH_NOARGS,
+ {"__deepcopy__",(PyCFunction)array_copy, METH_O,
copy_doc},
{"extend", (PyCFunction)array_extend, METH_O,
extend_doc},
Modified: python/branches/bcannon-objcap/Modules/mmapmodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/mmapmodule.c (original)
+++ python/branches/bcannon-objcap/Modules/mmapmodule.c Mon Aug 28 21:49:46 2006
@@ -470,7 +470,7 @@
mmap_tell_method(mmap_object *self, PyObject *unused)
{
CHECK_VALID(NULL);
- return PyInt_FromLong((long) self->pos);
+ return PyInt_FromSize_t(self->pos);
}
static PyObject *
Modified: python/branches/bcannon-objcap/Modules/parsermodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/parsermodule.c (original)
+++ python/branches/bcannon-objcap/Modules/parsermodule.c Mon Aug 28 21:49:46 2006
@@ -74,7 +74,8 @@
node2tuple(node *n, /* node to convert */
SeqMaker mkseq, /* create sequence */
SeqInserter addelem, /* func. to add elem. in seq. */
- int lineno) /* include line numbers? */
+ int lineno, /* include line numbers? */
+ int col_offset) /* include column offsets? */
{
if (n == NULL) {
Py_INCREF(Py_None);
@@ -95,7 +96,7 @@
}
(void) addelem(v, 0, w);
for (i = 0; i < NCH(n); i++) {
- w = node2tuple(CHILD(n, i), mkseq, addelem, lineno);
+ w = node2tuple(CHILD(n, i), mkseq, addelem, lineno, col_offset);
if (w == NULL) {
Py_DECREF(v);
return ((PyObject*) NULL);
@@ -108,12 +109,14 @@
return (v);
}
else if (ISTERMINAL(TYPE(n))) {
- PyObject *result = mkseq(2 + lineno);
+ PyObject *result = mkseq(2 + lineno + col_offset);
if (result != NULL) {
(void) addelem(result, 0, PyInt_FromLong(TYPE(n)));
(void) addelem(result, 1, PyString_FromString(STR(n)));
if (lineno == 1)
(void) addelem(result, 2, PyInt_FromLong(n->n_lineno));
+ if (col_offset == 1)
+ (void) addelem(result, 3, PyInt_FromLong(n->n_col_offset));
}
return (result);
}
@@ -289,29 +292,35 @@
parser_st2tuple(PyST_Object *self, PyObject *args, PyObject *kw)
{
PyObject *line_option = 0;
+ PyObject *col_option = 0;
PyObject *res = 0;
int ok;
- static char *keywords[] = {"ast", "line_info", NULL};
+ static char *keywords[] = {"ast", "line_info", "col_info", NULL};
if (self == NULL) {
- ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:st2tuple", keywords,
- &PyST_Type, &self, &line_option);
+ ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|OO:st2tuple", keywords,
+ &PyST_Type, &self, &line_option,
+ &col_option);
}
else
- ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:totuple", &keywords[1],
- &line_option);
+ ok = PyArg_ParseTupleAndKeywords(args, kw, "|OO:totuple", &keywords[1],
+ &line_option, &col_option);
if (ok != 0) {
int lineno = 0;
+ int col_offset = 0;
if (line_option != NULL) {
lineno = (PyObject_IsTrue(line_option) != 0) ? 1 : 0;
}
+ if (col_option != NULL) {
+ col_offset = (PyObject_IsTrue(col_option) != 0) ? 1 : 0;
+ }
/*
* Convert ST into a tuple representation. Use Guido's function,
* since it's known to work already.
*/
res = node2tuple(((PyST_Object*)self)->st_node,
- PyTuple_New, PyTuple_SetItem, lineno);
+ PyTuple_New, PyTuple_SetItem, lineno, col_offset);
}
return (res);
}
@@ -327,28 +336,34 @@
parser_st2list(PyST_Object *self, PyObject *args, PyObject *kw)
{
PyObject *line_option = 0;
+ PyObject *col_option = 0;
PyObject *res = 0;
int ok;
- static char *keywords[] = {"ast", "line_info", NULL};
+ static char *keywords[] = {"ast", "line_info", "col_info", NULL};
if (self == NULL)
- ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:st2list", keywords,
- &PyST_Type, &self, &line_option);
+ ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|OO:st2list", keywords,
+ &PyST_Type, &self, &line_option,
+ &col_option);
else
- ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:tolist", &keywords[1],
- &line_option);
+ ok = PyArg_ParseTupleAndKeywords(args, kw, "|OO:tolist", &keywords[1],
+ &line_option, &col_option);
if (ok) {
int lineno = 0;
+ int col_offset = 0;
if (line_option != 0) {
lineno = PyObject_IsTrue(line_option) ? 1 : 0;
}
+ if (col_option != NULL) {
+ col_offset = (PyObject_IsTrue(col_option) != 0) ? 1 : 0;
+ }
/*
* Convert ST into a tuple representation. Use Guido's function,
* since it's known to work already.
*/
res = node2tuple(self->st_node,
- PyList_New, PyList_SetItem, lineno);
+ PyList_New, PyList_SetItem, lineno, col_offset);
}
return (res);
}
Modified: python/branches/bcannon-objcap/Objects/classobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/classobject.c (original)
+++ python/branches/bcannon-objcap/Objects/classobject.c Mon Aug 28 21:49:46 2006
@@ -91,8 +91,22 @@
}
Py_INCREF(bases);
}
+
+ if (getattrstr == NULL) {
+ getattrstr = PyString_InternFromString("__getattr__");
+ if (getattrstr == NULL)
+ goto alloc_error;
+ setattrstr = PyString_InternFromString("__setattr__");
+ if (setattrstr == NULL)
+ goto alloc_error;
+ delattrstr = PyString_InternFromString("__delattr__");
+ if (delattrstr == NULL)
+ goto alloc_error;
+ }
+
op = PyObject_GC_New(PyClassObject, &PyClass_Type);
if (op == NULL) {
+alloc_error:
Py_DECREF(bases);
return NULL;
}
@@ -101,17 +115,7 @@
op->cl_dict = dict;
Py_XINCREF(name);
op->cl_name = name;
- if (getattrstr == NULL) {
- getattrstr = PyString_InternFromString("__getattr__");
- if (getattrstr == NULL)
- return NULL;
- setattrstr = PyString_InternFromString("__setattr__");
- if (setattrstr == NULL)
- return NULL;
- delattrstr = PyString_InternFromString("__delattr__");
- if (delattrstr == NULL)
- return NULL;
- }
+
op->cl_getattr = class_lookup(op, getattrstr, &dummy);
op->cl_setattr = class_lookup(op, setattrstr, &dummy);
op->cl_delattr = class_lookup(op, delattrstr, &dummy);
Modified: python/branches/bcannon-objcap/Objects/fileobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/fileobject.c (original)
+++ python/branches/bcannon-objcap/Objects/fileobject.c Mon Aug 28 21:49:46 2006
@@ -922,7 +922,7 @@
ndone += nnow;
ntodo -= nnow;
}
- return PyInt_FromLong((long)ndone);
+ return PyInt_FromSsize_t(ndone);
}
/**************************************************************************
Modified: python/branches/bcannon-objcap/Objects/listobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/listobject.c (original)
+++ python/branches/bcannon-objcap/Objects/listobject.c Mon Aug 28 21:49:46 2006
@@ -1398,7 +1398,7 @@
PyObject *compare;
PyObject **dest;
int result = -1; /* guilty until proved innocent */
- Py_ssize_t min_gallop = ms->min_gallop;
+ Py_ssize_t min_gallop;
assert(ms && pa && pb && na > 0 && nb > 0 && pa + na == pb);
if (MERGE_GETMEM(ms, na) < 0)
@@ -1414,6 +1414,7 @@
if (na == 1)
goto CopyB;
+ min_gallop = ms->min_gallop;
compare = ms->compare;
for (;;) {
Py_ssize_t acount = 0; /* # of times A won in a row */
@@ -1531,7 +1532,7 @@
int result = -1; /* guilty until proved innocent */
PyObject **basea;
PyObject **baseb;
- Py_ssize_t min_gallop = ms->min_gallop;
+ Py_ssize_t min_gallop;
assert(ms && pa && pb && na > 0 && nb > 0 && pa + na == pb);
if (MERGE_GETMEM(ms, nb) < 0)
@@ -1550,6 +1551,7 @@
if (nb == 1)
goto CopyA;
+ min_gallop = ms->min_gallop;
compare = ms->compare;
for (;;) {
Py_ssize_t acount = 0; /* # of times A won in a row */
Modified: python/branches/bcannon-objcap/Objects/unicodeobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/unicodeobject.c (original)
+++ python/branches/bcannon-objcap/Objects/unicodeobject.c Mon Aug 28 21:49:46 2006
@@ -2040,7 +2040,32 @@
static const char *hexdigit = "0123456789abcdef";
- repr = PyString_FromStringAndSize(NULL, 2 + 6*size + 1);
+ /* XXX(nnorwitz): rather than over-allocating, it would be
+ better to choose a different scheme. Perhaps scan the
+ first N-chars of the string and allocate based on that size.
+ */
+ /* Initial allocation is based on the longest-possible unichr
+ escape.
+
+ In wide (UTF-32) builds '\U00xxxxxx' is 10 chars per source
+ unichr, so in this case it's the longest unichr escape. In
+ narrow (UTF-16) builds this is five chars per source unichr
+ since there are two unichrs in the surrogate pair, so in narrow
+ (UTF-16) builds it's not the longest unichr escape.
+
+ In wide or narrow builds '\uxxxx' is 6 chars per source unichr,
+ so in the narrow (UTF-16) build case it's the longest unichr
+ escape.
+ */
+
+ repr = PyString_FromStringAndSize(NULL,
+ 2
+#ifdef Py_UNICODE_WIDE
+ + 10*size
+#else
+ + 6*size
+#endif
+ + 1);
if (repr == NULL)
return NULL;
@@ -2065,15 +2090,6 @@
#ifdef Py_UNICODE_WIDE
/* Map 21-bit characters to '\U00xxxxxx' */
else if (ch >= 0x10000) {
- Py_ssize_t offset = p - PyString_AS_STRING(repr);
-
- /* Resize the string if necessary */
- if (offset + 12 > PyString_GET_SIZE(repr)) {
- if (_PyString_Resize(&repr, PyString_GET_SIZE(repr) + 100))
- return NULL;
- p = PyString_AS_STRING(repr) + offset;
- }
-
*p++ = '\\';
*p++ = 'U';
*p++ = hexdigit[(ch >> 28) & 0x0000000F];
@@ -2086,8 +2102,8 @@
*p++ = hexdigit[ch & 0x0000000F];
continue;
}
-#endif
- /* Map UTF-16 surrogate pairs to Unicode \UXXXXXXXX escapes */
+#else
+ /* Map UTF-16 surrogate pairs to '\U00xxxxxx' */
else if (ch >= 0xD800 && ch < 0xDC00) {
Py_UNICODE ch2;
Py_UCS4 ucs;
@@ -2112,6 +2128,7 @@
s--;
size++;
}
+#endif
/* Map 16-bit characters to '\uxxxx' */
if (ch >= 256) {
Modified: python/branches/bcannon-objcap/PC/pyconfig.h
==============================================================================
--- python/branches/bcannon-objcap/PC/pyconfig.h (original)
+++ python/branches/bcannon-objcap/PC/pyconfig.h Mon Aug 28 21:49:46 2006
@@ -280,9 +280,9 @@
their Makefile (other compilers are generally
taken care of by distutils.) */
# ifdef _DEBUG
-# pragma comment(lib,"python25_d.lib")
+# pragma comment(lib,"python26_d.lib")
# else
-# pragma comment(lib,"python25.lib")
+# pragma comment(lib,"python26.lib")
# endif /* _DEBUG */
# endif /* _MSC_VER */
# endif /* Py_BUILD_CORE */
Modified: python/branches/bcannon-objcap/PCbuild/_ctypes.vcproj
==============================================================================
--- python/branches/bcannon-objcap/PCbuild/_ctypes.vcproj (original)
+++ python/branches/bcannon-objcap/PCbuild/_ctypes.vcproj Mon Aug 28 21:49:46 2006
@@ -4,6 +4,7 @@
Version="7.10"
Name="_ctypes"
ProjectGUID="{F22F40F4-D318-40DC-96B3-88DC81CE0894}"
+ RootNamespace="_ctypes"
Keyword="Win32Proj">
<Platforms>
<Platform
@@ -128,7 +129,7 @@
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
- AdditionalOptions=" /USECL:MS_OPTERON"
+ AdditionalOptions=" /USECL:MS_OPTERON /GS-"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\Include,..\PC,..\Modules\_ctypes\libffi_msvc"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
@@ -268,6 +269,41 @@
</File>
<File
RelativePath="..\Modules\_ctypes\libffi_msvc\win32.c">
+ <FileConfiguration
+ Name="ReleaseAMD64|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\Modules\_ctypes\libffi_msvc\win64.asm">
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAMD64|Win32">
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="amd64_ml64 /nologo /c /Fo "$(IntDir)\win64.obj" "$(InputPath)"
+"
+ Outputs=""$(IntDir)\win64.obj""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseItanium|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCCustomBuildTool"/>
+ </FileConfiguration>
</File>
</Files>
<Globals>
Modified: python/branches/bcannon-objcap/PCbuild/_ssl.mak
==============================================================================
--- python/branches/bcannon-objcap/PCbuild/_ssl.mak (original)
+++ python/branches/bcannon-objcap/PCbuild/_ssl.mak Mon Aug 28 21:49:46 2006
@@ -1,21 +1,37 @@
!IFDEF DEBUG
-MODULE=_ssl_d.pyd
-TEMP_DIR=x86-temp-debug/_ssl
+SUFFIX=_d.pyd
+TEMP=x86-temp-debug/
CFLAGS=/Od /Zi /MDd /LDd /DDEBUG /D_DEBUG /DWIN32
SSL_LIB_DIR=$(SSL_DIR)/out32.dbg
!ELSE
-MODULE=_ssl.pyd
-TEMP_DIR=x86-temp-release/_ssl
+SUFFIX=.pyd
+TEMP=x86-temp-release/
CFLAGS=/Ox /MD /LD /DWIN32
SSL_LIB_DIR=$(SSL_DIR)/out32
!ENDIF
INCLUDES=-I ../Include -I ../PC -I $(SSL_DIR)/inc32
-LIBS=gdi32.lib wsock32.lib user32.lib advapi32.lib /libpath:$(SSL_LIB_DIR) libeay32.lib ssleay32.lib
-SOURCE=../Modules/_ssl.c $(SSL_LIB_DIR)/libeay32.lib $(SSL_LIB_DIR)/ssleay32.lib
+SSL_LIBS=gdi32.lib wsock32.lib user32.lib advapi32.lib /LIBPATH:$(SSL_LIB_DIR) libeay32.lib ssleay32.lib
+SSL_SOURCE=../Modules/_ssl.c
-$(MODULE): $(SOURCE) ../PC/*.h ../Include/*.h
- @if not exist "$(TEMP_DIR)/." mkdir "$(TEMP_DIR)"
- cl /nologo $(SOURCE) $(CFLAGS) /Fo$(TEMP_DIR)\$*.obj $(INCLUDES) /link /out:$(MODULE) $(LIBS)
+HASH_LIBS=gdi32.lib user32.lib advapi32.lib /libpath:$(SSL_LIB_DIR) libeay32.lib
+HASH_SOURCE=../Modules/_hashopenssl.c
+
+all: _ssl$(SUFFIX) _hashlib$(SUFFIX)
+
+# Split compile/link into two steps to better support VSExtComp
+_ssl$(SUFFIX): $(SSL_SOURCE) $(SSL_LIB_DIR)/libeay32.lib $(SSL_LIB_DIR)/ssleay32.lib ../PC/*.h ../Include/*.h
+ @if not exist "$(TEMP)/_ssl/." mkdir "$(TEMP)/_ssl"
+ cl /nologo /c $(SSL_SOURCE) $(CFLAGS) /Fo$(TEMP)\_ssl\$*.obj $(INCLUDES)
+ link /nologo @<<
+ /dll /out:_ssl$(SUFFIX) $(TEMP)\_ssl\$*.obj $(SSL_LIBS)
+<<
+
+_hashlib$(SUFFIX): $(HASH_SOURCE) $(SSL_LIB_DIR)/libeay32.lib ../PC/*.h ../Include/*.h
+ @if not exist "$(TEMP)/_hashlib/." mkdir "$(TEMP)/_hashlib"
+ cl /nologo /c $(HASH_SOURCE) $(CFLAGS) /Fo$(TEMP)\_hashlib\$*.obj $(INCLUDES)
+ link /nologo @<<
+ /dll /out:_hashlib$(SUFFIX) $(HASH_LIBS) $(TEMP)\_hashlib\$*.obj
+<<
Modified: python/branches/bcannon-objcap/PCbuild/_ssl.vcproj
==============================================================================
--- python/branches/bcannon-objcap/PCbuild/_ssl.vcproj (original)
+++ python/branches/bcannon-objcap/PCbuild/_ssl.vcproj Mon Aug 28 21:49:46 2006
@@ -75,6 +75,9 @@
<File
RelativePath="..\Modules\_ssl.c">
</File>
+ <File
+ RelativePath="..\Modules\_hashopenssl.c">
+ </File>
</Files>
<Globals>
</Globals>
Modified: python/branches/bcannon-objcap/PCbuild/build_ssl.py
==============================================================================
--- python/branches/bcannon-objcap/PCbuild/build_ssl.py (original)
+++ python/branches/bcannon-objcap/PCbuild/build_ssl.py Mon Aug 28 21:49:46 2006
@@ -1,7 +1,7 @@
-# Script for building the _ssl module for Windows.
+# Script for building the _ssl and _hashlib modules for Windows.
# Uses Perl to setup the OpenSSL environment correctly
# and build OpenSSL, then invokes a simple nmake session
-# for _ssl.pyd itself.
+# for the actual _ssl.pyd and _hashlib.pyd DLLs.
# THEORETICALLY, you can:
# * Unpack the latest SSL release one level above your main Python source
@@ -10,8 +10,8 @@
# * Install ActivePerl and ensure it is somewhere on your path.
# * Run this script from the PCBuild directory.
#
-# it should configure and build SSL, then build the ssl Python extension
-# without intervention.
+# it should configure and build SSL, then build the _ssl and _hashlib
+# Python extensions without intervention.
import os, sys, re
@@ -59,7 +59,8 @@
candidates = []
for s in sources:
try:
- s = os.path.abspath(s)
+ # note: do not abspath s; the build will fail if any
+ # higher up directory name has spaces in it.
fnames = os.listdir(s)
except os.error:
fnames = []
@@ -82,31 +83,9 @@
print "Found an SSL directory at '%s'" % (best_name,)
else:
print "Could not find an SSL directory in '%s'" % (sources,)
+ sys.stdout.flush()
return best_name
-def run_32all_py():
- # ms\32all.bat will reconfigure OpenSSL and then try to build
- # all outputs (debug/nondebug/dll/lib). So we filter the file
- # to exclude any "nmake" commands and then execute.
- tempname = "ms\\32all_py.bat"
-
- in_bat = open("ms\\32all.bat")
- temp_bat = open(tempname,"w")
- while 1:
- cmd = in_bat.readline()
- print 'cmd', repr(cmd)
- if not cmd: break
- if cmd.strip()[:5].lower() == "nmake":
- continue
- temp_bat.write(cmd)
- in_bat.close()
- temp_bat.close()
- os.system(tempname)
- try:
- os.remove(tempname)
- except:
- pass
-
def run_configure(configure, do_script):
os.system("perl Configure "+configure)
os.system(do_script)
@@ -117,12 +96,14 @@
arch = "x86"
debug = False
configure = "VC-WIN32"
- makefile = "32.mak"
+ do_script = "ms\\do_masm"
+ makefile = "ms\\nt.mak"
elif sys.argv[1] == "Debug":
arch = "x86"
debug = True
configure = "VC-WIN32"
- makefile="d32.mak"
+ do_script = "ms\\do_masm"
+ makefile="ms\\d32.mak"
elif sys.argv[1] == "ReleaseItanium":
arch = "ia64"
debug = False
@@ -148,8 +129,9 @@
sys.exit(1)
print "Found a working perl at '%s'" % (perl,)
+ sys.stdout.flush()
# Look for SSL 2 levels up from pcbuild - ie, same place zlib etc all live.
- ssl_dir = find_best_ssl_dir(("../..",))
+ ssl_dir = find_best_ssl_dir(("..\\..",))
if ssl_dir is None:
sys.exit(1)
@@ -157,31 +139,40 @@
try:
os.chdir(ssl_dir)
# If the ssl makefiles do not exist, we invoke Perl to generate them.
- if not os.path.isfile(makefile):
+ # Due to a bug in this script, the makefile sometimes ended up empty
+ # Force a regeneration if it is.
+ if not os.path.isfile(makefile) or os.path.getsize(makefile)==0:
print "Creating the makefiles..."
+ sys.stdout.flush()
# Put our working Perl at the front of our path
- os.environ["PATH"] = os.path.split(perl)[0] + \
+ os.environ["PATH"] = os.path.dirname(perl) + \
os.pathsep + \
os.environ["PATH"]
- if arch=="x86":
- run_32all_py()
- else:
- run_configure(configure, do_script)
+ run_configure(configure, do_script)
+ if arch=="x86" and debug:
+ # the do_masm script in openssl doesn't generate a debug
+ # build makefile so we generate it here:
+ os.system("perl util\mk1mf.pl debug "+configure+" >"+makefile)
# Now run make.
- print "Executing nmake over the ssl makefiles..."
- rc = os.system("nmake /nologo -f "+makefile)
+ makeCommand = "nmake /nologo PERL=\"%s\" -f \"%s\"" %(perl, makefile)
+ print "Executing ssl makefiles:", makeCommand
+ sys.stdout.flush()
+ rc = os.system(makeCommand)
if rc:
- print "Executing d32.mak failed"
+ print "Executing "+makefile+" failed"
print rc
sys.exit(rc)
finally:
os.chdir(old_cd)
# And finally, we can build the _ssl module itself for Python.
- defs = "SSL_DIR=%s" % (ssl_dir,)
+ defs = "SSL_DIR=\"%s\"" % (ssl_dir,)
if debug:
defs = defs + " " + "DEBUG=1"
- rc = os.system('nmake /nologo -f _ssl.mak ' + defs + " " + make_flags)
+ makeCommand = 'nmake /nologo -f _ssl.mak ' + defs + " " + make_flags
+ print "Executing:", makeCommand
+ sys.stdout.flush()
+ rc = os.system(makeCommand)
sys.exit(rc)
if __name__=='__main__':
Modified: python/branches/bcannon-objcap/PCbuild/pythoncore.vcproj
==============================================================================
--- python/branches/bcannon-objcap/PCbuild/pythoncore.vcproj (original)
+++ python/branches/bcannon-objcap/PCbuild/pythoncore.vcproj Mon Aug 28 21:49:46 2006
@@ -39,15 +39,15 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="getbuildinfo.o"
- OutputFile="./python25.dll"
+ OutputFile="./python26.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
IgnoreDefaultLibraryNames="libc"
GenerateDebugInformation="TRUE"
- ProgramDatabaseFile=".\./python25.pdb"
+ ProgramDatabaseFile=".\./python26.pdb"
SubSystem="2"
BaseAddress="0x1e000000"
- ImportLibrary=".\./python25.lib"
+ ImportLibrary=".\./python26.lib"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
@@ -99,15 +99,15 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="getbuildinfo.o"
- OutputFile="./python25_d.dll"
+ OutputFile="./python26_d.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
IgnoreDefaultLibraryNames="libc"
GenerateDebugInformation="TRUE"
- ProgramDatabaseFile=".\./python25_d.pdb"
+ ProgramDatabaseFile=".\./python26_d.pdb"
SubSystem="2"
BaseAddress="0x1e000000"
- ImportLibrary=".\./python25_d.lib"
+ ImportLibrary=".\./python26_d.lib"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
@@ -166,15 +166,15 @@
Name="VCLinkerTool"
AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK"
AdditionalDependencies="getbuildinfo.o"
- OutputFile="./python25.dll"
+ OutputFile="./python26.dll"
LinkIncremental="1"
SuppressStartupBanner="FALSE"
IgnoreDefaultLibraryNames="libc"
GenerateDebugInformation="TRUE"
- ProgramDatabaseFile=".\./python25.pdb"
+ ProgramDatabaseFile=".\./python26.pdb"
SubSystem="2"
BaseAddress="0x1e000000"
- ImportLibrary=".\./python25.lib"
+ ImportLibrary=".\./python26.lib"
TargetMachine="0"/>
<Tool
Name="VCMIDLTool"/>
@@ -233,15 +233,15 @@
Name="VCLinkerTool"
AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK"
AdditionalDependencies="getbuildinfo.o"
- OutputFile="./python25.dll"
+ OutputFile="./python26.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
IgnoreDefaultLibraryNames="libc"
GenerateDebugInformation="TRUE"
- ProgramDatabaseFile=".\./python25.pdb"
+ ProgramDatabaseFile=".\./python26.pdb"
SubSystem="2"
BaseAddress="0x1e000000"
- ImportLibrary=".\./python25.lib"
+ ImportLibrary=".\./python26.lib"
TargetMachine="0"/>
<Tool
Name="VCMIDLTool"/>
@@ -464,6 +464,9 @@
RelativePath="..\Python\compile.c">
</File>
<File
+ RelativePath="..\Python\peephole.c">
+ </File>
+ <File
RelativePath="..\Objects\complexobject.c">
</File>
<File
Modified: python/branches/bcannon-objcap/PCbuild/readme.txt
==============================================================================
--- python/branches/bcannon-objcap/PCbuild/readme.txt (original)
+++ python/branches/bcannon-objcap/PCbuild/readme.txt Mon Aug 28 21:49:46 2006
@@ -12,7 +12,7 @@
The proper order to build subprojects:
1) pythoncore (this builds the main Python DLL and library files,
- python25.{dll, lib} in Release mode)
+ python26.{dll, lib} in Release mode)
NOTE: in previous releases, this subproject was
named after the release number, e.g. python20.
@@ -26,7 +26,7 @@
test slave; see SUBPROJECTS below)
When using the Debug setting, the output files have a _d added to
-their name: python25_d.dll, python_d.exe, parser_d.pyd, and so on.
+their name: python26_d.dll, python_d.exe, parser_d.pyd, and so on.
SUBPROJECTS
-----------
Modified: python/branches/bcannon-objcap/Python/compile.c
==============================================================================
--- python/branches/bcannon-objcap/Python/compile.c (original)
+++ python/branches/bcannon-objcap/Python/compile.c Mon Aug 28 21:49:46 2006
@@ -394,613 +394,6 @@
return dest;
}
-/* Begin: Peephole optimizations ----------------------------------------- */
-
-#define GETARG(arr, i) ((int)((arr[i+2]<<8) + arr[i+1]))
-#define UNCONDITIONAL_JUMP(op) (op==JUMP_ABSOLUTE || op==JUMP_FORWARD)
-#define ABSOLUTE_JUMP(op) (op==JUMP_ABSOLUTE || op==CONTINUE_LOOP)
-#define GETJUMPTGT(arr, i) (GETARG(arr,i) + (ABSOLUTE_JUMP(arr[i]) ? 0 : i+3))
-#define SETARG(arr, i, val) arr[i+2] = val>>8; arr[i+1] = val & 255
-#define CODESIZE(op) (HAS_ARG(op) ? 3 : 1)
-#define ISBASICBLOCK(blocks, start, bytes) \
- (blocks[start]==blocks[start+bytes-1])
-
-/* Replace LOAD_CONST c1. LOAD_CONST c2 ... LOAD_CONST cn BUILD_TUPLE n
- with LOAD_CONST (c1, c2, ... cn).
- The consts table must still be in list form so that the
- new constant (c1, c2, ... cn) can be appended.
- Called with codestr pointing to the first LOAD_CONST.
- Bails out with no change if one or more of the LOAD_CONSTs is missing.
- Also works for BUILD_LIST when followed by an "in" or "not in" test.
-*/
-static int
-tuple_of_constants(unsigned char *codestr, int n, PyObject *consts)
-{
- PyObject *newconst, *constant;
- Py_ssize_t i, arg, len_consts;
-
- /* Pre-conditions */
- assert(PyList_CheckExact(consts));
- assert(codestr[n*3] == BUILD_TUPLE || codestr[n*3] == BUILD_LIST);
- assert(GETARG(codestr, (n*3)) == n);
- for (i=0 ; i<n ; i++)
- assert(codestr[i*3] == LOAD_CONST);
-
- /* Buildup new tuple of constants */
- newconst = PyTuple_New(n);
- if (newconst == NULL)
- return 0;
- len_consts = PyList_GET_SIZE(consts);
- for (i=0 ; i<n ; i++) {
- arg = GETARG(codestr, (i*3));
- assert(arg < len_consts);
- constant = PyList_GET_ITEM(consts, arg);
- Py_INCREF(constant);
- PyTuple_SET_ITEM(newconst, i, constant);
- }
-
- /* Append folded constant onto consts */
- if (PyList_Append(consts, newconst)) {
- Py_DECREF(newconst);
- return 0;
- }
- Py_DECREF(newconst);
-
- /* Write NOPs over old LOAD_CONSTS and
- add a new LOAD_CONST newconst on top of the BUILD_TUPLE n */
- memset(codestr, NOP, n*3);
- codestr[n*3] = LOAD_CONST;
- SETARG(codestr, (n*3), len_consts);
- return 1;
-}
-
-/* Replace LOAD_CONST c1. LOAD_CONST c2 BINOP
- with LOAD_CONST binop(c1,c2)
- The consts table must still be in list form so that the
- new constant can be appended.
- Called with codestr pointing to the first LOAD_CONST.
- Abandons the transformation if the folding fails (i.e. 1+'a').
- If the new constant is a sequence, only folds when the size
- is below a threshold value. That keeps pyc files from
- becoming large in the presence of code like: (None,)*1000.
-*/
-static int
-fold_binops_on_constants(unsigned char *codestr, PyObject *consts)
-{
- PyObject *newconst, *v, *w;
- Py_ssize_t len_consts, size;
- int opcode;
-
- /* Pre-conditions */
- assert(PyList_CheckExact(consts));
- assert(codestr[0] == LOAD_CONST);
- assert(codestr[3] == LOAD_CONST);
-
- /* Create new constant */
- v = PyList_GET_ITEM(consts, GETARG(codestr, 0));
- w = PyList_GET_ITEM(consts, GETARG(codestr, 3));
- opcode = codestr[6];
- switch (opcode) {
- case BINARY_POWER:
- newconst = PyNumber_Power(v, w, Py_None);
- break;
- case BINARY_MULTIPLY:
- newconst = PyNumber_Multiply(v, w);
- break;
- case BINARY_DIVIDE:
- /* Cannot fold this operation statically since
- the result can depend on the run-time presence
- of the -Qnew flag */
- return 0;
- case BINARY_TRUE_DIVIDE:
- newconst = PyNumber_TrueDivide(v, w);
- break;
- case BINARY_FLOOR_DIVIDE:
- newconst = PyNumber_FloorDivide(v, w);
- break;
- case BINARY_MODULO:
- newconst = PyNumber_Remainder(v, w);
- break;
- case BINARY_ADD:
- newconst = PyNumber_Add(v, w);
- break;
- case BINARY_SUBTRACT:
- newconst = PyNumber_Subtract(v, w);
- break;
- case BINARY_SUBSCR:
- newconst = PyObject_GetItem(v, w);
- break;
- case BINARY_LSHIFT:
- newconst = PyNumber_Lshift(v, w);
- break;
- case BINARY_RSHIFT:
- newconst = PyNumber_Rshift(v, w);
- break;
- case BINARY_AND:
- newconst = PyNumber_And(v, w);
- break;
- case BINARY_XOR:
- newconst = PyNumber_Xor(v, w);
- break;
- case BINARY_OR:
- newconst = PyNumber_Or(v, w);
- break;
- default:
- /* Called with an unknown opcode */
- PyErr_Format(PyExc_SystemError,
- "unexpected binary operation %d on a constant",
- opcode);
- return 0;
- }
- if (newconst == NULL) {
- PyErr_Clear();
- return 0;
- }
- size = PyObject_Size(newconst);
- if (size == -1)
- PyErr_Clear();
- else if (size > 20) {
- Py_DECREF(newconst);
- return 0;
- }
-
- /* Append folded constant into consts table */
- len_consts = PyList_GET_SIZE(consts);
- if (PyList_Append(consts, newconst)) {
- Py_DECREF(newconst);
- return 0;
- }
- Py_DECREF(newconst);
-
- /* Write NOP NOP NOP NOP LOAD_CONST newconst */
- memset(codestr, NOP, 4);
- codestr[4] = LOAD_CONST;
- SETARG(codestr, 4, len_consts);
- return 1;
-}
-
-static int
-fold_unaryops_on_constants(unsigned char *codestr, PyObject *consts)
-{
- PyObject *newconst=NULL, *v;
- Py_ssize_t len_consts;
- int opcode;
-
- /* Pre-conditions */
- assert(PyList_CheckExact(consts));
- assert(codestr[0] == LOAD_CONST);
-
- /* Create new constant */
- v = PyList_GET_ITEM(consts, GETARG(codestr, 0));
- opcode = codestr[3];
- switch (opcode) {
- case UNARY_NEGATIVE:
- /* Preserve the sign of -0.0 */
- if (PyObject_IsTrue(v) == 1)
- newconst = PyNumber_Negative(v);
- break;
- case UNARY_CONVERT:
- newconst = PyObject_Repr(v);
- break;
- case UNARY_INVERT:
- newconst = PyNumber_Invert(v);
- break;
- default:
- /* Called with an unknown opcode */
- PyErr_Format(PyExc_SystemError,
- "unexpected unary operation %d on a constant",
- opcode);
- return 0;
- }
- if (newconst == NULL) {
- PyErr_Clear();
- return 0;
- }
-
- /* Append folded constant into consts table */
- len_consts = PyList_GET_SIZE(consts);
- if (PyList_Append(consts, newconst)) {
- Py_DECREF(newconst);
- return 0;
- }
- Py_DECREF(newconst);
-
- /* Write NOP LOAD_CONST newconst */
- codestr[0] = NOP;
- codestr[1] = LOAD_CONST;
- SETARG(codestr, 1, len_consts);
- return 1;
-}
-
-static unsigned int *
-markblocks(unsigned char *code, int len)
-{
- unsigned int *blocks = (unsigned int *)PyMem_Malloc(len*sizeof(int));
- int i,j, opcode, blockcnt = 0;
-
- if (blocks == NULL) {
- PyErr_NoMemory();
- return NULL;
- }
- memset(blocks, 0, len*sizeof(int));
-
- /* Mark labels in the first pass */
- for (i=0 ; i<len ; i+=CODESIZE(opcode)) {
- opcode = code[i];
- switch (opcode) {
- case FOR_ITER:
- case JUMP_FORWARD:
- case JUMP_IF_FALSE:
- case JUMP_IF_TRUE:
- case JUMP_ABSOLUTE:
- case CONTINUE_LOOP:
- case SETUP_LOOP:
- case SETUP_EXCEPT:
- case SETUP_FINALLY:
- j = GETJUMPTGT(code, i);
- blocks[j] = 1;
- break;
- }
- }
- /* Build block numbers in the second pass */
- for (i=0 ; i<len ; i++) {
- blockcnt += blocks[i]; /* increment blockcnt over labels */
- blocks[i] = blockcnt;
- }
- return blocks;
-}
-
-/* Perform basic peephole optimizations to components of a code object.
- The consts object should still be in list form to allow new constants
- to be appended.
-
- To keep the optimizer simple, it bails out (does nothing) for code
- containing extended arguments or that has a length over 32,700. That
- allows us to avoid overflow and sign issues. Likewise, it bails when
- the lineno table has complex encoding for gaps >= 255.
-
- Optimizations are restricted to simple transformations occuring within a
- single basic block. All transformations keep the code size the same or
- smaller. For those that reduce size, the gaps are initially filled with
- NOPs. Later those NOPs are removed and the jump addresses retargeted in
- a single pass. Line numbering is adjusted accordingly. */
-
-static PyObject *
-optimize_code(PyObject *code, PyObject* consts, PyObject *names,
- PyObject *lineno_obj)
-{
- Py_ssize_t i, j, codelen;
- int nops, h, adj;
- int tgt, tgttgt, opcode;
- unsigned char *codestr = NULL;
- unsigned char *lineno;
- int *addrmap = NULL;
- int new_line, cum_orig_line, last_line, tabsiz;
- int cumlc=0, lastlc=0; /* Count runs of consecutive LOAD_CONSTs */
- unsigned int *blocks = NULL;
- char *name;
-
- /* Bail out if an exception is set */
- if (PyErr_Occurred())
- goto exitUnchanged;
-
- /* Bypass optimization when the lineno table is too complex */
- assert(PyString_Check(lineno_obj));
- lineno = (unsigned char*)PyString_AS_STRING(lineno_obj);
- tabsiz = PyString_GET_SIZE(lineno_obj);
- if (memchr(lineno, 255, tabsiz) != NULL)
- goto exitUnchanged;
-
- /* Avoid situations where jump retargeting could overflow */
- assert(PyString_Check(code));
- codelen = PyString_Size(code);
- if (codelen > 32700)
- goto exitUnchanged;
-
- /* Make a modifiable copy of the code string */
- codestr = (unsigned char *)PyMem_Malloc(codelen);
- if (codestr == NULL)
- goto exitUnchanged;
- codestr = (unsigned char *)memcpy(codestr,
- PyString_AS_STRING(code), codelen);
-
- /* Verify that RETURN_VALUE terminates the codestring. This allows
- the various transformation patterns to look ahead several
- instructions without additional checks to make sure they are not
- looking beyond the end of the code string.
- */
- if (codestr[codelen-1] != RETURN_VALUE)
- goto exitUnchanged;
-
- /* Mapping to new jump targets after NOPs are removed */
- addrmap = (int *)PyMem_Malloc(codelen * sizeof(int));
- if (addrmap == NULL)
- goto exitUnchanged;
-
- blocks = markblocks(codestr, codelen);
- if (blocks == NULL)
- goto exitUnchanged;
- assert(PyList_Check(consts));
-
- for (i=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
- opcode = codestr[i];
-
- lastlc = cumlc;
- cumlc = 0;
-
- switch (opcode) {
-
- /* Replace UNARY_NOT JUMP_IF_FALSE POP_TOP with
- with JUMP_IF_TRUE POP_TOP */
- case UNARY_NOT:
- if (codestr[i+1] != JUMP_IF_FALSE ||
- codestr[i+4] != POP_TOP ||
- !ISBASICBLOCK(blocks,i,5))
- continue;
- tgt = GETJUMPTGT(codestr, (i+1));
- if (codestr[tgt] != POP_TOP)
- continue;
- j = GETARG(codestr, i+1) + 1;
- codestr[i] = JUMP_IF_TRUE;
- SETARG(codestr, i, j);
- codestr[i+3] = POP_TOP;
- codestr[i+4] = NOP;
- break;
-
- /* not a is b --> a is not b
- not a in b --> a not in b
- not a is not b --> a is b
- not a not in b --> a in b
- */
- case COMPARE_OP:
- j = GETARG(codestr, i);
- if (j < 6 || j > 9 ||
- codestr[i+3] != UNARY_NOT ||
- !ISBASICBLOCK(blocks,i,4))
- continue;
- SETARG(codestr, i, (j^1));
- codestr[i+3] = NOP;
- break;
-
- /* Replace LOAD_GLOBAL/LOAD_NAME None
- with LOAD_CONST None */
- case LOAD_NAME:
- case LOAD_GLOBAL:
- j = GETARG(codestr, i);
- name = PyString_AsString(PyTuple_GET_ITEM(names, j));
- if (name == NULL || strcmp(name, "None") != 0)
- continue;
- for (j=0 ; j < PyList_GET_SIZE(consts) ; j++) {
- if (PyList_GET_ITEM(consts, j) == Py_None) {
- codestr[i] = LOAD_CONST;
- SETARG(codestr, i, j);
- cumlc = lastlc + 1;
- break;
- }
- }
- break;
-
- /* Skip over LOAD_CONST trueconst
- JUMP_IF_FALSE xx POP_TOP */
- case LOAD_CONST:
- cumlc = lastlc + 1;
- j = GETARG(codestr, i);
- if (codestr[i+3] != JUMP_IF_FALSE ||
- codestr[i+6] != POP_TOP ||
- !ISBASICBLOCK(blocks,i,7) ||
- !PyObject_IsTrue(PyList_GET_ITEM(consts, j)))
- continue;
- memset(codestr+i, NOP, 7);
- cumlc = 0;
- break;
-
- /* Try to fold tuples of constants (includes a case for lists
- which are only used for "in" and "not in" tests).
- Skip over BUILD_SEQN 1 UNPACK_SEQN 1.
- Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2.
- Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */
- case BUILD_TUPLE:
- case BUILD_LIST:
- j = GETARG(codestr, i);
- h = i - 3 * j;
- if (h >= 0 &&
- j <= lastlc &&
- ((opcode == BUILD_TUPLE &&
- ISBASICBLOCK(blocks, h, 3*(j+1))) ||
- (opcode == BUILD_LIST &&
- codestr[i+3]==COMPARE_OP &&
- ISBASICBLOCK(blocks, h, 3*(j+2)) &&
- (GETARG(codestr,i+3)==6 ||
- GETARG(codestr,i+3)==7))) &&
- tuple_of_constants(&codestr[h], j, consts)) {
- assert(codestr[i] == LOAD_CONST);
- cumlc = 1;
- break;
- }
- if (codestr[i+3] != UNPACK_SEQUENCE ||
- !ISBASICBLOCK(blocks,i,6) ||
- j != GETARG(codestr, i+3))
- continue;
- if (j == 1) {
- memset(codestr+i, NOP, 6);
- } else if (j == 2) {
- codestr[i] = ROT_TWO;
- memset(codestr+i+1, NOP, 5);
- } else if (j == 3) {
- codestr[i] = ROT_THREE;
- codestr[i+1] = ROT_TWO;
- memset(codestr+i+2, NOP, 4);
- }
- break;
-
- /* Fold binary ops on constants.
- LOAD_CONST c1 LOAD_CONST c2 BINOP --> LOAD_CONST binop(c1,c2) */
- case BINARY_POWER:
- case BINARY_MULTIPLY:
- case BINARY_TRUE_DIVIDE:
- case BINARY_FLOOR_DIVIDE:
- case BINARY_MODULO:
- case BINARY_ADD:
- case BINARY_SUBTRACT:
- case BINARY_SUBSCR:
- case BINARY_LSHIFT:
- case BINARY_RSHIFT:
- case BINARY_AND:
- case BINARY_XOR:
- case BINARY_OR:
- if (lastlc >= 2 &&
- ISBASICBLOCK(blocks, i-6, 7) &&
- fold_binops_on_constants(&codestr[i-6], consts)) {
- i -= 2;
- assert(codestr[i] == LOAD_CONST);
- cumlc = 1;
- }
- break;
-
- /* Fold unary ops on constants.
- LOAD_CONST c1 UNARY_OP --> LOAD_CONST unary_op(c) */
- case UNARY_NEGATIVE:
- case UNARY_CONVERT:
- case UNARY_INVERT:
- if (lastlc >= 1 &&
- ISBASICBLOCK(blocks, i-3, 4) &&
- fold_unaryops_on_constants(&codestr[i-3], consts)) {
- i -= 2;
- assert(codestr[i] == LOAD_CONST);
- cumlc = 1;
- }
- break;
-
- /* Simplify conditional jump to conditional jump where the
- result of the first test implies the success of a similar
- test or the failure of the opposite test.
- Arises in code like:
- "if a and b:"
- "if a or b:"
- "a and b or c"
- "(a and b) and c"
- x:JUMP_IF_FALSE y y:JUMP_IF_FALSE z --> x:JUMP_IF_FALSE z
- x:JUMP_IF_FALSE y y:JUMP_IF_TRUE z --> x:JUMP_IF_FALSE y+3
- where y+3 is the instruction following the second test.
- */
- case JUMP_IF_FALSE:
- case JUMP_IF_TRUE:
- tgt = GETJUMPTGT(codestr, i);
- j = codestr[tgt];
- if (j == JUMP_IF_FALSE || j == JUMP_IF_TRUE) {
- if (j == opcode) {
- tgttgt = GETJUMPTGT(codestr, tgt) - i - 3;
- SETARG(codestr, i, tgttgt);
- } else {
- tgt -= i;
- SETARG(codestr, i, tgt);
- }
- break;
- }
- /* Intentional fallthrough */
-
- /* Replace jumps to unconditional jumps */
- case FOR_ITER:
- case JUMP_FORWARD:
- case JUMP_ABSOLUTE:
- case CONTINUE_LOOP:
- case SETUP_LOOP:
- case SETUP_EXCEPT:
- case SETUP_FINALLY:
- tgt = GETJUMPTGT(codestr, i);
- if (!UNCONDITIONAL_JUMP(codestr[tgt]))
- continue;
- tgttgt = GETJUMPTGT(codestr, tgt);
- if (opcode == JUMP_FORWARD) /* JMP_ABS can go backwards */
- opcode = JUMP_ABSOLUTE;
- if (!ABSOLUTE_JUMP(opcode))
- tgttgt -= i + 3; /* Calc relative jump addr */
- if (tgttgt < 0) /* No backward relative jumps */
- continue;
- codestr[i] = opcode;
- SETARG(codestr, i, tgttgt);
- break;
-
- case EXTENDED_ARG:
- goto exitUnchanged;
-
- /* Replace RETURN LOAD_CONST None RETURN with just RETURN */
- case RETURN_VALUE:
- if (i+4 >= codelen ||
- codestr[i+4] != RETURN_VALUE ||
- !ISBASICBLOCK(blocks,i,5))
- continue;
- memset(codestr+i+1, NOP, 4);
- break;
- }
- }
-
- /* Fixup linenotab */
- for (i=0, nops=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
- addrmap[i] = i - nops;
- if (codestr[i] == NOP)
- nops++;
- }
- cum_orig_line = 0;
- last_line = 0;
- for (i=0 ; i < tabsiz ; i+=2) {
- cum_orig_line += lineno[i];
- new_line = addrmap[cum_orig_line];
- assert (new_line - last_line < 255);
- lineno[i] =((unsigned char)(new_line - last_line));
- last_line = new_line;
- }
-
- /* Remove NOPs and fixup jump targets */
- for (i=0, h=0 ; i<codelen ; ) {
- opcode = codestr[i];
- switch (opcode) {
- case NOP:
- i++;
- continue;
-
- case JUMP_ABSOLUTE:
- case CONTINUE_LOOP:
- j = addrmap[GETARG(codestr, i)];
- SETARG(codestr, i, j);
- break;
-
- case FOR_ITER:
- case JUMP_FORWARD:
- case JUMP_IF_FALSE:
- case JUMP_IF_TRUE:
- case SETUP_LOOP:
- case SETUP_EXCEPT:
- case SETUP_FINALLY:
- j = addrmap[GETARG(codestr, i) + i + 3] - addrmap[i] - 3;
- SETARG(codestr, i, j);
- break;
- }
- adj = CODESIZE(opcode);
- while (adj--)
- codestr[h++] = codestr[i++];
- }
- assert(h + nops == codelen);
-
- code = PyString_FromStringAndSize((char *)codestr, h);
- PyMem_Free(addrmap);
- PyMem_Free(codestr);
- PyMem_Free(blocks);
- return code;
-
- exitUnchanged:
- if (blocks != NULL)
- PyMem_Free(blocks);
- if (addrmap != NULL)
- PyMem_Free(addrmap);
- if (codestr != NULL)
- PyMem_Free(codestr);
- Py_INCREF(code);
- return code;
-}
-
-/* End: Peephole optimizations ----------------------------------------- */
-
/*
Leave this debugging code for just a little longer.
@@ -1175,6 +568,7 @@
if (n >= 0) {
wrapper = PyList_GET_ITEM(c->c_stack, n);
c->u = (struct compiler_unit *)PyCObject_AsVoidPtr(wrapper);
+ assert(c->u);
/* we are deleting from a list so this really shouldn't fail */
if (PySequence_DelItem(c->c_stack, n) < 0)
Py_FatalError("compiler_exit_scope()");
@@ -2288,6 +1682,8 @@
compiler_continue(struct compiler *c)
{
static const char LOOP_ERROR_MSG[] = "'continue' not properly in loop";
+ static const char IN_FINALLY_ERROR_MSG[] =
+ "'continue' not supported inside 'finally' clause";
int i;
if (!c->u->u_nfblocks)
@@ -2299,15 +1695,18 @@
break;
case EXCEPT:
case FINALLY_TRY:
- while (--i >= 0 && c->u->u_fblock[i].fb_type != LOOP)
- ;
+ while (--i >= 0 && c->u->u_fblock[i].fb_type != LOOP) {
+ /* Prevent continue anywhere under a finally
+ even if hidden in a sub-try or except. */
+ if (c->u->u_fblock[i].fb_type == FINALLY_END)
+ return compiler_error(c, IN_FINALLY_ERROR_MSG);
+ }
if (i == -1)
return compiler_error(c, LOOP_ERROR_MSG);
ADDOP_JABS(c, CONTINUE_LOOP, c->u->u_fblock[i].fb_block);
break;
case FINALLY_END:
- return compiler_error(c,
- "'continue' not supported inside 'finally' clause");
+ return compiler_error(c, IN_FINALLY_ERROR_MSG);
}
return 1;
@@ -4422,7 +3821,7 @@
if (flags < 0)
goto error;
- bytecode = optimize_code(a->a_bytecode, consts, names, a->a_lnotab);
+ bytecode = PyCode_Optimize(a->a_bytecode, consts, names, a->a_lnotab);
if (!bytecode)
goto error;
Modified: python/branches/bcannon-objcap/Python/pythonrun.c
==============================================================================
--- python/branches/bcannon-objcap/Python/pythonrun.c (original)
+++ python/branches/bcannon-objcap/Python/pythonrun.c Mon Aug 28 21:49:46 2006
@@ -531,11 +531,15 @@
bimod = _PyImport_FindExtension("__builtin__", "__builtin__");
if (bimod != NULL) {
interp->builtins = PyModule_GetDict(bimod);
+ if (interp->builtins == NULL)
+ goto handle_error;
Py_INCREF(interp->builtins);
}
sysmod = _PyImport_FindExtension("sys", "sys");
if (bimod != NULL && sysmod != NULL) {
interp->sysdict = PyModule_GetDict(sysmod);
+ if (interp->sysdict == NULL)
+ goto handle_error;
Py_INCREF(interp->sysdict);
PySys_SetPath(Py_GetPath());
PyDict_SetItemString(interp->sysdict, "modules",
@@ -549,6 +553,7 @@
if (!PyErr_Occurred())
return tstate;
+handle_error:
/* Oops, it didn't work. Undo it all. */
PyErr_Print();
Modified: python/branches/bcannon-objcap/Python/symtable.c
==============================================================================
--- python/branches/bcannon-objcap/Python/symtable.c (original)
+++ python/branches/bcannon-objcap/Python/symtable.c Mon Aug 28 21:49:46 2006
@@ -221,8 +221,8 @@
return st;
st->st_filename = filename;
st->st_future = future;
- if (!symtable_enter_block(st, GET_IDENTIFIER(top), ModuleBlock,
- (void *)mod, 0)) {
+ if (!GET_IDENTIFIER(top) ||
+ !symtable_enter_block(st, top, ModuleBlock, (void *)mod, 0)) {
PySymtable_Free(st);
return NULL;
}
@@ -1123,12 +1123,13 @@
VISIT(st, expr, e->v.UnaryOp.operand);
break;
case Lambda_kind: {
- if (!symtable_add_def(st, GET_IDENTIFIER(lambda), DEF_LOCAL))
+ if (!GET_IDENTIFIER(lambda) ||
+ !symtable_add_def(st, lambda, DEF_LOCAL))
return 0;
if (e->v.Lambda.args->defaults)
VISIT_SEQ(st, expr, e->v.Lambda.args->defaults);
/* XXX how to get line numbers for expressions */
- if (!symtable_enter_block(st, GET_IDENTIFIER(lambda),
+ if (!symtable_enter_block(st, lambda,
FunctionBlock, (void *)e, 0))
return 0;
VISIT_IN_BLOCK(st, arguments, e->v.Lambda.args, (void*)e);
@@ -1404,8 +1405,8 @@
/* Outermost iterator is evaluated in current scope */
VISIT(st, expr, outermost->iter);
/* Create generator scope for the rest */
- if (!symtable_enter_block(st, GET_IDENTIFIER(genexpr),
- FunctionBlock, (void *)e, 0)) {
+ if (!GET_IDENTIFIER(genexpr) ||
+ !symtable_enter_block(st, genexpr, FunctionBlock, (void *)e, 0)) {
return 0;
}
st->st_cur->ste_generator = 1;
@@ -1419,7 +1420,5 @@
VISIT_SEQ_TAIL_IN_BLOCK(st, comprehension,
e->v.GeneratorExp.generators, 1, (void*)e);
VISIT_IN_BLOCK(st, expr, e->v.GeneratorExp.elt, (void*)e);
- if (!symtable_exit_block(st, (void *)e))
- return 0;
- return 1;
+ return symtable_exit_block(st, (void *)e);
}
Modified: python/branches/bcannon-objcap/README
==============================================================================
--- python/branches/bcannon-objcap/README (original)
+++ python/branches/bcannon-objcap/README Mon Aug 28 21:49:46 2006
@@ -1,5 +1,5 @@
-This is Python version 2.5 beta 3
-=================================
+This is Python version 2.5 rc 1
+===============================
Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation.
All rights reserved.
Modified: python/branches/bcannon-objcap/Tools/buildbot/external.bat
==============================================================================
--- python/branches/bcannon-objcap/Tools/buildbot/external.bat (original)
+++ python/branches/bcannon-objcap/Tools/buildbot/external.bat Mon Aug 28 21:49:46 2006
@@ -28,6 +28,7 @@
cd tk8.4.12\win
nmake -f makefile.vc TCLDIR=..\..\tcl8.4.12
nmake -f makefile.vc TCLDIR=..\..\tcl8.4.12 INSTALLDIR=..\..\tcltk install
+ cd ..\..
)
@rem sqlite
Modified: python/branches/bcannon-objcap/Tools/msi/msi.py
==============================================================================
--- python/branches/bcannon-objcap/Tools/msi/msi.py (original)
+++ python/branches/bcannon-objcap/Tools/msi/msi.py Mon Aug 28 21:49:46 2006
@@ -89,7 +89,8 @@
'_msi.pyd',
'_ctypes.pyd',
'_ctypes_test.pyd',
- '_sqlite3.pyd'
+ '_sqlite3.pyd',
+ '_hashlib.pyd'
]
# Well-known component UUIDs
@@ -871,6 +872,12 @@
version=version, language=lang)
tmpfiles.append("msvcr71.dll")
+ # Check if _ctypes.pyd exists
+ have_ctypes = os.path.exists(srcdir+"/PCBuild/_ctypes.pyd")
+ if not have_ctypes:
+ print "WARNING: _ctypes.pyd not found, ctypes will not be included"
+ extensions.remove("_ctypes.pyd")
+
# Add all .py files in Lib, except lib-tk, test
dirs={}
pydirs = [(root,"Lib")]
@@ -888,6 +895,8 @@
# data: Lib/email/test
# output: Lib/test
testsuite.set_current()
+ elif not have_ctypes and dir == "ctypes":
+ continue
else:
default_feature.set_current()
lib = PyDirectory(db, cab, parent, dir, dir, "%s|%s" % (parent.make_short(dir), dir))
Modified: python/branches/bcannon-objcap/configure
==============================================================================
--- python/branches/bcannon-objcap/configure (original)
+++ python/branches/bcannon-objcap/configure Mon Aug 28 21:49:46 2006
@@ -1,7 +1,7 @@
#! /bin/sh
-# From configure.in Revision: 47267 .
+# From configure.in Revision: 51173 .
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.59 for python 2.5.
+# Generated by GNU Autoconf 2.59 for python 2.6.
#
# Report bugs to <http://www.python.org/python-bugs>.
#
@@ -270,8 +270,8 @@
# Identity of this package.
PACKAGE_NAME='python'
PACKAGE_TARNAME='python'
-PACKAGE_VERSION='2.5'
-PACKAGE_STRING='python 2.5'
+PACKAGE_VERSION='2.6'
+PACKAGE_STRING='python 2.6'
PACKAGE_BUGREPORT='http://www.python.org/python-bugs'
ac_unique_file="Include/object.h"
@@ -781,7 +781,7 @@
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures python 2.5 to adapt to many kinds of systems.
+\`configure' configures python 2.6 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -838,7 +838,7 @@
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of python 2.5:";;
+ short | recursive ) echo "Configuration of python 2.6:";;
esac
cat <<\_ACEOF
@@ -991,7 +991,7 @@
test -n "$ac_init_help" && exit 0
if $ac_init_version; then
cat <<\_ACEOF
-python configure 2.5
+python configure 2.6
generated by GNU Autoconf 2.59
Copyright (C) 2003 Free Software Foundation, Inc.
@@ -1005,7 +1005,7 @@
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by python $as_me 2.5, which was
+It was created by python $as_me 2.6, which was
generated by GNU Autoconf 2.59. Invocation command line was
$ $0 $@
@@ -1357,7 +1357,7 @@
mv confdefs.h.new confdefs.h
-VERSION=2.5
+VERSION=2.6
SOVERSION=1.0
@@ -22610,7 +22610,7 @@
} >&5
cat >&5 <<_CSEOF
-This file was extended by python $as_me 2.5, which was
+This file was extended by python $as_me 2.6, which was
generated by GNU Autoconf 2.59. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -22670,7 +22670,7 @@
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
-python config.status 2.5
+python config.status 2.6
configured by $0, generated by GNU Autoconf 2.59,
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
Modified: python/branches/bcannon-objcap/configure.in
==============================================================================
--- python/branches/bcannon-objcap/configure.in (original)
+++ python/branches/bcannon-objcap/configure.in Mon Aug 28 21:49:46 2006
@@ -1,7 +1,7 @@
dnl Process this file with autoconf 2.0 or later to make a configure script.
# Set VERSION so we only need to edit in one place (i.e., here)
-m4_define(PYTHON_VERSION, 2.5)
+m4_define(PYTHON_VERSION, 2.6)
AC_REVISION($Revision$)
AC_PREREQ(2.59)
1
0
r51629 - python/branches/hoxworth-stdlib_logging-soc/test_smtpd_logging.py
by jackilyn.hoxworth 28 Aug '06
by jackilyn.hoxworth 28 Aug '06
28 Aug '06
Author: jackilyn.hoxworth
Date: Mon Aug 28 02:22:37 2006
New Revision: 51629
Added:
python/branches/hoxworth-stdlib_logging-soc/test_smtpd_logging.py
Log:
Added: python/branches/hoxworth-stdlib_logging-soc/test_smtpd_logging.py
==============================================================================
--- (empty file)
+++ python/branches/hoxworth-stdlib_logging-soc/test_smtpd_logging.py Mon Aug 28 02:22:37 2006
@@ -0,0 +1,23 @@
+import smtpd
+import logging
+from cStringIO import StringIO
+
+# ... run the tests ...
+log=logging.getLogger("py.smtpd")
+stringLog = StringIO()
+
+# define the handler and level
+handler = logging.StreamHandler(stringLog)
+log.setLevel(logging.INFO)
+
+# add the handler to the logger
+log.addHandler(handler)
+
+smtpd._log.info("message 1")
+
+print stringLog.getvalue() # For testing purposes
+
+if stringLog.getvalue() != "Error: It worked":
+ print "it worked"
+else:
+ print "it didn't work"
\ No newline at end of file
2
2
(sorry, I sent thit to the checkins list instead of to you)
This looks more like the older "someone has to be watching to tell if
it failed" format.
Much better than nothing, but not the goal. If you're checking in
what you already have, great; if you're writing new, try to make it
auto-checkable (though this is still much better than nothing.)
-jJ
1
0
r51630 - peps/trunk/pep-0352.txt peps/trunk/pep-0358.txt peps/trunk/pep-3001.txt peps/trunk/pep-3099.txt
by georg.brandl 28 Aug '06
by georg.brandl 28 Aug '06
28 Aug '06
Author: georg.brandl
Date: Mon Aug 28 11:50:10 2006
New Revision: 51630
Modified:
peps/trunk/pep-0352.txt (props changed)
peps/trunk/pep-0358.txt (props changed)
peps/trunk/pep-3001.txt (props changed)
peps/trunk/pep-3099.txt (props changed)
Log:
Set missing "svn:keywords" property for some PEPs.
1
0
r51624 - in python/trunk/Lib: genericpath.py macpath.py ntpath.py os2emxpath.py posixpath.py test/test_genericpath.py
by jack.diederich 27 Aug '06
by jack.diederich 27 Aug '06
27 Aug '06
Author: jack.diederich
Date: Sat Aug 26 20:42:06 2006
New Revision: 51624
Added:
python/trunk/Lib/genericpath.py
python/trunk/Lib/test/test_genericpath.py
Modified:
python/trunk/Lib/macpath.py
python/trunk/Lib/ntpath.py
python/trunk/Lib/os2emxpath.py
python/trunk/Lib/posixpath.py
Log:
- Move functions common to all path modules into genericpath.py and have the
OS speicifc path modules import them.
- Have os2emxpath import common functions fron ntpath instead of using copies
Added: python/trunk/Lib/genericpath.py
==============================================================================
--- (empty file)
+++ python/trunk/Lib/genericpath.py Sat Aug 26 20:42:06 2006
@@ -0,0 +1,78 @@
+"""
+Path operations common to more than one OS
+Do not use directly. The OS specific modules import the appropriate
+functions from this module themselves.
+"""
+import os
+import stat
+
+__all__ = ['commonprefix', 'exists', 'getatime', 'getctime', 'getmtime',
+ 'getsize', 'isdir', 'isfile']
+
+
+# Does a path exist?
+# This is false for dangling symbolic links on systems that support them.
+def exists(path):
+ """Test whether a path exists. Returns False for broken symbolic links"""
+ try:
+ st = os.stat(path)
+ except os.error:
+ return False
+ return True
+
+
+# This follows symbolic links, so both islink() and isdir() can be true
+# for the same path ono systems that support symlinks
+def isfile(path):
+ """Test whether a path is a regular file"""
+ try:
+ st = os.stat(path)
+ except os.error:
+ return False
+ return stat.S_ISREG(st.st_mode)
+
+
+# Is a path a directory?
+# This follows symbolic links, so both islink() and isdir()
+# can be true for the same path on systems that support symlinks
+def isdir(s):
+ """Return true if the pathname refers to an existing directory."""
+ try:
+ st = os.stat(s)
+ except os.error:
+ return False
+ return stat.S_ISDIR(st.st_mode)
+
+
+def getsize(filename):
+ """Return the size of a file, reported by os.stat()."""
+ return os.stat(filename).st_size
+
+
+def getmtime(filename):
+ """Return the last modification time of a file, reported by os.stat()."""
+ return os.stat(filename).st_mtime
+
+
+def getatime(filename):
+ """Return the last access time of a file, reported by os.stat()."""
+ return os.stat(filename).st_atime
+
+
+def getctime(filename):
+ """Return the metadata change time of a file, reported by os.stat()."""
+ return os.stat(filename).st_ctime
+
+
+# Return the longest prefix of all list elements.
+def commonprefix(m):
+ "Given a list of pathnames, returns the longest common leading component"
+ if not m: return ''
+ s1 = min(m)
+ s2 = max(m)
+ n = min(len(s1), len(s2))
+ for i in xrange(n):
+ if s1[i] != s2[i]:
+ return s1[:i]
+ return s1[:n]
+
Modified: python/trunk/Lib/macpath.py
==============================================================================
--- python/trunk/Lib/macpath.py (original)
+++ python/trunk/Lib/macpath.py Sat Aug 26 20:42:06 2006
@@ -2,6 +2,7 @@
import os
from stat import *
+from genericpath import *
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
"basename","dirname","commonprefix","getsize","getmtime",
@@ -101,31 +102,6 @@
components = split(s)
return len(components) == 2 and components[1] == ''
-def isdir(s):
- """Return true if the pathname refers to an existing directory."""
-
- try:
- st = os.stat(s)
- except os.error:
- return 0
- return S_ISDIR(st.st_mode)
-
-
-# Get size, mtime, atime of files.
-
-def getsize(filename):
- """Return the size of a file, reported by os.stat()."""
- return os.stat(filename).st_size
-
-def getmtime(filename):
- """Return the last modification time of a file, reported by os.stat()."""
- return os.stat(filename).st_mtime
-
-def getatime(filename):
- """Return the last access time of a file, reported by os.stat()."""
- return os.stat(filename).st_atime
-
-
def islink(s):
"""Return true if the pathname refers to a symbolic link."""
@@ -135,29 +111,6 @@
except:
return False
-
-def isfile(s):
- """Return true if the pathname refers to an existing regular file."""
-
- try:
- st = os.stat(s)
- except os.error:
- return False
- return S_ISREG(st.st_mode)
-
-def getctime(filename):
- """Return the creation time of a file, reported by os.stat()."""
- return os.stat(filename).st_ctime
-
-def exists(s):
- """Test whether a path exists. Returns False for broken symbolic links"""
-
- try:
- st = os.stat(s)
- except os.error:
- return False
- return True
-
# Is `stat`/`lstat` a meaningful difference on the Mac? This is safe in any
# case.
@@ -170,20 +123,6 @@
return False
return True
-# Return the longest prefix of all list elements.
-
-def commonprefix(m):
- "Given a list of pathnames, returns the longest common leading component"
- if not m: return ''
- s1 = min(m)
- s2 = max(m)
- n = min(len(s1), len(s2))
- for i in xrange(n):
- if s1[i] != s2[i]:
- return s1[:i]
- return s1[:n]
-
-
def expandvars(path):
"""Dummy to retain interface-compatibility with other operating systems."""
return path
Modified: python/trunk/Lib/ntpath.py
==============================================================================
--- python/trunk/Lib/ntpath.py (original)
+++ python/trunk/Lib/ntpath.py Sat Aug 26 20:42:06 2006
@@ -8,6 +8,7 @@
import os
import stat
import sys
+from genericpath import *
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
"basename","dirname","commonprefix","getsize","getmtime",
@@ -206,86 +207,18 @@
"""Returns the directory component of a pathname"""
return split(p)[0]
-
-# Return the longest prefix of all list elements.
-
-def commonprefix(m):
- "Given a list of pathnames, returns the longest common leading component"
- if not m: return ''
- s1 = min(m)
- s2 = max(m)
- n = min(len(s1), len(s2))
- for i in xrange(n):
- if s1[i] != s2[i]:
- return s1[:i]
- return s1[:n]
-
-
-# Get size, mtime, atime of files.
-
-def getsize(filename):
- """Return the size of a file, reported by os.stat()"""
- return os.stat(filename).st_size
-
-def getmtime(filename):
- """Return the last modification time of a file, reported by os.stat()"""
- return os.stat(filename).st_mtime
-
-def getatime(filename):
- """Return the last access time of a file, reported by os.stat()"""
- return os.stat(filename).st_atime
-
-def getctime(filename):
- """Return the creation time of a file, reported by os.stat()."""
- return os.stat(filename).st_ctime
-
# Is a path a symbolic link?
# This will always return false on systems where posix.lstat doesn't exist.
def islink(path):
- """Test for symbolic link. On WindowsNT/95 always returns false"""
+ """Test for symbolic link.
+ On WindowsNT/95 and OS/2 always returns false
+ """
return False
-
-# Does a path exist?
-
-def exists(path):
- """Test whether a path exists"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return True
-
+# alias exists to lexists
lexists = exists
-
-# Is a path a dos directory?
-# This follows symbolic links, so both islink() and isdir() can be true
-# for the same path.
-
-def isdir(path):
- """Test whether a path is a directory"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return stat.S_ISDIR(st.st_mode)
-
-
-# Is a path a regular file?
-# This follows symbolic links, so both islink() and isdir() can be true
-# for the same path.
-
-def isfile(path):
- """Test whether a path is a regular file"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return stat.S_ISREG(st.st_mode)
-
-
# Is a path a mount point? Either a root (with or without drive letter)
# or an UNC path with at most a / or \ after the mount point.
Modified: python/trunk/Lib/os2emxpath.py
==============================================================================
--- python/trunk/Lib/os2emxpath.py (original)
+++ python/trunk/Lib/os2emxpath.py Sat Aug 26 20:42:06 2006
@@ -7,6 +7,9 @@
import os
import stat
+from genericpath import *
+from ntpath import (expanduser, expandvars, isabs, islink, splitdrive,
+ splitext, split, walk)
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
"basename","dirname","commonprefix","getsize","getmtime",
@@ -36,18 +39,6 @@
return s.replace('\\', '/').lower()
-# Return whether a path is absolute.
-# Trivial in Posix, harder on the Mac or MS-DOS.
-# For DOS it is absolute if it starts with a slash or backslash (current
-# volume), or if a pathname after the volume letter and colon / UNC resource
-# starts with a slash or backslash.
-
-def isabs(s):
- """Test whether a path is absolute"""
- s = splitdrive(s)[1]
- return s != '' and s[:1] in '/\\'
-
-
# Join two (or more) paths.
def join(a, *p):
@@ -63,17 +54,6 @@
return path
-# Split a path in a drive specification (a drive letter followed by a
-# colon) and the path specification.
-# It is always true that drivespec + pathspec == p
-def splitdrive(p):
- """Split a pathname into drive and path specifiers. Returns a 2-tuple
-"(drive,path)"; either part may be empty"""
- if p[1:2] == ':':
- return p[0:2], p[2:]
- return '', p
-
-
# Parse UNC paths
def splitunc(p):
"""Split a pathname into UNC mount point and relative path specifiers.
@@ -103,57 +83,6 @@
return '', p
-# Split a path in head (everything up to the last '/') and tail (the
-# rest). After the trailing '/' is stripped, the invariant
-# join(head, tail) == p holds.
-# The resulting head won't end in '/' unless it is the root.
-
-def split(p):
- """Split a pathname.
-
- Return tuple (head, tail) where tail is everything after the final slash.
- Either part may be empty."""
-
- d, p = splitdrive(p)
- # set i to index beyond p's last slash
- i = len(p)
- while i and p[i-1] not in '/\\':
- i = i - 1
- head, tail = p[:i], p[i:] # now tail has no slashes
- # remove trailing slashes from head, unless it's all slashes
- head2 = head
- while head2 and head2[-1] in '/\\':
- head2 = head2[:-1]
- head = head2 or head
- return d + head, tail
-
-
-# Split a path in root and extension.
-# The extension is everything starting at the last dot in the last
-# pathname component; the root is everything before that.
-# It is always true that root + ext == p.
-
-def splitext(p):
- """Split the extension from a pathname.
-
- Extension is everything from the last dot to the end.
- Return (root, ext), either part may be empty."""
- root, ext = '', ''
- for c in p:
- if c in ['/','\\']:
- root, ext = root + ext + c, ''
- elif c == '.':
- if ext:
- root, ext = root + ext, c
- else:
- ext = c
- elif ext:
- ext = ext + c
- else:
- root = root + c
- return root, ext
-
-
# Return the tail (basename) part of a path.
def basename(p):
@@ -168,84 +97,12 @@
return split(p)[0]
-# Return the longest prefix of all list elements.
-
-def commonprefix(m):
- "Given a list of pathnames, returns the longest common leading component"
- if not m: return ''
- s1 = min(m)
- s2 = max(m)
- n = min(len(s1), len(s2))
- for i in xrange(n):
- if s1[i] != s2[i]:
- return s1[:i]
- return s1[:n]
-
-
-# Get size, mtime, atime of files.
-
-def getsize(filename):
- """Return the size of a file, reported by os.stat()"""
- return os.stat(filename).st_size
-
-def getmtime(filename):
- """Return the last modification time of a file, reported by os.stat()"""
- return os.stat(filename).st_mtime
-
-def getatime(filename):
- """Return the last access time of a file, reported by os.stat()"""
- return os.stat(filename).st_atime
-
-def getctime(filename):
- """Return the creation time of a file, reported by os.stat()."""
- return os.stat(filename).st_ctime
-
-# Is a path a symbolic link?
-# This will always return false on systems where posix.lstat doesn't exist.
-
-def islink(path):
- """Test for symbolic link. On OS/2 always returns false"""
- return False
-
-
-# Does a path exist?
-# This is false for dangling symbolic links.
-
-def exists(path):
- """Test whether a path exists"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return True
-
+# alias exists to lexists
lexists = exists
# Is a path a directory?
-def isdir(path):
- """Test whether a path is a directory"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return stat.S_ISDIR(st.st_mode)
-
-
-# Is a path a regular file?
-# This follows symbolic links, so both islink() and isdir() can be true
-# for the same path.
-
-def isfile(path):
- """Test whether a path is a regular file"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return stat.S_ISREG(st.st_mode)
-
-
# Is a path a mount point? Either a root (with or without drive letter)
# or an UNC path with at most a / or \ after the mount point.
@@ -258,131 +115,6 @@
return len(p) == 1 and p[0] in '/\\'
-# Directory tree walk.
-# For each directory under top (including top itself, but excluding
-# '.' and '..'), func(arg, dirname, filenames) is called, where
-# dirname is the name of the directory and filenames is the list
-# of files (and subdirectories etc.) in the directory.
-# The func may modify the filenames list, to implement a filter,
-# or to impose a different order of visiting.
-
-def walk(top, func, arg):
- """Directory tree walk whth callback function.
-
- walk(top, func, arg) calls func(arg, d, files) for each directory d
- in the tree rooted at top (including top itself); files is a list
- of all the files and subdirs in directory d."""
- try:
- names = os.listdir(top)
- except os.error:
- return
- func(arg, top, names)
- exceptions = ('.', '..')
- for name in names:
- if name not in exceptions:
- name = join(top, name)
- if isdir(name):
- walk(name, func, arg)
-
-
-# Expand paths beginning with '~' or '~user'.
-# '~' means $HOME; '~user' means that user's home directory.
-# If the path doesn't begin with '~', or if the user or $HOME is unknown,
-# the path is returned unchanged (leaving error reporting to whatever
-# function is called with the expanded path as argument).
-# See also module 'glob' for expansion of *, ? and [...] in pathnames.
-# (A function should also be defined to do full *sh-style environment
-# variable expansion.)
-
-def expanduser(path):
- """Expand ~ and ~user constructs.
-
- If user or $HOME is unknown, do nothing."""
- if path[:1] != '~':
- return path
- i, n = 1, len(path)
- while i < n and path[i] not in '/\\':
- i = i + 1
- if i == 1:
- if 'HOME' in os.environ:
- userhome = os.environ['HOME']
- elif not 'HOMEPATH' in os.environ:
- return path
- else:
- try:
- drive = os.environ['HOMEDRIVE']
- except KeyError:
- drive = ''
- userhome = join(drive, os.environ['HOMEPATH'])
- else:
- return path
- return userhome + path[i:]
-
-
-# Expand paths containing shell variable substitutions.
-# The following rules apply:
-# - no expansion within single quotes
-# - no escape character, except for '$$' which is translated into '$'
-# - ${varname} is accepted.
-# - varnames can be made out of letters, digits and the character '_'
-# XXX With COMMAND.COM you can use any characters in a variable name,
-# XXX except '^|<>='.
-
-def expandvars(path):
- """Expand shell variables of form $var and ${var}.
-
- Unknown variables are left unchanged."""
- if '$' not in path:
- return path
- import string
- varchars = string.letters + string.digits + '_-'
- res = ''
- index = 0
- pathlen = len(path)
- while index < pathlen:
- c = path[index]
- if c == '\'': # no expansion within single quotes
- path = path[index + 1:]
- pathlen = len(path)
- try:
- index = path.index('\'')
- res = res + '\'' + path[:index + 1]
- except ValueError:
- res = res + path
- index = pathlen - 1
- elif c == '$': # variable or '$$'
- if path[index + 1:index + 2] == '$':
- res = res + c
- index = index + 1
- elif path[index + 1:index + 2] == '{':
- path = path[index+2:]
- pathlen = len(path)
- try:
- index = path.index('}')
- var = path[:index]
- if var in os.environ:
- res = res + os.environ[var]
- except ValueError:
- res = res + path
- index = pathlen - 1
- else:
- var = ''
- index = index + 1
- c = path[index:index + 1]
- while c != '' and c in varchars:
- var = var + c
- index = index + 1
- c = path[index:index + 1]
- if var in os.environ:
- res = res + os.environ[var]
- if c != '':
- res = res + c
- else:
- res = res + c
- index = index + 1
- return res
-
-
# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B.
def normpath(path):
Modified: python/trunk/Lib/posixpath.py
==============================================================================
--- python/trunk/Lib/posixpath.py (original)
+++ python/trunk/Lib/posixpath.py Sat Aug 26 20:42:06 2006
@@ -12,6 +12,7 @@
import os
import stat
+from genericpath import *
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
"basename","dirname","commonprefix","getsize","getmtime",
@@ -119,37 +120,6 @@
return split(p)[0]
-# Return the longest prefix of all list elements.
-
-def commonprefix(m):
- "Given a list of pathnames, returns the longest common leading component"
- if not m: return ''
- s1 = min(m)
- s2 = max(m)
- n = min(len(s1), len(s2))
- for i in xrange(n):
- if s1[i] != s2[i]:
- return s1[:i]
- return s1[:n]
-
-# Get size, mtime, atime of files.
-
-def getsize(filename):
- """Return the size of a file, reported by os.stat()."""
- return os.stat(filename).st_size
-
-def getmtime(filename):
- """Return the last modification time of a file, reported by os.stat()."""
- return os.stat(filename).st_mtime
-
-def getatime(filename):
- """Return the last access time of a file, reported by os.stat()."""
- return os.stat(filename).st_atime
-
-def getctime(filename):
- """Return the metadata change time of a file, reported by os.stat()."""
- return os.stat(filename).st_ctime
-
# Is a path a symbolic link?
# This will always return false on systems where os.lstat doesn't exist.
@@ -161,19 +131,6 @@
return False
return stat.S_ISLNK(st.st_mode)
-
-# Does a path exist?
-# This is false for dangling symbolic links.
-
-def exists(path):
- """Test whether a path exists. Returns False for broken symbolic links"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return True
-
-
# Being true for dangling symbolic links is also useful.
def lexists(path):
@@ -185,32 +142,6 @@
return True
-# Is a path a directory?
-# This follows symbolic links, so both islink() and isdir() can be true
-# for the same path.
-
-def isdir(path):
- """Test whether a path is a directory"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return stat.S_ISDIR(st.st_mode)
-
-
-# Is a path a regular file?
-# This follows symbolic links, so both islink() and isfile() can be true
-# for the same path.
-
-def isfile(path):
- """Test whether a path is a regular file"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return stat.S_ISREG(st.st_mode)
-
-
# Are two filenames really pointing to the same file?
def samefile(f1, f2):
Added: python/trunk/Lib/test/test_genericpath.py
==============================================================================
--- (empty file)
+++ python/trunk/Lib/test/test_genericpath.py Sat Aug 26 20:42:06 2006
@@ -0,0 +1,184 @@
+import unittest
+from test import test_support
+import os
+import genericpath
+
+class AllCommonTest(unittest.TestCase):
+
+ def assertIs(self, a, b):
+ self.assert_(a is b)
+
+ def test_commonprefix(self):
+ self.assertEqual(
+ genericpath.commonprefix([]),
+ ""
+ )
+ self.assertEqual(
+ genericpath.commonprefix(["/home/swenson/spam", "/home/swen/spam"]),
+ "/home/swen"
+ )
+ self.assertEqual(
+ genericpath.commonprefix(["/home/swen/spam", "/home/swen/eggs"]),
+ "/home/swen/"
+ )
+ self.assertEqual(
+ genericpath.commonprefix(["/home/swen/spam", "/home/swen/spam"]),
+ "/home/swen/spam"
+ )
+
+ def test_getsize(self):
+ f = open(test_support.TESTFN, "wb")
+ try:
+ f.write("foo")
+ f.close()
+ self.assertEqual(genericpath.getsize(test_support.TESTFN), 3)
+ finally:
+ if not f.closed:
+ f.close()
+ os.remove(test_support.TESTFN)
+
+ def test_time(self):
+ f = open(test_support.TESTFN, "wb")
+ try:
+ f.write("foo")
+ f.close()
+ f = open(test_support.TESTFN, "ab")
+ f.write("bar")
+ f.close()
+ f = open(test_support.TESTFN, "rb")
+ d = f.read()
+ f.close()
+ self.assertEqual(d, "foobar")
+
+ self.assert_(
+ genericpath.getctime(test_support.TESTFN) <=
+ genericpath.getmtime(test_support.TESTFN)
+ )
+ finally:
+ if not f.closed:
+ f.close()
+ os.remove(test_support.TESTFN)
+
+ def test_exists(self):
+ self.assertIs(genericpath.exists(test_support.TESTFN), False)
+ f = open(test_support.TESTFN, "wb")
+ try:
+ f.write("foo")
+ f.close()
+ self.assertIs(genericpath.exists(test_support.TESTFN), True)
+ finally:
+ if not f.close():
+ f.close()
+ try:
+ os.remove(test_support.TESTFN)
+ except os.error:
+ pass
+
+ self.assertRaises(TypeError, genericpath.exists)
+
+ def test_isdir(self):
+ self.assertIs(genericpath.isdir(test_support.TESTFN), False)
+ f = open(test_support.TESTFN, "wb")
+ try:
+ f.write("foo")
+ f.close()
+ self.assertIs(genericpath.isdir(test_support.TESTFN), False)
+ os.remove(test_support.TESTFN)
+ os.mkdir(test_support.TESTFN)
+ self.assertIs(genericpath.isdir(test_support.TESTFN), True)
+ os.rmdir(test_support.TESTFN)
+ finally:
+ if not f.close():
+ f.close()
+ try:
+ os.remove(test_support.TESTFN)
+ except os.error:
+ pass
+ try:
+ os.rmdir(test_support.TESTFN)
+ except os.error:
+ pass
+
+ self.assertRaises(TypeError, genericpath.isdir)
+
+ def test_isfile(self):
+ self.assertIs(genericpath.isfile(test_support.TESTFN), False)
+ f = open(test_support.TESTFN, "wb")
+ try:
+ f.write("foo")
+ f.close()
+ self.assertIs(genericpath.isfile(test_support.TESTFN), True)
+ os.remove(test_support.TESTFN)
+ os.mkdir(test_support.TESTFN)
+ self.assertIs(genericpath.isfile(test_support.TESTFN), False)
+ os.rmdir(test_support.TESTFN)
+ finally:
+ if not f.close():
+ f.close()
+ try:
+ os.remove(test_support.TESTFN)
+ except os.error:
+ pass
+ try:
+ os.rmdir(test_support.TESTFN)
+ except os.error:
+ pass
+
+ self.assertRaises(TypeError, genericpath.isdir)
+
+ def test_samefile(self):
+ f = open(test_support.TESTFN + "1", "wb")
+ try:
+ f.write("foo")
+ f.close()
+ self.assertIs(
+ genericpath.samefile(
+ test_support.TESTFN + "1",
+ test_support.TESTFN + "1"
+ ),
+ True
+ )
+ # If we don't have links, assume that os.stat doesn't return resonable
+ # inode information and thus, that samefile() doesn't work
+ if hasattr(os, "symlink"):
+ os.symlink(
+ test_support.TESTFN + "1",
+ test_support.TESTFN + "2"
+ )
+ self.assertIs(
+ genericpath.samefile(
+ test_support.TESTFN + "1",
+ test_support.TESTFN + "2"
+ ),
+ True
+ )
+ os.remove(test_support.TESTFN + "2")
+ f = open(test_support.TESTFN + "2", "wb")
+ f.write("bar")
+ f.close()
+ self.assertIs(
+ genericpath.samefile(
+ test_support.TESTFN + "1",
+ test_support.TESTFN + "2"
+ ),
+ False
+ )
+ finally:
+ if not f.close():
+ f.close()
+ try:
+ os.remove(test_support.TESTFN + "1")
+ except os.error:
+ pass
+ try:
+ os.remove(test_support.TESTFN + "2")
+ except os.error:
+ pass
+
+ self.assertRaises(TypeError, genericpath.samefile)
+
+def test_main():
+ test_support.run_unittest(AllCommonTest)
+
+if __name__=="__main__":
+ test_main()
3
3
path in py3K Re: r51624 - in python/trunk/Lib: genericpath.py macpath.py ntpath.py os2emxpath.py posixpath.py test/test_genericpath.py
by Jim Jewett 27 Aug '06
by Jim Jewett 27 Aug '06
27 Aug '06
In Py3K, is it still safe to assume that a list of paths will be
(enough like) ordinary strings?
I ask because of the various Path object discussions; it wasn't clear
that a Path object should be a sequence of (normalized unicode?)
characters (rather than path components), that the path would always
be normalized or absolute, or even that it would implement the LE (or
LT?) comparison operator.
-jJ
On 8/26/06, jack.diederich <python-checkins(a)python.org> wrote:
> Author: jack.diederich
> Date: Sat Aug 26 20:42:06 2006
> New Revision: 51624
> Added: python/trunk/Lib/genericpath.py
> +# Return the longest prefix of all list elements.
> +def commonprefix(m):
> + "Given a list of pathnames, returns the longest common leading component"
> + if not m: return ''
> + s1 = min(m)
> + s2 = max(m)
> + n = min(len(s1), len(s2))
> + for i in xrange(n):
> + if s1[i] != s2[i]:
> + return s1[:i]
> + return s1[:n]
2
1