Python3 fixes: standard tests OK

This commit is contained in:
Helmut Merz 2024-09-25 09:30:37 +02:00
parent 53be77b5b9
commit ce7015b224
10 changed files with 61 additions and 110 deletions

View file

@ -253,7 +253,7 @@ For testing we use some simple files from the tests directory:
>>> from loops import tests
>>> import os
>>> path = os.path.join(*tests.__path__)
>>> img.data = open(os.path.join(path, 'test_icon.png')).read()
>>> img.data = open(os.path.join(path, 'test_icon.png'), 'rb').read()
>>> img.getSize()
381
>>> img.getImageSize()
@ -262,7 +262,7 @@ For testing we use some simple files from the tests directory:
'image/png'
>>> pdf = Resource('A pdf File')
>>> pdf.data = open(os.path.join(path, 'test.pdf')).read()
>>> pdf.data = open(os.path.join(path, 'test.pdf'), 'rb').read()
>>> pdf.getSize()
25862
>>> pdf.getImageSize()
@ -661,9 +661,9 @@ Breadcrumbs
>>> view = NodeView(m114, request)
>>> request.annotations.setdefault('loops.view', {})['nodeView'] = view
>>> view.breadcrumbs()
[{'url': 'http://127.0.0.1/loops/views/m1', 'label': 'Menu'},
{'url': 'http://127.0.0.1/loops/views/m1/m11', 'label': 'Zope'},
{'url': 'http://127.0.0.1/loops/views/m1/m11/m114', 'label': ''}]
[{'label': 'Menu', 'url': 'http://127.0.0.1/loops/views/m1'},
{'label': 'Zope', 'url': 'http://127.0.0.1/loops/views/m1/m11'},
{'label': '', 'url': 'http://127.0.0.1/loops/views/m1/m11/m114'}]
End-user Forms and Special Views
@ -714,7 +714,7 @@ been created during setup.
>>> form = CreateObjectForm(m112, TestRequest())
>>> form.presetTypesForAssignment
[{'token': 'loops:concept:customer', 'title': 'Customer'}]
[{'title': 'Customer', 'token': 'loops:concept:customer'}]
If the node's target is a type concept we don't get any assignments because
it does not make much sense to assign resources or other concepts as

View file

@ -1,35 +1,18 @@
#
# Copyright (c) 2015 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.browser.auth
"""
Login, logout, unauthorized stuff.
""" Login, logout, unauthorized stuff.
"""
from zope.app.exception.browser.unauthorized import Unauthorized as DefaultUnauth
from zope.app.security.interfaces import IAuthentication
from zope.app.security.interfaces import ILogout, IUnauthenticatedPrincipal
from zope.authentication.interfaces import IAuthentication
from zope.authentication.interfaces import ILogout, IUnauthenticatedPrincipal
from zope.browserpage import ViewPageTemplateFile
from zope.cachedescriptors.property import Lazy
from zope import component
from zope.interface import implements
from zope.interface import implementer
from loops.browser.concept import ConceptView
from loops.browser.node import NodeView
from zope.app.pagetemplate import ViewPageTemplateFile
from zope.cachedescriptors.property import Lazy
template = ViewPageTemplateFile('auth.pt')
@ -57,9 +40,9 @@ class LoginForm(NodeView):
return self
@implementer(ILogout)
class Logout(object):
implements(ILogout)
def __init__(self, context, request):
self.context = context

View file

@ -5,7 +5,7 @@
import os.path
from zope.authentication.interfaces import IUnauthenticatedPrincipal
from zope.browserpagge import ViewPageTemplateFile
from zope.browserpage import ViewPageTemplateFile
from zope.cachedescriptors.property import Lazy
from zope import component
from zope.catalog.interfaces import ICatalog

View file

@ -187,6 +187,8 @@ class Concept(Contained, Persistent):
usePredicateIndex=usePredicateIndex)
if canListObject(r.second, noSecurityCheck) and
IConcept.providedBy(r.second))
if sort is None:
return rels
return sorted(rels, key=sort)
def getChildren(self, predicates=None, sort='default',

View file

@ -1,23 +1,6 @@
#
# 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.expert.query
"""
Generic query functionality for retrieving stuff from a loops database.
""" Generic query functionality for retrieving stuff from a loops database.
"""
from BTrees.IIBTree import IITreeSet
@ -25,7 +8,7 @@ from BTrees.IFBTree import IFBucket, IFBTree, IFTreeSet
from BTrees.IOBTree import IOBucket, IOBTree
from zope import interface, component
from zope.component import adapts
from zope.interface import implements, implementer
from zope.interface import implementer
from zope.cachedescriptors.property import Lazy
from zope.intid.interfaces import IIntIds
@ -91,10 +74,9 @@ def AnyKeyword(value):
# concept map queries
@implementer(IQuery)
class ConceptMapTerm(Term):
implements(IQuery)
def __init__(self, concept, **kw):
self.context = concept
for k, v in kw.items():

View file

@ -6,8 +6,6 @@ This file documents and tests a bunch of facilities that support the
loops framework, mostly provided by sub-packages of the cybertools
package.
($Id$)
Let's first do some basic imports
>>> from zope import interface, component
@ -22,48 +20,48 @@ Let's first do some basic imports
>>> concepts, resources, views = t.setup()
>>> concepts['hasType'].title
u'has Type'
'has Type'
>>> loopsRoot = site['loops']
We also add some example concepts,
>>> from loops.concept import Concept
>>> cc1 = Concept(u'Zope')
>>> cc1 = Concept('Zope')
>>> concepts['cc1'] = cc1
>>> cc1.title
u'Zope'
'Zope'
>>> cc2 = Concept(u'Zope 3')
>>> cc2 = Concept('Zope 3')
>>> concepts['cc2'] = cc2
>>> cc2.title
u'Zope 3'
'Zope 3'
resources,
>>> from loops.resource import Resource
>>> file1 = resources['file1'] = Resource(u'A file')
>>> file1 = resources['file1'] = Resource('A file')
>>> file1.resourceType = concepts['file']
(note: the use of Document is deprecated)
>>> from loops.resource import Document
>>> doc1 = Document(u'Zope Info')
>>> doc1 = Document('Zope Info')
>>> resources['doc1'] = doc1
>>> doc1.title
u'Zope Info'
'Zope Info'
>>> img1 = resources['img1'] = Resource(u'An Image')
>>> img1 = resources['img1'] = Resource('An Image')
>>> img1.resourceType = concepts['file']
and nodes (in view space):
>>> from loops.view import Node
>>> m1 = Node(u'Home')
>>> m1 = Node('Home')
>>> views['m1'] = m1
>>> m1.nodeType = 'menu'
>>> m1p1 = Node(u'Page')
>>> m1p1 = Node('Page')
>>> m1['p1'] = m1p1
>>> m1p1.nodeType = 'page'
@ -85,7 +83,7 @@ As we have not yet associated a type with one of our content objects we get
>>> cc1_type.typeProvider is None
True
>>> cc1_type.title
u'Unknown Type'
'Unknown Type'
>>> cc1_type.token
'.unknown'
@ -107,9 +105,9 @@ So let's check the type of the type object:
>>> type_type.typeProvider is typeObject
True
>>> type_type.title
u'Type'
'Type'
>>> type_type.token
u'.loops/concepts/type'
'.loops/concepts/type'
>>> type_type.tokenForSearch
'loops:concept:type'
>>> type_type.qualifiers
@ -117,7 +115,7 @@ So let's check the type of the type object:
Now we register another type ('topic') and assign it to cc1:
>>> concepts['topic'] = Concept(u'Topic')
>>> concepts['topic'] = Concept('Topic')
>>> topic = concepts['topic']
>>> topic.conceptType = typeObject
>>> cc1.conceptType = topic
@ -147,9 +145,9 @@ Now let's have a look at resources.
>>> component.provideAdapter(LoopsType, (IResource,), IType)
>>> file1_type = IType(file1)
>>> file1_type.title
u'File'
'File'
>>> file1_type.token
u'.loops/concepts/file'
'.loops/concepts/file'
>>> file1_type.tokenForSearch
'loops:resource:file'
>>> file1_type.qualifiers
@ -167,7 +165,7 @@ Now let's have a look at resources.
>>> doc1_type = IType(doc1)
>>> doc1_type.title
u'Document'
'Document'
>>> doc1_type.token
'loops.resource.Document'
>>> doc1_type.tokenForSearch
@ -181,11 +179,11 @@ Now let's have a look at resources.
>>> img1_type = IType(img1)
>>> img1_type.token
u'.loops/concepts/file'
'.loops/concepts/file'
>>> img1_type.tokenForSearch
'loops:resource:file'
>>> img1_type.title
u'File'
'File'
Using the type machinery we can also specify options that may be used
for controlling e.g. storage for external files.
@ -194,8 +192,8 @@ for controlling e.g. storage for external files.
>>> from loops.resource import FileAdapter
>>> component.provideAdapter(FileAdapter, provides=IFile)
>>> extfile = concepts['extfile'] = Concept(u'External File')
>>> ef1 = resources['ef1'] = Resource(u'Extfile #1')
>>> extfile = concepts['extfile'] = Concept('External File')
>>> ef1 = resources['ef1'] = Resource('Extfile #1')
>>> ef1.resourceType = extfile
>>> ef1_type = IType(ef1)
>>> IType(ef1).options
@ -208,7 +206,7 @@ for controlling e.g. storage for external files.
>>> IType(ef1).options
['dummy', 'storage:varsubdir', 'storage_parameters:extfiles']
>>> IType(ef1).optionsDict
{'default': ['dummy'], 'storage_parameters': 'extfiles', 'storage': 'varsubdir'}
{'default': ['dummy'], 'storage': 'varsubdir', 'storage_parameters': 'extfiles'}
Can we find out somehow which types are available? This is the time to look
for a type manager. This could be a utility; but in the loops package it
@ -265,10 +263,10 @@ This is done by assigning this interface to topic_type.typeProvider,
i.e. the 'topic' concept, via an adapter:
>>> class ITopic(Interface): pass
>>> from zope.interface import implements
>>> from zope.interface import implementer
>>> class Topic(object):
... implements(ITopic)
... def __init__(self, context): pass
>>> Topic = implementer(ITopic)(Topic)
>>> from loops.interfaces import IConcept
>>> component.provideAdapter(Topic, (IConcept,), ITopic)
@ -299,7 +297,7 @@ context object's type:
>>> from loops.browser.common import BaseView
>>> view = BaseView(cc1, TestRequest())
>>> view.typeTitle
u'Topic'
'Topic'
>>> view.typeInterface
<InterfaceClass ...ITopic>
>>> view.typeAdapter
@ -321,7 +319,7 @@ been provided by the setup, but we have to register a corresponding adapter.
Next we need a concept of this type:
>>> simpleQuery = concepts['simpleQuery'] = Concept(u'Simple query')
>>> simpleQuery = concepts['simpleQuery'] = Concept('Simple query')
>>> simpleQuery.conceptType = query
>>> sq_type = IType(simpleQuery)
>>> sq_adapter = sq_type.typeInterface(simpleQuery)
@ -426,7 +424,7 @@ Folders
map.
>>> tFolder = addAndConfigureObject(concepts, Concept, 'folder',
... title=u'Folder', conceptType=typeObject)
... title='Folder', conceptType=typeObject)
Usually we want to create folders only in objects of a certain type,
e.g. in a domain. So we activate the folder creation action by providing
@ -444,7 +442,7 @@ If we now create a domain and set up a view on it it will provide the
folder creation action.
>>> general = addAndConfigureObject(concepts, Concept, 'general',
... title=u'General', conceptType=tDomain)
... title='General', conceptType=tDomain)
>>> from loops.browser.concept import ConceptView
>>> view = ConceptView(general, TestRequest())
@ -454,7 +452,7 @@ folder creation action.
Let's now create a folder.
>>> f01 = addAndConfigureObject(concepts, Concept, 'f01',
... title=u'Test Folder', conceptType=tFolder)
... title='Test Folder', conceptType=tFolder)
A folder should be associated with a FolderView that provides two actions
for editing the folder and for creating a new subfolder.

View file

@ -1,5 +1,6 @@
import unittest, doctest
import warnings
from zope.interface.verify import verifyClass
from zope.intid.interfaces import IIntIds
@ -22,6 +23,7 @@ class Test(unittest.TestCase):
"Basic tests for the loops package."
def testInterfaces(self):
warnings.filterwarnings('ignore', category=ResourceWarning)
verifyClass(ILoops, Loops)
self.assertTrue(ILoops.providedBy(Loops()))
verifyClass(IConcept, Concept)
@ -45,7 +47,7 @@ def test_suite():
return unittest.TestSuite((
unittest.makeSuite(Test),
doctest.DocFileSuite('../README.txt', optionflags=flags),
#doctest.DocFileSuite('../helpers.txt', optionflags=flags),
doctest.DocFileSuite('../helpers.txt', optionflags=flags),
))
if __name__ == '__main__':

View file

@ -165,7 +165,7 @@ class ResourceType(LoopsType):
@Lazy
def title(self):
cn = self.className
return self.typeTitles.get(cn, unicode(cn))
return self.typeTitles.get(cn, cn)
@Lazy
def token(self):

View file

@ -1,28 +1,11 @@
#
# Copyright (c) 2015 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.versioning.browser
"""
View classes for versioning.
""" View classes for versioning.
"""
from zope import interface, component
from zope.app.pagetemplate import ViewPageTemplateFile
from zope.app.security.interfaces import IUnauthenticatedPrincipal
from zope.authentication.interfaces import IUnauthenticatedPrincipal
from zope.browserpage import ViewPageTemplateFile
from zope.cachedescriptors.property import Lazy
from loops.browser.common import BaseView

View file

@ -16,8 +16,9 @@ dependencies = [
"py-scopes",
"markdown",
"python-dotenv",
"zope.app.renderer",
"zope.app.authentication",
"zope.app.exception",
"zope.app.renderer",
"zope.browsermenu",
"zope.i18n",
"zope.pluggableauth",