From arigo at codespeak.net Sat Oct 1 16:07:05 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 1 Oct 2005 16:07:05 +0200 (CEST) Subject: [py-svn] r18055 - in py/dist/py/path/local: . testing Message-ID: <20051001140705.2CEFB27C09@code1.codespeak.net> Author: arigo Date: Sat Oct 1 16:06:58 2005 New Revision: 18055 Modified: py/dist/py/path/local/local.py py/dist/py/path/local/testing/test_local.py Log: Lock the numbered temporary directories while they are in use. Strategy: '.lock' files in the temporary directory, removed at process exit, but ignored if it's more than 2 days old. Modified: py/dist/py/path/local/local.py ============================================================================== --- py/dist/py/path/local/local.py (original) +++ py/dist/py/path/local/local.py Sat Oct 1 16:06:58 2005 @@ -6,7 +6,7 @@ """ from __future__ import generators -import sys, os, stat, re +import sys, os, stat, re, atexit import py from py.__.path import common @@ -535,7 +535,8 @@ raise py.error.ENOENT(dpath, "could not create tempdir, %d tries" % tries) mkdtemp = classmethod(mkdtemp) - def make_numbered_dir(cls, prefix='session-', rootdir=None, keep=3): + def make_numbered_dir(cls, prefix='session-', rootdir=None, keep=3, + lock_timeout = 172800): # two days """ return unique directory with a number greater than the current maximum one. The number is assumed to start directly after prefix. if keep is true directories with a number less than (maxnum-keep) @@ -564,11 +565,33 @@ # make the new directory udir = rootdir.mkdir(prefix + str(maxnum+1)) + # put a .lock file in the new directory that will be removed at + # process exit + lockfile = udir.join('.lock') + if hasattr(lockfile, 'mksymlinkto'): + lockfile.mksymlinkto(str(os.getpid())) + else: + lockfile.write(str(os.getpid())) + def try_remove_lockfile(): + try: + lockfile.remove() + except py.error.Error: + pass + atexit.register(try_remove_lockfile) + # prune old directories if keep: for path in rootdir.listdir(): num = parse_num(path) if num is not None and num <= (maxnum - keep): + lf = path.join('.lock') + try: + t1 = lf.lstat().mtime + t2 = lockfile.lstat().mtime + if abs(t2-t1) < lock_timeout: + continue # skip directories still locked + except py.error.Error: + pass # assume that it means that there is no 'lf' try: path.remove(rec=1) except py.error.Error: Modified: py/dist/py/path/local/testing/test_local.py ============================================================================== --- py/dist/py/path/local/testing/test_local.py (original) +++ py/dist/py/path/local/testing/test_local.py Sat Oct 1 16:06:58 2005 @@ -192,7 +192,8 @@ root = self.tmpdir root.ensure('base.not_an_int', dir=1) for i in range(10): - numdir = local.make_numbered_dir(prefix='base.', rootdir=root, keep=2) + numdir = local.make_numbered_dir(prefix='base.', rootdir=root, + keep=2, lock_timeout=0) assert numdir.check() assert numdir.basename == 'base.%d' %i if i>=1: @@ -202,6 +203,16 @@ if i>=3: assert not numdir.new(ext=str(i-3)).check() + def test_locked_make_numbered_dir(self): + root = self.tmpdir + for i in range(10): + numdir = local.make_numbered_dir(prefix='base.', rootdir=root, + keep=2) + assert numdir.check() + assert numdir.basename == 'base.%d' %i + for j in range(i): + assert numdir.new(ext=str(j)).check() + def test_error_preservation(self): py.test.raises (EnvironmentError, self.root.join('qwoeqiwe').mtime) py.test.raises (EnvironmentError, self.root.join('qwoeqiwe').read) From jan at codespeak.net Thu Oct 6 02:13:11 2005 From: jan at codespeak.net (jan at codespeak.net) Date: Thu, 6 Oct 2005 02:13:11 +0200 (CEST) Subject: [py-svn] r18208 - in py/dist/py/magic: . testing Message-ID: <20051006001311.0D75B27B52@code1.codespeak.net> Author: jan Date: Thu Oct 6 02:13:10 2005 New Revision: 18208 Modified: py/dist/py/magic/exprinfo.py py/dist/py/magic/testing/test_exprinfo.py Log: issue21 escape newlines in reinterpretations of assert statements Modified: py/dist/py/magic/exprinfo.py ============================================================================== --- py/dist/py/magic/exprinfo.py (original) +++ py/dist/py/magic/exprinfo.py Thu Oct 6 02:13:10 2005 @@ -47,7 +47,15 @@ def nice_explanation(self): # uck! See CallFunc for where \n{ and \n} escape sequences are used - lines = (self.explanation or '').split('\n') + raw_lines = (self.explanation or '').split('\n') + # escape newlines not followed by { and } + lines = [raw_lines[0]] + for l in raw_lines[1:]: + if l.startswith('{') or l.startswith('}'): + lines.append(l) + else: + lines[-1] += '\\n' + l + result = lines[:1] stack = [0] stackcnt = [0] Modified: py/dist/py/magic/testing/test_exprinfo.py ============================================================================== --- py/dist/py/magic/testing/test_exprinfo.py (original) +++ py/dist/py/magic/testing/test_exprinfo.py Thu Oct 6 02:13:10 2005 @@ -84,6 +84,17 @@ msg = getmsg(excinfo) assert msg == 'assert 66 == 67\n + where 66 = global_f(v=11)' +def test_interpretable_escapes_newlines(): + class X(object): + def __repr__(self): + return '1\n2' + def g(): + assert X() == 'XXX' + + excinfo = getexcinfo(AssertionError, g) + msg = getmsg(excinfo) + assert msg == "assert 1\\n2 == 'XXX'\n + where 1\\n2 = ()" + def test_keyboard_interrupt(): # XXX this test is slightly strange because it is not # clear that "interpret" should execute "raise" statements From cfbolz at codespeak.net Wed Oct 19 23:02:47 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 19 Oct 2005 23:02:47 +0200 (CEST) Subject: [py-svn] r18779 - py/dist/py/misc/cmdline Message-ID: <20051019210247.312E327B73@code1.codespeak.net> Author: cfbolz Date: Wed Oct 19 23:02:46 2005 New Revision: 18779 Modified: py/dist/py/misc/cmdline/countloc.py Log: refactor countloc a bit to be able to use it programatically Modified: py/dist/py/misc/cmdline/countloc.py ============================================================================== --- py/dist/py/misc/cmdline/countloc.py (original) +++ py/dist/py/misc/cmdline/countloc.py Wed Oct 19 23:02:46 2005 @@ -48,13 +48,10 @@ numfiles += 1 return numfiles -def countloc(): - counter = FileCounter() - args = py.std.sys.argv[1:] - if not args: - args = ['.'] - locations = [py.path.local(x) for x in args] - +def get_loccount(locations=None): + if locations is None: + localtions = [py.path.local()] + counter = FileCounter() for loc in locations: counter.addrecursive(loc, '*.py', rec=nodot) @@ -67,8 +64,15 @@ numtestfiles = counter.getnumfiles(istestfile) numtestlines = counter.getnumlines(istestfile) - #for x,y in counter.counts.items(): - # print "%3d %30s" % (y,x) + return counter, numfiles, numlines, numtestfiles, numtestlines + +def countloc(): + args = py.std.sys.argv[1:] + if not args: + args = ['.'] + locations = [py.path.local(x) for x in args] + (counter, numfiles, numlines, numtestfiles, + numtestlines) = get_loccount(locations) items = counter.file2numlines.items() items.sort(lambda x,y: cmp(x[1], y[1])) From arigo at codespeak.net Sun Oct 23 21:38:37 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 23 Oct 2005 21:38:37 +0200 (CEST) Subject: [py-svn] r18846 - py/dist/py/misc Message-ID: <20051023193837.4A30827B83@code1.codespeak.net> Author: arigo Date: Sun Oct 23 21:38:36 2005 New Revision: 18846 Modified: py/dist/py/misc/error.py Log: Make this work even if exceptions are new-style (as in PyPy, and probably as in CPython at some point). Modified: py/dist/py/misc/error.py ============================================================================== --- py/dist/py/misc/error.py (original) +++ py/dist/py/misc/error.py Sun Oct 23 21:38:36 2005 @@ -43,7 +43,7 @@ return _errno2class[eno] except KeyError: clsname = py.std.errno.errorcode.get(eno, "UnknownErrno%d" %(eno,)) - cls = py.std.new.classobj(clsname, (Error,), + cls = type(Error)(clsname, (Error,), {'__module__':'py.error', '__doc__': py.std.os.strerror(eno)}) _errno2class[eno] = cls From cfbolz at codespeak.net Tue Oct 25 19:16:17 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 25 Oct 2005 19:16:17 +0200 (CEST) Subject: [py-svn] r18968 - py/dist/py/path/svn/testing Message-ID: <20051025171617.1E0BC27B5F@code1.codespeak.net> Author: cfbolz Date: Tue Oct 25 19:16:15 2005 New Revision: 18968 Added: py/dist/py/path/svn/testing/test_test_repo.py Modified: py/dist/py/path/svn/testing/svntestbase.py Log: add a nice way to create test repositories Modified: py/dist/py/path/svn/testing/svntestbase.py ============================================================================== --- py/dist/py/path/svn/testing/svntestbase.py (original) +++ py/dist/py/path/svn/testing/svntestbase.py Tue Oct 25 19:16:15 2005 @@ -31,6 +31,7 @@ wc = py.path.svnwc(wcdir) return ("file://%s" % repo, wc) + def save_repowc(): repo, wc = getrepowc() repo = py.path.local(repo[len("file://"):]) @@ -49,7 +50,17 @@ wc.localpath.remove() savedrepo.move(repo) savedwc.localpath.move(wc.localpath) - + +# create an empty repository for testing purposes and return the url to it +def make_test_repo(name="test-repository"): + repo = py.test.ensuretemp(name) + try: + py.process.cmdexec('svnadmin create %s' % repo) + except: + repo.remove() + raise + return py.path.svnurl("file://%s" % repo) + class CommonSvnTests(CommonFSTests): def setup_method(self, meth): Added: py/dist/py/path/svn/testing/test_test_repo.py ============================================================================== --- (empty file) +++ py/dist/py/path/svn/testing/test_test_repo.py Tue Oct 25 19:16:15 2005 @@ -0,0 +1,18 @@ +import py +from py.__.path.svn.testing.svntestbase import make_test_repo + +class TestMakeRepo(object): + def setup_class(cls): + cls.repo = make_test_repo() + cls.wc = py.path.svnwc(py.test.ensuretemp("test-wc").join("wc")) + + def test_empty_checkout(self): + self.wc.checkout(self.repo) + assert len(self.wc.listdir()) == 0 + + def test_checkin(self): + p = self.wc.join("a_file") + p.write("test file") + p.add() + self.wc.commit("some test") + assert p.info().rev == 1 From dialtone at codespeak.net Fri Oct 28 13:07:11 2005 From: dialtone at codespeak.net (dialtone at codespeak.net) Date: Fri, 28 Oct 2005 13:07:11 +0200 (CEST) Subject: [py-svn] r19114 - py/dist/py/process Message-ID: <20051028110711.EB2F527BA8@code1.codespeak.net> Author: dialtone Date: Fri Oct 28 13:07:09 2005 New Revision: 19114 Modified: py/dist/py/process/cmdexec.py Log: fixing cmdexec to handle EINTR, EPIPE, EAGAIN and other errors that are in the select spec. Modified: py/dist/py/process/cmdexec.py ============================================================================== --- py/dist/py/process/cmdexec.py (original) +++ py/dist/py/process/cmdexec.py Fri Oct 28 13:07:09 2005 @@ -25,6 +25,7 @@ """ __tracebackhide__ = True import popen2 + import errno #print "execing", cmd child = popen2.Popen3(cmd, 1) @@ -36,8 +37,14 @@ # only the next three lines appear to prevent # the read call from blocking infinitely. import fcntl - fcntl.fcntl(stdout, fcntl.F_SETFL, os.O_NONBLOCK) - fcntl.fcntl(stderr, fcntl.F_SETFL, os.O_NONBLOCK) + def set_non_block(fd): + flags = fcntl.fcntl(fd, fcntl.F_GETFL) + flags = flags | os.O_NONBLOCK + fcntl.fcntl(fd, fcntl.F_SETFL, flags) + set_non_block(stdout.fileno()) + set_non_block(stderr.fileno()) + #fcntl.fcntl(stdout, fcntl.F_SETFL, os.O_NONBLOCK) + #fcntl.fcntl(stderr, fcntl.F_SETFL, os.O_NONBLOCK) import select out, err = [], [] @@ -45,9 +52,29 @@ r_list = filter(lambda x: x and not x.closed, [stdout, stderr]) if not r_list: break - r_list = select.select(r_list, [], [])[0] + try: + r_list = select.select(r_list, [], [])[0] + except (select.error, IOError), se: + if se.args[0] == errno.EINTR: + continue + else: + raise for r in r_list: - data = r.read() # XXX see XXX above + try: + data = r.read() # XXX see XXX above + except IOError, io: + if io.args[0] == errno.EAGAIN: + continue + # Connection Lost + raise + except OSError, ose: + if ose.errno == errno.EPIPE: + # Connection Lost + raise + if ose.errno == errno.EAGAIN: # MacOS-X does this + continue + raise + if not data: r.close() continue From arigo at codespeak.net Mon Oct 31 18:15:32 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 31 Oct 2005 18:15:32 +0100 (CET) Subject: [py-svn] r19273 - in py/dist/py: . compat/testing execnet/script test/tkinter/icon Message-ID: <20051031171532.DAB4A27B64@code1.codespeak.net> Author: arigo Date: Mon Oct 31 18:15:12 2005 New Revision: 19273 Modified: py/dist/py/compat/testing/conftest.py (props changed) py/dist/py/execnet/script/shell.py py/dist/py/initpkg.py py/dist/py/test/tkinter/icon/green.gif (props changed) py/dist/py/test/tkinter/icon/green.png (props changed) py/dist/py/test/tkinter/icon/green_aqua.gif (props changed) py/dist/py/test/tkinter/icon/green_aqua.png (props changed) py/dist/py/test/tkinter/icon/green_s.gif (props changed) py/dist/py/test/tkinter/icon/green_s.png (props changed) py/dist/py/test/tkinter/icon/green_s_aqua.gif (props changed) py/dist/py/test/tkinter/icon/green_s_aqua.png (props changed) py/dist/py/test/tkinter/icon/red.gif (props changed) py/dist/py/test/tkinter/icon/red.png (props changed) py/dist/py/test/tkinter/icon/red_aqua.gif (props changed) py/dist/py/test/tkinter/icon/red_aqua.png (props changed) py/dist/py/test/tkinter/icon/red_c.gif (props changed) py/dist/py/test/tkinter/icon/red_c.png (props changed) py/dist/py/test/tkinter/icon/red_c_aqua.gif (props changed) py/dist/py/test/tkinter/icon/red_c_aqua.png (props changed) py/dist/py/test/tkinter/icon/yellow.gif (props changed) py/dist/py/test/tkinter/icon/yellow.png (props changed) py/dist/py/test/tkinter/icon/yellow_aqua.gif (props changed) py/dist/py/test/tkinter/icon/yellow_aqua.png (props changed) py/dist/py/test/tkinter/icon/yellow_s.gif (props changed) py/dist/py/test/tkinter/icon/yellow_s.png (props changed) Log: * removed the svn:executable flag where it is not meaningful * fixed the #! line of executable scripts Modified: py/dist/py/execnet/script/shell.py ============================================================================== --- py/dist/py/execnet/script/shell.py (original) +++ py/dist/py/execnet/script/shell.py Mon Oct 31 18:15:12 2005 @@ -1,3 +1,4 @@ +#! /usr/bin/env python """ a remote python shell Modified: py/dist/py/initpkg.py ============================================================================== --- py/dist/py/initpkg.py (original) +++ py/dist/py/initpkg.py Mon Oct 31 18:15:12 2005 @@ -25,8 +25,7 @@ import sys import os assert sys.version_info >= (2,2,0), "py lib requires python 2.2 or higher" - -ModuleType = type(sys.modules[__name__]) +from types import ModuleType # --------------------------------------------------- # Package Object