From d43d69e3db2a0353bacfd51ff263acce002b6882 Mon Sep 17 00:00:00 2001 From: holger krekel Date: Tue, 25 Aug 2009 16:14:15 +0200 Subject: [PATCH] death to "misc" directories. moved most files out of py/misc, either to a private attic or to other places in the lib. --HG-- branch : trunk --- MANIFEST | 66 ++---- .../findmissingdocstrings.py | 0 bin-for-dist/test_install.py | 111 ++++++++++ doc/changelog.txt | 2 + doc/code.txt | 2 +- doc/confrest.py | 1 - doc/download.txt | 4 +- py/__init__.py | 2 +- py/{misc/cmdline => _testing}/__init__.py | 0 py/{misc/testing => _testing}/test_api.py | 0 py/{misc/testing => _testing}/test_com.py | 0 py/{misc/testing => _testing}/test_error.py | 0 py/{misc/testing => _testing}/test_initpkg.py | 0 py/{misc/testing => _testing}/test_std.py | 0 py/{ => bin}/env.cmd | 0 py/{ => bin}/env.py | 0 py/cmdline/pycountloc.py | 76 ++++++- py/error.py | 3 + py/misc/_dist.py | 208 ------------------ py/misc/buildcmodule.py | 87 -------- py/misc/cache.py | 21 +- py/misc/cmdline/countloc.py | 84 ------- py/misc/difftime.py | 32 --- py/misc/dynpkg.py | 84 ------- py/misc/svnlook.py | 34 --- py/misc/terminal_helper.py | 14 -- py/misc/testing/data/svnlookrepo.dump | 160 -------------- py/misc/testing/test_install.py | 16 -- py/misc/testing/test_svnlook.py | 60 ----- py/misc/testing/test_terminal.py | 25 --- py/{misc => }/std.py | 5 +- py/test/plugin/pytest_pytester.py | 105 --------- setup.py | 17 +- 33 files changed, 230 insertions(+), 989 deletions(-) rename {py/misc => bin-for-dist}/findmissingdocstrings.py (100%) create mode 100644 bin-for-dist/test_install.py rename py/{misc/cmdline => _testing}/__init__.py (100%) rename py/{misc/testing => _testing}/test_api.py (100%) rename py/{misc/testing => _testing}/test_com.py (100%) rename py/{misc/testing => _testing}/test_error.py (100%) rename py/{misc/testing => _testing}/test_initpkg.py (100%) rename py/{misc/testing => _testing}/test_std.py (100%) rename py/{ => bin}/env.cmd (100%) rename py/{ => bin}/env.py (100%) delete mode 100644 py/misc/_dist.py delete mode 100644 py/misc/buildcmodule.py delete mode 100755 py/misc/cmdline/countloc.py delete mode 100644 py/misc/difftime.py delete mode 100644 py/misc/dynpkg.py delete mode 100644 py/misc/svnlook.py delete mode 100644 py/misc/terminal_helper.py delete mode 100644 py/misc/testing/data/svnlookrepo.dump delete mode 100644 py/misc/testing/test_install.py delete mode 100644 py/misc/testing/test_svnlook.py delete mode 100644 py/misc/testing/test_terminal.py rename py/{misc => }/std.py (74%) diff --git a/MANIFEST b/MANIFEST index 569d1814b..e4ae911f2 100644 --- a/MANIFEST +++ b/MANIFEST @@ -4,6 +4,7 @@ MANIFEST README.txt _findpy.py bin-for-dist/all-plat.sh +bin-for-dist/findmissingdocstrings.py bin-for-dist/gendoc.py bin-for-dist/genscripts.py bin-for-dist/gensetup.py @@ -98,6 +99,7 @@ py/__init__.py py/_com.py py/bin/_findpy.py py/bin/py.cleanup +py/bin/py.convert_unittest py/bin/py.countloc py/bin/py.lookup py/bin/py.rest @@ -105,6 +107,7 @@ py/bin/py.svnwcrevert py/bin/py.test py/bin/py.which py/bin/win32/py.cleanup.cmd +py/bin/win32/py.convert_unittest.cmd py/bin/win32/py.countloc.cmd py/bin/win32/py.lookup.cmd py/bin/win32/py.rest.cmd @@ -125,6 +128,7 @@ py/builtin/testing/test_set.py py/builtin/testing/test_sorted.py py/cmdline/__init__.py py/cmdline/pycleanup.py +py/cmdline/pyconvert_unittest.py py/cmdline/pycountloc.py py/cmdline/pylookup.py py/cmdline/pyrest.py @@ -133,6 +137,7 @@ py/cmdline/pytest.py py/cmdline/pywhich.py py/cmdline/testing/__init__.py py/cmdline/testing/test_cmdline.py +py/cmdline/testing/test_convert_unittest.py py/cmdline/testing/test_generic.py py/code/__init__.py py/code/code.py @@ -196,22 +201,15 @@ py/execnet/testing/test_xspec.py py/execnet/xspec.py py/initpkg.py py/io/__init__.py -py/io/dupfile.py -py/io/fdcapture.py -py/io/stdcapture.py +py/io/capture.py py/io/terminalwriter.py py/io/testing/__init__.py -py/io/testing/test_dupfile.py -py/io/testing/test_fdcapture.py -py/io/testing/test_stdcapture.py +py/io/testing/test_capture.py py/io/testing/test_terminalwriter.py py/log/__init__.py -py/log/consumer.py -py/log/logger.py -py/log/producer.py +py/log/log.py py/log/testing/__init__.py py/log/testing/test_log.py -py/log/testing/test_logger.py py/log/testing/test_warning.py py/log/warning.py py/magic/__init__.py @@ -229,19 +227,10 @@ py/magic/testing/test_patch.py py/magic/testing/test_viewtype.py py/magic/viewtype.py py/misc/__init__.py -py/misc/_dist.py -py/misc/buildcmodule.py py/misc/cache.py -py/misc/cmdline/__init__.py -py/misc/cmdline/countloc.py -py/misc/difftime.py -py/misc/dynpkg.py py/misc/error.py -py/misc/findmissingdocstrings.py py/misc/rest.py py/misc/std.py -py/misc/svnlook.py -py/misc/terminal_helper.py py/misc/testing/__init__.py py/misc/testing/data/svnlookrepo.dump py/misc/testing/test_api.py @@ -251,8 +240,6 @@ py/misc/testing/test_error.py py/misc/testing/test_initpkg.py py/misc/testing/test_install.py py/misc/testing/test_std.py -py/misc/testing/test_svnlook.py -py/misc/testing/test_terminal.py py/path/__init__.py py/path/common.py py/path/gateway/TODO.txt @@ -260,32 +247,19 @@ py/path/gateway/__init__.py py/path/gateway/channeltest.py py/path/gateway/channeltest2.py py/path/gateway/remotepath.py -py/path/local/__init__.py -py/path/local/common.py -py/path/local/local.py -py/path/local/posix.py -py/path/local/testing/__init__.py -py/path/local/testing/test_local.py -py/path/local/testing/test_posix.py -py/path/local/testing/test_win.py -py/path/local/win.py -py/path/svn/__init__.py -py/path/svn/cache.py -py/path/svn/quoting.txt -py/path/svn/svncommon.py -py/path/svn/testing/__init__.py -py/path/svn/testing/repotest.dump -py/path/svn/testing/svntestbase.py -py/path/svn/testing/test_auth.py -py/path/svn/testing/test_test_repo.py -py/path/svn/testing/test_urlcommand.py -py/path/svn/testing/test_wccommand.py -py/path/svn/urlcommand.py -py/path/svn/wccommand.py +py/path/local.py +py/path/notes-svn-quoting.txt +py/path/svnurl.py +py/path/svnwc.py py/path/testing/__init__.py py/path/testing/common.py py/path/testing/fscommon.py -py/path/testing/test_api.py +py/path/testing/repotest.dump +py/path/testing/svntestbase.py +py/path/testing/test_local.py +py/path/testing/test_svnauth.py +py/path/testing/test_svnurl.py +py/path/testing/test_svnwc.py py/process/__init__.py py/process/cmdexec.py py/process/forkedfunc.py @@ -412,10 +386,6 @@ py/thread/pool.py py/thread/testing/__init__.py py/thread/testing/test_io.py py/thread/testing/test_pool.py -py/tool/__init__.py -py/tool/testing/__init__.py -py/tool/testing/test_utestconvert.py -py/tool/utestconvert.py py/xmlobj/__init__.py py/xmlobj/html.py py/xmlobj/misc.py diff --git a/py/misc/findmissingdocstrings.py b/bin-for-dist/findmissingdocstrings.py similarity index 100% rename from py/misc/findmissingdocstrings.py rename to bin-for-dist/findmissingdocstrings.py diff --git a/bin-for-dist/test_install.py b/bin-for-dist/test_install.py new file mode 100644 index 000000000..3d258792d --- /dev/null +++ b/bin-for-dist/test_install.py @@ -0,0 +1,111 @@ +import py +import subprocess +import os + + +# +# experimental funcargs for venv/install-tests +# + +pytest_plugins = 'pytest_pytester', + +def pytest_funcarg__venv(request): + p = request.config.mktemp(request.function.__name__, numbered=True) + venv = VirtualEnv(str(p)) + return venv + +def pytest_funcarg__py_setup(request): + testdir = request.getfuncargvalue('testdir') + rootdir = py.path.local(py.__file__).dirpath().dirpath() + setup = rootdir.join('setup.py') + if not setup.check(): + py.test.skip("not found: %r" % setup) + return SetupBuilder(setup, testdir.tmpdir) + +class SetupBuilder: + def __init__(self, setup_path, tmpdir): + self.setup_path = setup_path + self.tmpdir = tmpdir + assert setup_path.check() + + def make_sdist(self, destdir=None): + temp = self.tmpdir.mkdir('dist') + args = ['python', 'setup.py', 'sdist', '--dist-dir', str(temp)] + old = self.setup_path.dirpath().chdir() + try: + subcall(args) + finally: + old.chdir() + l = temp.listdir('py-*') + assert len(l) == 1 + sdist = l[0] + if destdir is None: + destdir = self.setup_path.dirpath('build') + assert destdir.check() + else: + destdir = py.path.local(destdir) + target = destdir.join(sdist.basename) + sdist.copy(target) + return target + +def subcall(args): + if hasattr(subprocess, 'check_call'): + subprocess.check_call(args) + else: + subprocess.call(args) +# code taken from Ronny Pfannenschmidt's virtualenvmanager + +class VirtualEnv(object): + def __init__(self, path): + #XXX: supply the python executable + self.path = path + + def __repr__(self): + return "" %(self.path) + + def _cmd(self, name): + return os.path.join(self.path, 'bin', name) + + def ensure(self): + if not os.path.exists(self._cmd('python')): + self.create() + + def create(self, sitepackages=False): + args = ['virtualenv', self.path] + if not sitepackages: + args.append('--no-site-packages') + subcall(args) + + def makegateway(self): + python = self._cmd('python') + return py.execnet.makegateway("popen//python=%s" %(python,)) + + def pcall(self, cmd, *args, **kw): + self.ensure() + return subprocess.call([ + self._cmd(cmd) + ] + list(args), + **kw) + + + def easy_install(self, *packages, **kw): + args = [] + if 'index' in kw: + index = kw['index'] + if isinstance(index, (list, tuple)): + for i in index: + args.extend(['-i', i]) + else: + args.extend(['-i', index]) + + args.extend(packages) + self.pcall('easy_install', *args) + + +def test_make_sdist_and_run_it(py_setup, venv): + sdist = py_setup.make_sdist(venv.path) + venv.easy_install(str(sdist)) + gw = venv.makegateway() + ch = gw.remote_exec("import py ; channel.send(py.__version__)") + version = ch.receive() + assert version == py.__version__ diff --git a/doc/changelog.txt b/doc/changelog.txt index 2f6f9daed..3c595a830 100644 --- a/doc/changelog.txt +++ b/doc/changelog.txt @@ -1,6 +1,8 @@ Changes between 1.0.x and 'trunk' ===================================== +* cleanup py/misc, move tests to bin-for-dist + * introduce delattr/delitem/delenv methods to py.test's monkeypatch funcarg * consolidate py.log implementation, remove old approach. diff --git a/doc/code.txt b/doc/code.txt index 3eca5b2f7..5d8685b70 100644 --- a/doc/code.txt +++ b/doc/code.txt @@ -113,7 +113,7 @@ Example (using the 'first' TracebackItem instance created above):: >>> frame = first.frame >>> isinstance(frame.code, py.code.Code) True - >>> isinstance(frame.eval('self'), py.__.path.local.local.LocalPath) + >>> isinstance(frame.eval('self'), py.path.local) True >>> [namevalue[0] for namevalue in frame.getargs()] ['cls', 'path'] diff --git a/doc/confrest.py b/doc/confrest.py index 05b42c4ca..74a43b3e1 100644 --- a/doc/confrest.py +++ b/doc/confrest.py @@ -1,6 +1,5 @@ import py from py.__.misc.rest import convert_rest_html, strip_html_header -from py.__.misc.difftime import worded_time html = py.xml.html diff --git a/doc/download.txt b/doc/download.txt index 4b606354b..fca8b4a82 100644 --- a/doc/download.txt +++ b/doc/download.txt @@ -82,12 +82,12 @@ system wide ``PATH`` settings. There are helper scripts that set ``PYTHONPATH`` on windows execute:: # inside autoexec.bat or shell startup - c:\\path\to\checkout\py\env.cmd + c:\\path\to\checkout\py\bin\env.cmd on linux/OSX add this to your shell initialization:: # inside .bashrc - eval `python ~/path/to/checkout/py/env.py` + eval `python ~/path/to/checkout/py/bin/env.py` both of which which will get you good settings for ``PYTHONPATH`` and ``PATH``. diff --git a/py/__init__.py b/py/__init__.py index 34e06f403..3058c23e5 100644 --- a/py/__init__.py +++ b/py/__init__.py @@ -96,7 +96,7 @@ initpkg(__name__, '_thread.ThreadOut' : ('./thread/io.py', 'ThreadOut'), # hook into the top-level standard library - 'std' : ('./misc/std.py', 'std'), + 'std' : ('./std.py', 'std'), 'process.__doc__' : ('./process/__init__.py', '__doc__'), 'process.cmdexec' : ('./process/cmdexec.py', 'cmdexec'), diff --git a/py/misc/cmdline/__init__.py b/py/_testing/__init__.py similarity index 100% rename from py/misc/cmdline/__init__.py rename to py/_testing/__init__.py diff --git a/py/misc/testing/test_api.py b/py/_testing/test_api.py similarity index 100% rename from py/misc/testing/test_api.py rename to py/_testing/test_api.py diff --git a/py/misc/testing/test_com.py b/py/_testing/test_com.py similarity index 100% rename from py/misc/testing/test_com.py rename to py/_testing/test_com.py diff --git a/py/misc/testing/test_error.py b/py/_testing/test_error.py similarity index 100% rename from py/misc/testing/test_error.py rename to py/_testing/test_error.py diff --git a/py/misc/testing/test_initpkg.py b/py/_testing/test_initpkg.py similarity index 100% rename from py/misc/testing/test_initpkg.py rename to py/_testing/test_initpkg.py diff --git a/py/misc/testing/test_std.py b/py/_testing/test_std.py similarity index 100% rename from py/misc/testing/test_std.py rename to py/_testing/test_std.py diff --git a/py/env.cmd b/py/bin/env.cmd similarity index 100% rename from py/env.cmd rename to py/bin/env.cmd diff --git a/py/env.py b/py/bin/env.py similarity index 100% rename from py/env.py rename to py/bin/env.py diff --git a/py/cmdline/pycountloc.py b/py/cmdline/pycountloc.py index 5f5a525d7..71786ce29 100755 --- a/py/cmdline/pycountloc.py +++ b/py/cmdline/pycountloc.py @@ -13,9 +13,83 @@ report them separately. """ import py from py.compat import optparse -from py.__.misc.cmdline.countloc import countloc def main(): parser = optparse.OptionParser(usage=__doc__) (options, args) = parser.parse_args() countloc(args) + +def nodot(p): + return p.check(dotfile=0) + +class FileCounter(object): + def __init__(self): + self.file2numlines = {} + self.numlines = 0 + self.numfiles = 0 + + def addrecursive(self, directory, fil="*.py", rec=nodot): + for x in directory.visit(fil, rec): + self.addfile(x) + + def addfile(self, fn, emptylines=False): + if emptylines: + s = len(p.readlines()) + else: + s = 0 + for i in fn.readlines(): + if i.strip(): + s += 1 + self.file2numlines[fn] = s + self.numfiles += 1 + self.numlines += s + + def getnumlines(self, fil): + numlines = 0 + for path, value in self.file2numlines.items(): + if fil(path): + numlines += value + return numlines + + def getnumfiles(self, fil): + numfiles = 0 + for path in self.file2numlines: + if fil(path): + numfiles += 1 + return numfiles + +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) + + def istestfile(p): + return p.check(fnmatch='test_*.py') + isnottestfile = lambda x: not istestfile(x) + + numfiles = counter.getnumfiles(isnottestfile) + numlines = counter.getnumlines(isnottestfile) + numtestfiles = counter.getnumfiles(istestfile) + numtestlines = counter.getnumlines(istestfile) + + return counter, numfiles, numlines, numtestfiles, numtestlines + +def countloc(paths=None): + if not paths: + paths = ['.'] + locations = [py.path.local(x) for x in paths] + (counter, numfiles, numlines, numtestfiles, + numtestlines) = get_loccount(locations) + + items = counter.file2numlines.items() + items.sort(lambda x,y: cmp(x[1], y[1])) + for x, y in items: + print "%3d %30s" % (y,x) + + print "%30s %3d" %("number of testfiles", numtestfiles) + print "%30s %3d" %("number of non-empty testlines", numtestlines) + print "%30s %3d" %("number of files", numfiles) + print "%30s %3d" %("number of non-empty lines", numlines) + diff --git a/py/error.py b/py/error.py index c3423709c..870f82395 100644 --- a/py/error.py +++ b/py/error.py @@ -1,4 +1,7 @@ +""" +create errno-specific classes for IO or os calls. +""" import sys, os, errno class Error(EnvironmentError): diff --git a/py/misc/_dist.py b/py/misc/_dist.py deleted file mode 100644 index 42cb05217..000000000 --- a/py/misc/_dist.py +++ /dev/null @@ -1,208 +0,0 @@ -import py -import sys, os, re -from distutils import sysconfig -from distutils import core -try: - import subprocess -except ImportError: - from py.__.compat import subprocess - -winextensions = 1 -if sys.platform == 'win32': - try: - import _winreg, win32gui, win32con - except ImportError: - winextensions = 0 - -class Params: - """ a crazy hack to convince distutils to please - install all of our files inside the package. - """ - _sitepackages = py.path.local(sysconfig.get_python_lib()) - def __init__(self, pkgmod): - name = pkgmod.__name__ - self._pkgdir = py.path.local(pkgmod.__file__).dirpath() - self._rootdir = self._pkgdir.dirpath() - self._pkgtarget = self._sitepackages.join(name) - self._datadict = {} - self.packages = [] - self.scripts = [] - self.hacktree() - self.data_files = self._datadict.items() - self.data_files.sort() - self.packages.sort() - self.scripts.sort() - - def hacktree(self): - for p in self._pkgdir.visit(None, lambda x: x.basename != '.svn'): - if p.check(file=1): - if p.ext in ('.pyc', '.pyo'): - continue - if p.dirpath().basename == 'bin': - self.scripts.append(p.relto(self._rootdir)) - self.adddatafile(p) - elif p.ext == '.py': - self.addpythonfile(p) - else: - self.adddatafile(p) - #else: - # if not p.listdir(): - # self.adddatafile(p.ensure('dummy')) - - def adddatafile(self, p): - if p.ext in ('.pyc', 'pyo'): - return - target = self._pkgtarget.join(p.dirpath().relto(self._pkgdir)) - l = self._datadict.setdefault(str(target), []) - l.append(p.relto(self._rootdir)) - - def addpythonfile(self, p): - parts = p.parts() - for above in p.parts(reverse=True)[1:]: - if self._pkgdir.relto(above): - dottedname = p.dirpath().relto(self._rootdir).replace(p.sep, '.') - if dottedname not in self.packages: - self.packages.append(dottedname) - break - if not above.join('__init__.py').check(): - self.adddatafile(p) - #print "warning, added data file", p - break - -#if sys.platform != 'win32': -# scripts.remove('py/bin/pytest.cmd') -#else: -# scripts.remove('py/bin/py.test') -# - -### helpers: -def checknonsvndir(p): - if p.basename != '.svn' and p.check(dir=1): - return True - -def dump(params): - print "packages" - for x in params.packages: - print "package ", x - print - print "scripts" - for x in params.scripts: - print "script ", x - print - - print "data files" - for x in params.data_files: - print "data file ", x - print - -def addbindir2path(): - if sys.platform != 'win32' or not winextensions: - return - - # Add py/bin to PATH environment variable - bindir = os.path.join(sysconfig.get_python_lib(), "py", "bin", "win32") - - # check for the user path - ureg = _winreg.ConnectRegistry(None, _winreg.HKEY_CURRENT_USER) - ukey = r"Environment" - - # not every user has his own path on windows - try: - upath = get_registry_value(ureg, ukey, "PATH") - except WindowsError: - upath="" - # if bindir allready in userpath -> do nothing - if bindir in upath: - return - - reg = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) - key = r"SYSTEM\CurrentControlSet\Control\Session Manager\Environment" - path = get_registry_value(reg, key, "Path") - # if bindir allready in systempath -> do nothing - if bindir in path: - return - path += ";" + bindir - print "Setting PATH to:", path - - pathset=False - try: - set_registry_value(reg, key, "PATH", path) - pathset=True - except WindowsError: - print "cannot set systempath, falling back to userpath" - pass - - if not pathset: - try: - if len(upath)>0: #if no user path present - upath += ";" - upath+=bindir - set_registry_value(ureg, ukey, "Path", upath) - pathset=True - except WindowsError: - print "cannot set userpath, please add %s to your path" % (bindir,) - return - - #print "Current PATH is:", get_registry_value(reg, key, "Path") - - # Propagate changes throughout the system - win32gui.SendMessageTimeout(win32con.HWND_BROADCAST, - win32con.WM_SETTINGCHANGE, 0, "Environment", - win32con.SMTO_ABORTIFHUNG, 5000) - - # Propagate changes to current command prompt - p = subprocess.Popen("set PATH=%s" % path, shell=True) - os.waitpid(p.pid, 0) - -def get_registry_value(reg, key, value_name): - k = _winreg.OpenKey(reg, key) - value = _winreg.QueryValueEx(k, value_name)[0] - _winreg.CloseKey(k) - return value - -def set_registry_value(reg, key, value_name, value): - k = _winreg.OpenKey(reg, key, 0, _winreg.KEY_WRITE) - value_type = _winreg.REG_SZ - # if we handle the Path value, then set its type to REG_EXPAND_SZ - # so that things like %SystemRoot% get automatically expanded by the - # command prompt - if value_name == "Path": - value_type = _winreg.REG_EXPAND_SZ - _winreg.SetValueEx(k, value_name, 0, value_type, value) - _winreg.CloseKey(k) - -### end helpers - -def setup(pkg, **kw): - """ invoke distutils on a given package. - """ - if 'install' in sys.argv[1:]: - print "precompiling greenlet module" - try: - x = py.magic.greenlet() - except (RuntimeError, ImportError): - print "could not precompile greenlet module, skipping" - - params = Params(pkg) - #dump(params) - source = getattr(pkg, '__pkg__', pkg) - namelist = list(core.setup_keywords) - namelist.extend(['packages', 'scripts', 'data_files']) - for name in namelist: - for ns in (source, params): - if hasattr(ns, name): - kw[name] = getattr(ns, name) - break - - #script_args = sys.argv[1:] - #if 'install' in script_args: - # script_args = ['--quiet'] + script_args - # #print "installing", py - #py.std.pprint.pprint(kw) - core.setup(**kw) - if 'install' in sys.argv[1:]: - addbindir2path() - x = params._rootdir.join('build') - if x.check(): - print "removing", x - x.remove() diff --git a/py/misc/buildcmodule.py b/py/misc/buildcmodule.py deleted file mode 100644 index e9eef585b..000000000 --- a/py/misc/buildcmodule.py +++ /dev/null @@ -1,87 +0,0 @@ -""" -A utility to build a Python extension module from C, wrapping distutils. -""" -import py - -# set to true for automatic re-compilation of extensions -AUTOREGEN = True - -# XXX we should distutils in a subprocess, because it messes up the -# environment and who knows what else. Currently we just save -# and restore os.environ. - -def make_module_from_c(cfile): - import os, sys, imp - from distutils.core import setup - from distutils.extension import Extension - debug = 0 - - #try: - # from distutils.log import set_threshold - # set_threshold(10000) - #except ImportError: - # print "ERROR IMPORTING" - # pass - - dirpath = cfile.dirpath() - modname = cfile.purebasename - - # find the expected extension of the compiled C module - for ext, mode, filetype in imp.get_suffixes(): - if filetype == imp.C_EXTENSION: - break - else: - raise ImportError, "cannot find the file name suffix of C ext modules" - lib = dirpath.join(modname+ext) - - # XXX argl! we need better "build"-locations alltogether! - if lib.check() and AUTOREGEN and lib.stat().mtime < cfile.stat().mtime: - try: - lib.remove() - except EnvironmentError: - pass # XXX we just use the existing version, bah - - if not lib.check(): - c = py.io.StdCaptureFD() - try: - try: - saved_environ = os.environ.items() - try: - lastdir = dirpath.chdir() - try: - setup( - name = "pylibmodules", - ext_modules=[ - Extension(modname, [str(cfile)]) - ], - script_name = 'setup.py', - script_args = ['-q', 'build_ext', '--inplace'] - #script_args = ['build_ext', '--inplace'] - ) - finally: - lastdir.chdir() - finally: - for key, value in saved_environ: - if os.environ.get(key) != value: - os.environ[key] = value - finally: - foutput, foutput = c.done() - except KeyboardInterrupt: - raise - except SystemExit, e: - raise RuntimeError("cannot compile %s: %s\n%s" % (cfile, e, - foutput.read())) - # XXX do we need to do some check on fout/ferr? - # XXX not a nice way to import a module - if debug: - print "inserting path to sys.path", dirpath - sys.path.insert(0, str(dirpath)) - if debug: - print "import %(modname)s as testmodule" % locals() - exec py.code.compile("import %(modname)s as testmodule" % locals()) - try: - sys.path.remove(str(dirpath)) - except ValueError: - pass - - return testmodule diff --git a/py/misc/cache.py b/py/misc/cache.py index 12970e6d7..8526d4c0a 100644 --- a/py/misc/cache.py +++ b/py/misc/cache.py @@ -1,18 +1,13 @@ """ This module contains multithread-safe cache implementations. -Caches mainly have a +All Caches have a - __getitem__ and getorbuild() method + __getitem__ and getorbuild(key, builder) method where the latter either just return a cached value or first builds the value. -These are the current cache implementations: - - BuildcostAccessCache tracks building-time and accesses. Evicts - by product of num-accesses * build-time. - """ import py gettime = py.std.time.time @@ -74,10 +69,10 @@ class BasicCache(object): finally: self._lock.release() - def getorbuild(self, key, builder, *args, **kwargs): + def getorbuild(self, key, builder): entry = self.getentry(key) if entry is None: - entry = self.build(key, builder, *args, **kwargs) + entry = self.build(key, builder) return entry.value def _prunelowestweight(self): @@ -107,9 +102,9 @@ class BuildcostAccessCache(BasicCache): # time function to use for measuring build-times _time = gettime - def build(self, key, builder, *args, **kwargs): + def build(self, key, builder): start = self._time() - val = builder(*args, **kwargs) + val = builder() end = self._time() entry = WeightedCountingEntry(val, end-start) self.putentry(key, entry) @@ -137,9 +132,9 @@ class AgingCache(BasicCache): finally: self._lock.release() - def build(self, key, builder, *args, **kwargs): + def build(self, key, builder): ctime = gettime() - val = builder(*args, **kwargs) + val = builder() entry = AgingEntry(val, ctime + self.maxseconds) self.putentry(key, entry) return entry diff --git a/py/misc/cmdline/countloc.py b/py/misc/cmdline/countloc.py deleted file mode 100755 index feb29e760..000000000 --- a/py/misc/cmdline/countloc.py +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/env python - -# hands on script to compute the non-empty Lines of Code -# for tests and non-test code - -import py - - -curdir = py.path.local() - - -def nodot(p): - return p.check(dotfile=0) - -class FileCounter(object): - def __init__(self): - self.file2numlines = {} - self.numlines = 0 - self.numfiles = 0 - - def addrecursive(self, directory, fil="*.py", rec=nodot): - for x in directory.visit(fil, rec): - self.addfile(x) - - def addfile(self, fn, emptylines=False): - if emptylines: - s = len(p.readlines()) - else: - s = 0 - for i in fn.readlines(): - if i.strip(): - s += 1 - self.file2numlines[fn] = s - self.numfiles += 1 - self.numlines += s - - def getnumlines(self, fil): - numlines = 0 - for path, value in self.file2numlines.items(): - if fil(path): - numlines += value - return numlines - - def getnumfiles(self, fil): - numfiles = 0 - for path in self.file2numlines: - if fil(path): - numfiles += 1 - return numfiles - -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) - - def istestfile(p): - return p.check(fnmatch='test_*.py') - isnottestfile = lambda x: not istestfile(x) - - numfiles = counter.getnumfiles(isnottestfile) - numlines = counter.getnumlines(isnottestfile) - numtestfiles = counter.getnumfiles(istestfile) - numtestlines = counter.getnumlines(istestfile) - - return counter, numfiles, numlines, numtestfiles, numtestlines - -def countloc(paths=None): - if not paths: - paths = ['.'] - locations = [py.path.local(x) for x in paths] - (counter, numfiles, numlines, numtestfiles, - numtestlines) = get_loccount(locations) - - items = counter.file2numlines.items() - items.sort(lambda x,y: cmp(x[1], y[1])) - for x, y in items: - print "%3d %30s" % (y,x) - - print "%30s %3d" %("number of testfiles", numtestfiles) - print "%30s %3d" %("number of non-empty testlines", numtestlines) - print "%30s %3d" %("number of files", numfiles) - print "%30s %3d" %("number of non-empty lines", numlines) diff --git a/py/misc/difftime.py b/py/misc/difftime.py deleted file mode 100644 index af2598bf9..000000000 --- a/py/misc/difftime.py +++ /dev/null @@ -1,32 +0,0 @@ -import py - -_time_desc = { - 1 : 'second', 60 : 'minute', 3600 : 'hour', 86400 : 'day', - 2628000 : 'month', 31536000 : 'year', } - -def worded_diff_time(ctime): - difftime = py.std.time.time() - ctime - keys = _time_desc.keys() - keys.sort() - for i, key in py.builtin.enumerate(keys): - if key >=difftime: - break - l = [] - keylist = keys[:i] - - keylist.reverse() - for key in keylist[:1]: - div = int(difftime / key) - if div==0: - break - difftime -= div * key - plural = div > 1 and 's' or '' - l.append('%d %s%s' %(div, _time_desc[key], plural)) - return ", ".join(l) + " ago " - -_months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] - -def worded_time(ctime): - tm = py.std.time.gmtime(ctime) - return "%s %d, %d" % (_months[tm.tm_mon-1], tm.tm_mday, tm.tm_year) diff --git a/py/misc/dynpkg.py b/py/misc/dynpkg.py deleted file mode 100644 index 5081b9158..000000000 --- a/py/misc/dynpkg.py +++ /dev/null @@ -1,84 +0,0 @@ -""" - -""" - -import py -import sys - -log = py.log.Logger("dynpkg", - info=py.log.STDOUT, - debug=py.log.STDOUT, - command=None) - -from distutils import util - -class DistPython: - def __init__(self, location=None, python=None): - if python is None: - python = py.std.sys.executable - self.python = python - if location is None: - location = py.path.local() - self.location = location - self.plat_specifier = '.%s-%s' % (util.get_platform(), sys.version[0:3]) - - def clean(self): - out = self._exec("clean -a") - #print out - - def build(self): - out = self._exec("build") - #print out - - def _exec(self, cmd): - python = self.python - old = self.location.chdir() - try: - cmd = "%(python)s setup.py %(cmd)s" % locals() - log.command(cmd) - out = py.process.cmdexec(cmd) - finally: - old.chdir() - return out - - def get_package_path(self, pkgname): - pkg = self._get_package_path(pkgname) - if pkg is None: - #self.clean() - self.build() - pkg = self._get_package_path(pkgname) - assert pkg is not None - return pkg - - def _get_package_path(self, pkgname): - major, minor = py.std.sys.version_info[:2] - #assert major >=2 and minor in (3,4,5) - suffix = "%s.%s" %(major, minor) - location = self.location - for base in [location.join('build', 'lib'), - location.join('build', 'lib'+ self.plat_specifier)]: - if base.check(dir=1): - for pkg in base.visit(lambda x: x.check(dir=1)): - if pkg.basename == pkgname: - # - if pkg.dirpath().basename == 'lib'+ self.plat_specifier or \ - pkg.dirpath().basename == 'lib': - return pkg - -def setpkg(finalpkgname, distdir): - assert distdir.check(dir=1) - dist = DistPython(distdir) - pkg = dist.get_package_path(finalpkgname) - assert pkg.check(dir=1) - sys.path.insert(0, str(pkg.dirpath())) - try: - modname = pkg.purebasename - if modname in sys.modules: - log.debug("removing from sys.modules:", modname) - del sys.modules[modname] - sys.modules[modname] = mod = __import__(modname) - finally: - sys.path[0] # XXX - log.info("module is at", mod.__file__) - return mod - diff --git a/py/misc/svnlook.py b/py/misc/svnlook.py deleted file mode 100644 index 21ddba20d..000000000 --- a/py/misc/svnlook.py +++ /dev/null @@ -1,34 +0,0 @@ - -import py - -class ChangeItem: - def __init__(self, repo, revision, line): - self.repo = py.path.local(repo) - self.revision = int(revision) - self.action = action = line[:4] - self.path = line[4:].strip() - self.added = action[0] == "A" - self.modified = action[0] == "M" - self.propchanged = action[1] == "U" - self.deleted = action[0] == "D" - - def svnurl(self): - return py.path.svnurl("file://%s/%s" %(self.repo, self.path), self.revision) - - def __repr__(self): - return "" %(self.action + self.path) - -def changed(repo, revision): - out = py.process.cmdexec("svnlook changed -r %s %s" %(revision, repo)) - l = [] - for line in out.strip().split('\n'): - l.append(ChangeItem(repo, revision, line)) - return l - -def author(repo, revision): - out = py.process.cmdexec("svnlook author -r %s %s" %(revision, repo)) - return out.strip() - -def youngest(repo): - out = py.process.cmdexec("svnlook youngest %s" %(repo,)) - return int(out) diff --git a/py/misc/terminal_helper.py b/py/misc/terminal_helper.py deleted file mode 100644 index 3696a2d33..000000000 --- a/py/misc/terminal_helper.py +++ /dev/null @@ -1,14 +0,0 @@ -""" - -(DEPRECATED) use py.io.TerminalWriter - -""" - -import sys, os -import py - -py.std.warnings.warn("py.__.misc.terminal_helper is deprecated, use py.io.TerminalWriter", - DeprecationWarning, stacklevel=2) - -from py.__.io.terminalwriter import get_terminal_width, terminal_width, ansi_print - diff --git a/py/misc/testing/data/svnlookrepo.dump b/py/misc/testing/data/svnlookrepo.dump deleted file mode 100644 index 4d1b2a7d3..000000000 --- a/py/misc/testing/data/svnlookrepo.dump +++ /dev/null @@ -1,160 +0,0 @@ -SVN-fs-dump-format-version: 2 - -UUID: 9cb23565-b10c-0410-b2e2-dde77f08022e - -Revision-number: 0 -Prop-content-length: 56 -Content-length: 56 - -K 8 -svn:date -V 27 -2006-02-13T18:39:13.605561Z -PROPS-END - -Revision-number: 1 -Prop-content-length: 111 -Content-length: 111 - -K 7 -svn:log -V 13 -A testdir - -K 10 -svn:author -V 3 -hpk -K 8 -svn:date -V 27 -2006-02-13T18:39:27.723346Z -PROPS-END - -Node-path: testdir -Node-kind: dir -Node-action: add -Prop-content-length: 10 -Content-length: 10 - -PROPS-END - - -Revision-number: 2 -Prop-content-length: 111 -Content-length: 111 - -K 7 -svn:log -V 13 -_M testdir - -K 10 -svn:author -V 3 -hpk -K 8 -svn:date -V 27 -2006-02-13T18:39:48.595729Z -PROPS-END - -Node-path: testdir -Node-kind: dir -Node-action: change -Prop-content-length: 28 -Content-length: 28 - -K 4 -key1 -V 4 -val2 -PROPS-END - - -Revision-number: 3 -Prop-content-length: 113 -Content-length: 113 - -K 7 -svn:log -V 15 -AM testdir2 - - -K 10 -svn:author -V 3 -hpk -K 8 -svn:date -V 27 -2006-02-13T18:40:53.307540Z -PROPS-END - -Node-path: testdir2 -Node-kind: dir -Node-action: add -Prop-content-length: 28 -Content-length: 28 - -K 4 -key2 -V 4 -val2 -PROPS-END - - -Revision-number: 4 -Prop-content-length: 113 -Content-length: 113 - -K 7 -svn:log -V 15 -D testdir2 - - -K 10 -svn:author -V 3 -hpk -K 8 -svn:date -V 27 -2006-02-13T18:41:07.188024Z -PROPS-END - -Node-path: testdir2 -Node-action: delete - - -Revision-number: 5 -Prop-content-length: 112 -Content-length: 112 - -K 7 -svn:log -V 14 -_M testdir - - -K 10 -svn:author -V 3 -hpk -K 8 -svn:date -V 27 -2006-02-13T18:42:03.179177Z -PROPS-END - -Node-path: testdir -Node-kind: dir -Node-action: change -Prop-content-length: 10 -Content-length: 10 - -PROPS-END - - diff --git a/py/misc/testing/test_install.py b/py/misc/testing/test_install.py deleted file mode 100644 index 211422231..000000000 --- a/py/misc/testing/test_install.py +++ /dev/null @@ -1,16 +0,0 @@ -import py - -def test_make_sdist_and_run_it(capfd, py_setup, venv): - try: - sdist = py_setup.make_sdist(venv.path) - venv.easy_install(str(sdist)) - gw = venv.makegateway() - ch = gw.remote_exec("import py ; channel.send(py.__version__)") - version = ch.receive() - assert version == py.__version__ - except KeyboardInterrupt: - raise - except: - print capfd.readouterr() - raise - capfd.close() diff --git a/py/misc/testing/test_svnlook.py b/py/misc/testing/test_svnlook.py deleted file mode 100644 index 087ce2862..000000000 --- a/py/misc/testing/test_svnlook.py +++ /dev/null @@ -1,60 +0,0 @@ - -import py -from py.__.misc import svnlook -data = py.magic.autopath().dirpath('data') - -if py.path.local.sysfind('svnlook') is None or \ - py.path.local.sysfind('svnadmin') is None: - py.test.skip("cannot test py.misc.svnlook, svn binaries not found") - -def test_svnlook(): - tempdir = py.test.ensuretemp("svnlook") - repo = tempdir.join("repo") - py.process.cmdexec('svnadmin create --fs-type fsfs "%s"' % repo) - py.process.cmdexec('svnadmin load "%s" < "%s"' %(repo, - data.join("svnlookrepo.dump"))) - - author = svnlook.author(repo, 1) - assert author == "hpk" - - for item in svnlook.changed(repo, 1): - svnurl = item.svnurl() - assert item.revision == 1 - assert (svnurl.strpath + "/") == "file://%s/%s" %(repo, item.path) - assert item.added - assert not item.modified - assert not item.propchanged - assert not item.deleted - assert item.path == "testdir/" - - for item in svnlook.changed(repo, 2): - assert item.revision == 2 - assert not item.added - assert not item.modified - assert item.propchanged - assert not item.deleted - assert item.path == "testdir/" - - for item in svnlook.changed(repo, 3): - assert item.revision == 3 - assert item.added - assert not item.modified - assert not item.propchanged - assert not item.deleted - assert item.path == "testdir2/" - - for item in svnlook.changed(repo, 4): - assert item.revision == 4 - assert not item.added - assert not item.modified - assert not item.propchanged - assert item.deleted - assert item.path == "testdir2/" - - for item in svnlook.changed(repo, 5): - assert item.revision == 5 - assert not item.added - assert not item.modified - assert item.propchanged - assert not item.deleted - assert item.path == "testdir/" diff --git a/py/misc/testing/test_terminal.py b/py/misc/testing/test_terminal.py deleted file mode 100644 index 8b0d44c20..000000000 --- a/py/misc/testing/test_terminal.py +++ /dev/null @@ -1,25 +0,0 @@ - -import os -import py -from py.__.misc.terminal_helper import get_terminal_width - -def test_terminal_width(): - """ Dummy test for get_terminal_width - """ - assert get_terminal_width() - try: - import fcntl - except ImportError: - py.test.skip('fcntl not supported on this platform') - def f(*args): - raise ValueError - ioctl = fcntl.ioctl - fcntl.ioctl = f - try: - cols = os.environ.get('COLUMNS', None) - os.environ['COLUMNS'] = '42' - assert get_terminal_width() == 41 - finally: - fcntl.ioctl = ioctl - if cols: - os.environ['COLUMNS'] = cols diff --git a/py/misc/std.py b/py/std.py similarity index 74% rename from py/misc/std.py rename to py/std.py index bef7ae8cc..bca23ea2d 100644 --- a/py/misc/std.py +++ b/py/std.py @@ -1,9 +1,8 @@ - import sys class Std(object): - """ makes all standard python modules available as a lazily - computed attribute. + """ makes top-level python modules available as an attribute, + importing them on first access. """ def __init__(self): diff --git a/py/test/plugin/pytest_pytester.py b/py/test/plugin/pytest_pytester.py index 9c1fb418b..a7d20d0f3 100644 --- a/py/test/plugin/pytest_pytester.py +++ b/py/test/plugin/pytest_pytester.py @@ -516,108 +516,3 @@ def test_testdir_runs_with_plugin(testdir): "*1 passed*" ]) -# -# experimental funcargs for venv/install-tests -# - -def pytest_funcarg__venv(request): - p = request.config.mktemp(request.function.__name__, numbered=True) - venv = VirtualEnv(str(p)) - return venv - -def pytest_funcarg__py_setup(request): - rootdir = py.path.local(py.__file__).dirpath().dirpath() - setup = rootdir.join('setup.py') - if not setup.check(): - py.test.skip("not found: %r" % setup) - return SetupBuilder(setup) - -class SetupBuilder: - def __init__(self, setup_path): - self.setup_path = setup_path - assert setup_path.check() - - def make_sdist(self, destdir=None): - temp = py.path.local.mkdtemp() - try: - args = ['python', str(self.setup_path), 'sdist', - '--dist-dir', str(temp)] - subcall(args) - l = temp.listdir('py-*') - assert len(l) == 1 - sdist = l[0] - if destdir is None: - destdir = self.setup_path.dirpath('build') - assert destdir.check() - else: - destdir = py.path.local(destdir) - target = destdir.join(sdist.basename) - sdist.copy(target) - return target - finally: - temp.remove() - -def subcall(args): - if hasattr(subprocess, 'check_call'): - subprocess.check_call(args) - else: - subprocess.call(args) -# code taken from Ronny Pfannenschmidt's virtualenvmanager - -class VirtualEnv(object): - def __init__(self, path): - #XXX: supply the python executable - self.path = path - - def __repr__(self): - return "" %(self.path) - - def _cmd(self, name): - return os.path.join(self.path, 'bin', name) - - def ensure(self): - if not os.path.exists(self._cmd('python')): - self.create() - - def create(self, sitepackages=False): - args = ['virtualenv', self.path] - if not sitepackages: - args.append('--no-site-packages') - subcall(args) - - def makegateway(self): - python = self._cmd('python') - return py.execnet.makegateway("popen//python=%s" %(python,)) - - def pcall(self, cmd, *args, **kw): - self.ensure() - return subprocess.call([ - self._cmd(cmd) - ] + list(args), - **kw) - - - def easy_install(self, *packages, **kw): - args = [] - if 'index' in kw: - index = kw['index'] - if isinstance(index, (list, tuple)): - for i in index: - args.extend(['-i', i]) - else: - args.extend(['-i', index]) - - args.extend(packages) - self.pcall('easy_install', *args) - - - @property - def has_pip(self): - return os.path.exists(self._cmd('pip')) - - def pip_install(self, *packages): - if not self.has_pip: - self.easy_install('pip') - - self.pcall('pip', *packages) - diff --git a/setup.py b/setup.py index 6a6a28146..1abb9c65d 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,6 @@ """ py lib / py.test setup.py file, autogenerated by gensetup.py + """ import os, sys @@ -38,6 +39,7 @@ def main(): author_email='holger at merlinux.eu, py-dev at codespeak.net', entry_points={'console_scripts': ['py.cleanup = py.cmdline:pycleanup', + 'py.convert_unittest = py.cmdline:pyconvert_unittest', 'py.countloc = py.cmdline:pycountloc', 'py.lookup = py.cmdline:pylookup', 'py.rest = py.cmdline:pyrest', @@ -74,14 +76,9 @@ def main(): 'py.magic', 'py.magic.testing', 'py.misc', - 'py.misc.cmdline', 'py.misc.testing', 'py.path', 'py.path.gateway', - 'py.path.local', - 'py.path.local.testing', - 'py.path.svn', - 'py.path.svn.testing', 'py.path.testing', 'py.process', 'py.process.testing', @@ -98,13 +95,12 @@ def main(): 'py.test.web', 'py.thread', 'py.thread.testing', - 'py.tool', - 'py.tool.testing', 'py.xmlobj', 'py.xmlobj.testing'], package_data={'py': ['LICENSE', 'bin/_findpy.py', 'bin/py.cleanup', + 'bin/py.convert_unittest', 'bin/py.countloc', 'bin/py.lookup', 'bin/py.rest', @@ -112,6 +108,7 @@ def main(): 'bin/py.test', 'bin/py.which', 'bin/win32/py.cleanup.cmd', + 'bin/win32/py.convert_unittest.cmd', 'bin/win32/py.countloc.cmd', 'bin/win32/py.lookup.cmd', 'bin/win32/py.rest.cmd', @@ -126,8 +123,8 @@ def main(): 'execnet/improve-remote-tracebacks.txt', 'misc/testing/data/svnlookrepo.dump', 'path/gateway/TODO.txt', - 'path/svn/quoting.txt', - 'path/svn/testing/repotest.dump', + 'path/notes-svn-quoting.txt', + 'path/testing/repotest.dump', 'rest/rest.sty.template', 'rest/testing/data/example.rst2pdfconfig', 'rest/testing/data/example1.dot', @@ -142,4 +139,4 @@ def main(): if __name__ == '__main__': main() - + \ No newline at end of file