From 509000a9961b225598ef609c0387f85ba6c02d1b Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Wed, 25 Sep 2024 10:58:27 +0200 Subject: [PATCH] Python3 fixes for expert tests (+dependencies) --- loops/expert/README.txt | 14 +++---- loops/expert/concept.py | 2 +- loops/expert/filter.py | 31 +++------------- loops/expert/instance.py | 28 ++------------ loops/expert/report.py | 31 +++------------- loops/expert/search.txt | 45 ++++++++++++----------- loops/expert/tests.py | 2 +- loops/expert/testsetup.py | 7 ++-- loops/external/annotation.py | 27 ++------------ loops/external/base.py | 33 +++-------------- loops/external/element.py | 4 +- loops/external/pyfunc.py | 35 ++++-------------- loops/knowledge/knowledge.py | 36 ++++-------------- loops/knowledge/qualification/__init__.py | 7 ++-- loops/knowledge/qualification/base.py | 26 ++----------- loops/knowledge/survey/base.py | 35 ++++-------------- loops/organize/task.py | 34 ++++------------- loops/setup.py | 9 +++-- loops/util.py | 9 +++-- 19 files changed, 108 insertions(+), 307 deletions(-) diff --git a/loops/expert/README.txt b/loops/expert/README.txt index 35fe082..bfcf6e7 100644 --- a/loops/expert/README.txt +++ b/loops/expert/README.txt @@ -5,8 +5,6 @@ loops - Linked Objects for Organization and Processing Services The loops expert - knows what is in a loops site and how to make use of it. - ($Id$) - Setting up a loops Site and Utilities ===================================== @@ -88,7 +86,7 @@ corresponding adapter and activate it for the current loops site. We have now to reindex all documents so that the state index gets populated according to the new settings. - >>> from zope.app.catalog.interfaces import ICatalog + >>> from zope.catalog.interfaces import ICatalog >>> catalog = component.getUtility(ICatalog) >>> from loops import util >>> for r in resources.values(): @@ -152,7 +150,7 @@ filtering the results; this defaults to ``canListObjects``. >>> from loops.expert.query import getObjects >>> objs = getObjects(query.Title('ty*').apply(), root=loopsRoot) >>> sorted(o.title for o in objs) - [u'Document Type', u'Type', u'has Type'] + ['Document Type', 'Type', 'has Type'] Filters @@ -180,19 +178,19 @@ concepts) that are direct or indirect children of jim. >>> qu = query.Type('loops:resource:textdocument') >>> objs = getObjects(qu.apply()) >>> sorted(o.title for o in objs) - [u'Doc 001', u'Doc 002', u'Doc 003'] + ['Doc 001', 'Doc 002', 'Doc 003'] >>> from loops.expert import filter >>> fltr = filter.Children(jim, recursive=True, includeResources=True) >>> sorted(o.title for o in getObjects((qu & fltr.query()).apply())) - [u'Doc 001', u'Doc 003'] + ['Doc 001', 'Doc 003'] >>> #fltr.check(resources['d001.txt']) >>> #fltr.check(resources['d002.txt']) >>> r1 = qu.apply() >>> r2 = fltr.apply(dict(zip(r1, getObjects(r1)))) >>> sorted(o.title for o in r2.values()) - [u'Doc 001', u'Doc 003'] + ['Doc 001', 'Doc 003'] Organizing Queries and Filters with Query Instances @@ -235,7 +233,7 @@ Reports >>> from loops.expert.report import ReportTypeSourceList >>> source = ReportTypeSourceList(report) >>> list(source) - [(u'default_concept_report', u'Default Concept Report')] + [('default_concept_report', 'Default Concept Report')] Fin de partie diff --git a/loops/expert/concept.py b/loops/expert/concept.py index c639ded..5bc3854 100644 --- a/loops/expert/concept.py +++ b/loops/expert/concept.py @@ -117,7 +117,7 @@ class FullQuery(BaseQuery): return ScoredSet(result, scores) if text or type != 'loops:*': # TODO: this may be highly inefficient! cat = self.catalog - if isinstance(type, basestring): + if isinstance(type, str): type = [type] for tp in type: if tp.endswith('*'): diff --git a/loops/expert/filter.py b/loops/expert/filter.py index 4ae52b0..47af215 100644 --- a/loops/expert/filter.py +++ b/loops/expert/filter.py @@ -1,29 +1,10 @@ -# -# Copyright (c) 2008 Helmut Merz helmutm@cy55.de -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# +# loops.expert.filter -""" -Filter query results. - -$Id$ +""" Filter query results. """ from BTrees.IOBTree import IOBTree -from zope.interface import implements +from zope.interface import implementer from cybertools.catalog.query import And from loops.expert.interfaces import IFilter @@ -31,10 +12,9 @@ from loops.expert.query import Children as ChildrenQuery from loops import util +@implementer(IFilter) class Filter(object): - implements(IFilter) - query = None def __init__(self, **kw): @@ -54,10 +34,9 @@ class Filter(object): return uid in self.query().apply() #.keys() +@implementer(IFilter) class Children(Filter): - implements(IFilter) - def __init__(self, parent, **kw): self.parent = parent super(Children, self).__init__(**kw) diff --git a/loops/expert/instance.py b/loops/expert/instance.py index 403f63b..30d090c 100644 --- a/loops/expert/instance.py +++ b/loops/expert/instance.py @@ -1,36 +1,16 @@ -# -# Copyright (c) 2008 Helmut Merz helmutm@cy55.de -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# +# loops.expert.instance -""" -Filter query results. - -$Id$ +""" Filter query results. """ -from zope.interface import implements +from zope.interface import implementer from loops.expert.interfaces import IQueryInstance +@implementer(IQueryInstance) class QueryInstance(object): - implements(IQueryInstance) - def __init__(self, query, *filters, **kw): self.query = query self.filters = filters diff --git a/loops/expert/report.py b/loops/expert/report.py index 068d548..4ebf9dd 100644 --- a/loops/expert/report.py +++ b/loops/expert/report.py @@ -1,28 +1,11 @@ -# -# Copyright (c) 2017 Helmut Merz helmutm@cy55.de -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# +# loops.expert.report -""" -Report type, report concept adapter, and other reporting stuff. +""" Report type, report concept adapter, and other reporting stuff. """ from zope import schema, component from zope.component import adapts -from zope.interface import Interface, Attribute, implements +from zope.interface import Interface, Attribute, implementer from zope.cachedescriptors.property import Lazy from zope.security.proxy import removeSecurityProxy from zope.traversing.api import getName @@ -67,10 +50,9 @@ class IReportInstance(IBaseReport): # report concept adapter and instances +@implementer(IReport) class Report(QueryConcept): - implements(IReport) - _contextAttributes = list(IReport) @Lazy @@ -80,9 +62,9 @@ class Report(QueryConcept): TypeInterfaceSourceList.typeInterfaces += (IReport,) +@implementer(IReportInstance) class ReportInstance(BaseReport): - implements(IReportInstance) adapts(IReport) rowFactory = Row @@ -144,10 +126,9 @@ class ReportInstance(BaseReport): return self.conceptManager['hasreport'] +@implementer(schema.interfaces.IIterableSource) class ReportTypeSourceList(object): - implements(schema.interfaces.IIterableSource) - def __init__(self, context): self.context = context diff --git a/loops/expert/search.txt b/loops/expert/search.txt index 24fa04b..ee33a0d 100755 --- a/loops/expert/search.txt +++ b/loops/expert/search.txt @@ -2,8 +2,6 @@ loops.search - Provide search functionality for the loops framework =================================================================== - ($Id$) - Let's do some basic set up @@ -11,7 +9,6 @@ Let's do some basic set up >>> site = placefulSetUp(True) >>> from zope import component, interface - >>> from zope.interface import implements and setup a simple loops site with a concept manager and some concepts (with all the type machinery, what in real life is done via standard @@ -32,7 +29,7 @@ ZCML setup): In addition we create a concept that holds the search page and a node (page) that links to this concept: - >>> search = concepts['search'] = Concept(u'Search') + >>> search = concepts['search'] = Concept('Search') >>> search.conceptType = query >>> from loops.view import Node @@ -105,13 +102,13 @@ resource we can search for and index it in the catalog. >>> from loops.resource import Resource >>> rplone = resources['plone'] = Resource() - >>> from zope.app.catalog.interfaces import ICatalog + >>> from zope.catalog.interfaces import ICatalog >>> from loops import util >>> catalog = component.getUtility(ICatalog) >>> catalog.index_doc(int(util.getUidForObject(rplone)), rplone) >>> from loops.expert.browser.search import SearchResults - >>> form = {'search.2.title': True, 'search.2.text': u'plone'} + >>> form = {'search.2.title': True, 'search.2.text': 'plone'} >>> request = TestRequest(form=form) >>> resultsView = SearchResults(page, request) @@ -121,7 +118,7 @@ resource we can search for and index it in the catalog. >>> results[0].context == rplone True - >>> form = {'search.2.title': True, 'search.2.text': u'foo'} + >>> form = {'search.2.title': True, 'search.2.text': 'foo'} >>> request = TestRequest(form=form) >>> resultsView = SearchResults(page, request) >>> len(list(resultsView.results)) @@ -133,10 +130,10 @@ Search via related concepts We first have to prepare some test concepts (topics); we also assign our test resource (rplone) from above to one of the topics: - >>> czope = concepts['zope'] = Concept(u'Zope') - >>> czope2 = concepts['zope2'] = Concept(u'Zope 2') - >>> czope3 = concepts['zope3'] = Concept(u'Zope 3') - >>> cplone = concepts['plone'] = Concept(u'Plone') + >>> czope = concepts['zope'] = Concept('Zope') + >>> czope2 = concepts['zope2'] = Concept('Zope 2') + >>> czope3 = concepts['zope3'] = Concept('Zope 3') + >>> cplone = concepts['plone'] = Concept('Plone') >>> for c in (czope, czope2, czope3, cplone): ... c.conceptType = topic ... catalog.index_doc(int(util.getUidForObject(c)), c) @@ -157,7 +154,7 @@ with them: >>> len(results) 5 >>> results[0].context.__name__ - u'plone' + 'plone' >>> uid = util.getUidForObject(concepts['zope3']) >>> form = {'search.3.type': 'loops:concept:topic', 'search.3.text': uid} @@ -167,17 +164,19 @@ with them: >>> len(results) 1 >>> results[0].context.__name__ - u'zope3' + 'zope3' To support easy entry of concepts to search for we can preselect the available concepts (optionally restricted to a certain type) by entering text parts of the concepts' titles: - >>> form = {'searchType': 'loops:concept:topic', 'name': u'zope'} + >>> form = {'searchType': 'loops:concept:topic', 'name': 'zope'} >>> request = TestRequest(form=form) >>> view = Search(page, request) >>> view.listConcepts() - '{"items": [{"id": "...", "name": "Zope", "label": "Zope (Thema)"}, {"id": "...", "name": "Zope 2", "label": "Zope 2 (Thema)"}, {"id": "...", "name": "Zope 3", "label": "Zope 3 (Thema)"}], "identifier": "id"}' + '{"identifier": "id", "items": [{...}]}' + +'{"items": [{"id": "...", "name": "Zope", "label": "Zope (Thema)"}, {"id": "...", "name": "Zope 2", "label": "Zope 2 (Thema)"}, {"id": "...", "name": "Zope 3", "label": "Zope 3 (Thema)"}], "identifier": "id"}' Preset Concept Types on Search Forms ------------------------------------ @@ -215,21 +214,23 @@ and thus include the customer type in the preset search types. ('concept', 'search') >>> searchView = Search(search, TestRequest()) >>> list(searchView.presetSearchTypes) - [{'token': 'loops:concept:customer', 'title': u'Customer'}] + [{'token': 'loops:concept:customer', 'title': 'Customer'}] >>> searchView.conceptsForType('loops:concept:customer') - [{'token': 'none', 'title': u'not selected'}, - {'token': '...', 'title': u'Customer 1'}, - {'token': '...', 'title': u'Customer 2'}, - {'token': '...', 'title': u'Customer 3'}] + [{'token': 'none', 'title': 'not selected'}, + {...}, {...}, {...}] + +{'token': '...', 'title': 'Customer 1'}, +{'token': '...', 'title': 'Customer 2'}, +{'token': '...', 'title': 'Customer 3'}] Let's use this new search option for querying: - >>> form = {'search.4.text_selected': u'75'} + >>> form = {'search.4.text_selected': '75'} >>> resultsView = SearchResults(page, TestRequest(form=form)) >>> results = list(resultsView.results) >>> results[0].title - u'Customer 1' + 'Customer 1' Automatic Filtering diff --git a/loops/expert/tests.py b/loops/expert/tests.py index f5f2453..95827ba 100755 --- a/loops/expert/tests.py +++ b/loops/expert/tests.py @@ -5,7 +5,7 @@ try: from loops.expert import query ignore = False except ImportError: - print 'Skipping loops.expert' + print('Skipping loops.expert') ignore = True class Test(unittest.TestCase): diff --git a/loops/expert/testsetup.py b/loops/expert/testsetup.py index 05d8b5e..7d7d8c4 100644 --- a/loops/expert/testsetup.py +++ b/loops/expert/testsetup.py @@ -1,11 +1,10 @@ -""" -Set up a loops site for testing. +# loops.expert.testsetup -$Id$ +""" Set up a loops site for testing. """ from zope import component -from zope.app.catalog.interfaces import ICatalog +from zope.catalog.interfaces import ICatalog from cybertools.typology.interfaces import IType from loops import util diff --git a/loops/external/annotation.py b/loops/external/annotation.py index cb25990..665f23e 100644 --- a/loops/external/annotation.py +++ b/loops/external/annotation.py @@ -1,32 +1,13 @@ -# -# Copyright (c) 2008 Helmut Merz helmutm@cy55.de -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# +# loops.external.annotation -""" -Export/import of annotations. - -$Id$ +""" Export/import of annotations. """ from datetime import datetime import time from zope.component import adapts from zope.dublincore.interfaces import IZopeDublinCore -from zope.interface import implements +from zope.interface import implementer from loops.external.element import Element, elementTypes from loops.external.interfaces import ISubExtractor @@ -51,9 +32,9 @@ class AnnotationsElement(Element): setattr(dc, k, v) +@implementer(ISubExtractor) class AnnotationsExtractor(object): - implements(ISubExtractor) adapts(ILoopsObject) dcAttributes = ('title', 'description', 'creators', 'created', 'modified') diff --git a/loops/external/base.py b/loops/external/base.py index 3fa71a8..a8da791 100644 --- a/loops/external/base.py +++ b/loops/external/base.py @@ -1,35 +1,16 @@ -# -# Copyright (c) 2010 Helmut Merz helmutm@cy55.de -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# +# loops.external.base -""" -Reading and writing loops objects (represented by IElement objects) +""" Reading and writing loops objects (represented by IElement objects) in Python function notation. - -$Id$ """ -from cStringIO import StringIO +from io import StringIO import itertools import os, sys import zdaemon from zope import component from zope.cachedescriptors.property import Lazy -from zope.interface import implements +from zope.interface import implementer from zope.traversing.api import getName, getParent from cybertools.composer.interfaces import IInstance @@ -73,10 +54,9 @@ class Base(object): return self.concepts.getTypePredicate() +@implementer(ILoader) class Loader(Base, BaseLoader, SetupManager): - implements(ILoader) - def __init__(self, context, resourceDirectory=None): #super(Loader, self).__init__(context, resourceDirectory) Base.__init__(self, context, resourceDirectory) @@ -89,10 +69,9 @@ class Loader(Base, BaseLoader, SetupManager): # def addConcept(self, ...): +@implementer(IExtractor) class Extractor(Base): - implements(IExtractor) - count = 0 def extract(self): diff --git a/loops/external/element.py b/loops/external/element.py index 9bc0b2e..d32a9a8 100644 --- a/loops/external/element.py +++ b/loops/external/element.py @@ -99,7 +99,7 @@ class TypeElement(ConceptElement): super(TypeElement, self).__init__(name, title, *args, **kw) ti = self.get('typeInterface') if ti: - if not isinstance(ti, basestring): + if not isinstance(ti, str): self['typeInterface'] = '.'.join((ti.__module__, ti.__name__)) def execute(self, loader): @@ -125,7 +125,7 @@ class RecordManagerElement(Element): def __init__(self, name, trackFactory, **kw): self['name'] = name tf = self['trackFactory'] = trackFactory - if not isinstance(tf, basestring): + if not isinstance(tf, str): self['trackFactory'] = '.'.join((tf.__module__, tf.__name__)) for k, v in kw.items(): self[k] = v diff --git a/loops/external/pyfunc.py b/loops/external/pyfunc.py index b4f7969..4e1bf89 100644 --- a/loops/external/pyfunc.py +++ b/loops/external/pyfunc.py @@ -1,50 +1,30 @@ -# -# Copyright (c) 2008 Helmut Merz helmutm@cy55.de -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# +# loops.external.pyfunc -""" -Reading and writing loops objects (represented by IElement objects) +""" Reading and writing loops objects (represented by IElement objects) in Python function notation. - -$Id$ """ from zope.cachedescriptors.property import Lazy -from zope.interface import implements +from zope.interface import implementer from loops.external.interfaces import IReader, IWriter from loops.external.element import elementTypes, toplevelElements +@implementer(IReader) class PyReader(object): - implements(IReader) - def read(self, input): if not isinstance(input, str): input = input.read() proc = InputProcessor() - exec input in proc + exec(input, proc) return proc.elements class InputProcessor(dict): - _constants = dict(True=True, False=False) + _constants = {'True': True, 'False': False} def __init__(self): self.elements = [] @@ -61,10 +41,9 @@ class InputProcessor(dict): return factory +@implementer(IWriter) class PyWriter(object): - implements(IWriter) - def write(self, elements, output, level=0): for idx, element in enumerate(elements): args = [] diff --git a/loops/knowledge/knowledge.py b/loops/knowledge/knowledge.py index e65cb9b..6b9a05c 100644 --- a/loops/knowledge/knowledge.py +++ b/loops/knowledge/knowledge.py @@ -1,29 +1,12 @@ -# -# Copyright (c) 2012 Helmut Merz helmutm@cy55.de -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# +# loops.knowledge.knowledge -""" -Adapters for IConcept providing interfaces from the +""" Adapters for IConcept providing interfaces from the cybertools.knowledge package. """ from zope import interface, component from zope.component import adapts -from zope.interface import implements +from zope.interface import implementer from zope.cachedescriptors.property import Lazy from cybertools.typology.interfaces import IType @@ -75,6 +58,7 @@ class KnowledgeAdapterMixin(object): return self.context == other.context +@implementer(IPerson) class Person(BasePerson, Knowing, KnowledgeAdapterMixin): """ A typeInterface adapter for concepts of type 'person', including knowledge/learning management features. @@ -85,8 +69,6 @@ class Person(BasePerson, Knowing, KnowledgeAdapterMixin): knowledge = ParentRelationSetProperty('knows') - implements(IPerson) - def getKnowledge(self): return (IKnowledgeElement(c) for c in self.context.getParents((self.knowsPred,))) @@ -98,12 +80,12 @@ class Person(BasePerson, Knowing, KnowledgeAdapterMixin): self.context.deassignParent(obj.context, (self.knowsPred,)) +@implementer(ITopic) class Topic(I18NAdapterBase, KnowledgeAdapterMixin): """ A typeInterface adapter for concepts of type 'topic' that may act as a knowledge element. """ - implements(ITopic) _adapterAttributes = I18NAdapterBase._adapterAttributes + ('parent',) def getParent(self): @@ -140,13 +122,12 @@ class Topic(I18NAdapterBase, KnowledgeAdapterMixin): + self.context.getResources((self.providesPred,))) +@implementer(ITask) class Task(BaseTask, KnowledgeAdapterMixin): """ A typeInterface adapter for concepts of type 'task' that may act as a knowledge requirement profile. """ - implements(ITask) - _adapterAttributes = BasePerson._adapterAttributes + ('requirements',) _noexportAttributes = ('requirements',) @@ -183,10 +164,9 @@ class Task(BaseTask, KnowledgeAdapterMixin): return sorted(result, key=lambda x: (-x['fit'], x['person'].title)) +@implementer(IKnowledgeProvider) class ConceptKnowledgeProvider(AdapterBase, KnowledgeAdapterMixin): - implements(IKnowledgeProvider) - def getProvidedKnowledge(self): return (IKnowledgeElement(c) for c in self.context.getParents((self.providesPred,))) @@ -198,9 +178,9 @@ class ConceptKnowledgeProvider(AdapterBase, KnowledgeAdapterMixin): self.context.deassignParent(obj.context, (self.providesPred,)) +@implementer(IKnowledgeProvider) class ResourceKnowledgeProvider(AdapterBase, KnowledgeAdapterMixin): - implements(IKnowledgeProvider) adapts(IResource) def getProvidedKnowledge(self): diff --git a/loops/knowledge/qualification/__init__.py b/loops/knowledge/qualification/__init__.py index 5b21388..cc3464b 100644 --- a/loops/knowledge/qualification/__init__.py +++ b/loops/knowledge/qualification/__init__.py @@ -1,17 +1,16 @@ '''package loops.knowledge.qualification''' from zope.component import adapts -from zope.interface import implementer, implements +from zope.interface import implementer from cybertools.tracking.interfaces import ITrackingStorage from loops.knowledge.qualification.interfaces import IQualificationRecord, \ IQualificationRecords from loops.organize.work.base import WorkItem, WorkItems +@implementer(IQualificationRecord) class QualificationRecord(WorkItem): - implements(IQualificationRecord) - typeName = 'QualificationRecord' typeInterface = IQualificationRecord statesDefinition = 'knowledge.qualification' @@ -24,9 +23,9 @@ class QualificationRecord(WorkItem): return new +@implementer(IQualificationRecords) class QualificationRecords(WorkItems): """ A tracking storage adapter managing qualification records.""" - implements(IQualificationRecords) adapts(ITrackingStorage) diff --git a/loops/knowledge/qualification/base.py b/loops/knowledge/qualification/base.py index 8a667e2..5ebe385 100644 --- a/loops/knowledge/qualification/base.py +++ b/loops/knowledge/qualification/base.py @@ -1,29 +1,12 @@ -# -# Copyright (c) 2013 Helmut Merz helmutm@cy55.de -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# +# loops.knowledge.qualification.base -""" -Controlling qualification activities of persons. +""" Controlling qualification activities of persons. Central part of CCM competence and certification management framework. """ from zope.component import adapts -from zope.interface import implementer, implements +from zope.interface import implementer from loops.common import AdapterBase from loops.interfaces import IConcept @@ -34,10 +17,9 @@ from loops.type import TypeInterfaceSourceList TypeInterfaceSourceList.typeInterfaces += (ICompetence,) +@implementer(ICompetence) class Competence(AdapterBase): - implements(ICompetence) - _contextAttributes = list(ICompetence) diff --git a/loops/knowledge/survey/base.py b/loops/knowledge/survey/base.py index 523364e..0ecc496 100644 --- a/loops/knowledge/survey/base.py +++ b/loops/knowledge/survey/base.py @@ -1,27 +1,10 @@ -# -# Copyright (c) 2016 Helmut Merz helmutm@cy55.de -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# +# loops.knowledge.survey.base -""" -Surveys used in knowledge management. +""" Surveys used in knowledge management. """ from zope.component import adapts -from zope.interface import implementer, implements +from zope.interface import implementer from cybertools.knowledge.survey.questionnaire import Questionnaire, \ QuestionGroup, Question, FeedbackItem @@ -35,10 +18,9 @@ TypeInterfaceSourceList.typeInterfaces += (IQuestionnaire, IQuestionGroup, IQuestion, IFeedbackItem) +@implementer(IQuestionnaire) class Questionnaire(AdapterBase, Questionnaire): - implements(IQuestionnaire) - _contextAttributes = list(IQuestionnaire) _adapterAttributes = AdapterBase._adapterAttributes + ( 'teamBasedEvaluation', @@ -74,10 +56,9 @@ class Questionnaire(AdapterBase, Questionnaire): yield qu +@implementer(IQuestionGroup) class QuestionGroup(AdapterBase, QuestionGroup): - implements(IQuestionGroup) - _contextAttributes = list(IQuestionGroup) _adapterAttributes = AdapterBase._adapterAttributes + ( 'questionnaire', 'questions', 'feedbackItems') @@ -109,10 +90,9 @@ class QuestionGroup(AdapterBase, QuestionGroup): return [obj for obj in self.subobjects if IFeedbackItem.providedBy(obj)] +@implementer(IQuestion) class Question(AdapterBase, Question): - implements(IQuestion) - _contextAttributes = list(IQuestion) _adapterAttributes = AdapterBase._adapterAttributes + ( 'text', 'questionnaire', 'answerRange', 'feedbackItems',) @@ -134,10 +114,9 @@ class Question(AdapterBase, Question): return self.questionGroup.questionnaire +@implementer(IFeedbackItem) class FeedbackItem(AdapterBase, FeedbackItem): - implements(IFeedbackItem) - _contextAttributes = list(IFeedbackItem) _adapterAttributes = AdapterBase._adapterAttributes + ( 'text',) diff --git a/loops/organize/task.py b/loops/organize/task.py index 5f1ad41..b84dc6c 100644 --- a/loops/organize/task.py +++ b/loops/organize/task.py @@ -1,29 +1,12 @@ -# -# Copyright (c) 2012 Helmut Merz helmutm@cy55.de -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# +# loops.organize.task -""" -Adapters for IConcept providing interfaces from the +""" Adapters for IConcept providing interfaces from the cybertools.organize package. """ from time import mktime from zope.component import adapts -from zope.interface import implements +from zope.interface import implementer from loops.organize.interfaces import ITask, IEvent, IAgendaItem from loops.interfaces import IConcept @@ -35,37 +18,34 @@ from loops.type import TypeInterfaceSourceList TypeInterfaceSourceList.typeInterfaces += (ITask, IEvent, IAgendaItem) +@implementer(ITask) class Task(AdapterBase): """ typeInterface adapter for concepts of type 'task' or 'project'. """ - implements(ITask) - _adapterAttributes = AdapterBase._adapterAttributes _contextAttributes = list(ITask) +@implementer(IEvent) class Event(Task): """ A scheduled event or appointment. """ - implements(IEvent) - _contextAttributes = list(IEvent) +@implementer(IAgendaItem) class AgendaItem(AdapterBase): """ Some topic (a sort of task) that is discussed during an event. """ - implements(IAgendaItem) - _contextAttributes = list(IAgendaItem) +@implementer(IIndexAttributes) class IndexAttributes(object): - implements(IIndexAttributes) adapts(ITask) def __init__(self, context): diff --git a/loops/setup.py b/loops/setup.py index 73b9592..ba5ef3c 100644 --- a/loops/setup.py +++ b/loops/setup.py @@ -227,14 +227,15 @@ class SetupManager(object): def getPredicate(self, predicate): if predicate is None: return self.concepts.getDefaultPredicate() - if isinstance(predicate, basestring): + if isinstance(predicate, str): return self.concepts[predicate] return predicate def log(self, message): - if isinstance(message, unicode): - message = message.encode('UTF-8') - print >> self.logger, message + #if isinstance(message, str): + # message = message.encode('UTF-8') + #print >> self.logger, message + print(message, file=self.logger) def addObject(self, container, class_, name, **kw): return addObject(container, class_, name, **kw) diff --git a/loops/util.py b/loops/util.py index 11e08ef..b6fe268 100644 --- a/loops/util.py +++ b/loops/util.py @@ -26,9 +26,12 @@ import cybertools from cybertools.meta.interfaces import IOptions from loops.browser.util import html_quote -import config -from loops.storage.compat.common import StorageFactory -storageFactory = StorageFactory(config) +try: # for testing! + import config + from loops.storage.compat.common import StorageFactory + storageFactory = StorageFactory(config) +except ImportError: + pass _ = MessageFactory('loops')