* fixing lots of remaining 3k compatibility issues, mostly with py.test itself.

* removing very old import-tests that IIRC relate to a time when there
  was a custom import hook in use.

* basically py.test internal tests pass now except py3/py2 distributed
  testing tests

--HG--
branch : trunk
This commit is contained in:
holger krekel 2009-09-04 21:47:49 +02:00
parent 1e51844519
commit bde56a8246
25 changed files with 102 additions and 128 deletions

View File

@ -1,7 +1,7 @@
import py, os, stat import py, os, stat
md5 = py.builtin._tryimport('hashlib.md5', 'md5.md5') md5 = py.builtin._tryimport('hashlib', 'md5').md5
queue = py.builtin._tryimport('queue.Queue', 'Queue.Queue') Queue = py.builtin._tryimport('queue', 'Queue').Queue
class RSync(object): class RSync(object):
""" This class allows to send a directory structure (recursively) """ This class allows to send a directory structure (recursively)

View File

@ -39,8 +39,9 @@ class TestLocalPath(common.CommonFSTests):
assert p == tmpdir assert p == tmpdir
def test_gethash(self, tmpdir): def test_gethash(self, tmpdir):
md5 = py.builtin._tryimport('md5.md5', 'hashlib.md5') md5 = py.builtin._tryimport('md5', 'hashlib').md5
sha = py.builtin._tryimport('sha.sha', 'hashlib.sha1') lib = py.builtin._tryimport('sha', 'hashlib')
sha = getattr(lib, 'sha1', getattr(lib, 'sha', None))
fn = tmpdir.join("testhashfile") fn = tmpdir.join("testhashfile")
data = 'hello'.encode('ascii') data = 'hello'.encode('ascii')
fn.write(data, mode="wb") fn.write(data, mode="wb")

View File

@ -12,12 +12,22 @@
""" """
from pickle import Pickler, Unpickler
import py import py
from py.__.execnet.gateway_base import Channel from py.__.execnet.gateway_base import Channel
import os import sys, os
#debug = open("log-mypickle-%d" % os.getpid(), 'w') #debug = open("log-mypickle-%d" % os.getpid(), 'w')
if sys.version_info >= (3,0):
makekey = lambda x: x
fromkey = lambda x: x
from pickle import _Pickler as Pickler
from pickle import _Unpickler as Unpickler
else:
makekey = str
fromkey = int
from pickle import Pickler, Unpickler
class MyPickler(Pickler): class MyPickler(Pickler):
""" Pickler with a custom memoize() """ Pickler with a custom memoize()
to take care of unique ID creation. to take care of unique ID creation.
@ -86,11 +96,11 @@ class ImmutablePickler:
def _updatepicklememo(self): def _updatepicklememo(self):
for x, obj in self._unpicklememo.items(): for x, obj in self._unpicklememo.items():
self._picklememo[id(obj)] = (int(x), obj) self._picklememo[id(obj)] = (fromkey(x), obj)
def _updateunpicklememo(self): def _updateunpicklememo(self):
for key,obj in self._picklememo.values(): for key,obj in self._picklememo.values():
key = str(key) key = makekey(key)
if key in self._unpicklememo: if key in self._unpicklememo:
assert self._unpicklememo[key] is obj assert self._unpicklememo[key] is obj
self._unpicklememo[key] = obj self._unpicklememo[key] = obj

View File

@ -6,24 +6,28 @@ class TestDistribution:
p1.dirpath("__init__.py").write("") p1.dirpath("__init__.py").write("")
p1.dirpath("conftest.py").write(py.code.Source(""" p1.dirpath("conftest.py").write(py.code.Source("""
import py import py
py.builtin.print_("importing conftest", __file__) from py.builtin import print_
print_("importing conftest", __file__)
Option = py.test.config.Option Option = py.test.config.Option
option = py.test.config.addoptions("someopt", option = py.test.config.addoptions("someopt",
Option('--someopt', action="store_true", dest="someopt", default=False)) Option('--someopt', action="store_true",
dest="someopt", default=False))
dist_rsync_roots = ['../dir'] dist_rsync_roots = ['../dir']
py.builtin.print_("added options", option) print_("added options", option)
py.builtin.print_("config file seen from conftest", py.test.config) print_("config file seen from conftest", py.test.config)
""")) """))
p1.write(py.code.Source(""" p1.write(py.code.Source("""
import py, conftest import py
from %s import conftest
from py.builtin import print_
def test_1(): def test_1():
py.builtin.print_("config from test_1", py.test.config) print_("config from test_1", py.test.config)
py.builtin.print_("conftest from test_1", conftest.__file__) print_("conftest from test_1", conftest.__file__)
py.builtin.print_("test_1: py.test.config.option.someopt", py.test.config.option.someopt) print_("test_1: py.test.config.option.someopt", py.test.config.option.someopt)
py.builtin.print_("test_1: conftest", conftest) print_("test_1: conftest", conftest)
py.builtin.print_("test_1: conftest.option.someopt", conftest.option.someopt) print_("test_1: conftest.option.someopt", conftest.option.someopt)
assert conftest.option.someopt assert conftest.option.someopt
""")) """ % p1.dirpath().purebasename ))
result = testdir.runpytest('-d', '--tx=popen', p1, '--someopt') result = testdir.runpytest('-d', '--tx=popen', p1, '--someopt')
assert result.ret == 0 assert result.ret == 0
extra = result.stdout.fnmatch_lines([ extra = result.stdout.fnmatch_lines([

View File

@ -1,8 +1,11 @@
import py import py
from py.__.test.dist.mypickle import ImmutablePickler, PickleChannel import sys
from py.__.test.dist.mypickle import UnpickleError
Queue = py.builtin._tryimport('queue', 'Queue').Queue
from py.__.test.dist.mypickle import ImmutablePickler, PickleChannel
from py.__.test.dist.mypickle import UnpickleError, makekey
# first let's test some basic functionality # first let's test some basic functionality
def pytest_generate_tests(metafunc): def pytest_generate_tests(metafunc):
@ -24,8 +27,8 @@ def pytest_generate_tests(metafunc):
metafunc.addcall(funcargs=dict(obj=obj, proto=proto)) metafunc.addcall(funcargs=dict(obj=obj, proto=proto))
def test_underlying_basic_pickling_mechanisms(picklemod): def test_underlying_basic_pickling_mechanisms(picklemod):
f1 = py.io.TextIO() f1 = py.io.BytesIO()
f2 = py.io.TextIO() f2 = py.io.BytesIO()
pickler1 = picklemod.Pickler(f1) pickler1 = picklemod.Pickler(f1)
unpickler1 = picklemod.Unpickler(f2) unpickler1 = picklemod.Unpickler(f2)
@ -49,7 +52,8 @@ def test_underlying_basic_pickling_mechanisms(picklemod):
pickler2.dump(d_other) pickler2.dump(d_other)
f2.seek(0) f2.seek(0)
unpickler1.memo = dict([(str(x), y) for x, y in pickler1.memo.values()]) unpickler1.memo = dict([(makekey(x), y)
for x, y in pickler1.memo.values()])
d_back = unpickler1.load() d_back = unpickler1.load()
assert d is d_back assert d is d_back
@ -177,7 +181,7 @@ class TestPickleChannelFunctional:
channel.send(a2 is a1) channel.send(a2 is a1)
""") """)
channel = PickleChannel(channel) channel = PickleChannel(channel)
queue = py.std.Queue.Queue() queue = Queue()
channel.setcallback(queue.put) channel.setcallback(queue.put)
a_received = queue.get(timeout=TESTTIMEOUT) a_received = queue.get(timeout=TESTTIMEOUT)
assert isinstance(a_received, A) assert isinstance(a_received, A)
@ -198,7 +202,7 @@ class TestPickleChannelFunctional:
channel.send(a2 is a1) channel.send(a2 is a1)
""") """)
channel = PickleChannel(channel) channel = PickleChannel(channel)
queue = py.std.Queue.Queue() queue = Queue()
channel.setcallback(queue.put, endmarker=-1) channel.setcallback(queue.put, endmarker=-1)
a_received = queue.get(timeout=TESTTIMEOUT) a_received = queue.get(timeout=TESTTIMEOUT)
@ -220,7 +224,7 @@ class TestPickleChannelFunctional:
channel.send(a1) channel.send(a1)
""") """)
channel = PickleChannel(channel) channel = PickleChannel(channel)
queue = py.std.Queue.Queue() queue = Queue()
a = channel.receive() a = channel.receive()
channel._ipickle._unpicklememo.clear() channel._ipickle._unpicklememo.clear()
channel.setcallback(queue.put, endmarker=-1) channel.setcallback(queue.put, endmarker=-1)

View File

@ -1,7 +1,8 @@
import py import py
from py.__.test.dist.txnode import TXNode from py.__.test.dist.txnode import TXNode
Queue = py.builtin._tryimport("queue.Queue", "Queue.Queue") queue = py.builtin._tryimport("queue", "Queue")
Queue = queue.Queue
class EventQueue: class EventQueue:
def __init__(self, registry, queue=None): def __init__(self, registry, queue=None):
@ -15,7 +16,7 @@ class EventQueue:
while 1: while 1:
try: try:
eventcall = self.queue.get(timeout=timeout) eventcall = self.queue.get(timeout=timeout)
except py.std.Queue.Empty: except queue.Empty:
#print "node channel", self.node.channel #print "node channel", self.node.channel
#print "remoteerror", self.node.channel._getremoteerror() #print "remoteerror", self.node.channel._getremoteerror()
py.builtin.print_("seen events", events) py.builtin.print_("seen events", events)

View File

@ -10,6 +10,7 @@
from __future__ import generators from __future__ import generators
import py import py
import sys
from py.__.test.session import Session from py.__.test.session import Session
from py.__.test.dist.mypickle import PickleChannel from py.__.test.dist.mypickle import PickleChannel
from py.__.test.looponfail import util from py.__.test.looponfail import util
@ -70,14 +71,19 @@ class RemoteControl(object):
channel = self.gateway.remote_exec(source=""" channel = self.gateway.remote_exec(source="""
from py.__.test.dist.mypickle import PickleChannel from py.__.test.dist.mypickle import PickleChannel
from py.__.test.looponfail.remote import slave_runsession from py.__.test.looponfail.remote import slave_runsession
outchannel = channel.gateway.newchannel()
channel.send(outchannel)
channel = PickleChannel(channel) channel = PickleChannel(channel)
config, fullwidth, hasmarkup = channel.receive() config, fullwidth, hasmarkup = channel.receive()
import sys
sys.stdout = sys.stderr = outchannel.makefile('w')
slave_runsession(channel, config, fullwidth, hasmarkup) slave_runsession(channel, config, fullwidth, hasmarkup)
""", stdout=out, stderr=out) """)
channel = PickleChannel(channel) remote_outchannel = channel.receive()
remote_outchannel.setcallback(out._file.write)
channel = self.channel = PickleChannel(channel)
channel.send((self.config, out.fullwidth, out.hasmarkup)) channel.send((self.config, out.fullwidth, out.hasmarkup))
self.trace("set up of slave session complete") self.trace("set up of slave session complete")
self.channel = channel
def ensure_teardown(self): def ensure_teardown(self):
if hasattr(self, 'channel'): if hasattr(self, 'channel'):

View File

@ -25,7 +25,9 @@ class Passed(OutcomeException):
pass pass
class Skipped(OutcomeException): class Skipped(OutcomeException):
pass # XXX slighly hackish: on 3k we fake to live in the builtins
# in order to have Skipped exception printing shorter/nicer
__module__ = 'builtins'
class Failed(OutcomeException): class Failed(OutcomeException):
pass pass

View File

@ -67,8 +67,8 @@ per-test capturing. Here is an example test function:
.. sourcecode:: python .. sourcecode:: python
def test_myoutput(capsys): def test_myoutput(capsys):
print "hello" print ("hello")
print >>sys.stderr, "world" sys.stderr.write("world\n")
out, err = capsys.readouterr() out, err = capsys.readouterr()
assert out == "hello\\n" assert out == "hello\\n"
assert err == "world\\n" assert err == "world\\n"

View File

@ -48,7 +48,7 @@ def test_execnetplugin(testdir):
sys._gw = py.execnet.PopenGateway() sys._gw = py.execnet.PopenGateway()
def test_world(): def test_world():
assert hasattr(sys, '_gw') assert hasattr(sys, '_gw')
py.test.raises(KeyError, "sys._gw.exit()") # already closed assert sys._gw not in sys._gw._cleanup._activegateways
""", "-s", "--debug") """, "-s", "--debug")
reprec.assertoutcome(passed=2) reprec.assertoutcome(passed=2)

View File

@ -30,7 +30,7 @@ def pytest_configure(__multicall__, config):
tw.sep("-") tw.sep("-")
options = [opt for opt in options if opt._long_opts] options = [opt for opt in options if opt._long_opts]
options.sort(lambda x, y: cmp(x._long_opts, y._long_opts)) options.sort(key=lambda x: x._long_opts)
for opt in options: for opt in options:
if not opt._long_opts: if not opt._long_opts:
continue continue

View File

@ -8,7 +8,7 @@ def pytest_addoption(parser):
def pytest_configure(config): def pytest_configure(config):
hooklog = config.getvalue("hooklog") hooklog = config.getvalue("hooklog")
if hooklog: if hooklog:
config._hooklogfile = open(hooklog, 'w', 0) config._hooklogfile = open(hooklog, 'w')
config._hooklog_oldperformcall = config.hook._performcall config._hooklog_oldperformcall = config.hook._performcall
config.hook._performcall = (lambda name, multicall: config.hook._performcall = (lambda name, multicall:
logged_call(name=name, multicall=multicall, config=config)) logged_call(name=name, multicall=multicall, config=config))

View File

@ -37,7 +37,7 @@ def pytest_configure(__multicall__, config):
import tempfile import tempfile
__multicall__.execute() __multicall__.execute()
if config.option.pastebin == "all": if config.option.pastebin == "all":
config._pastebinfile = tempfile.TemporaryFile() config._pastebinfile = tempfile.TemporaryFile('w+')
tr = config.pluginmanager.impname2plugin['terminalreporter'] tr = config.pluginmanager.impname2plugin['terminalreporter']
oldwrite = tr._tw.write oldwrite = tr._tw.write
def tee_write(s, **kwargs): def tee_write(s, **kwargs):
@ -53,7 +53,7 @@ def pytest_unconfigure(config):
del config._pastebinfile del config._pastebinfile
proxyid = getproxy().newPaste("python", sessionlog) proxyid = getproxy().newPaste("python", sessionlog)
pastebinurl = "%s%s" % (url.show, proxyid) pastebinurl = "%s%s" % (url.show, proxyid)
print >>sys.stderr, "session-log:", pastebinurl sys.stderr.write("session-log: %s" % pastebinurl)
tr = config.pluginmanager.impname2plugin['terminalreporter'] tr = config.pluginmanager.impname2plugin['terminalreporter']
del tr._tw.__dict__['write'] del tr._tw.__dict__['write']

View File

@ -379,7 +379,7 @@ class ReportRecorder(object):
return passed, skipped, failed return passed, skipped, failed
def countoutcomes(self): def countoutcomes(self):
return map(len, self.listoutcomes()) return [len(x) for x in self.listoutcomes()]
def assertoutcome(self, passed=0, skipped=0, failed=0): def assertoutcome(self, passed=0, skipped=0, failed=0):
realpassed, realskipped, realfailed = self.listoutcomes() realpassed, realskipped, realfailed = self.listoutcomes()

View File

@ -426,7 +426,7 @@ class TestDoctest:
>>> assert abspath >>> assert abspath
>>> i=3 >>> i=3
>>> print i >>> print (i)
3 3
yes yes yes yes
@ -450,7 +450,7 @@ class TestDoctest:
def test_doctest_indentation(self, testdir): def test_doctest_indentation(self, testdir):
footxt = testdir.maketxtfile(foo= footxt = testdir.maketxtfile(foo=
'..\n >>> print "foo\\n bar"\n foo\n bar\n') '..\n >>> print ("foo\\n bar")\n foo\n bar\n')
reprec = testdir.inline_run(footxt) reprec = testdir.inline_run(footxt)
passed, skipped, failed = reprec.countoutcomes() passed, skipped, failed = reprec.countoutcomes()
assert failed == 0 assert failed == 0

View File

@ -99,22 +99,22 @@ def test_func_generator_setup(testdir):
import sys import sys
def setup_module(mod): def setup_module(mod):
print "setup_module" print ("setup_module")
mod.x = [] mod.x = []
def setup_function(fun): def setup_function(fun):
print "setup_function" print ("setup_function")
x.append(1) x.append(1)
def teardown_function(fun): def teardown_function(fun):
print "teardown_function" print ("teardown_function")
x.pop() x.pop()
def test_one(): def test_one():
assert x == [1] assert x == [1]
def check(): def check():
print "check" print ("check")
print >>sys.stderr, "e" sys.stderr.write("e\\n")
assert x == [1] assert x == [1]
yield check yield check
assert x == [1] assert x == [1]

View File

@ -171,7 +171,7 @@ class TestTerminal:
def g(): def g():
raise IndexError raise IndexError
def test_func(): def test_func():
print 6*7 print (6*7)
g() # --calling-- g() # --calling--
""") """)
for tbopt in ["long", "short", "no"]: for tbopt in ["long", "short", "no"]:
@ -179,9 +179,9 @@ class TestTerminal:
result = testdir.runpytest('--tb=%s' % tbopt) result = testdir.runpytest('--tb=%s' % tbopt)
s = result.stdout.str() s = result.stdout.str()
if tbopt == "long": if tbopt == "long":
assert 'print 6*7' in s assert 'print (6*7)' in s
else: else:
assert 'print 6*7' not in s assert 'print (6*7)' not in s
if tbopt != "no": if tbopt != "no":
assert '--calling--' in s assert '--calling--' in s
assert 'IndexError' in s assert 'IndexError' in s
@ -411,7 +411,7 @@ class TestFixtureReporting:
def test_setup_fixture_error(self, testdir): def test_setup_fixture_error(self, testdir):
p = testdir.makepyfile(""" p = testdir.makepyfile("""
def setup_function(function): def setup_function(function):
print "setup func" print ("setup func")
assert 0 assert 0
def test_nada(): def test_nada():
pass pass
@ -431,7 +431,7 @@ class TestFixtureReporting:
def test_nada(): def test_nada():
pass pass
def teardown_function(function): def teardown_function(function):
print "teardown func" print ("teardown func")
assert 0 assert 0
""") """)
result = testdir.runpytest() result = testdir.runpytest()
@ -450,7 +450,7 @@ class TestFixtureReporting:
assert 0, "failingfunc" assert 0, "failingfunc"
def teardown_function(function): def teardown_function(function):
print "teardown func" print ("teardown func")
assert False assert False
""") """)
result = testdir.runpytest() result = testdir.runpytest()

View File

@ -1 +0,0 @@
from package import shared_lib

View File

@ -1 +0,0 @@
import shared_lib

View File

@ -1,3 +0,0 @@
"""
Just a dummy module
"""

View File

@ -1,53 +0,0 @@
import sys
import os
import py
def setup_module(mod=None):
if mod is None:
f = __file__
else:
f = mod.__file__
sys.path.append(os.path.dirname(os.path.dirname(f)))
def teardown_module(mod=None):
if mod is None:
f = __file__
else:
f = mod.__file__
sys.path.remove(os.path.dirname(os.path.dirname(f)))
def test_import():
global shared_lib, module_that_imports_shared_lib
import shared_lib
from package import shared_lib as shared_lib2
import module_that_imports_shared_lib
import absolute_import_shared_lib
all_modules = [
('shared_lib', shared_lib),
('shared_lib2', shared_lib2),
('module_that_imports_shared_lib',
module_that_imports_shared_lib.shared_lib),
('absolute_import_shared_lib',
absolute_import_shared_lib.shared_lib),
]
bad_matches = []
while all_modules:
name1, mod1 = all_modules[0]
all_modules = all_modules[1:]
for name2, mod2 in all_modules:
if mod1 is not mod2:
bad_matches.append((name1, mod1, name2, mod2))
for name1, mod1, name2, mod2 in bad_matches:
print("These modules should be identical:")
print(" %s:" % name1)
print(" ", mod1)
print(" %s:" % name2)
print(" ", mod2)
py.builtin.print_()
if bad_matches:
assert False
if __name__ == "__main__":
setup_module()
test_import
teardown_module()

View File

@ -26,12 +26,12 @@ class Test_genitems:
def test_subdir_conftest_error(self, testdir): def test_subdir_conftest_error(self, testdir):
tmp = testdir.tmpdir tmp = testdir.tmpdir
tmp.ensure("sub", "conftest.py").write("raise SyntaxError()\n") tmp.ensure("sub", "conftest.py").write("raise SyntaxError('x')\n")
items, reprec = testdir.inline_genitems(tmp) items, reprec = testdir.inline_genitems(tmp)
collectionfailures = reprec.getfailedcollections() collectionfailures = reprec.getfailedcollections()
assert len(collectionfailures) == 1 assert len(collectionfailures) == 1
ev = collectionfailures[0] ev = collectionfailures[0]
assert ev.longrepr.reprcrash.message.startswith("SyntaxError") assert "SyntaxError: x" in ev.longrepr.reprcrash.message
def test_example_items1(self, testdir): def test_example_items1(self, testdir):
p = testdir.makepyfile(''' p = testdir.makepyfile('''

View File

@ -1,6 +1,6 @@
import py import py
import marshal import sys
class TestRaises: class TestRaises:
def test_raises(self): def test_raises(self):
@ -42,3 +42,10 @@ def test_pytest_exit():
excinfo = py.code.ExceptionInfo() excinfo = py.code.ExceptionInfo()
assert excinfo.errisinstance(KeyboardInterrupt) assert excinfo.errisinstance(KeyboardInterrupt)
def test_exception_printing_skip():
try:
py.test.skip("hello")
except Exception:
excinfo = py.code.ExceptionInfo()
s = excinfo.exconly(tryshort=True)
assert s.startswith("Skipped")

View File

@ -1,4 +1,5 @@
import py import py
import pickle
def setglobals(request): def setglobals(request):
oldconfig = py.test.config oldconfig = py.test.config
@ -129,44 +130,41 @@ class TestConfigPickling:
assert option.gdest == 11 assert option.gdest == 11
def test_config_picklability(self, testdir): def test_config_picklability(self, testdir):
import cPickle
config = testdir.parseconfig() config = testdir.parseconfig()
s = cPickle.dumps(config) s = pickle.dumps(config)
newconfig = cPickle.loads(s) newconfig = pickle.loads(s)
assert hasattr(newconfig, "topdir") assert hasattr(newconfig, "topdir")
assert newconfig.topdir == py.path.local() assert newconfig.topdir == py.path.local()
def test_collector_implicit_config_pickling(self, testdir): def test_collector_implicit_config_pickling(self, testdir):
from cPickle import Pickler, Unpickler
tmpdir = testdir.tmpdir tmpdir = testdir.tmpdir
testdir.chdir() testdir.chdir()
testdir.makepyfile(hello="def test_x(): pass") testdir.makepyfile(hello="def test_x(): pass")
config = testdir.parseconfig(tmpdir) config = testdir.parseconfig(tmpdir)
col = config.getfsnode(config.topdir) col = config.getfsnode(config.topdir)
io = py.io.TextIO() io = py.io.BytesIO()
pickler = Pickler(io) pickler = pickle.Pickler(io)
pickler.dump(col) pickler.dump(col)
io.seek(0) io.seek(0)
unpickler = Unpickler(io) unpickler = pickle.Unpickler(io)
col2 = unpickler.load() col2 = unpickler.load()
assert col2.name == col.name assert col2.name == col.name
assert col2.listnames() == col.listnames() assert col2.listnames() == col.listnames()
def test_config_and_collector_pickling(self, testdir): def test_config_and_collector_pickling(self, testdir):
from pickle import Pickler, Unpickler
tmpdir = testdir.tmpdir tmpdir = testdir.tmpdir
dir1 = tmpdir.ensure("somedir", dir=1) dir1 = tmpdir.ensure("somedir", dir=1)
config = testdir.parseconfig() config = testdir.parseconfig()
col = config.getfsnode(config.topdir) col = config.getfsnode(config.topdir)
col1 = col.join(dir1.basename) col1 = col.join(dir1.basename)
assert col1.parent is col assert col1.parent is col
io = py.io.TextIO() io = py.io.BytesIO()
pickler = Pickler(io) pickler = pickle.Pickler(io)
pickler.dump(col) pickler.dump(col)
pickler.dump(col1) pickler.dump(col1)
pickler.dump(col) pickler.dump(col)
io.seek(0) io.seek(0)
unpickler = Unpickler(io) unpickler = pickle.Unpickler(io)
topdir = tmpdir.ensure("newtopdir", dir=1) topdir = tmpdir.ensure("newtopdir", dir=1)
topdir.ensure("somedir", dir=1) topdir.ensure("somedir", dir=1)
old = topdir.chdir() old = topdir.chdir()