diff --git a/.gitignore b/.gitignore index df93547..e1033af 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ lib include man parts +*.egg-info/ __pycache__ .* @@ -13,3 +14,7 @@ __pycache__ *.pyc *.pyo *.so + +coverage.xml +htmlcov/ +eggs/ diff --git a/.travis.yml b/.travis.yml index dce0257..72e76ff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,29 @@ language: python +sudo: false python: - 2.7 + - 3.4 + - 3.5 + - 3.6 + install: - - python bootstrap.py - - bin/buildout + - pip install six==1.10.0 # force here to avoid conflict with zc.recipe.testrunner + - pip install -U setuptools==33.1.1 + - pip install coveralls coverage + - pip install zc.buildout + - buildout bootstrap + - buildout + script: - - bin/test -v1 + - coverage run bin/test -v1 +after_success: + - coverage combine + - coveralls + notifications: email: false + +cache: + pip: true + directories: + - eggs/ diff --git a/CHANGES.rst b/CHANGES.rst index 538d3bb..36283a6 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -6,6 +6,12 @@ Changelog - Zope trunk compatibility for product init. +- Fix _findModificationTime for ZODB 5 + [davisagli] + +- Add Support for Python 3 + [rudaporto, pbauer, icemac, davisagli] + 1.1.3 - 2010-10-02 ------------------ diff --git a/bootstrap.py b/bootstrap.py new file mode 100644 index 0000000..a629566 --- /dev/null +++ b/bootstrap.py @@ -0,0 +1,189 @@ +############################################################################## +# +# Copyright (c) 2006 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Bootstrap a buildout-based project + +Simply run this script in a directory containing a buildout.cfg. +The script accepts buildout command-line options, so you can +use the -c option to specify an alternate configuration file. +""" + +import os +import shutil +import sys +import tempfile + +from optparse import OptionParser + +tmpeggs = tempfile.mkdtemp() + +usage = '''\ +[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options] + +Bootstraps a buildout-based project. + +Simply run this script in a directory containing a buildout.cfg, using the +Python that you want bin/buildout to use. + +Note that by using --find-links to point to local resources, you can keep +this script from going over the network. +''' + +parser = OptionParser(usage=usage) +parser.add_option("-v", "--version", help="use a specific zc.buildout version") + +parser.add_option("-t", "--accept-buildout-test-releases", + dest='accept_buildout_test_releases', + action="store_true", default=False, + help=("Normally, if you do not specify a --version, the " + "bootstrap script and buildout gets the newest " + "*final* versions of zc.buildout and its recipes and " + "extensions for you. If you use this flag, " + "bootstrap and buildout will get the newest releases " + "even if they are alphas or betas.")) +parser.add_option("-c", "--config-file", + help=("Specify the path to the buildout configuration " + "file to be used.")) +parser.add_option("-f", "--find-links", + help=("Specify a URL to search for buildout releases")) +parser.add_option("--allow-site-packages", + action="store_true", default=False, + help=("Let bootstrap.py use existing site packages")) +parser.add_option("--setuptools-version", + help="use a specific setuptools version") + + +options, args = parser.parse_args() + +###################################################################### +# load/install setuptools + +try: + if options.allow_site_packages: + import setuptools + import pkg_resources + from urllib.request import urlopen +except ImportError: + from urllib2 import urlopen + +ez = {} +exec(urlopen('https://bootstrap.pypa.io/ez_setup.py').read(), ez) + +if not options.allow_site_packages: + # ez_setup imports site, which adds site packages + # this will remove them from the path to ensure that incompatible versions + # of setuptools are not in the path + import site + # inside a virtualenv, there is no 'getsitepackages'. + # We can't remove these reliably + if hasattr(site, 'getsitepackages'): + for sitepackage_path in site.getsitepackages(): + sys.path[:] = [x for x in sys.path if sitepackage_path not in x] + +setup_args = dict(to_dir=tmpeggs, download_delay=0) + +if options.setuptools_version is not None: + setup_args['version'] = options.setuptools_version + +ez['use_setuptools'](**setup_args) +import setuptools +import pkg_resources + +# This does not (always?) update the default working set. We will +# do it. +for path in sys.path: + if path not in pkg_resources.working_set.entries: + pkg_resources.working_set.add_entry(path) + +###################################################################### +# Install buildout + +ws = pkg_resources.working_set + +cmd = [sys.executable, '-c', + 'from setuptools.command.easy_install import main; main()', + '-mZqNxd', tmpeggs] + +find_links = os.environ.get( + 'bootstrap-testing-find-links', + options.find_links or + ('http://downloads.buildout.org/' + if options.accept_buildout_test_releases else None) + ) +if find_links: + cmd.extend(['-f', find_links]) + +setuptools_path = ws.find( + pkg_resources.Requirement.parse('setuptools')).location + +requirement = 'zc.buildout' +version = options.version +if version is None and not options.accept_buildout_test_releases: + # Figure out the most recent final version of zc.buildout. + import setuptools.package_index + _final_parts = '*final-', '*final' + + def _final_version(parsed_version): + try: + return not parsed_version.is_prerelease + except AttributeError: + # Older setuptools + for part in parsed_version: + if (part[:1] == '*') and (part not in _final_parts): + return False + return True + + index = setuptools.package_index.PackageIndex( + search_path=[setuptools_path]) + if find_links: + index.add_find_links((find_links,)) + req = pkg_resources.Requirement.parse(requirement) + if index.obtain(req) is not None: + best = [] + bestv = None + for dist in index[req.project_name]: + distv = dist.parsed_version + if _final_version(distv): + if bestv is None or distv > bestv: + best = [dist] + bestv = distv + elif distv == bestv: + best.append(dist) + if best: + best.sort() + version = best[-1].version +if version: + requirement = '=='.join((requirement, version)) +cmd.append(requirement) + +import subprocess +if subprocess.call(cmd, env=dict(os.environ, PYTHONPATH=setuptools_path)) != 0: + raise Exception( + "Failed to execute command:\n%s" % repr(cmd)[1:-1]) + +###################################################################### +# Import and run buildout + +ws.add_entry(tmpeggs) +ws.require(requirement) +import zc.buildout.buildout + +if not [a for a in args if '=' not in a]: + args.append('bootstrap') + +# if -c was provided, we push it back into args for buildout' main function +if options.config_file is not None: + args[0:0] = ['-c', options.config_file] + +zc.buildout.buildout.main(args) +shutil.rmtree(tmpeggs) diff --git a/buildout.cfg b/buildout.cfg new file mode 100644 index 0000000..9a8a35b --- /dev/null +++ b/buildout.cfg @@ -0,0 +1,22 @@ +[buildout] +extends = + https://raw.githubusercontent.com/zopefoundation/Zope/master/versions.cfg + https://raw.githubusercontent.com/zopefoundation/Zope/master/sources.cfg +develop = . +parts = interpreter test coverage + +[interpreter] +recipe = zc.recipe.egg +interpreter = python +eggs = + AccessControl + tox + +[test] +recipe = zc.recipe.testrunner +eggs = Products.ZopeVersionControl + +[coverage] +recipe = zc.recipe.testrunner +eggs = Products.ZopeVersionControl +defaults = ['--coverage', '../../coverage', '-v', '--auto-progress'] diff --git a/setup.py b/setup.py index 8274357..f70d0e3 100755 --- a/setup.py +++ b/setup.py @@ -12,6 +12,10 @@ 'Framework :: Zope2', 'Programming Language :: Python', 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', ], license='ZPL', author='Zope Foundation and Contributors', @@ -28,7 +32,8 @@ 'Acquisition', 'DateTime', 'transaction', - 'ZODB3', + 'six', + 'ZODB', 'Zope2', ], ) diff --git a/src/Products/ZopeVersionControl/EventLog.py b/src/Products/ZopeVersionControl/EventLog.py index ca80bb6..ba1216c 100644 --- a/src/Products/ZopeVersionControl/EventLog.py +++ b/src/Products/ZopeVersionControl/EventLog.py @@ -11,11 +11,12 @@ # ############################################################################## +from .Utility import _findUserId from App.class_init import default__class_init__ as InitializeClass -from Persistence import Persistent from AccessControl import ClassSecurityInfo from BTrees.IOBTree import IOBTree -from Utility import _findUserId +from Persistence import Persistent + import time MAX32 = int(2**31 - 1) diff --git a/src/Products/ZopeVersionControl/Repository.py b/src/Products/ZopeVersionControl/Repository.py index bb8bfc3..b5a93dd 100644 --- a/src/Products/ZopeVersionControl/Repository.py +++ b/src/Products/ZopeVersionControl/Repository.py @@ -11,25 +11,22 @@ # ############################################################################## -__version__='$Revision: 1.14 $'[11:-2] - -import time -from random import randint - +from . import Utility +from .EventLog import LogEntry +from .nonversioned import getNonVersionedData, restoreNonVersionedData +from .Utility import isAVersionableResource, VersionControlError, VersionInfo +from .Utility import use_vc_permission, _findPath +from .ZopeVersionHistory import ZopeVersionHistory +from AccessControl import ClassSecurityInfo from Acquisition import Implicit, aq_parent, aq_inner -from ZopeVersionHistory import ZopeVersionHistory from App.class_init import default__class_init__ as InitializeClass -from Persistence import Persistent -from AccessControl import ClassSecurityInfo -from Utility import use_vc_permission, _findPath -from Utility import isAVersionableResource, VersionControlError, VersionInfo -from DateTime.DateTime import DateTime -from BTrees.OOBTree import OOBTree from BTrees.OIBTree import OIBTree +from BTrees.OOBTree import OOBTree +from DateTime.DateTime import DateTime +from Persistence import Persistent +from random import randint -from EventLog import LogEntry -import Utility -from nonversioned import getNonVersionedData, restoreNonVersionedData +import time class Repository(Implicit, Persistent): @@ -55,7 +52,7 @@ def createVersionHistory(self, object): # the version or version history yet have a _p_jar, which causes # copy operations to fail. To work around that, we share our _p_jar. history_id = None - while history_id is None or self._histories.has_key(history_id): + while history_id is None or history_id in self._histories: history_id = str(randint(1, 9999999999)) history = ZopeVersionHistory(history_id, object) self._histories[history_id] = history @@ -81,8 +78,8 @@ def replaceState(self, obj, new_state): "The class of the versioned object has changed. %s != %s" % (repr(obj.__class__, new_state.__class__))) obj._p_changed = 1 - for key in obj.__dict__.keys(): - if not new_state.__dict__.has_key(key): + for key in list(obj.__dict__.keys()): + if not key in new_state.__dict__: del obj.__dict__[key] for key, value in new_state.__dict__.items(): obj.__dict__[key] = value @@ -328,23 +325,24 @@ def updateResource(self, object, selector=None): # If the selector is non-null, we find the version specified # and update the sticky tag. Later we'll check the version we # found and decide whether we really need to update the object. - if history.hasVersionId(selector): + if type(selector) is str and history.hasVersionId(selector): version = history.getVersionById(selector) sticky = ('V', selector) - elif self._labels.has_key(selector): + elif type(selector) is str and selector in self._labels: version = history.getVersionByLabel(selector) sticky = ('L', selector) - elif self._branches.has_key(selector): + elif type(selector) is str and selector in self._branches: version = history.getLatestVersion(selector) if selector == 'mainline': sticky = None else: sticky = ('B', selector) else: - try: date = DateTime(selector) - except: + try: + date = DateTime(selector) + except Exception: raise VersionControlError( 'Invalid version selector: %s' % selector ) @@ -386,11 +384,11 @@ def labelResource(self, object, label, force=0): ) # Make sure that labels and branch ids do not collide. - if self._branches.has_key(label) or label == 'mainline': + if label in self._branches or label == 'mainline': raise VersionControlError( 'The label value given is already in use as an activity id.' ) - if not self._labels.has_key(label): + if not label in self._labels: self._labels[label] = 1 history = self.getVersionHistory(info.history_id) @@ -412,17 +410,17 @@ def makeActivity(self, object, branch_id): branch_id = branch_id or None # Make sure that activity ids and labels do not collide. - if self._labels.has_key(branch_id) or branch_id == 'mainline': + if branch_id in self._labels or branch_id == 'mainline': raise VersionControlError( 'The value given is already in use as a version label.' ) - if not self._branches.has_key(branch_id): + if not branch_id in self._branches: self._branches[branch_id] = 1 history = self.getVersionHistory(info.history_id) - if history._branches.has_key(branch_id): + if branch_id in history._branches: raise VersionControlError( 'The resource is already associated with the given activity.' ) @@ -442,11 +440,11 @@ def getVersionOfResource(self, history_id, selector): version = history.getVersionById(selector) sticky = ('V', selector) - elif self._labels.has_key(selector): + elif selector in self._labels: version = history.getVersionByLabel(selector) sticky = ('L', selector) - elif self._branches.has_key(selector): + elif selector in self._branches: version = history.getLatestVersion(selector) sticky = ('B', selector) else: diff --git a/src/Products/ZopeVersionControl/Utility.py b/src/Products/ZopeVersionControl/Utility.py index 08868bd..83d2196 100644 --- a/src/Products/ZopeVersionControl/Utility.py +++ b/src/Products/ZopeVersionControl/Utility.py @@ -70,7 +70,7 @@ def clone(self, clear_sticky=0): for name, value in self.__dict__.items(): dict[name] = value if clear_sticky: - if dict.has_key('sticky'): + if 'sticky' in dict: del dict['sticky'] info.user_id = _findUserId() info.timestamp = time.time() @@ -128,35 +128,31 @@ def _findModificationTime(object): latest = mtime conn = object._p_jar load = conn._storage.load - try: - version = conn._version - except AttributeError: - # ZODB 3.9+ compatibility - version = None refs = referencesf - oids=[object._p_oid] - done_oids={} - done=done_oids.has_key + oids = [object._p_oid] + done_oids = set() + done = done_oids.__contains__ first = 1 while oids: - oid=oids[0] + oid = oids[0] del oids[0] if done(oid): continue - done_oids[oid]=1 - try: p, serial = load(oid, version) - except: pass # invalid reference! + done_oids.add(oid) + try: + p, serial = load(oid) + except Exception: + pass # invalid reference! else: if first is not None: first = None else: - if p.find('U\x0b__vc_info__') == -1: + if p.find(b'U\x0b__vc_info__') == -1: mtime = TimeStamp(serial).timeTime() if mtime > latest: latest = mtime refs(p, oids) return latest - diff --git a/src/Products/ZopeVersionControl/Version.py b/src/Products/ZopeVersionControl/Version.py index ba34131..87296d4 100644 --- a/src/Products/ZopeVersionControl/Version.py +++ b/src/Products/ZopeVersionControl/Version.py @@ -13,20 +13,16 @@ __version__='$Revision: 1.11 $'[11:-2] -import tempfile import time -from cStringIO import StringIO -from cPickle import Pickler, Unpickler -from Acquisition import Implicit, aq_parent, aq_inner, aq_base +from Acquisition import Implicit, aq_base from App.class_init import default__class_init__ as InitializeClass from Persistence import Persistent from AccessControl import ClassSecurityInfo -from BTrees.OOBTree import OOBTree from OFS.SimpleItem import SimpleItem - -from Utility import VersionControlError -from nonversioned import listNonVersionedObjects, removeNonVersionedData +from ZODB._compat import BytesIO +from ZODB._compat import Pickler, Unpickler +from .nonversioned import listNonVersionedObjects, removeNonVersionedData def cloneByPickle(obj, ignore_list=()): @@ -40,7 +36,7 @@ def cloneByPickle(obj, ignore_list=()): ignore_dict[id(o)] = o def persistent_id(ob, ignore_dict=ignore_dict): - if ignore_dict.has_key(id(ob)): + if id(ob) in ignore_dict: return 'ignored' if getattr(ob, '_p_changed', 0) is None: ob._p_changed = 0 @@ -54,7 +50,7 @@ def persistent_load(ref): placeholder.id = "ignored_subobject" return placeholder - stream = StringIO() + stream = BytesIO() p = Pickler(stream, 1) p.persistent_id = persistent_id p.dump(obj) diff --git a/src/Products/ZopeVersionControl/VersionHistory.py b/src/Products/ZopeVersionControl/VersionHistory.py index 7145b68..340a9d5 100644 --- a/src/Products/ZopeVersionControl/VersionHistory.py +++ b/src/Products/ZopeVersionControl/VersionHistory.py @@ -11,18 +11,17 @@ # ############################################################################## -__version__='$Revision: 1.4 $'[11:-2] - -from App.class_init import default__class_init__ as InitializeClass -from Persistence import Persistent +from .EventLog import EventLog, LogEntry +from .Utility import VersionControlError +from .ZopeVersion import ZopeVersion from AccessControl import ClassSecurityInfo -from EventLog import EventLog, LogEntry -from Utility import VersionControlError -from ZopeVersion import ZopeVersion -from BTrees.IOBTree import IOBTree +from Acquisition import Implicit +from App.class_init import default__class_init__ as InitializeClass from BTrees.IIBTree import IIBTree +from BTrees.IOBTree import IOBTree from BTrees.OOBTree import OOBTree -from Acquisition import Implicit +from Persistence import Persistent + import time MAX32 = int(2**31 - 1) @@ -87,7 +86,7 @@ def labelVersion(self, version_id, label, force=0): def createBranch(self, branch_id, version_id): """Create a new branch associated with the given branch_id. The new branch is rooted at the version named by version_id.""" - if self._branches.has_key(branch_id): + if branch_id in self._branches: raise VersionControlError( 'Activity already exists: %s' % branch_id ) @@ -135,7 +134,7 @@ def createVersion(self, object, branch_id): security.declarePrivate('hasVersionId') def hasVersionId(self, version_id): """Return true if history contains a version with the given id.""" - return self._versions.has_key(version_id) + return version_id in self._versions security.declarePrivate('isLatestVersion') def isLatestVersion(self, version_id, branch_id): diff --git a/src/Products/ZopeVersionControl/VersionSupport.py b/src/Products/ZopeVersionControl/VersionSupport.py index 3e80f07..654c226 100644 --- a/src/Products/ZopeVersionControl/VersionSupport.py +++ b/src/Products/ZopeVersionControl/VersionSupport.py @@ -11,13 +11,13 @@ # ############################################################################## -__version__='$Revision: 1.4 $'[11:-2] - -import ExtensionClass, AccessControl, Acquisition +from .Utility import use_vc_permission +from .Utility import VersionControlError, isAVersionableResource from App.class_init import default__class_init__ as InitializeClass from App.special_dtml import DTMLFile -from Utility import VersionControlError, isAVersionableResource -from Utility import use_vc_permission + +import AccessControl +import ExtensionClass class VersionSupport(ExtensionClass.Base): diff --git a/src/Products/ZopeVersionControl/ZopeRepository.py b/src/Products/ZopeVersionControl/ZopeRepository.py index 608c68d..eb50794 100644 --- a/src/Products/ZopeVersionControl/ZopeRepository.py +++ b/src/Products/ZopeVersionControl/ZopeRepository.py @@ -11,12 +11,13 @@ # ############################################################################## +from . import Repository +from .SequenceWrapper import SequenceWrapper from App.class_init import default__class_init__ as InitializeClass from App.special_dtml import DTMLFile -from SequenceWrapper import SequenceWrapper + import AccessControl import OFS -import Repository # BBB Zope 2.12 try: @@ -77,7 +78,7 @@ def __getitem__(self, name): history = self._histories.get(name) if history is not None: return history.__of__(self) - raise KeyError, name + raise KeyError(name) security.declarePrivate('objectIds') def objectIds(self, spec=None): diff --git a/src/Products/ZopeVersionControl/ZopeVersion.py b/src/Products/ZopeVersionControl/ZopeVersion.py index 58b6f5a..97c99a0 100644 --- a/src/Products/ZopeVersionControl/ZopeVersion.py +++ b/src/Products/ZopeVersionControl/ZopeVersion.py @@ -11,10 +11,12 @@ # ############################################################################## +from . import Version from App.class_init import default__class_init__ as InitializeClass from App.special_dtml import DTMLFile -import OFS, AccessControl -import Version + +import OFS +import AccessControl # BBB Zope 2.12 try: diff --git a/src/Products/ZopeVersionControl/ZopeVersionHistory.py b/src/Products/ZopeVersionControl/ZopeVersionHistory.py index a2505a7..f20d557 100644 --- a/src/Products/ZopeVersionControl/ZopeVersionHistory.py +++ b/src/Products/ZopeVersionControl/ZopeVersionHistory.py @@ -11,10 +11,12 @@ # ############################################################################## +from . import VersionHistory from App.class_init import default__class_init__ as InitializeClass from App.special_dtml import DTMLFile -import OFS, AccessControl -import VersionHistory + +import AccessControl +import OFS # BBB Zope 2.12 try: @@ -73,7 +75,7 @@ def __getitem__(self, name): activity = self._branches.get(name) if activity is not None: return activity.__of__(self) - raise KeyError, name + raise KeyError(name) security.declarePrivate('objectIds') def objectIds(self, spec=None): diff --git a/src/Products/ZopeVersionControl/__init__.py b/src/Products/ZopeVersionControl/__init__.py index 4ea203c..ab9128c 100644 --- a/src/Products/ZopeVersionControl/__init__.py +++ b/src/Products/ZopeVersionControl/__init__.py @@ -11,10 +11,11 @@ # ############################################################################## -import ZopeRepository +from . import ZopeRepository from App.class_init import default__class_init__ as InitializeClass from App.ImageFile import ImageFile + def initialize(context): context.registerClass( @@ -35,7 +36,7 @@ def initialize(context): def install_hack(): # Hackery - don't try this at home, kids. :) This is temporary for # testing purposes only. - from VersionSupport import VersionSupport + from .VersionSupport import VersionSupport import OFS.SimpleItem, App.Management method = App.Management.Tabs.filtered_manage_options diff --git a/src/Products/ZopeVersionControl/nonversioned.py b/src/Products/ZopeVersionControl/nonversioned.py index 2120b2b..71e8439 100644 --- a/src/Products/ZopeVersionControl/nonversioned.py +++ b/src/Products/ZopeVersionControl/nonversioned.py @@ -15,13 +15,11 @@ $Id$ """ +from .interfaces import INonVersionedData +from .VersionSupport import isAVersionableResource from Acquisition import aq_base from OFS.ObjectManager import ObjectManager - -from interfaces import INonVersionedData -from VersionSupport import isAVersionableResource -from zope.interface import implements - +from zope.interface import implementer try: # Optional support for references. @@ -69,10 +67,10 @@ def restoreNonVersionedData(obj, dict): +@implementer(INonVersionedData) class StandardNonVersionedDataAdapter: """Non-versioned data adapter for arbitrary things. """ - implements(INonVersionedData) def __init__(self, obj): self.obj = obj @@ -101,14 +99,14 @@ def getNonVersionedData(self): def restoreNonVersionedData(self, data): for attr in self.attrs: - if data.has_key(attr): + if attr in data: setattr(aq_base(self.obj), attr, data[attr]) +@implementer(INonVersionedData) class ObjectManagerNonVersionedDataAdapter(StandardNonVersionedDataAdapter): """Non-versioned data adapter for object managers. """ - implements(INonVersionedData) def listNonVersionedObjects(self): contents = self.getNonVersionedData()['contents'] @@ -124,7 +122,7 @@ def removeNonVersionedData(self): removed[name] = 1 if obj._objects: obj._objects = tuple([info for info in obj._objects - if not removed.has_key(info['id'])]) + if info['id'] not in removed]) def getNonVersionedData(self): contents = {} @@ -154,7 +152,7 @@ def restoreNonVersionedData(self, data): ignore[name] = 1 # Restore the items of the container. for name, value in data['contents'].items(): - if not ignore.has_key(name): + if name not in ignore: obj._setOb(name, aq_base(value)) if not hasattr(obj, '_tree'): # Avoid generating events, since nothing was ever really diff --git a/src/Products/ZopeVersionControl/tests/common.py b/src/Products/ZopeVersionControl/tests/common.py index 0f31478..e6ac615 100644 --- a/src/Products/ZopeVersionControl/tests/common.py +++ b/src/Products/ZopeVersionControl/tests/common.py @@ -26,7 +26,6 @@ def common_setUp(self): # Install a hack to make SimpleItem version aware, so that the # tests work. In normal development, you would mix in the # VersionSupport class on an as-needed basis. - import cStringIO from AccessControl.SecurityManagement import newSecurityManager from OFS.Application import Application from OFS.DTMLDocument import addDTMLDocument @@ -38,7 +37,11 @@ def common_setUp(self): from Products.ZopeVersionControl.ZopeRepository import addRepository from ZODB import DB + from ZODB._compat import PY3 from ZODB.DemoStorage import DemoStorage + + from six import StringIO + s = DemoStorage() self.connection = DB( s ).open() try: @@ -46,7 +49,7 @@ def common_setUp(self): a = Application() r['Application'] = a self.root = a - responseOut = self.responseOut = cStringIO.StringIO() + responseOut = self.responseOut = StringIO() self.app = makerequest( self.root, stdout=responseOut ) self.app.acl_users.userFolderAddUser('UnitTester', '123', (), ()) manage_addFolder(self.app, 'folder1') diff --git a/src/Products/ZopeVersionControl/tests/testReferenceVersioning.py b/src/Products/ZopeVersionControl/tests/testReferenceVersioning.py index 5a4b583..385b535 100644 --- a/src/Products/ZopeVersionControl/tests/testReferenceVersioning.py +++ b/src/Products/ZopeVersionControl/tests/testReferenceVersioning.py @@ -16,8 +16,8 @@ """ import unittest -from common import common_setUp -from common import common_tearDown +from .common import common_setUp +from .common import common_tearDown has_refs = 1 try: diff --git a/src/Products/ZopeVersionControl/tests/testVersionControl.py b/src/Products/ZopeVersionControl/tests/testVersionControl.py index d410bfe..9ce3a08 100644 --- a/src/Products/ZopeVersionControl/tests/testVersionControl.py +++ b/src/Products/ZopeVersionControl/tests/testVersionControl.py @@ -16,10 +16,10 @@ """ import unittest -from common import get_transaction -from common import common_setUp -from common import common_tearDown -from common import common_commit +from .common import get_transaction +from .common import common_setUp +from .common import common_tearDown +from .common import common_commit class VersionControlTests(unittest.TestCase): diff --git a/src/Products/ZopeVersionControl/tests/testVersionHistory.py b/src/Products/ZopeVersionControl/tests/testVersionHistory.py index c40df85..75581a2 100644 --- a/src/Products/ZopeVersionControl/tests/testVersionHistory.py +++ b/src/Products/ZopeVersionControl/tests/testVersionHistory.py @@ -16,8 +16,8 @@ """ import unittest -from common import common_setUp -from common import common_tearDown +from .common import common_setUp +from .common import common_tearDown class VersionHistoryTests(unittest.TestCase): diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..18796b9 --- /dev/null +++ b/tox.ini @@ -0,0 +1,59 @@ +[tox] +envlist = + # flake8, + py27, + py34, + py35, + py36, + # isort, + coverage-report, + +skip_missing_interpreters = False + +[testenv] +usedevelop = True +extras = + develop + test + +install_command = pip install --no-cache-dir --no-binary=:all: {opts} {packages} + +commands = + coverage run {envbindir}/zope-testrunner --path=src --all {posargs:-pvc} +deps = + .[test] + zope.testrunner + coverage +setenv = + PIP_NO_CACHE = 1 + COVERAGE_FILE=.coverage.{envname} + +[testenv:coverage-report] +basepython = python2.7 +deps = coverage +setenv = + COVERAGE_FILE=.coverage +skip_install = true +commands = + coverage erase + coverage combine + coverage html -i + coverage xml -i + coverage report -i + +[testenv:isort] +basepython = python2.7 +deps = isort +commands = + isort --check-only --recursive {toxinidir}/src {toxinidir}/tests {posargs} + +[testenv:isort-apply] +basepython = python2.7 +deps = isort +commands = + isort --apply --recursive {toxinidir}/src {toxinidir}/tests {posargs} + +[testenv:flake8] +basepython = python2.7 +deps = flake8 +commands = flake8 --doctests src tests setup.py