meta: Python3 fixes

This commit is contained in:
Helmut Merz 2024-09-22 17:16:33 +02:00
parent b60d6d3b10
commit 8d260908a5
5 changed files with 33 additions and 92 deletions

View file

@ -2,8 +2,6 @@
Meta Information Management Meta Information Management
=========================== ===========================
($Id$)
Configuration Options, Settings, Preferences Configuration Options, Settings, Preferences
============================================ ============================================
@ -51,7 +49,7 @@ Loading options as Python code
>>> config.controller.telnet.port >>> config.controller.telnet.port
5001 5001
>>> print config >>> print(config)
controller.telnet(port=5001) controller.telnet(port=5001)
controller(names=('cmdline', 'telnet')) controller(names=('cmdline', 'telnet'))
scheduler(name='core') scheduler(name='core')

View file

@ -1,39 +1,19 @@
# # cybertools.meta.config
# Copyright (c) 2009 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
#
""" """ Basic implementations for configuration options
Basic implementations for configuration options
$Id$
""" """
import os import os
from zope.interface import implements from zope.interface import implementer
from cybertools.meta.element import Element from cybertools.meta.element import Element
from cybertools.meta.interfaces import IOptions, IConfigurator from cybertools.meta.interfaces import IOptions, IConfigurator
from cybertools.meta.namespace import AutoNamespace, Executor, ExecutionError from cybertools.meta.namespace import AutoNamespace, Executor, ExecutionError
@implementer(IOptions)
class Options(AutoNamespace): class Options(AutoNamespace):
implements(IOptions)
def __call__(self, key, default=None): def __call__(self, key, default=None):
value = self value = self
for part in key.split('.'): for part in key.split('.'):
@ -59,10 +39,9 @@ class GlobalOptions(Options):
return super(GlobalOptions, self).__call__(key, default) return super(GlobalOptions, self).__call__(key, default)
@implementer(IConfigurator)
class Configurator(object): class Configurator(object):
implements(IConfigurator)
def __init__(self, context): def __init__(self, context):
self.context = context self.context = context

View file

@ -1,29 +1,10 @@
# # cybertools.meta.element
# 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
#
""" """ Building flexible hierarchical object structures with XML-like
Building flexible hierarchical object structures with XML-like
elements. elements.
$Id$
""" """
from cStringIO import StringIO from io import StringIO
from cybertools.util.jeep import Jeep from cybertools.util.jeep import Jeep
@ -59,7 +40,7 @@ class Element(dict):
elif isinstance(key, Element): elif isinstance(key, Element):
self.children.append(key) self.children.append(key)
return key return key
elif isinstance(key, (int, long, basestring)): elif isinstance(key, (int, str)):
return self.children[key] return self.children[key]
else: else:
raise KeyError(key) raise KeyError(key)
@ -78,8 +59,8 @@ class Element(dict):
else: else:
self[key] = value self[key] = value
def __iter__(self): #def __iter__(self):
return iter(self.children) # return iter(self.children)
def __str__(self): def __str__(self):
return self.__name__ return self.__name__

View file

@ -1,27 +1,8 @@
# # cybertools.meta.namespace
# 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
#
""" """ Special namespaces for execution of Python code, e.g. for implementing
Special namespaces for execution of Python code, e.g. for implementing
configuration or export/import formats, or providing a restricted Python configuration or export/import formats, or providing a restricted Python
for scripts or an interactive interpreter. for scripts or an interactive interpreter.
$Id$
""" """
import traceback import traceback
@ -34,7 +15,7 @@ _not_found = object()
class BaseNamespace(dict): class BaseNamespace(dict):
builtins = '__builtins__', 'dir', 'output' builtins = '__builtins__', 'dir', 'output', 'print'
def __init__(self, *args, **kw): def __init__(self, *args, **kw):
self.__builtins__ = {} self.__builtins__ = {}
@ -43,7 +24,10 @@ class BaseNamespace(dict):
self[key] = getattr(self, key) self[key] = getattr(self, key)
def output(self, value): def output(self, value):
print value print(value)
def print(self, *vals):
print(*vals)
def dir(self, obj=None): def dir(self, obj=None):
if obj is None: if obj is None:
@ -100,7 +84,7 @@ class Executor(object):
def execute(self, text): def execute(self, text):
error = '' error = ''
try: try:
exec text in self.namespace exec(text, self.namespace)
except: except:
error = traceback.format_exc() error = traceback.format_exc()
return error return error

View file

@ -2,8 +2,6 @@
Python Execution in Special Dynamic Namespaces Python Execution in Special Dynamic Namespaces
============================================== ==============================================
$Id$
>>> from cybertools.meta import namespace >>> from cybertools.meta import namespace
@ -15,16 +13,16 @@ A Very Restricted Basic Namespace
We We
>>> code = """ >>> code = """
... print 'Hello' ... print('Hello')
... # a comment ... # a comment
... print dir('') ... print(dir(''))
... print '__builtins__:', __builtins__ ... print('__builtins__:', __builtins__)
... output('something') ... output('something')
... a = 'a is a variable' ... a = 'a is a variable'
... if a: ... if a:
... print a ... print(a)
... """ ... """
>>> exec code in minimal >>> exec(code, minimal)
Hello Hello
['__add__', ..., 'zfill'] ['__add__', ..., 'zfill']
__builtins__: {} __builtins__: {}
@ -40,12 +38,12 @@ of the namespace later.
By setting the ``__builtins__`` mapping to an empty dictionary the minimal By setting the ``__builtins__`` mapping to an empty dictionary the minimal
namespace provides a secure restricted execution environment. namespace provides a secure restricted execution environment.
>>> exec "import os" in minimal >>> exec("import os", minimal)
Traceback (most recent call last): Traceback (most recent call last):
... ...
ImportError: __import__ not found ImportError: __import__ not found
>>> exec "f = open('dummy.txt', 'w')" in minimal >>> exec("f = open('dummy.txt', 'w')", minimal)
Traceback (most recent call last): Traceback (most recent call last):
... ...
NameError: open NameError: open
@ -68,7 +66,7 @@ Elements and sub-elements (children)
>>> symbols['annotation'] = ElementFactory(symbols, 'annotation') >>> symbols['annotation'] = ElementFactory(symbols, 'annotation')
>>> symbols['child'] = ElementFactory(symbols, 'child') >>> symbols['child'] = ElementFactory(symbols, 'child')
>>> exec code in symbols >>> exec(code, symbols)
>>> symbols.topic.instances >>> symbols.topic.instances
[<Element 'zope3'>, <Element 'python'>] [<Element 'zope3'>, <Element 'python'>]
@ -84,7 +82,7 @@ A Namespace Automatically Generating Elements
>>> auto = namespace.AutoNamespace() >>> auto = namespace.AutoNamespace()
>>> exec "print something" in auto >>> exec("print(something)", auto)
something something
>>> auto.something >>> auto.something
@ -112,15 +110,16 @@ value and an - hopefully empty - error string.
(None, 'Traceback...ZeroDivisionError...') (None, 'Traceback...ZeroDivisionError...')
Trying to execute a statement leads to a syntax error. Trying to execute a statement leads to a syntax error.
... in Python3 print is a function ...
>>> ev.evaluate('print something_else') ev.evaluate('print(something_else)')
(None, 'Traceback...SyntaxError...') (None, 'Traceback...SyntaxError...')
But we can explicitly allow the execution of statements. The result But we can explicitly allow the execution of statements. The result
of executing a statement is None. of executing a statement is None.
>>> ev = namespace.Evaluator(auto, allowExec=True) >>> ev = namespace.Evaluator(auto, allowExec=True)
>>> ev.evaluate('print something_else') >>> ev.evaluate('print(something_else)')
something_else something_else
(None, '') (None, '')
>>> ev.evaluate('25 * 25') >>> ev.evaluate('25 * 25')