Commit de2001ff authored by Julien Muchembled's avatar Julien Muchembled

Teach restricted Python about new language features

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@43622 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent f24737bd
...@@ -29,15 +29,9 @@ ...@@ -29,15 +29,9 @@
"""A wrapper module for simplejson or json.""" """A wrapper module for simplejson or json."""
try: from Products.ERP5Type.Utils import deprecated
from simplejson import dumps, loads import json
except ImportError:
try:
from json import dumps, loads
except ImportError:
def dumps(*args, **kw):
raise RuntimeError('You must install simplejson to use Products.ERP5Type.JSON.dumps.')
def loads(*args, **kw):
raise RuntimeError('You must install simplejson to use Products.ERP5Type.JSON.loads.')
deprecated = deprecated("%r is deprecated; use 'json' instead." % __name__)
dumps = deprecated(json.dumps)
loads = deprecated(json.loads)
...@@ -400,6 +400,6 @@ __all__ = ['JSONEncoder'] ...@@ -400,6 +400,6 @@ __all__ = ['JSONEncoder']
def encodeInJson(o): def encodeInJson(o):
from warnings import warn from warnings import warn
warn('Products.ERP5Type.JSONEncoder.encodeInJson is deprecated; use Products.ERP5Type.JSON.dumps instead.', warn('Products.ERP5Type.JSONEncoder.encodeInJson is deprecated; use json.dumps instead.',
DeprecationWarning) DeprecationWarning)
return JSONEncoder().encode(o) return JSONEncoder().encode(o)
...@@ -216,14 +216,19 @@ def _showwarning(message, category, filename, lineno, file=None, line=None): ...@@ -216,14 +216,19 @@ def _showwarning(message, category, filename, lineno, file=None, line=None):
file.write(warnings.formatwarning(message, category, filename, lineno)) file.write(warnings.formatwarning(message, category, filename, lineno))
warnings.showwarning = _showwarning warnings.showwarning = _showwarning
@simple_decorator def deprecated(message=''):
def deprecated(wrapped): @simple_decorator
message = "Use of '%s' function (%s, line %s) is deprecated." % ( def _deprecated(wrapped):
wrapped.__name__, wrapped.__module__, wrapped.func_code.co_firstlineno) m = message or "Use of '%s' function (%s, line %s) is deprecated." % (
def wrapper(*args, **kw): wrapped.__name__, wrapped.__module__, wrapped.func_code.co_firstlineno)
warnings.warn(message, DeprecationWarning, 2) def deprecated(*args, **kw):
return wrapped(*args, **kw) warnings.warn(m, DeprecationWarning, 2)
return wrapper return wrapped(*args, **kw)
return deprecated
if callable(message):
m, message = message, ''
return _deprecated(m)
return _deprecated
##################################################### #####################################################
# Useful methods # Useful methods
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
############################################################################## ##############################################################################
# Load all monkey patches # Load all monkey patches
from Products.ERP5Type.patches import Restricted
from Products.ERP5Type.patches import m2crypto from Products.ERP5Type.patches import m2crypto
from Products.ERP5Type.patches import ObjectManager from Products.ERP5Type.patches import ObjectManager
from Products.ERP5Type.patches import PropertyManager from Products.ERP5Type.patches import PropertyManager
......
...@@ -26,17 +26,6 @@ ...@@ -26,17 +26,6 @@
# #
############################################################################## ##############################################################################
import collections # XXX deprecated; use 'collections' instead, even on Python < 2.7
try:
from collections import OrderedDict
except ImportError:
try:
from ordereddict import OrderedDict
collections.OrderedDict = OrderedDict
except ImportError:
OrderedDict = None
if OrderedDict is not None and \ from collections import OrderedDict
getattr(OrderedDict, '__allow_access_to_unprotected_subobjects__',
None) is None:
OrderedDict.__allow_access_to_unprotected_subobjects__ = 1
#############################################################################
#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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
#
##############################################################################
import sys
from RestrictedPython.RestrictionMutator import RestrictionMutator
# Unsafe attributes on protected objects are already disallowed at execution
# and we don't want to maintain a duplicated list of exceptions.
RestrictionMutator.checkName = RestrictionMutator.checkAttrName = \
lambda *args, **kw: None
from Acquisition import aq_acquire
from AccessControl import getSecurityManager
from AccessControl.ZopeGuards import (safe_builtins, _marker, Unauthorized,
aq_validate, guard, guarded_getattr, guarded_iter, SafeIter, NullIter,
ContainerAssertions, GuardedDictType, _dict_white_list)
# TODO: add buffer/bytearray
def add_builtins(**kw):
assert not set(safe_builtins).intersection(kw)
safe_builtins.update(kw)
del safe_builtins['dict']
del safe_builtins['list']
add_builtins(Ellipsis=Ellipsis, NotImplemented=NotImplemented,
dict=dict, list=list, set=set, frozenset=frozenset)
add_builtins(classmethod=classmethod, object=object, property=property,
slice=slice, staticmethod=staticmethod, super=super, type=type)
if sys.version_info >= (2, 6):
add_builtins(bin=bin, format=format)
def guarded_next(iterator, default=_marker):
"""next(iterator[, default])
Return the next item from the iterator. If default is given
and the iterator is exhausted, it is returned instead of
raising StopIteration.
"""
try:
iternext = guarded_getattr(iterator, 'next').__call__
# this way an AttributeError while executing next() isn't hidden
# (2.6 does this too)
except AttributeError:
raise TypeError("%s object is not an iterator"
% type(iterator).__name__)
try:
return iternext()
except StopIteration:
if default is _marker:
raise
return default
add_builtins(next=guarded_next)
def _check_type_access(name, v):
def factory(inst, name):
if not (name == 'fromkeys' and type(inst) is dict):
# fallback to default security
aq_acquire(inst, name, aq_validate, getSecurityManager().validate)
return v
return factory
ContainerAssertions[type] = _check_type_access
class SafeIterItems(SafeIter):
def next(self):
ob = self._next()
c = self.container
guard(c, ob[0])
guard(c, ob[1])
return ob
def get_iteritems(c, name):
return lambda: SafeIterItems(c.iteritems(), c)
_dict_white_list['iteritems'] = get_iteritems
if sys.version_info < (2, 5):
# these are backported in Products.ERP5Type.patches.python
def guarded_any(seq):
return any(guarded_iter(seq))
safe_builtins['any'] = guarded_any
def guarded_all(seq):
return all(guarded_iter(seq))
safe_builtins['all'] = guarded_all
def guarded_sorted(seq, cmp=None, key=None, reverse=False):
if not isinstance(seq, SafeIter):
for i, x in enumerate(seq):
guard(seq, x, i)
return sorted(seq, cmp=cmp, key=key, reverse=reverse)
safe_builtins['sorted'] = guarded_sorted
def guarded_reversed(seq):
return SafeIter(reversed(seq))
safe_builtins['reversed'] = guarded_reversed
def get_set_pop(s, name):
def guarded_pop():
v = s.pop()
try:
guard(s, v)
except Unauthorized:
s.add(v)
raise
return v
return guarded_pop
_set_white_get = {
'add': 1, 'clear': 1, 'copy': 1, 'difference': 1, 'difference_update': 1,
'discard': 1, 'intersection': 1, 'intersection_update': 1, 'isdisjoint': 1,
'issubset': 1, 'issuperset': 1, 'pop': get_set_pop, 'remove': 1,
'symmetric_difference': 1, 'symmetric_difference_update': 1, 'union': 1,
'update': 1}.get
def _check_set_access(name, value):
# Check whether value is a set method
self = getattr(value, '__self__', None)
if self is None: # item
return 1
# Disallow spoofing
if type(self) is not set:
return 0
if getattr(value, '__name__', None) != name:
return 0
return _set_white_get(name, 0)
ContainerAssertions[set] = _check_set_access
ContainerAssertions[frozenset] = 1
from collections import OrderedDict
OrderedDict.__allow_access_to_unprotected_subobjects__ = 1
from AccessControl import allow_module, allow_class, allow_type
from AccessControl import ModuleSecurityInfo
# given as example in Products.PythonScripts.module_access_examples
allow_module('base64')
allow_module('binascii')
allow_module('bisect')
allow_module('colorsys')
allow_module('crypt')
##
allow_module('pprint')
ModuleSecurityInfo('json').declarePublic('dumps', 'loads')
import re
allow_module('fnmatch')
allow_module('re')
allow_type(type(re.compile('')))
allow_type(type(re.match('x','x')))
import cStringIO
f = cStringIO.StringIO()
allow_module('cStringIO')
allow_module('StringIO')
allow_type(type(f))
ModuleSecurityInfo('cgi').declarePublic('escape', 'parse_header')
allow_module('difflib')
allow_module('hashlib')
allow_module('time')
allow_module('urlparse')
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
# #
############################################################################## ##############################################################################
import sys import sys, types
if sys.version_info < (2, 5): if sys.version_info < (2, 5):
import __builtin__, imp import __builtin__, imp
...@@ -85,3 +85,26 @@ if sys.version_info < (2, 5): ...@@ -85,3 +85,26 @@ if sys.version_info < (2, 5):
object = _ordered_dict(object) object = _ordered_dict(object)
return orig_safe_repr(object, context, maxlevels, level) return orig_safe_repr(object, context, maxlevels, level)
_pprint._safe_repr = _safe_repr _pprint._safe_repr = _safe_repr
if sys.version_info < (2, 6):
try:
import simplejson as json
except ImportError, missing_simplejson:
class dummy(types.ModuleType):
def __getattr__(self, name):
raise missing_simplejson
json = dummy('dummy_json')
sys.modules['json'] = json
if sys.version_info < (2, 7):
try:
from ordereddict import OrderedDict
except ImportError, missing_ordereddict:
def OrderedDict(*args, **kw):
raise missing_ordereddict
import collections
collections.OrderedDict = ordereddict.OrderedDict
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment