add python3 suppport based on 2to3 script

This commit is contained in:
Stefan Klug 2015-10-27 21:10:24 +01:00
parent caef0e85d0
commit 4f91a30fec
68 changed files with 597 additions and 576 deletions

View file

@ -21,9 +21,9 @@ from appy.gen.layout import Table, defaultFieldLayouts
from appy.gen import utils as gutils
from appy.px import Px
from appy.shared import utils as sutils
from group import Group
from search import Search
from page import Page
from .group import Group
from .page import Page
import collections
# In this file, names "list" and "dict" refer to sub-modules. To use Python
# builtin types, use __builtins__['list'] and __builtins__['dict']
@ -370,7 +370,7 @@ class Field:
labelName = name
trPrefix = None
if self.label:
if isinstance(self.label, basestring): trPrefix = self.label
if isinstance(self.label, str): trPrefix = self.label
else: # It is a tuple (trPrefix, name)
if self.label[1]: labelName = self.label[1]
if self.label[0]: trPrefix = self.label[0]
@ -382,16 +382,16 @@ class Field:
self.helpId = self.labelId + '_help'
# Determine read and write permissions for this field
rp = self.specificReadPermission
if rp and not isinstance(rp, basestring):
if rp and not isinstance(rp, str):
self.readPermission = '%s: Read %s %s' % (appName, prefix, name)
elif rp and isinstance(rp, basestring):
elif rp and isinstance(rp, str):
self.readPermission = rp
else:
self.readPermission = 'read'
wp = self.specificWritePermission
if wp and not isinstance(wp, basestring):
if wp and not isinstance(wp, str):
self.writePermission = '%s: Write %s %s' % (appName, prefix, name)
elif wp and isinstance(wp, basestring):
elif wp and isinstance(wp, str):
self.writePermission = wp
else:
self.writePermission = 'write'
@ -442,7 +442,7 @@ class Field:
self.readPermission
if not obj.allows(perm): return
# Evaluate self.show
if callable(self.show):
if isinstance(self.show, collections.Callable):
res = self.callMethod(obj, self.show)
else:
res = self.show
@ -480,7 +480,7 @@ class Field:
if not masterData: return True
else:
master, masterValue = masterData
if masterValue and callable(masterValue): return True
if masterValue and isinstance(masterValue, collections.Callable): return True
reqValue = master.getRequestValue(obj)
# reqValue can be a list or not
if type(reqValue) not in sutils.sequenceTypes:
@ -496,8 +496,8 @@ class Field:
if isinstance(mapping, __builtins__['dict']):
# Is it a dict like {'label':..., 'descr':...}, or is it directly a
# dict with a mapping?
for k, v in mapping.iteritems():
if (k not in self.labelTypes) or isinstance(v, basestring):
for k, v in mapping.items():
if (k not in self.labelTypes) or isinstance(v, str):
# It is already a mapping
return {'label':mapping, 'descr':mapping, 'help':mapping}
# If we are here, we have {'label':..., 'descr':...}. Complete
@ -520,7 +520,7 @@ class Field:
areDefault = True
layouts = self.computeDefaultLayouts()
else:
if isinstance(layouts, basestring):
if isinstance(layouts, str):
# The user specified a single layoutString (the "edit" one)
layouts = {'edit': layouts}
elif isinstance(layouts, Table):
@ -541,8 +541,8 @@ class Field:
# We have now a dict of layouts in p_layouts. Ensure now that a Table
# instance is created for every layout (=value from the dict). Indeed,
# a layout could have been expressed as a simple layout string.
for layoutType in layouts.iterkeys():
if isinstance(layouts[layoutType], basestring):
for layoutType in layouts.keys():
if isinstance(layouts[layoutType], str):
layouts[layoutType] = Table(layouts[layoutType])
# Derive "view", "search" and "cell" layouts from the "edit" layout
# when relevant.
@ -566,11 +566,11 @@ class Field:
if areDefault and not self.group and \
not ((self.type == 'String') and (self.format == self.XHTML)) and \
not (self.type == 'Ref'):
for layoutType in layouts.iterkeys():
for layoutType in layouts.keys():
layouts[layoutType].width = ''
# Remove letters "r" from the layouts if the field is not required.
if not self.required:
for layoutType in layouts.iterkeys():
for layoutType in layouts.keys():
layouts[layoutType].removeElement('r')
# Derive some boolean values from the layouts.
self.hasLabel = self.hasLayoutElement('l', layouts)
@ -597,7 +597,7 @@ class Field:
def hasLayoutElement(self, element, layouts):
'''This method returns True if the given layout p_element can be found
at least once among the various p_layouts defined for this field.'''
for layout in layouts.itervalues():
for layout in layouts.values():
if element in layout.layoutString: return True
return False
@ -610,7 +610,7 @@ class Field:
'''Gets, as a string, the layouts as could have been specified as input
value for the Field constructor.'''
res = '{'
for k, v in self.layouts.iteritems():
for k, v in self.layouts.items():
res += '"%s":"%s",' % (k, v.layoutString)
res += '}'
return res
@ -650,7 +650,7 @@ class Field:
if self.isEmptyValue(obj, value):
# If there is no value, get the default value if any: return
# self.default, of self.default() if it is a method.
if callable(self.default):
if isinstance(self.default, collections.Callable):
try:
# Caching a default value can lead to problems. For example,
# the process of creating an object from another one, or
@ -660,7 +660,7 @@ class Field:
# but it they depend on values set at (b), and are cached
# and indexed, (c) will get the wrong, cached value.
return self.callMethod(obj, self.default, cache=False)
except Exception, e:
except Exception as e:
# Already logged. Here I do not raise the exception,
# because it can be raised as the result of reindexing
# the object in situations that are not foreseen by
@ -723,12 +723,13 @@ class Field:
# Start by getting the field value on p_obj
res = self.getValue(obj)
# Zope catalog does not like unicode strings
if isinstance(res, unicode): res = res.encode('utf-8')
if isinstance(value, str):
res = value.encode('utf-8')
if forSearch and (res != None):
if type(res) in sutils.sequenceTypes:
vals = []
for v in res:
if isinstance(v, unicode): vals.append(v.encode('utf-8'))
if isinstance(v, str): vals.append(v.encode('utf-8'))
else: vals.append(str(v))
res = ' '.join(vals)
else:
@ -824,7 +825,7 @@ class Field:
this field is the slave of another field.'''
if not self.master: return ''
res = 'slave*%s*' % self.masterName
if not callable(self.masterValue):
if not isinstance(self.masterValue, collections.Callable):
res += '*'.join(self.masterValue)
else:
res += '+'
@ -866,7 +867,7 @@ class Field:
def securityCheck(self, obj, value):
'''This method performs some security checks on the p_value that
represents user input.'''
if not isinstance(value, basestring): return
if not isinstance(value, str): return
# Search Javascript code in the value (prevent XSS attacks).
if '<script' in value:
obj.log('Detected Javascript in user input.', type='error')
@ -900,14 +901,14 @@ class Field:
# It is a custom function: execute it
try:
validValue = self.validator(obj, value)
if isinstance(validValue, basestring) and validValue:
if isinstance(validValue, str) and validValue:
# Validation failed; and p_validValue contains an error
# message.
return validValue
else:
if not validValue:
return obj.translate('field_invalid')
except Exception, e:
except Exception as e:
return str(e)
except:
return obj.translate('field_invalid')
@ -931,7 +932,7 @@ class Field:
obj = obj.appy()
try:
return gutils.callMethod(obj, method, cache=cache)
except TypeError, te:
except TypeError as te:
# Try a version of the method that would accept self as an
# additional parameter. In this case, we do not try to cache the
# value (we do not call gutils.callMethod), because the value may
@ -939,11 +940,11 @@ class Field:
tb = sutils.Traceback.get()
try:
return method(obj, self)
except Exception, e:
except Exception as e:
obj.log(tb, type='error')
# Raise the initial error.
raise te
except Exception, e:
except Exception as e:
obj.log(sutils.Traceback.get(), type='error')
raise e
@ -951,7 +952,7 @@ class Field:
'''Gets the value of attribue p_name on p_self, which can be a simple
value or the result of a method call on p_obj.'''
res = getattr(self, name)
if not callable(res): return res
if not isinstance(res, collections.Callable): return res
return self.callMethod(obj, res)
def process(self, obj):

View file

@ -123,7 +123,7 @@ class Boolean(Field):
def getStorableValue(self, obj, value):
if not self.isEmptyValue(obj, value):
exec 'res = %s' % value
exec('res = %s' % value)
return res
def isTrue(self, obj, dbValue):
@ -131,7 +131,7 @@ class Boolean(Field):
not?'''
rq = obj.REQUEST
# Get the value we must compare (from request or from database)
if rq.has_key(self.name):
if self.name in rq:
return rq.get(self.name) in ('True', 1, '1')
return dbValue
# ------------------------------------------------------------------------------

View file

@ -1263,20 +1263,20 @@ class Calendar(Field):
maxDay = (maxYear, maxDate.month(), maxDate.day())
# Browse years
years = getattr(obj, self.name)
for year in years.keys():
for year in list(years.keys()):
# Don't take this year into account if outside interval
if minDate and (year < minYear): continue
if maxDate and (year > maxYear): continue
months = years[year]
# Browse this year's months
for month in months.keys():
for month in list(months.keys()):
# Don't take this month into account if outside interval
thisMonth = (year, month)
if minDate and (thisMonth < minMonth): continue
if maxDate and (thisMonth > maxMonth): continue
days = months[month]
# Browse this month's days
for day in days.keys():
for day in list(days.keys()):
# Don't take this day into account if outside interval
thisDay = (year, month, day)
if minDate and (thisDay < minDay): continue

View file

@ -47,7 +47,7 @@ class Computed(Field):
# the user interface while m_method computes the value stored in the
# catalog.
self.formatMethod = formatMethod
if isinstance(self.method, basestring):
if isinstance(self.method, str):
# A legacy macro identifier. Raise an exception
raise Exception(self.WRONG_METHOD % self.method)
# Does field computation produce plain text or XHTML?
@ -99,6 +99,6 @@ class Computed(Field):
res = self.formatMethod(obj, value)
else:
res = value
if not isinstance(res, basestring): res = str(res)
if not isinstance(res, str): res = str(res)
return res
# ------------------------------------------------------------------------------

View file

@ -219,7 +219,7 @@ class Date(Field):
def getSelectableYears(self):
'''Gets the list of years one may select for this field.'''
res = range(self.startYear, self.endYear + 1)
res = list(range(self.startYear, self.endYear + 1))
if self.reverseYears: res.reverse()
return res
@ -227,7 +227,7 @@ class Date(Field):
DateTime = obj.getProductConfig().DateTime
try:
value = DateTime(value)
except DateTime.DateError, ValueError:
except DateTime.DateError as ValueError:
return obj.translate('bad_date')
def getFormattedValue(self, obj, value, layoutType='view',
@ -278,7 +278,7 @@ class Date(Field):
# Get the value we must compare (from request or from database)
rq = obj.REQUEST
partName = '%s_%s' % (self.name, fieldPart)
if rq.has_key(partName):
if partName in rq:
compValue = rq.get(partName)
if compValue.isdigit():
compValue = int(compValue)

View file

@ -108,7 +108,7 @@ class FileInfo:
'''Removes the file from the filesystem.'''
try:
os.remove(osPathJoin(dbFolder, self.fsPath, self.fsName))
except Exception, e:
except Exception as e:
# If the current ZODB transaction is re-triggered, the file may
# already have been deleted.
pass
@ -207,10 +207,10 @@ class FileInfo:
if fileObj.data.__class__.__name__ == 'Pdata':
# The file content is splitted in several chunks
f.write(fileObj.data.data)
nextPart = fileObj.data.next
nextPart = fileObj.data.__next__
while nextPart:
f.write(nextPart.data)
nextPart = nextPart.next
nextPart = nextPart.__next__
else:
# Only one chunk
f.write(fileObj.data)
@ -393,7 +393,7 @@ class File(Field):
def validateValue(self, obj, value):
form = obj.REQUEST.form
action = '%s_delete' % self.name
if (not value or not value.filename) and form.has_key(action) and \
if (not value or not value.filename) and action in form and \
not form[action]:
# If this key is present but empty, it means that the user selected
# "replace the file with a new one". So in this case he must provide
@ -450,7 +450,7 @@ class File(Field):
# Case c
fileInfo = (value.name, value.content, value.mimeType)
info.writeFile(self.name, fileInfo, dbFolder)
elif isinstance(value, basestring):
elif isinstance(value, str):
# Case d
info.copyFile(self.name, value, dbFolder)
elif isinstance(value, FileInfo):

View file

@ -40,7 +40,7 @@ class Group:
# which will be used for HTML param "width".
if wide == True:
self.wide = '100%'
elif isinstance(wide, basestring):
elif isinstance(wide, str):
self.wide = wide
else:
self.wide = ''
@ -106,7 +106,7 @@ class Group:
can be a string or a Group instance; this method returns always a
Group instance.'''
res = groupData
if res and isinstance(res, basestring):
if res and isinstance(res, str):
# Group data is given as a string. 2 more possibilities:
# (a) groupData is simply the name of the group;
# (b) groupData is of the form <groupName>_<numberOfColumns>.
@ -336,7 +336,7 @@ class UiGroup:
# All p_group attributes become self attributes. This is required
# because a UiGroup, in some PXs, must behave like a Field (ie, have
# the same attributes, like "master".
for name, value in group.__dict__.iteritems():
for name, value in group.__dict__.items():
if not name.startswith('_'):
setattr(self, name, value)
self.group = group
@ -346,7 +346,7 @@ class UiGroup:
labelName = self.name
prefix = className
if group.label:
if isinstance(group.label, basestring): prefix = group.label
if isinstance(group.label, str): prefix = group.label
else: # It is a tuple (className, name)
if group.label[1]: labelName = group.label[1]
if group.label[0]: prefix = group.label[0]

View file

@ -60,7 +60,7 @@ class Integer(Field):
height, maxChars, colspan, master, masterValue, focus,
historized, mapping, label, sdefault, scolspan, swidth,
sheight, persist, view, xml)
self.pythonType = long
self.pythonType = int
def validateValue(self, obj, value):
try:

View file

@ -132,7 +132,7 @@ class List(Field):
name = requestName or self.name # A List may be into another List (?)
prefix = name + '*' + self.fields[0][0] + '*'
res = {}
for key in request.keys():
for key in list(request.keys()):
if not key.startswith(prefix): continue
# I have found a row. Gets its index.
row = Object()
@ -145,7 +145,7 @@ class List(Field):
setattr(row, subName, v)
res[rowIndex] = row
# Produce a sorted list
keys = res.keys()
keys = list(res.keys())
keys.sort()
res = [res[key] for key in keys]
# I store in the request this computed value. This way, when individual

View file

@ -83,13 +83,13 @@ class Ogone(Field):
# Create a new dict by removing p_keysToIgnore from p_values, and by
# upperizing all keys.
shaRes = {}
for k, v in values.iteritems():
for k, v in values.items():
if k in keysToIgnore: continue
# Ogone: we must not include empty values.
if (v == None) or (v == ''): continue
shaRes[k.upper()] = v
# Create a sorted list of keys
keys = shaRes.keys()
keys = list(shaRes.keys())
keys.sort()
shaList = []
for k in keys:
@ -127,7 +127,7 @@ class Ogone(Field):
# Ogone's response.
res['paramplus'] = 'name=%s' % self.name
# Ensure every value is a str
for k in res.iterkeys():
for k in res.keys():
if not isinstance(res[k], str):
res[k] = str(res[k])
# Compute a SHA-1 key as required by Ogone and add it to the res
@ -154,7 +154,7 @@ class Ogone(Field):
'administrator has been contacted.')
# Create a nice object from the form.
response = Object()
for k, v in obj.REQUEST.form.iteritems():
for k, v in obj.REQUEST.form.items():
setattr(response, k, v)
# Call the field method that handles the response received from Ogone.
url = self.responseMethod(obj.appy(), response)

View file

@ -16,6 +16,7 @@
# ------------------------------------------------------------------------------
from appy import Object
import collections
# ------------------------------------------------------------------------------
class Page:
@ -53,7 +54,7 @@ class Page:
(c) a Page instance.
This method returns always a Page instance.'''
res = pageData
if res and isinstance(res, basestring):
if res and isinstance(res, str):
# Page data is given as a string.
pageElems = pageData.rsplit('_', 1)
if len(pageElems) == 1: # We have case (a)

View file

@ -16,7 +16,7 @@
# ------------------------------------------------------------------------------
import time, os, os.path
from file import FileInfo
from .file import FileInfo
from appy import Object
from appy.fields import Field
from appy.px import Px
@ -25,6 +25,7 @@ from appy.gen import utils as gutils
from appy.pod import PodError
from appy.pod.renderer import Renderer
from appy.shared import utils as sutils
import collections
# ------------------------------------------------------------------------------
class Mailing:
@ -170,7 +171,7 @@ class Pod(Field):
# of your app will be referred as "Test.odt" in self.template. If it is
# stored within sub-folder "pod", it will be referred as "pod/Test.odt".
if not template: raise Exception(Pod.NO_TEMPLATE)
if isinstance(template, basestring):
if isinstance(template, str):
self.template = [template]
elif isinstance(template, tuple):
self.template = list(template)
@ -396,7 +397,7 @@ class Pod(Field):
formats = self.showTemplate(obj, template)
if not formats: continue
elif isinstance(formats, bool): formats = self.formats
elif isinstance(formats, basestring): formats = (formats,)
elif isinstance(formats, str): formats = (formats,)
res.append(Object(template=template, formats=formats,
freezeFormats=self.getFreezeFormats(obj, template)))
return res
@ -525,7 +526,7 @@ class Pod(Field):
templatePath = self.getTemplatePath(diskFolder, template)
# Get or compute the specific POD context
specificContext = None
if callable(self.context):
if isinstance(self.context, collections.Callable):
specificContext = self.callMethod(obj, self.context)
else:
specificContext = self.context
@ -544,7 +545,7 @@ class Pod(Field):
# Retrieve query params
cmd = ', '.join(Pod.queryParams)
cmd += " = queryData.split(';')"
exec cmd
exec(cmd)
# (re-)execute the query, but without any limit on the number of
# results; return Appy objects.
objs = tool.o.executeQuery(obj.o.portal_type, searchName=search,
@ -559,7 +560,7 @@ class Pod(Field):
# when generating frozen documents).
if '_checked' not in podContext: podContext['_checked'] = Object()
# Define a potential global styles mapping
if callable(self.stylesMapping):
if isinstance(self.stylesMapping, collections.Callable):
stylesMapping = self.callMethod(obj, self.stylesMapping)
else:
stylesMapping = self.stylesMapping
@ -575,7 +576,7 @@ class Pod(Field):
try:
renderer = Renderer(**rendererParams)
renderer.run()
except PodError, pe:
except PodError as pe:
if not os.path.exists(result):
# In some (most?) cases, when OO returns an error, the result is
# nevertheless generated.
@ -643,7 +644,7 @@ class Pod(Field):
# Generate the document
doc = self.getValue(obj, template=template, format=format,
result=result)
if isinstance(doc, basestring):
if isinstance(doc, str):
# An error occurred, the document was not generated.
obj.log(self.FREEZE_ERROR % (format, self.name, doc),
type='error')
@ -658,7 +659,7 @@ class Pod(Field):
obj.log('freeze: overwriting %s...' % result)
doc = self.getValue(obj, template=template, format='odt',
result=result)
if isinstance(doc, basestring):
if isinstance(doc, str):
self.log(self.FREEZE_ERROR % ('odt', self.name, doc),
type='error')
raise Exception(self.FREEZE_FATAL_ERROR)
@ -762,7 +763,7 @@ class Pod(Field):
res = self.getValue(obj, template=template, format=format,
queryData=rq.get('queryData'),
customContext=self.getCustomContext(obj, rq))
if isinstance(res, basestring):
if isinstance(res, str):
# An error has occurred, and p_res contains the error message
obj.say(res)
return tool.goto(rq.get('HTTP_REFERER'))

View file

@ -23,6 +23,7 @@ from appy.px import Px
from appy.gen.layout import Table
from appy.gen import utils as gutils
from appy.shared import utils as sutils
import collections
# ------------------------------------------------------------------------------
class Ref(Field):
@ -826,7 +827,7 @@ class Ref(Field):
# If this field is an ajax-updatable slave, no need to compute
# possible values: it will be overridden by method self.masterValue
# by a subsequent ajax request (=the "if" statement above).
if self.masterValue and callable(self.masterValue):
if self.masterValue and isinstance(self.masterValue, collections.Callable):
objects = []
else:
if not self.select:
@ -921,7 +922,7 @@ class Ref(Field):
res = self.getAttribute(obj, 'numbered')
if not res: return res
# Returns the column width.
if not isinstance(res, basestring): return '15px'
if not isinstance(res, str): return '15px'
return res
def getMenuUrl(self, zobj, tied):
@ -996,14 +997,14 @@ class Ref(Field):
# Also ensure that multiplicities are enforced.
if not value:
nbOfRefs = 0
elif isinstance(value, basestring):
elif isinstance(value, str):
nbOfRefs = 1
else:
nbOfRefs = len(value)
minRef = self.multiplicity[0]
maxRef = self.multiplicity[1]
if maxRef == None:
maxRef = sys.maxint
maxRef = sys.maxsize
if nbOfRefs < minRef:
return obj.translate('min_ref_violated')
elif nbOfRefs > maxRef:
@ -1119,7 +1120,7 @@ class Ref(Field):
if type(objects) not in sutils.sequenceTypes: objects = [objects]
tool = obj.getTool()
for i in range(len(objects)):
if isinstance(objects[i], basestring):
if isinstance(objects[i], str):
# We have an UID here
objects[i] = tool.getObject(objects[i], appy=True)
else:

View file

@ -19,7 +19,7 @@ from appy.px import Px
from appy.gen import utils as gutils
from appy.gen.indexer import defaultIndexes
from appy.shared import utils as sutils
from group import Group
from .group import Group
# ------------------------------------------------------------------------------
class Search:
@ -85,12 +85,12 @@ class Search:
(fieldName == 'SearchableText'):
# For TextIndex indexes. We must split p_fieldValue into keywords.
res = gutils.Keywords(fieldValue).get()
elif isinstance(fieldValue, basestring) and fieldValue.endswith('*'):
elif isinstance(fieldValue, str) and fieldValue.endswith('*'):
v = fieldValue[:-1]
# Warning: 'z' is higher than 'Z'!
res = {'query':(v,v+'z'), 'range':'min:max'}
elif type(fieldValue) in sutils.sequenceTypes:
if fieldValue and isinstance(fieldValue[0], basestring):
if fieldValue and isinstance(fieldValue[0], str):
# We have a list of string values (ie: we need to
# search v1 or v2 or...)
res = fieldValue
@ -118,7 +118,7 @@ class Search:
sortBy and sortOrder (and not "resolve" them to Zope's sort_on and
sort_order).'''
# Put search criteria in p_criteria
for name, value in self.fields.iteritems():
for name, value in self.fields.items():
# Management of searches restricted to objects linked through a
# Ref field: not implemented yet.
if name == '_ref': continue

View file

@ -25,6 +25,7 @@ from appy.shared.data import countries
from appy.shared.xml_parser import XhtmlCleaner
from appy.shared.diff import HtmlDiff
from appy.shared import utils as sutils
import collections
# ------------------------------------------------------------------------------
digit = re.compile('[0-9]')
@ -471,7 +472,7 @@ class String(Field):
res = True
if type(self.validator) in (list, tuple):
for elem in self.validator:
if not isinstance(elem, basestring):
if not isinstance(elem, str):
res = False
break
else:
@ -533,7 +534,7 @@ class String(Field):
if not value:
if self.isMultiValued(): return emptyTuple
else: return value
if isinstance(value, basestring) and self.isMultiValued():
if isinstance(value, str) and self.isMultiValued():
value = [value]
elif isinstance(value, tuple):
value = list(value)
@ -602,8 +603,7 @@ class String(Field):
identifies the language-specific part we will work on.'''
res = None
lastEvent = None
name = language and ('%s-%s' % (self.name, language)) or self.name
for event in obj.workflow_history['appy']:
for event in obj.workflow_history.values()[0]:
if event['action'] != '_datachange_': continue
if name not in event['changes']: continue
if res == None:
@ -660,7 +660,7 @@ class String(Field):
res = obj.formatText(res, format='html')
# If value starts with a carriage return, add a space; else, it will
# be ignored.
if isinstance(res, basestring) and \
if isinstance(res, str) and \
(res.startswith('\n') or res.startswith('\r\n')): res = ' ' + res
return res
@ -774,7 +774,7 @@ class String(Field):
# If this field is an ajax-updatable slave, no need to compute
# possible values: it will be overridden by method self.masterValue
# by a subsequent ajax request (=the "if" statement above).
if self.masterValue and callable(self.masterValue) and \
if self.masterValue and isinstance(self.masterValue, collections.Callable) and \
not ignoreMasterValues: return []
if isinstance(self.validator, Selection):
# We need to call self.methodName for getting the (dynamic)
@ -808,9 +808,9 @@ class String(Field):
obj = brains[0].getObject()
# Do we need to call the method on the object or on the wrapper?
if methodName.startswith('_appy_'):
exec 'res = obj.%s(*args)' % methodName
exec('res = obj.%s(*args)' % methodName)
else:
exec 'res = obj.appy().%s(*args)' % methodName
exec('res = obj.appy().%s(*args)' % methodName)
if not withTranslations: res = [v[0] for v in res]
elif isinstance(res, list): res = res[:]
else:
@ -847,7 +847,7 @@ class String(Field):
elif self.isSelect:
# Check that the value is among possible values
possibleValues = self.getPossibleValues(obj,ignoreMasterValues=True)
if isinstance(value, basestring):
if isinstance(value, str):
error = value not in possibleValues
else:
error = False
@ -872,7 +872,7 @@ class String(Field):
return value
def getUnilingualStorableValue(self, obj, value):
isString = isinstance(value, basestring)
isString = isinstance(value, str)
isEmpty = Field.isEmptyValue(self, obj, value)
# Apply transform if required
if isString and not isEmpty and (self.transform != 'none'):
@ -1021,7 +1021,7 @@ class String(Field):
if self.allowImageUpload:
ckAttrs['filebrowserUploadUrl'] = '%s/upload' % obj.absolute_url()
ck = []
for k, v in ckAttrs.iteritems():
for k, v in ckAttrs.items():
if isinstance(v, int): sv = str(v)
if isinstance(v, bool): sv = str(v).lower()
else: sv = '"%s"' % v
@ -1059,7 +1059,7 @@ class String(Field):
name containing a row number from a field within a list field.'''
rq = obj.REQUEST
# Get the value we must compare (from request or from database)
if rq.has_key(fieldName):
if fieldName in rq:
compValue = rq.get(fieldName)
else:
compValue = dbValue

View file

@ -14,10 +14,12 @@
# You should have received a copy of the GNU General Public License along with
# Appy. If not, see <http://www.gnu.org/licenses/>.
# ------------------------------------------------------------------------------
import types, string
from group import Group
import types
import .string
from .group import Group
from appy.px import Px
from appy.gen.utils import User
import collections
# Default Appy permissions -----------------------------------------------------
r, w, d = ('read', 'write', 'delete')
@ -73,7 +75,7 @@ class State:
exists, or creates a Role instance, puts it in self.usedRoles and
returns it else. If it is a Role instance, the method stores it in
self.usedRoles if it is not in it yet and returns it.'''
if isinstance(role, basestring):
if isinstance(role, str):
if role in self.usedRoles:
return self.usedRoles[role]
else:
@ -88,24 +90,24 @@ class State:
def standardizeRoles(self):
'''This method converts, within self.permissions, every role to a
Role instance. Every used role is stored in self.usedRoles.'''
for permission, roles in self.permissions.iteritems():
for permission, roles in self.permissions.items():
if not roles: continue # Nobody may have this permission
if isinstance(roles, basestring) or isinstance(roles, Role):
if isinstance(roles, str) or isinstance(roles, Role):
self.permissions[permission] = [self.getRole(roles)]
elif isinstance(roles, list):
for i in range(len(roles)): roles[i] = self.getRole(roles[i])
else: # A tuple
self.permissions[permission] = [self.getRole(r) for r in roles]
def getUsedRoles(self): return self.usedRoles.values()
def getUsedRoles(self): return list(self.usedRoles.values())
def addRoles(self, roleNames, permissions=()):
'''Adds p_roleNames in self.permissions. If p_permissions is specified,
roles are added to those permissions only. Else, roles are added for
every permission within self.permissions.'''
if isinstance(roleNames, basestring): roleNames = (roleNames,)
if isinstance(permissions, basestring): permissions = (permissions,)
for perm, roles in self.permissions.iteritems():
if isinstance(roleNames, str): roleNames = (roleNames,)
if isinstance(permissions, str): permissions = (permissions,)
for perm, roles in self.permissions.items():
if permissions and (perm not in permissions): continue
for roleName in roleNames:
# Do nothing if p_roleName is already almong roles.
@ -124,9 +126,9 @@ class State:
'''Removes p_roleNames within dict self.permissions. If p_permissions is
specified, removal is restricted to those permissions. Else, removal
occurs throughout the whole dict self.permissions.'''
if isinstance(roleNames, basestring): roleNames = (roleNames,)
if isinstance(permissions, basestring): permissions = (permissions,)
for perm, roles in self.permissions.iteritems():
if isinstance(roleNames, str): roleNames = (roleNames,)
if isinstance(permissions, str): permissions = (permissions,)
for perm, roles in self.permissions.items():
if permissions and (perm not in permissions): continue
for roleName in roleNames:
# Remove this role if present in roles for this permission.
@ -138,9 +140,9 @@ class State:
def setRoles(self, roleNames, permissions=()):
'''Sets p_rolesNames for p_permissions if not empty, for every
permission in self.permissions else.'''
if isinstance(roleNames, basestring): roleNames = (roleNames,)
if isinstance(permissions, basestring): permissions = (permissions,)
for perm in self.permissions.iterkeys():
if isinstance(roleNames, str): roleNames = (roleNames,)
if isinstance(permissions, str): permissions = (permissions,)
for perm in self.permissions.keys():
if permissions and (perm not in permissions): continue
roles = self.permissions[perm] = []
for roleName in roleNames:
@ -150,8 +152,8 @@ class State:
'''Replaces p_oldRoleName by p_newRoleName. If p_permissions is
specified, the replacement is restricted to those permissions. Else,
replacements apply to the whole dict self.permissions.'''
if isinstance(permissions, basestring): permissions = (permissions,)
for perm, roles in self.permissions.iteritems():
if isinstance(permissions, str): permissions = (permissions,)
for perm, roles in self.permissions.items():
if permissions and (perm not in permissions): continue
# Find and delete p_oldRoleName
for role in roles:
@ -170,7 +172,7 @@ class State:
worklflow, this method will always return True (I mean: in this case,
having an isolated state does not mean the state has been
deactivated).'''
for tr in wf.__dict__.itervalues():
for tr in wf.__dict__.values():
if not isinstance(tr, Transition): continue
if not tr.hasState(self, True): continue
# Transition "tr" has this state as start state. If the end state is
@ -200,7 +202,7 @@ class Transition:
# be useful for "undo" transitions, for example.
self.states = self.standardiseStates(states)
self.condition = condition
if isinstance(condition, basestring):
if isinstance(condition, str):
# The condition specifies the name of a role.
self.condition = Role(condition)
self.action = action
@ -276,7 +278,7 @@ class Transition:
def isShowable(self, workflow, obj):
'''Is this transition showable?'''
if callable(self.show):
if isinstance(self.show, collections.Callable):
return self.show(workflow, obj.appy())
else:
return self.show
@ -330,7 +332,7 @@ class Transition:
for condition in self.condition:
# "Unwrap" role names from Role instances
if isinstance(condition, Role): condition = condition.name
if isinstance(condition, basestring): # It is a role
if isinstance(condition, str): # It is a role
if hasRole == None:
hasRole = False
if user.has_role(condition, obj):
@ -450,7 +452,7 @@ class Transition:
transition = getattr(workflow, transition)
# Browse all transitions and find the one starting at p_transition's end
# state and coming back to p_transition's start state.
for trName, tr in workflow.__dict__.iteritems():
for trName, tr in workflow.__dict__.items():
if not isinstance(tr, Transition) or (tr == transition): continue
if transition.isSingle():
if tr.hasState(transition.states[1], True) and \