[py-svn] r66011 - in py/trunk: . doc doc/announce doc/test py py/execnet py/execnet/testing py/io py/io/testing py/test py/test/plugin py/test/testing
hpk at codespeak.net
hpk at codespeak.net
Sun Jun 28 11:51:43 CEST 2009
Author: hpk
Date: Sun Jun 28 11:51:40 2009
New Revision: 66011
Removed:
py/trunk/TODO.txt
Modified:
py/trunk/CHANGELOG
py/trunk/MANIFEST
py/trunk/README.txt (contents, props changed)
py/trunk/doc/announce/release-1.0.0.txt
py/trunk/doc/download.txt
py/trunk/doc/execnet.txt
py/trunk/doc/test/funcargs.txt
py/trunk/py/__init__.py
py/trunk/py/execnet/gateway.py
py/trunk/py/execnet/testing/test_gateway.py
py/trunk/py/io/stdcapture.py
py/trunk/py/io/testing/test_stdcapture.py
py/trunk/py/test/collect.py
py/trunk/py/test/funcargs.py
py/trunk/py/test/plugin/pytest_runner.py
py/trunk/py/test/plugin/pytest_terminal.py
py/trunk/py/test/pycollect.py
py/trunk/py/test/testing/test_funcargs.py
py/trunk/py/test/testing/test_genitems.py
py/trunk/setup.py
Log:
updating trunk
Modified: py/trunk/CHANGELOG
==============================================================================
--- py/trunk/CHANGELOG (original)
+++ py/trunk/CHANGELOG Sun Jun 28 11:51:40 2009
@@ -1,4 +1,21 @@
-$Id$
+Changes between 1.0.0b3 and 1.0.0
+=============================================
+
+* remove scope-argument from request.addfinalizer() because
+ request.cached_setup has the scope arg. TOOWTDI.
+
+* perform setup finalization before reporting failures
+
+* apply modified patches from Andreas Kloeckner to allow
+ test functions to have no func_code (#22) and to make
+ "-k" and function keywords work (#20)
+
+* apply patch from Daniel Peolzleithner (issue #23)
+
+* resolve issue #18, multiprocessing.Manager() and
+ redirection clash
+
+* make __name__ == "__channelexec__" for remote_exec code
Changes between 1.0.0b1 and 1.0.0b3
=============================================
Modified: py/trunk/MANIFEST
==============================================================================
--- py/trunk/MANIFEST (original)
+++ py/trunk/MANIFEST Sun Jun 28 11:51:40 2009
@@ -1,9 +1,11 @@
+MANIFEST
+py/__init__.py
+setup.py
.hgignore
+.hgtags
CHANGELOG
LICENSE
-MANIFEST
README.txt
-TODO.txt
_findpy.py
doc/announce/release-0.9.0.txt
doc/announce/release-0.9.2.txt
@@ -59,7 +61,6 @@
example/pytest/test_setup_flow_example.py
ez_setup.py
py/LICENSE
-py/__init__.py
py/_com.py
py/bin/_findpy.py
py/bin/_genscripts.py
@@ -382,5 +383,4 @@
py/xmlobj/testing/test_html.py
py/xmlobj/testing/test_xml.py
py/xmlobj/visit.py
-py/xmlobj/xml.py
-setup.py
\ No newline at end of file
+py/xmlobj/xml.py
\ No newline at end of file
Modified: py/trunk/README.txt
==============================================================================
--- py/trunk/README.txt (original)
+++ py/trunk/README.txt Sun Jun 28 11:51:40 2009
@@ -17,4 +17,3 @@
holger krekel, holger at merlinux eu
-$Id$
Deleted: /py/trunk/TODO.txt
==============================================================================
--- /py/trunk/TODO.txt Sun Jun 28 11:51:40 2009
+++ (empty file)
@@ -1,95 +0,0 @@
-Things to do for 1.0.0
-=========================
-
-py.test
---------------
-
-- clarify setup/run events and runner.py versus pytest_runner.py,
- introduce a general pytest_item_setup(item, setupstate)
- and always isolate py._com.comregistry when py lib's own tests are run
-
-- hook review and hook docs
-
-- turn deprecation / apiwarnings into events, report them at the end?
-
-- nightly test runs on multiple platforms
-
-py.execnet
---------------
-
-- cross-python version (2.2/2.3-2.5/6) and cross-platform testing of
- setup/teardown semantics
-
-py.test apigen plugin
----------------------------
-
-- make it work again with the new plugin arch
-
-packaging / svn-mercurial interaction
---------------------------------------------
-
-- decide if to go with or without setuptools, check windows 2.6
- availability
-
-- open a mercurial branch for releases?
-
-- write a script to dumb-bridge the mercurial repo to svn
- (i.e. forget about svn history)
-
-1.1 and beyond
-=================================
-
-refactorings
-------------------
-
-- refine doctests usage (particularly skips of doctests if
- some imports/conditions are not satisfied)
- - check if it works on win32
- - refine error reporting (don't show python tracebacks)
-
-- py.log: unify API, possibly deprecate duplicate ones,
- base things on a Config object (hte latter almost a feature though)
- (M988)
-
-- see to teardown more eagerly
-
-features
---------------
-
-- (Harald Armin Massa): make py2exe work with py lib
-
-- optimize file checking with --looponfailing (harald has code for win32)
-
-- have a py.test scan/run database for results and test names
- etc. (to allow quicker selection of tests and post-run
- information on failures etc.) (M760)
-
-- have config options from environment, command line or conftest's
-
- have py/doc/config/"OPTNAME".txt for each option pypy-style
-
- py.test --showconfig shows current configuration according
- to envvars, cmdlineopts and conftests considered for your dir location.
-
- py.test --help-conftest lists all possible environment envs
- py.test --help-env lists all possible environment envs
-
-- consider features of py.apigen (recheck closed "M1016")
-
-- integrate rlcompleter2 (make it remotely workable)
- and maybe integrate with "pdb" / pdbplus (M975)
-
-- integrate native collecting of unittest.py tests from py.test
- (along the PyPy lib-python tests) (M987)
-
-- provide an automated conversion script helper for converting
- unittest.py based tests to py.test ones. (M987)
-
-- references from ReST docs to modules, functions and classes
- of apigen generated html docs (M960)
-
-- py.test.pdb - there is my hack for a while now, which integrates
- rlcompleter2 with pdb. First of all it requires some strange changes
- to rlcompleter itself, which has no tests. Long-term plan would be
- to have pyrepl+rlcompleter2+pdb fixes integrated into pylib and
- have it tested. This requires work though.
Modified: py/trunk/doc/announce/release-1.0.0.txt
==============================================================================
--- py/trunk/doc/announce/release-1.0.0.txt (original)
+++ py/trunk/doc/announce/release-1.0.0.txt Sun Jun 28 11:51:40 2009
@@ -1,22 +1,53 @@
-py lib 1.0.0: distributed testing and dynamic code deployment
-===============================================================
+py.test / py lib 1.0.0: new test plugins, funcargs and cleanups
+============================================================================
-XXX draft
+Welcome to the 1.0 release bringing new flexibility and
+power to testing with Python. Main news:
-Welcome to the 1.0.0 py lib release - a python library aiming
-to support agile and test-driven development.
+* improved test architecture, featuring super-simple project
+ specific or cross-project single-file plugins, e.g:
-It works with Linux, OSX and Win32, on Python 2.3, 2.4, 2.5 and 2.6.
+ * pytest_unittest.py: run traditional unittest.py tests
+ * pytest_xfail.py: mark tests as "expected to fail"
+ * pytest_pocoo.py: automatically send tracebacks to pocoo paste service
+ * pytest_monkeypatch.py: safely patch parts of your environment in a test function
+ * pytest_figleaf.py: generate html coverage reports
+ * pytest_resultlog.py: generate buildbot-friendly output
-Main API/Tool Features:
+ and many more!
+
+* funcargs - bringing new flexibilty and zero-boilerplate to Python testing:
+
+ - cleanly separated test code and test configuration and test value setup
+ - ideal for integration and functional tests
+ - new generative tests -> deprecation of yield-generated tests
+
+* distributed testing and distributed execution (py.execnet):
+
+ - new unified "TX" URL scheme for specifying remote resources
+ - new sync/async ways to handle multiple remote processes
+ - much improved documentation
+
+
+See the py.test documentation for more info:
+
+ http://pytest.org
+
+The py lib also got smaller and focuses on offering much of the
+well-tested py.test code in independent namespaces:
-* py.test: cross-project testing tool with many advanced features
* py.execnet: ad-hoc code distribution to SSH, Socket and local sub processes
-* py.code: support for dynamically running and debugging python code
+* py.code: higher-level introspection and dynamic generation of python code
* py.path: path abstractions over local and subversion files
-Download/Install: http://codespeak.net/py/1.0.0/download.html
-Documentation/API: http://codespeak.net/py/1.0.0/index.html
+Some non-strictly-test related code, notably greenlets/co-routines
+and apigen now live on their own and have been removed, also simplifying
+the installation procedures.
+
+The whole package works well with Linux, OSX and Win32, on
+Python 2.3, 2.4, 2.5 and 2.6. (Expect Python3 compatibility soon!)
+
+Download/Install: http://codespeak.net/py/dist/download.html
best,
holger
Modified: py/trunk/doc/download.txt
==============================================================================
--- py/trunk/doc/download.txt (original)
+++ py/trunk/doc/download.txt Sun Jun 28 11:51:40 2009
@@ -2,7 +2,7 @@
Downloading
==============
-.. _`PyPI project page`: http://pypi.python.org/pypi?%3Aaction=pkg_edit&name=py
+.. _`PyPI project page`: http://pypi.python.org/pypi/py/
Latest Release, see `PyPI project page`_
Modified: py/trunk/doc/execnet.txt
==============================================================================
--- py/trunk/doc/execnet.txt (original)
+++ py/trunk/doc/execnet.txt Sun Jun 28 11:51:40 2009
@@ -233,3 +233,19 @@
socketgw = py.execnet.SocketGateway.new_remote(popengw, ("127.0.0.1", 0))
print socketgw._rinfo() # print some info about the remote environment
+
+
+Sending a module / checking if run through remote_exec
+--------------------------------------------------------------
+
+You can pass a module object to ``remote_exec`` in which case
+its source code will be sent. No dependencies will be transferred
+so the module must be self-contained or only use modules that are
+installed on the "other" side. Module code can detect if it is
+running in a remote_exec situation by checking for the special
+``__name__`` attribute like this::
+
+ if __name__ == '__channelexec__':
+ # ... call module functions ...
+
+
Modified: py/trunk/doc/test/funcargs.txt
==============================================================================
--- py/trunk/doc/test/funcargs.txt (original)
+++ py/trunk/doc/test/funcargs.txt Sun Jun 28 11:51:40 2009
@@ -39,7 +39,7 @@
.. _`funcarg provider`:
-funcarg providers: setting up test function arguments
+funcarg providers: instantiating test function arguments
==============================================================
Test functions can specify one ore more arguments ("funcargs")
@@ -120,7 +120,27 @@
``request.param``: if exists was passed by a `parametrizing test generator`_
-perform scoped setup and teardown
+teardown/cleanup after test function execution
+------------------------------------------------
+
+.. sourcecode:: python
+
+ def addfinalizer(func):
+ """ call a finalizer function when test function finishes. """
+
+Calling ``request.addfinalizer()`` is useful for scheduling teardown
+functions. Here is an example for providing a ``myfile``
+object that is to be closed when the test function finishes.
+
+.. sourcecode:: python
+
+ def pytest_funcarg__myfile(self, request):
+ # ... create and open a unique per-function "myfile" object ...
+ request.addfinalizer(lambda: myfile.close())
+ return myfile
+
+
+perform scope-specific setup and cleanup
---------------------------------------------
.. sourcecode:: python
@@ -148,30 +168,6 @@
)
-cleanup after test function execution
----------------------------------------------
-
-.. sourcecode:: python
-
- def addfinalizer(func, scope="function"):
- """ register calling a a finalizer function.
- scope == 'function': when the single test function run finishes.
- scope == 'module': when tests in a different module are run
- scope == 'session': when tests of the session have run.
- """
-
-Calling ``request.addfinalizer()`` is useful for scheduling teardown
-functions. The given scope determines when the teardown function
-will be called. Here is a basic example for providing a ``myfile``
-object that is to be closed when the test function finishes.
-
-.. sourcecode:: python
-
- def pytest_funcarg__myfile(self, request):
- # ... create and open a unique per-function "myfile" object ...
- request.addfinalizer(lambda: myfile.close())
- return myfile
-
requesting values of other funcargs
---------------------------------------------
Modified: py/trunk/py/__init__.py
==============================================================================
--- py/trunk/py/__init__.py (original)
+++ py/trunk/py/__init__.py Sun Jun 28 11:51:40 2009
@@ -19,7 +19,7 @@
"""
from initpkg import initpkg
-version = "1.0.0b3"
+version = "1.0.0b6"
initpkg(__name__,
description = "py.test and pylib: advanced testing tool and networking lib",
Modified: py/trunk/py/execnet/gateway.py
==============================================================================
--- py/trunk/py/execnet/gateway.py (original)
+++ py/trunk/py/execnet/gateway.py Sun Jun 28 11:51:40 2009
@@ -230,7 +230,7 @@
from sys import exc_info
channel, (source, outid, errid) = item
try:
- loc = { 'channel' : channel }
+ loc = { 'channel' : channel, '__name__': '__channelexec__'}
self._trace("execution starts:", repr(source)[:50])
close = self._local_redirect_thread_output(outid, errid)
try:
Modified: py/trunk/py/execnet/testing/test_gateway.py
==============================================================================
--- py/trunk/py/execnet/testing/test_gateway.py (original)
+++ py/trunk/py/execnet/testing/test_gateway.py Sun Jun 28 11:51:40 2009
@@ -92,6 +92,11 @@
def test_repr_doesnt_crash(self):
assert isinstance(repr(self), str)
+ def test_attribute__name__(self):
+ channel = self.gw.remote_exec("channel.send(__name__)")
+ name = channel.receive()
+ assert name == "__channelexec__"
+
def test_correct_setup_no_py(self):
channel = self.gw.remote_exec("""
import sys
Modified: py/trunk/py/io/stdcapture.py
==============================================================================
--- py/trunk/py/io/stdcapture.py (original)
+++ py/trunk/py/io/stdcapture.py Sun Jun 28 11:51:40 2009
@@ -136,6 +136,11 @@
readline = read
readlines = read
__iter__ = read
+
+ def fileno(self):
+ raise ValueError("redirected Stdin is pseudofile, has no fileno()")
+ def isatty(self):
+ return False
try:
devnullpath = os.devnull
Modified: py/trunk/py/io/testing/test_stdcapture.py
==============================================================================
--- py/trunk/py/io/testing/test_stdcapture.py (original)
+++ py/trunk/py/io/testing/test_stdcapture.py Sun Jun 28 11:51:40 2009
@@ -1,6 +1,15 @@
import os, sys
import py
+def test_dontreadfrominput():
+ from py.__.io.stdcapture import DontReadFromInput
+ f = DontReadFromInput()
+ assert not f.isatty()
+ py.test.raises(IOError, f.read)
+ py.test.raises(IOError, f.readlines)
+ py.test.raises(IOError, iter, f)
+ py.test.raises(ValueError, f.fileno)
+
class TestStdCapture:
def getcapture(self, **kw):
return py.io.StdCapture(**kw)
Modified: py/trunk/py/test/collect.py
==============================================================================
--- py/trunk/py/test/collect.py (original)
+++ py/trunk/py/test/collect.py Sun Jun 28 11:51:40 2009
@@ -204,7 +204,7 @@
def _matchonekeyword(self, key, chain):
elems = key.split(".")
# XXX O(n^2), anyone cares?
- chain = [item._keywords() for item in chain if item._keywords()]
+ chain = [item.readkeywords() for item in chain if item._keywords()]
for start, _ in enumerate(chain):
if start + len(elems) > len(chain):
return False
Modified: py/trunk/py/test/funcargs.py
==============================================================================
--- py/trunk/py/test/funcargs.py (original)
+++ py/trunk/py/test/funcargs.py Sun Jun 28 11:51:40 2009
@@ -113,7 +113,7 @@
val = setup()
cache[cachekey] = val
if teardown is not None:
- self.addfinalizer(lambda: teardown(val), scope=scope)
+ self._addfinalizer(lambda: teardown(val), scope=scope)
return val
def getfuncargvalue(self, argname):
@@ -142,10 +142,14 @@
return None
raise ValueError("unknown finalization scope %r" %(scope,))
- def addfinalizer(self, finalizer, scope="function"):
+ def _addfinalizer(self, finalizer, scope):
colitem = self._getscopeitem(scope)
self.config._setupstate.addfinalizer(finalizer=finalizer, colitem=colitem)
+ def addfinalizer(self, finalizer):
+ """ call the given finalizer after test function finished execution. """
+ self._addfinalizer(finalizer, scope="function")
+
def __repr__(self):
return "<FuncargRequest for %r>" %(self._pyfuncitem)
Modified: py/trunk/py/test/plugin/pytest_runner.py
==============================================================================
--- py/trunk/py/test/plugin/pytest_runner.py (original)
+++ py/trunk/py/test/plugin/pytest_runner.py Sun Jun 28 11:51:40 2009
@@ -19,11 +19,14 @@
action="store_true", dest="boxed", default=False,
help="box each test run in a separate process")
+# XXX move to pytest_sessionstart and fix py.test owns tests
def pytest_configure(config):
config._setupstate = SetupState()
-def pytest_unconfigure(config):
- config._setupstate.teardown_all()
+def pytest_sessionfinish(session, exitstatus, excrepr=None):
+ # XXX see above
+ if hasattr(session.config, '_setupstate'):
+ session.config._setupstate.teardown_all()
def pytest_make_collect_report(collector):
call = collector.config.guardedcall(
Modified: py/trunk/py/test/plugin/pytest_terminal.py
==============================================================================
--- py/trunk/py/test/plugin/pytest_terminal.py (original)
+++ py/trunk/py/test/plugin/pytest_terminal.py Sun Jun 28 11:51:40 2009
@@ -204,6 +204,7 @@
msg = "python: platform %s -- Python %s" % (sys.platform, verinfo)
if self.config.option.verbose or self.config.option.debug:
msg += " -- " + str(sys.executable)
+ msg += " -- pytest-%s" % (py.__version__)
self.write_line(msg)
if self.config.option.debug or self.config.option.traceconfig:
@@ -227,7 +228,8 @@
for i, testarg in py.builtin.enumerate(self.config.args):
self.write_line("test object %d: %s" %(i+1, testarg))
- def pytest_sessionfinish(self, session, exitstatus, excrepr=None):
+ def pytest_sessionfinish(self, __call__, session, exitstatus, excrepr=None):
+ __call__.execute()
self._tw.line("")
if exitstatus in (0, 1, 2):
self.summary_failures()
Modified: py/trunk/py/test/pycollect.py
==============================================================================
--- py/trunk/py/test/pycollect.py (original)
+++ py/trunk/py/test/pycollect.py Sun Jun 28 11:51:40 2009
@@ -133,11 +133,11 @@
res = self._deprecated_join(name)
if res is not None:
return res
- if obj.func_code.co_flags & 32: # generator function
+ if is_generator(obj):
# XXX deprecation warning
return self.Generator(name, parent=self)
- else:
- return self._genfunctions(name, obj)
+ else:
+ return self._genfunctions(name, obj)
def _genfunctions(self, name, funcobj):
module = self.getparent(Module).obj
@@ -152,6 +152,12 @@
return self.Function(name, parent=self)
return funcargs.FunctionCollector(name=name,
parent=self, calls=metafunc._calls)
+
+def is_generator(func):
+ try:
+ return (func.func_code.co_flags & 32) # generator function
+ except AttributeError: # c / builtin functions have no func_code
+ return False
class Module(py.test.collect.File, PyCollectorMixin):
def _getobj(self):
Modified: py/trunk/py/test/testing/test_funcargs.py
==============================================================================
--- py/trunk/py/test/testing/test_funcargs.py (original)
+++ py/trunk/py/test/testing/test_funcargs.py Sun Jun 28 11:51:40 2009
@@ -163,15 +163,11 @@
req._fillfuncargs()
assert item.funcargs == {'something': 1}
- def test_request_addfinalizer_scopes(self, testdir):
+ def test_request_addfinalizer(self, testdir):
item = testdir.getitem("""
teardownlist = []
def pytest_funcarg__something(request):
- for scope in ("function", "module", "session"):
- request.addfinalizer(
- lambda x=scope: teardownlist.append(x),
- scope=scope)
-
+ request.addfinalizer(lambda: teardownlist.append(1))
def test_func(something): pass
""")
req = funcargs.FuncargRequest(item)
@@ -183,16 +179,7 @@
assert not teardownlist
ss.teardown_exact(item)
print ss.stack
- assert teardownlist == ['function']
- ss.teardown_exact(item.parent)
- assert teardownlist == ['function', 'module']
- ss.teardown_all()
- assert teardownlist == ['function', 'module', 'session']
-
- def test_request_addfinalizer_unknown_scope(self, testdir):
- item = testdir.getitem("def test_func(): pass")
- req = funcargs.FuncargRequest(item)
- py.test.raises(ValueError, "req.addfinalizer(None, scope='xyz')")
+ assert teardownlist == [1]
def test_request_getmodulepath(self, testdir):
modcol = testdir.getmodulecol("def test_somefunc(): pass")
@@ -200,7 +187,6 @@
req = funcargs.FuncargRequest(item)
assert req.fspath == modcol.fspath
-
class TestRequestCachedSetup:
def test_request_cachedsetup(self, testdir):
item1,item2 = testdir.getitems("""
Modified: py/trunk/py/test/testing/test_genitems.py
==============================================================================
--- py/trunk/py/test/testing/test_genitems.py (original)
+++ py/trunk/py/test/testing/test_genitems.py Sun Jun 28 11:51:40 2009
@@ -121,3 +121,16 @@
item = dlist[0].items[0]
assert item.name == "test_one"
+
+ def test_keyword_extra(self, testdir):
+ p = testdir.makepyfile("""
+ def test_one():
+ assert 0
+ test_one.mykeyword = True
+ """)
+ reprec = testdir.inline_run("-k", "-mykeyword", p)
+ passed, skipped, failed = reprec.countoutcomes()
+ assert passed + skipped + failed == 0
+ reprec = testdir.inline_run("-k", "mykeyword", p)
+ passed, skipped, failed = reprec.countoutcomes()
+ assert failed == 1
Modified: py/trunk/setup.py
==============================================================================
--- py/trunk/setup.py (original)
+++ py/trunk/setup.py Sun Jun 28 11:51:40 2009
@@ -1,16 +1,16 @@
"""
- setup file for 'py' package based on:
-
- https://codespeak.net/svn/py/trunk, revision=65224
-
- autogenerated by gensetup.py
+autogenerated by gensetup.py
+setup file for 'py' package based on:
+
+revision: 1181:8a8203ee5eb85837b6a40d95d861af42008d1a4c
+
"""
import os, sys
import ez_setup
ez_setup.use_setuptools()
-from setuptools import setup, Extension
-
+from setuptools import setup
+
long_description = """
advanced testing and development support library:
@@ -35,7 +35,7 @@
name='py',
description='py.test and pylib: advanced testing tool and networking lib',
long_description = long_description,
- version='1.0.0b3',
+ version='1.0.0b5',
url='http://pylib.org',
license='MIT license',
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
@@ -60,9 +60,7 @@
'Topic :: System :: Distributed Computing',
'Topic :: Utilities',
'Programming Language :: Python'],
- packages=['example.funcarg.mysetup',
- 'example.funcarg.mysetup2',
- 'py',
+ packages=['py',
'py.builtin',
'py.builtin.testing',
'py.cmdline',
More information about the pytest-commit
mailing list