add python3 suppport based on 2to3 script
This commit is contained in:
parent
caef0e85d0
commit
4f91a30fec
68 changed files with 597 additions and 576 deletions
|
@ -13,18 +13,18 @@ class TestMixin:
|
|||
'''Returns the list of sub-modules of p_app that are non-empty.'''
|
||||
res = []
|
||||
try:
|
||||
exec 'import %s' % moduleName
|
||||
exec 'moduleObj = %s' % moduleName
|
||||
exec('import %s' % moduleName)
|
||||
exec('moduleObj = %s' % moduleName)
|
||||
moduleFile = moduleObj.__file__
|
||||
if moduleFile.endswith('.pyc'):
|
||||
moduleFile = moduleFile[:-1]
|
||||
except ImportError, ie:
|
||||
except ImportError as ie:
|
||||
return res
|
||||
except SyntaxError, se:
|
||||
except SyntaxError as se:
|
||||
return res
|
||||
# Include the module if not empty. "Emptyness" is determined by the
|
||||
# absence of names beginning with other chars than "__".
|
||||
for elem in moduleObj.__dict__.iterkeys():
|
||||
for elem in moduleObj.__dict__.keys():
|
||||
if not elem.startswith('__'):
|
||||
res.append(moduleObj)
|
||||
break
|
||||
|
@ -66,10 +66,10 @@ def afterTest(test):
|
|||
'''Is executed after every test.'''
|
||||
g = test.globs
|
||||
appName = g['tool'].o.getAppName()
|
||||
exec 'from Products.%s import cov, covFolder, totalNumberOfTests, ' \
|
||||
'countTest' % appName
|
||||
exec('from Products.%s import cov, covFolder, totalNumberOfTests, ' \
|
||||
'countTest' % appName)
|
||||
countTest()
|
||||
exec 'from Products.%s import numberOfExecutedTests' % appName
|
||||
exec('from Products.%s import numberOfExecutedTests' % appName)
|
||||
if cov and (numberOfExecutedTests == totalNumberOfTests):
|
||||
cov.stop()
|
||||
appModules = test.getNonEmptySubModules(appName)
|
||||
|
|
|
@ -13,6 +13,7 @@ from appy.shared import mimeTypes
|
|||
from appy.shared import utils as sutils
|
||||
from appy.shared.data import languages
|
||||
from appy.shared.ldap_connector import LdapConnector
|
||||
import collections
|
||||
try:
|
||||
from AccessControl.ZopeSecurityPolicy import _noroles
|
||||
except ImportError:
|
||||
|
@ -36,7 +37,7 @@ class ToolMixin(BaseMixin):
|
|||
p_metaTypeOrAppyType.'''
|
||||
appName = self.getProductConfig().PROJECTNAME
|
||||
res = metaTypeOrAppyClass
|
||||
if not isinstance(metaTypeOrAppyClass, basestring):
|
||||
if not isinstance(metaTypeOrAppyClass, str):
|
||||
res = gutils.getClassName(metaTypeOrAppyClass, appName)
|
||||
if res.find('_wrappers') != -1:
|
||||
elems = res.split('_')
|
||||
|
@ -439,7 +440,7 @@ class ToolMixin(BaseMixin):
|
|||
|
||||
def quote(self, s, escapeWithEntity=True):
|
||||
'''Returns the quoted version of p_s.'''
|
||||
if not isinstance(s, basestring): s = str(s)
|
||||
if not isinstance(s, str): s = str(s)
|
||||
repl = escapeWithEntity and ''' or "\\'"
|
||||
s = s.replace('\r\n', '').replace('\n', '').replace("'", repl)
|
||||
return "'%s'" % s
|
||||
|
@ -452,7 +453,7 @@ class ToolMixin(BaseMixin):
|
|||
|
||||
def getZopeClass(self, name):
|
||||
'''Returns the Zope class whose name is p_name.'''
|
||||
exec 'from Products.%s.%s import %s as C'% (self.getAppName(),name,name)
|
||||
exec('from Products.%s.%s import %s as C'% (self.getAppName(),name,name))
|
||||
return C
|
||||
|
||||
def getAppyClass(self, zopeName, wrapper=False):
|
||||
|
@ -476,12 +477,12 @@ class ToolMixin(BaseMixin):
|
|||
'''Gets the different ways objects of p_klass can be created (currently:
|
||||
via a web form or programmatically only). Result is a list.'''
|
||||
res = []
|
||||
if not klass.__dict__.has_key('create'):
|
||||
if 'create' not in klass.__dict__:
|
||||
return ['form']
|
||||
else:
|
||||
means = klass.create
|
||||
if means:
|
||||
if isinstance(means, basestring): res = [means]
|
||||
if isinstance(means, str): res = [means]
|
||||
else: res = means
|
||||
return res
|
||||
|
||||
|
@ -511,7 +512,7 @@ class ToolMixin(BaseMixin):
|
|||
else:
|
||||
creators = self.getProductConfig().appConfig.defaultCreators
|
||||
# Resolve case (3): if "creators" is a method, execute it.
|
||||
if callable(creators): creators = creators(self.appy())
|
||||
if isinstance(creators, collections.Callable): creators = creators(self.appy())
|
||||
# Resolve case (2)
|
||||
if isinstance(creators, bool) or not creators: return creators
|
||||
# Resolve case (1): checks whether the user has at least one of the
|
||||
|
@ -595,7 +596,7 @@ class ToolMixin(BaseMixin):
|
|||
rq = self.REQUEST
|
||||
# Store the search criteria in the session
|
||||
criteria = self._getDefaultSearchCriteria()
|
||||
for name in rq.form.keys():
|
||||
for name in list(rq.form.keys()):
|
||||
if name.startswith('w_') and not self._searchValueIsEmpty(name):
|
||||
hasStar = name.find('*') != -1
|
||||
fieldName = not hasStar and name[2:] or name[2:name.find('*')]
|
||||
|
@ -609,17 +610,17 @@ class ToolMixin(BaseMixin):
|
|||
# The type of the value is encoded after char "*".
|
||||
name, type = name.split('*')
|
||||
if type == 'bool':
|
||||
exec 'value = %s' % value
|
||||
exec('value = %s' % value)
|
||||
elif type in ('int', 'float'):
|
||||
# Get the "from" value
|
||||
if not value: value = None
|
||||
else:
|
||||
exec 'value = %s(value)' % type
|
||||
exec('value = %s(value)' % type)
|
||||
# Get the "to" value
|
||||
toValue = rq.form['%s_to' % name[2:]].strip()
|
||||
if not toValue: toValue = None
|
||||
else:
|
||||
exec 'toValue = %s(toValue)' % type
|
||||
exec('toValue = %s(toValue)' % type)
|
||||
value = (value, toValue)
|
||||
elif type == 'date':
|
||||
prefix = name[2:]
|
||||
|
@ -640,8 +641,8 @@ class ToolMixin(BaseMixin):
|
|||
if len(type) > 6:
|
||||
transform = type.split('-')[1]
|
||||
if (transform != 'none') and value:
|
||||
exec 'value = value.%s()' % \
|
||||
self.transformMethods[transform]
|
||||
exec('value = value.%s()' % \
|
||||
self.transformMethods[transform])
|
||||
if isinstance(value, list):
|
||||
# It is a list of values. Check if we have an operator for
|
||||
# the field, to see if we make an "and" or "or" for all
|
||||
|
@ -697,7 +698,7 @@ class ToolMixin(BaseMixin):
|
|||
it among search criteria in the session.'''
|
||||
if not refInfo and (self.REQUEST.get('search', None) == 'customSearch'):
|
||||
criteria = self.REQUEST.SESSION.get('searchCriteria', None)
|
||||
if criteria and criteria.has_key('_ref'): refInfo = criteria['_ref']
|
||||
if criteria and '_ref' in criteria: refInfo = criteria['_ref']
|
||||
if not refInfo: return None, None
|
||||
objectUid, fieldName = refInfo.split(':')
|
||||
obj = self.getObject(objectUid)
|
||||
|
@ -856,7 +857,7 @@ class ToolMixin(BaseMixin):
|
|||
try:
|
||||
creds = creds.split(' ')[-1]
|
||||
login, password = base64.decodestring(creds).split(':', 1)
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
pass
|
||||
# b. Identify the user from the authentication cookie.
|
||||
if not login:
|
||||
|
@ -968,7 +969,7 @@ class ToolMixin(BaseMixin):
|
|||
# Invalidate the user session.
|
||||
try:
|
||||
sdm = self.session_data_manager
|
||||
except AttributeError, ae:
|
||||
except AttributeError as ae:
|
||||
# When ran in test mode, session_data_manager is not there.
|
||||
sdm = None
|
||||
if sdm:
|
||||
|
@ -977,7 +978,7 @@ class ToolMixin(BaseMixin):
|
|||
session.invalidate()
|
||||
self.log('logged out.')
|
||||
# Remove user from variable "loggedUsers"
|
||||
if self.loggedUsers.has_key(userId): del self.loggedUsers[userId]
|
||||
if userId in self.loggedUsers: del self.loggedUsers[userId]
|
||||
return self.goto(self.getApp().absolute_url())
|
||||
|
||||
# This dict stores, for every logged user, the date/time of its last access
|
||||
|
@ -1247,7 +1248,7 @@ class ToolMixin(BaseMixin):
|
|||
if hasattr(klass, 'popup'):
|
||||
res.target = 'appyIFrame'
|
||||
d = klass.popup
|
||||
if isinstance(d, basestring):
|
||||
if isinstance(d, str):
|
||||
# Width only
|
||||
params = d[:-2]
|
||||
else:
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
- mixins/ToolMixin is mixed in with the generated application Tool class.'''
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
import os, os.path, re, sys, types, urllib, cgi
|
||||
import os, os.path, re, sys, types, urllib.request, urllib.parse, urllib.error, cgi
|
||||
from appy import Object
|
||||
from appy.px import Px
|
||||
from appy.fields.workflow import UiTransition
|
||||
|
@ -15,6 +15,7 @@ from appy.shared import utils as sutils
|
|||
from appy.shared.data import rtlLanguages
|
||||
from appy.shared.xml_parser import XmlMarshaller, XmlUnmarshaller
|
||||
from appy.shared.diff import HtmlDiff
|
||||
import collections
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
NUMBERED_ID = re.compile('.+\d{4}$')
|
||||
|
@ -371,9 +372,9 @@ class BaseMixin:
|
|||
# p_errors object. Within this object, for every error message that is
|
||||
# not a string, we replace it with the standard validation error for the
|
||||
# corresponding field.
|
||||
for key, value in errors.__dict__.iteritems():
|
||||
for key, value in errors.__dict__.items():
|
||||
resValue = value
|
||||
if not isinstance(resValue, basestring):
|
||||
if not isinstance(resValue, str):
|
||||
resValue = self.translate('field_invalid')
|
||||
setattr(errors, key, resValue)
|
||||
return msg
|
||||
|
@ -419,7 +420,7 @@ class BaseMixin:
|
|||
# Trigger field-specific validation
|
||||
self.intraFieldValidation(errors, values)
|
||||
if errors.__dict__:
|
||||
for k,v in errors.__dict__.iteritems(): rq.set('%s_error' % k, v)
|
||||
for k,v in errors.__dict__.items(): rq.set('%s_error' % k, v)
|
||||
self.say(errorMessage)
|
||||
return self.gotoEdit()
|
||||
|
||||
|
@ -427,7 +428,7 @@ class BaseMixin:
|
|||
msg = self.interFieldValidation(errors, values)
|
||||
if not msg: msg = errorMessage
|
||||
if errors.__dict__:
|
||||
for k,v in errors.__dict__.iteritems(): rq.set('%s_error' % k, v)
|
||||
for k,v in errors.__dict__.items(): rq.set('%s_error' % k, v)
|
||||
self.say(msg)
|
||||
return self.gotoEdit()
|
||||
|
||||
|
@ -506,7 +507,7 @@ class BaseMixin:
|
|||
# Get the list of indexes that apply on this object. Else, Zope
|
||||
# will reindex all indexes defined in the catalog, and through
|
||||
# acquisition, wrong methods can be called on wrong objects.
|
||||
iNames = self.wrapperClass.getIndexes().keys()
|
||||
iNames = list(self.wrapperClass.getIndexes().keys())
|
||||
catalog.catalog_object(self, path, idxs=iNames)
|
||||
|
||||
def xml(self, action=None):
|
||||
|
@ -529,14 +530,14 @@ class BaseMixin:
|
|||
elif isinstance(methodRes, file):
|
||||
res = methodRes.read()
|
||||
methodRes.close()
|
||||
elif isinstance(methodRes, basestring) and \
|
||||
elif isinstance(methodRes, str) and \
|
||||
methodRes.startswith('<?xml'): # Already XML
|
||||
return methodRes
|
||||
else:
|
||||
marshaller = XmlMarshaller()
|
||||
oType = isinstance(methodRes, Object) and 'popo' or 'appy'
|
||||
res = marshaller.marshall(methodRes, objectType=oType)
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
tb = sutils.Traceback.get()
|
||||
res = XmlMarshaller(rootTag='exception').marshall(tb)
|
||||
self.log(tb, type='error')
|
||||
|
@ -548,7 +549,7 @@ class BaseMixin:
|
|||
'''Prints a p_msg in the user interface. p_logLevel may be "info",
|
||||
"warning" or "error".'''
|
||||
rq = self.REQUEST
|
||||
if 'messages' not in rq.SESSION.keys():
|
||||
if 'messages' not in list(rq.SESSION.keys()):
|
||||
plist = self.getProductConfig().PersistentList
|
||||
messages = rq.SESSION['messages'] = plist()
|
||||
else:
|
||||
|
@ -619,7 +620,7 @@ class BaseMixin:
|
|||
For a multilingual string field, p_changes can contain a key for
|
||||
every language, of the form <field name>-<language>.'''
|
||||
# Add to the p_changes dict the field labels
|
||||
for name in changes.keys():
|
||||
for name in list(changes.keys()):
|
||||
# "name" can contain the language for multilingual fields.
|
||||
if '-' in name:
|
||||
fieldName, lg = name.split('-')
|
||||
|
@ -646,7 +647,7 @@ class BaseMixin:
|
|||
historized fields, while p_self already contains the (potentially)
|
||||
modified values.'''
|
||||
# Remove from previousData all values that were not changed
|
||||
for name in previousData.keys():
|
||||
for name in list(previousData.keys()):
|
||||
field = self.getAppyType(name)
|
||||
prev = previousData[name]
|
||||
curr = field.getValue(self)
|
||||
|
@ -655,7 +656,7 @@ class BaseMixin:
|
|||
((prev == '') and (curr == None)):
|
||||
del previousData[name]
|
||||
continue
|
||||
except UnicodeDecodeError, ude:
|
||||
except UnicodeDecodeError as ude:
|
||||
# The string comparisons above may imply silent encoding-related
|
||||
# conversions that may produce this exception.
|
||||
continue
|
||||
|
@ -743,15 +744,15 @@ class BaseMixin:
|
|||
else:
|
||||
klass = self.appy().klass
|
||||
moduleName = klass.__module__
|
||||
exec 'import %s' % moduleName
|
||||
exec 'reload(%s)' % moduleName
|
||||
exec 'res = %s.%s' % (moduleName, klass.__name__)
|
||||
exec('import %s' % moduleName)
|
||||
exec('reload(%s)' % moduleName)
|
||||
exec('res = %s.%s' % (moduleName, klass.__name__))
|
||||
# More manipulations may have occurred in m_update
|
||||
if hasattr(res, 'update'):
|
||||
parentName= res.__bases__[-1].__name__
|
||||
moduleName= 'Products.%s.wrappers' % self.getTool().getAppName()
|
||||
exec 'import %s' % moduleName
|
||||
exec 'parent = %s.%s' % (moduleName, parentName)
|
||||
exec('import %s' % moduleName)
|
||||
exec('parent = %s.%s' % (moduleName, parentName))
|
||||
res.update(parent)
|
||||
return res
|
||||
|
||||
|
@ -839,15 +840,15 @@ class BaseMixin:
|
|||
req = self.REQUEST
|
||||
for field in self.getAllAppyTypes():
|
||||
if field.page.name != pageName: continue
|
||||
if field.masterValue and callable(field.masterValue):
|
||||
if field.masterValue and isinstance(field.masterValue, collections.Callable):
|
||||
# We have a slave field that is updated via ajax requests.
|
||||
name = field.name
|
||||
# Remember the request value for this field if present.
|
||||
if req.has_key(name) and req[name]:
|
||||
if name in req and req[name]:
|
||||
requestValues[name] = req[name]
|
||||
# Remember the validation error for this field if present.
|
||||
errorKey = '%s_error' % name
|
||||
if req.has_key(errorKey):
|
||||
if errorKey in req:
|
||||
errors[name] = req[errorKey]
|
||||
return sutils.getStringDict(requestValues), sutils.getStringDict(errors)
|
||||
|
||||
|
@ -899,7 +900,7 @@ class BaseMixin:
|
|||
del phases[res[i].name]
|
||||
del res[i]
|
||||
# Compute next/previous phases of every phase
|
||||
for ph in phases.itervalues():
|
||||
for ph in phases.values():
|
||||
ph.computeNextPrevious(res)
|
||||
ph.totalNbOfPhases = len(res)
|
||||
# Restrict the result to the current phase if required
|
||||
|
@ -1208,7 +1209,7 @@ class BaseMixin:
|
|||
# fields' old values by their formatted counterparts.
|
||||
event = history[i].copy()
|
||||
event['changes'] = {}
|
||||
for name, oldValue in history[i]['changes'].iteritems():
|
||||
for name, oldValue in history[i]['changes'].items():
|
||||
# "name" can specify a language-specific part in a
|
||||
# multilingual field. "oldValue" is a tuple
|
||||
# (value, fieldName).
|
||||
|
@ -1455,7 +1456,7 @@ class BaseMixin:
|
|||
# Add users or groups having, locally, this role on this object.
|
||||
localRoles = getattr(self.aq_base, '__ac_local_roles__', None)
|
||||
if not localRoles: return res
|
||||
for id, roles in localRoles.iteritems():
|
||||
for id, roles in localRoles.items():
|
||||
for role in roles:
|
||||
if role in res:
|
||||
usr = 'user:%s' % id
|
||||
|
@ -1465,7 +1466,7 @@ class BaseMixin:
|
|||
def showState(self):
|
||||
'''Must I show self's current state ?'''
|
||||
stateShow = self.State(name=False).show
|
||||
if callable(stateShow):
|
||||
if isinstance(stateShow, collections.Callable):
|
||||
return stateShow(self.getWorkflow(), self.appy())
|
||||
return stateShow
|
||||
|
||||
|
@ -1479,7 +1480,7 @@ class BaseMixin:
|
|||
if not hasattr(klass, 'showTransitions'): return (layoutType=='view')
|
||||
showValue = klass.showTransitions
|
||||
# This value can be a single value or a tuple/list of values.
|
||||
if isinstance(showValue, basestring): return layoutType == showValue
|
||||
if isinstance(showValue, str): return layoutType == showValue
|
||||
return layoutType in showValue
|
||||
|
||||
getUrlDefaults = {'page':True, 'nav':True}
|
||||
|
@ -1524,8 +1525,8 @@ class BaseMixin:
|
|||
if 'nav' not in kwargs: kwargs['nav'] = True
|
||||
# Create URL parameters from kwargs
|
||||
params = []
|
||||
for name, value in kwargs.iteritems():
|
||||
if isinstance(value, basestring):
|
||||
for name, value in kwargs.items():
|
||||
if isinstance(value, str):
|
||||
params.append('%s=%s' % (name, value))
|
||||
elif self.REQUEST.get(name, ''):
|
||||
params.append('%s=%s' % (name, self.REQUEST[name]))
|
||||
|
@ -1601,7 +1602,7 @@ class BaseMixin:
|
|||
# Find the name of the method to call.
|
||||
methodName = rq.QUERY_STRING.split('=')[1]
|
||||
return self.xml(action=methodName)
|
||||
elif rq.has_key('do'):
|
||||
elif 'do' in rq:
|
||||
# The user wants to call a method on this object and get its result
|
||||
# as XML.
|
||||
return self.xml(action=rq['do'])
|
||||
|
@ -1672,7 +1673,7 @@ class BaseMixin:
|
|||
if field.type != 'group':
|
||||
fieldMapping = field.mapping[label]
|
||||
if fieldMapping:
|
||||
if callable(fieldMapping):
|
||||
if isinstance(fieldMapping, collections.Callable):
|
||||
fieldMapping = field.callMethod(self, fieldMapping)
|
||||
mapping.update(fieldMapping)
|
||||
label = getattr(field, '%sId' % label)
|
||||
|
@ -1697,15 +1698,15 @@ class BaseMixin:
|
|||
# Perform replacements, according to p_format.
|
||||
res = self.formatText(res, format)
|
||||
# Perform variable replacements
|
||||
for name, repl in mapping.iteritems():
|
||||
if not isinstance(repl, basestring): repl = str(repl)
|
||||
for name, repl in mapping.items():
|
||||
if not isinstance(repl, str): repl = str(repl)
|
||||
res = res.replace('${%s}' % name, repl)
|
||||
return res
|
||||
|
||||
def getPageLayout(self, layoutType):
|
||||
'''Returns the layout corresponding to p_layoutType for p_self.'''
|
||||
res = self.wrapperClass.getPageLayouts()[layoutType]
|
||||
if isinstance(res, basestring): res = Table(res)
|
||||
if isinstance(res, str): res = Table(res)
|
||||
return res
|
||||
|
||||
def download(self, name=None):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue