summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/idlelib/NEWS.txt5
-rw-r--r--Lib/idlelib/configHandler.py7
-rwxr-xr-xLib/rational.py36
-rw-r--r--Lib/test/test_descr.py75
-rw-r--r--Lib/test/test_rational.py23
-rw-r--r--Lib/urllib2.py2
6 files changed, 143 insertions, 5 deletions
diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt
index 12a0c6f..d51d94e 100644
--- a/Lib/idlelib/NEWS.txt
+++ b/Lib/idlelib/NEWS.txt
@@ -45,6 +45,11 @@ What's New in IDLE 2.6a1?
*Release date: XX-XXX-200X* UNRELEASED, but merged into 3.0
+- There was an error on exit if no sys.exitfunc was defined. Issue 1647.
+
+- Could not open files in .idlerc directory if latter was hidden on Windows.
+ Issue 1743, Issue 1862.
+
- Configure Dialog: improved layout for keybinding. Patch 1457 Tal Einat.
- tabpage.py updated: tabbedPages.py now supports multiple dynamic rows
diff --git a/Lib/idlelib/configHandler.py b/Lib/idlelib/configHandler.py
index b5d9769..66bad74 100644
--- a/Lib/idlelib/configHandler.py
+++ b/Lib/idlelib/configHandler.py
@@ -139,7 +139,12 @@ class IdleUserConfParser(IdleConfParser):
"""
if not self.IsEmpty():
- cfgFile=open(self.file,'w')
+ fname = self.file
+ try:
+ cfgFile = open(fname, 'w')
+ except IOError:
+ fname.unlink()
+ cfgFile = open(fname, 'w')
self.write(cfgFile)
else:
self.RemoveFile()
diff --git a/Lib/rational.py b/Lib/rational.py
index 71ffff7..4a56cf2 100755
--- a/Lib/rational.py
+++ b/Lib/rational.py
@@ -171,6 +171,42 @@ class Rational(RationalAbc):
else:
return cls(digits, 10 ** -exp)
+ @classmethod
+ def from_continued_fraction(cls, seq):
+ 'Build a Rational from a continued fraction expessed as a sequence'
+ n, d = 1, 0
+ for e in reversed(seq):
+ n, d = d, n
+ n += e * d
+ return cls(n, d) if seq else cls(0)
+
+ def as_continued_fraction(self):
+ 'Return continued fraction expressed as a list'
+ n = self.numerator
+ d = self.denominator
+ cf = []
+ while d:
+ e = int(n // d)
+ cf.append(e)
+ n -= e * d
+ n, d = d, n
+ return cf
+
+ @classmethod
+ def approximate_from_float(cls, f, max_denominator):
+ 'Best rational approximation to f with a denominator <= max_denominator'
+ # XXX First cut at algorithm
+ # Still needs rounding rules as specified at
+ # http://en.wikipedia.org/wiki/Continued_fraction
+ cf = cls.from_float(f).as_continued_fraction()
+ result = Rational(0)
+ for i in range(1, len(cf)):
+ new = cls.from_continued_fraction(cf[:i])
+ if new.denominator > max_denominator:
+ break
+ result = new
+ return result
+
@property
def numerator(a):
return a._numerator
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index 8ccece1..7ef702b 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -1,7 +1,7 @@
# Test enhancements related to descriptors and new-style classes
-from test.test_support import verify, vereq, verbose, TestFailed, TESTFN
-from test.test_support import get_original_stdout
+# XXX Please, please, please, someone convert this to unittest style!
+from test.test_support import verify, vereq, verbose, TestFailed, TESTFN, get_original_stdout
from copy import deepcopy
import types
@@ -4173,6 +4173,8 @@ def test_assign_slice():
# ceval.c's assign_slice used to check for
# tp->tp_as_sequence->sq_slice instead of
# tp->tp_as_sequence->sq_ass_slice
+ if verbose:
+ print("Testing assign_slice...")
class C(object):
def __setitem__(self, idx, value):
@@ -4182,8 +4184,72 @@ def test_assign_slice():
c[1:2] = 3
vereq(c.value, 3)
+def test_weakref_in_del_segfault():
+ # This used to segfault until r60057
+ if verbose:
+ print("Testing weakref in del segfault...")
+
+ import weakref
+ global ref
+
+ class Target():
+ def __del__(self):
+ global ref
+ ref = weakref.ref(self)
+
+ w = Target()
+ del w
+ del ref
+
+def test_borrowed_ref_3_segfault():
+ # This used to segfault until r60224
+ if verbose:
+ print("Testing borrowed ref 3 segfault...")
+
+ class KeyFunc(object):
+ def __call__(self, n):
+ del d['key']
+ return 1
+
+ d = {'key': KeyFunc()}
+ try:
+ min(range(10), **d)
+ except:
+ pass
+
+def test_borrowed_ref_4_segfault():
+ # This used to segfault until r60224
+ if verbose:
+ print("Testing borrowed ref 4 segfault...")
+
+ import types
+ import builtins
+
+ class X(object):
+ def __getattr__(self, name):
+ # this is called with name == '__bases__' by PyObject_IsInstance()
+ # during the unbound method call -- it frees the unbound method
+ # itself before it invokes its im_func.
+ del builtins.__import__
+ return ()
+
+ pseudoclass = X()
+
+ class Y(object):
+ def __call__(self, *args):
+ # 'self' was freed already
+ return (self, args)
+
+ # make an unbound method
+ orig_import = __import__
+ try:
+ builtins.__import__ = types.MethodType(Y(), (pseudoclass, str))
+ import spam
+ finally:
+ builtins.__import__ = orig_import
+
def test_main():
- weakref_segfault() # Must be first, somehow
+ #XXXweakref_segfault() # Must be first, somehow
wrapper_segfault() # NB This one is slow
do_this_first()
class_docstrings()
@@ -4279,6 +4345,9 @@ def test_main():
methodwrapper()
notimplemented()
test_assign_slice()
+ test_weakref_in_del_segfault()
+ test_borrowed_ref_3_segfault()
+ test_borrowed_ref_4_segfault()
if verbose: print("All OK")
diff --git a/Lib/test/test_rational.py b/Lib/test/test_rational.py
index e57adce..1bd1814 100644
--- a/Lib/test/test_rational.py
+++ b/Lib/test/test_rational.py
@@ -135,6 +135,29 @@ class RationalTest(unittest.TestCase):
TypeError, "Cannot convert sNaN to Rational.",
R.from_decimal, Decimal("snan"))
+ def testFromContinuedFraction(self):
+ self.assertRaises(TypeError, R.from_continued_fraction, None)
+ phi = R.from_continued_fraction([1]*100)
+ self.assertEquals(round(phi - (1 + 5 ** 0.5) / 2, 10), 0.0)
+
+ minusphi = R.from_continued_fraction([-1]*100)
+ self.assertEquals(round(minusphi + (1 + 5 ** 0.5) / 2, 10), 0.0)
+
+ self.assertEquals(R.from_continued_fraction([0]), R(0))
+ self.assertEquals(R.from_continued_fraction([]), R(0))
+
+ def testAsContinuedFraction(self):
+ self.assertEqual(R.from_float(math.pi).as_continued_fraction()[:15],
+ [3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 3, 3])
+ self.assertEqual(R.from_float(-math.pi).as_continued_fraction()[:16],
+ [-4, 1, 6, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 3, 3])
+ self.assertEqual(R(0).as_continued_fraction(), [0])
+
+ def testApproximateFromFloat(self):
+ self.assertEqual(R.approximate_from_float(math.pi, 10000), R(355, 113))
+ self.assertEqual(R.approximate_from_float(-math.pi, 10000), R(-355, 113))
+ self.assertEqual(R.approximate_from_float(0.0, 10000), R(0))
+
def testConversions(self):
self.assertTypedEquals(-1, trunc(R(-11, 10)))
self.assertTypedEquals(-2, math.floor(R(-11, 10)))
diff --git a/Lib/urllib2.py b/Lib/urllib2.py
index fb2c303..3ad0b15 100644
--- a/Lib/urllib2.py
+++ b/Lib/urllib2.py
@@ -1286,7 +1286,7 @@ class FTPHandler(BaseHandler):
headers = mimetools.Message(sf)
return addinfourl(fp, headers, req.get_full_url())
except ftplib.all_errors as msg:
- raise URLError('ftp error %s' % msg).with_traceback(sys.exc_info()[2])
+ raise URLError('ftp error: %s' % msg).with_traceback(sys.exc_info()[2])
def connect_ftp(self, user, passwd, host, port, dirs, timeout):
fw = ftpwrapper(user, passwd, host, port, dirs, timeout)