diff options
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/idlelib/NEWS.txt | 5 | ||||
-rw-r--r-- | Lib/idlelib/configHandler.py | 7 | ||||
-rwxr-xr-x | Lib/rational.py | 36 | ||||
-rw-r--r-- | Lib/test/test_descr.py | 75 | ||||
-rw-r--r-- | Lib/test/test_rational.py | 23 | ||||
-rw-r--r-- | Lib/urllib2.py | 2 |
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) |