Commit ff013ffd authored by Arnaud Fontaine's avatar Arnaud Fontaine

WIP

parent 0a64b8cb
......@@ -197,7 +197,7 @@ class SQLNonContinuousIncreasingIdGenerator(IdGenerator):
if not (self.last_max_id_dict or
getattr(portal_ids, 'dict_length_ids', None) is None):
dump_dict = portal_ids.dict_length_ids
for id_group, last_id in dump_dict.items():
for id_group, last_id in list(dump_dict.items()):
last_insert_id = get_last_id_method(id_group=id_group)
last_id = int(last_id.value)
if len(last_insert_id) != 0:
......@@ -261,7 +261,7 @@ class SQLNonContinuousIncreasingIdGenerator(IdGenerator):
if not isinstance(id_dict, dict):
raise TypeError('the argument given is not a dictionary')
new_id_dict = {}
for key, value in id_dict.items():
for key, value in list(id_dict.items()):
if isinstance(value, int):
set_last_id_method(id_group=key, last_id=value)
# The id must be a ScalarMaxConflictResolver object for the persistent dict
......
......@@ -82,7 +82,7 @@ class SolverTypeInformation(Predicate, ERP5TypeInformation):
# Default Implementation (use categories and trivial case)
# this default implementation should be applicable to most
# solvers so that use of Type Based methods is very rare
for solver, configuration_list in movement_dict[movement].items():
for solver, configuration_list in list(movement_dict[movement].items()):
if solver is not self and solver.getTestedProperty() == self.getTestedProperty():
return AppropriateUIMessage(whatever) # XXX-TODO
......
......@@ -95,8 +95,8 @@ class StringAttributeMatchConstraint(PropertyExistenceConstraint):
'title' : '^[^ ]'
}
"""
property_list = property_dict.keys()
regex_list = property_dict.values()
property_list = list(property_dict.keys())
regex_list = list(property_dict.values())
regex_list_len = len(regex_list)
seen_property_set = set()
for property_index, property_id in enumerate(property_list):
......
......@@ -107,7 +107,7 @@ class ZODBContinuousIncreasingIdGenerator(IdGenerator):
portal_ids = getattr(self, 'portal_ids', None)
# Dump the dict_ids dictionary
if getattr(portal_ids, 'dict_ids', None) is not None:
for id_group, last_id in portal_ids.dict_ids.items():
for id_group, last_id in list(portal_ids.dict_ids.items()):
if not isinstance(id_group, str):
id_group = repr(id_group)
if id_group in self.last_id_dict and \
......
......@@ -46,6 +46,7 @@ from Products.ERP5Type.dynamic.portal_type_class import synchronizeDynamicModule
from Products.ERP5Type.mixin.response_header_generator import ResponseHeaderGenerator
from zLOG import LOG, INFO, WARNING, ERROR
from zExceptions import BadRequest
import os
import warnings
import transaction
......@@ -2267,7 +2268,10 @@ class ERP5Generator(PortalGenerator):
workflow_list = ['business_template_building_workflow',
'business_template_installation_workflow']
tool = p.portal_workflow
tool.manage_delObjects(filter(tool.hasObject, workflow_list))
try:
tool.manage_delObjects(list(filter(tool.hasObject, workflow_list)))
except BadRequest:
pass
self.bootstrap(tool, 'erp5_core', 'WorkflowTemplateItem', workflow_list)
getattr(p.portal_types, 'Business Template').setTypeWorkflowList(workflow_list)
......
......@@ -206,7 +206,7 @@ class InteractionWorkflowDefinition (DCWorkflowDefinition, ActiveObject):
security.declareProtected(Permissions.AccessContentsInformation, 'getTransitionValueList')
def getTransitionValueList(self):
if self.interactions is not None:
return self.interactions.values()
return list(self.interactions.values())
return []
security.declareProtected(Permissions.AccessContentsInformation, 'getTransitionReferenceList')
......@@ -218,7 +218,7 @@ class InteractionWorkflowDefinition (DCWorkflowDefinition, ActiveObject):
security.declareProtected(Permissions.AccessContentsInformation, 'getVariableValueList')
def getVariableValueList(self):
if self.variables is not None:
return self.variables.values()
return list(self.variables.values())
return []
security.declareProtected(Permissions.AccessContentsInformation, 'getPortalType')
......
......@@ -113,7 +113,7 @@ class CopyToTarget(TargetSolver):
parent_movement = None
for date_delta in ('start_date_delta', 'stop_date_delta'):
if date_delta in value_delta_dict.keys():
if date_delta in list(value_delta_dict.keys()):
if abs(value_delta_dict[date_delta]) <= \
applied_rule.getProperty('max_allowed_delta', max_allowed_delta):
value_delta_dict.pop(date_delta)
......
......@@ -367,7 +367,7 @@ class IdTool(BaseTool):
"""
if getattr(self, 'dict_length_ids', None) is None:
self.dict_length_ids = PersistentMapping()
return self.dict_length_ids.items()
return list(self.dict_length_ids.items())
security.declarePrivate('dumpDictLengthIdsItems')
def dumpDictLengthIdsItems(self):
......
......@@ -27,7 +27,9 @@
#
##############################################################################
from webdav.client import Resource
## XXX: WebDAV client implementation from ZServer
##from webdav.client import Resource
from past.builtins import cmp
from App.config import getConfiguration
......@@ -701,7 +703,7 @@ class TemplateTool (BaseTool):
"""
Get the list of repositories.
"""
return self.repository_dict.keys()
return list(self.repository_dict.keys())
security.declarePublic( 'decodeRepositoryBusinessTemplateUid' )
def decodeRepositoryBusinessTemplateUid(self, uid):
......@@ -775,7 +777,7 @@ class TemplateTool (BaseTool):
tuple (repository, id)
"""
result = None
for repository, property_dict_list in self.repository_dict.items():
for repository, property_dict_list in list(self.repository_dict.items()):
for property_dict in property_dict_list:
provision_list = property_dict.get('provision_list', [])
if title in provision_list:
......@@ -797,7 +799,7 @@ class TemplateTool (BaseTool):
the given business template
"""
result_list = []
for repository, property_dict_list in self.repository_dict.items():
for repository, property_dict_list in list(self.repository_dict.items()):
for property_dict in property_dict_list:
provision_list = property_dict['provision_list']
if (title in provision_list) and (property_dict['title'] not in result_list):
......@@ -817,7 +819,7 @@ class TemplateTool (BaseTool):
# for meta business templates
if bt[0] != 'meta':
result_list = []
for repository, property_dict_list in self.repository_dict.items():
for repository, property_dict_list in list(self.repository_dict.items()):
if repository == bt[0]:
for property_dict in property_dict_list:
if property_dict['id'] == bt[1]:
......@@ -910,7 +912,7 @@ class TemplateTool (BaseTool):
# Calculate the reverse dependency graph
reverse_dependency_dict = {}
for bt_id, dependency_id_list in dependency_dict.items():
for bt_id, dependency_id_list in list(dependency_dict.items()):
update_dependency_id_list = []
for dependency_id in dependency_id_list:
......@@ -1001,7 +1003,7 @@ class TemplateTool (BaseTool):
template_item_list = []
# First of all, filter Business Templates in repositories.
template_item_dict = {}
for repository, property_dict_list in self.repository_dict.items():
for repository, property_dict_list in list(self.repository_dict.items()):
for property_dict in property_dict_list:
title = property_dict['title']
if template_set and not(title in template_set):
......@@ -1023,7 +1025,7 @@ class TemplateTool (BaseTool):
template_item_dict[title] = (repository, property_dict)
# Next, select only updated business templates.
if update_only:
for repository, property_dict in template_item_dict.values():
for repository, property_dict in list(template_item_dict.values()):
installed_bt = \
self.getInstalledBusinessTemplate(property_dict['title'], strict=True)
if installed_bt is not None:
......
......@@ -299,7 +299,7 @@ class Amount(Base, VariatedMixin):
variation_list = resource.getVariationPropertyList()
else:
variation_list = []
for property_id, property_value in property_dict.items():
for property_id, property_value in list(property_dict.items()):
if property_id not in variation_list:
raise KeyError("Can not set the property variation %r" % property_id)
else:
......
......@@ -246,7 +246,7 @@ class AppliedRule(XMLObject, ExplainableMixin):
if sm_list:
r.setdefault(x.getSpecialise(), []).append(sm_list)
# For each rule...
for x in r.values():
for x in list(r.values()):
if len(x) > 1:
# There were several AR applying the same rule.
# Choose the one with a built SM (it will fail if
......@@ -316,7 +316,7 @@ class AppliedRule(XMLObject, ExplainableMixin):
try:
best_sm_list = best_dict[None]
except KeyError:
best_sm_list, = best_dict.values()
best_sm_list, = list(best_dict.values())
if len(best_sm_list) < len(sm_list):
sm_dict[k] = list(set(sm_list).difference(best_sm_list))
sm_list = best_sm_list
......@@ -367,7 +367,7 @@ class AppliedRule(XMLObject, ExplainableMixin):
old_dict[sm] = old_sm
sm = None
deleted = old_dict.items()
deleted = list(old_dict.items())
for delivery, sm_dict in deleted:
if not sm_dict:
del old_dict[delivery]
......@@ -386,7 +386,7 @@ class AppliedRule(XMLObject, ExplainableMixin):
del AppliedRule.isIndexable, SimulationMovement.isIndexable
self.recursiveReindexObject()
assert str not in map(type, old_dict), old_dict
return {k: sum(v.values(), []) for k, v in deleted}, delivery_set
return {k: sum(list(v.values()), []) for k, v in deleted}, delivery_set
simulation_tool._delObject(self.getId())
def _checkExpand(self):
......
......@@ -112,7 +112,7 @@ class ContributionPredicate(Predicate, XMLObject):
tested_base_category[bc] = tested_base_category[bc] or \
context.isMemberOf(c)
result = result and (0 not in tested_base_category.values())
result = result and (0 not in list(tested_base_category.values()))
# Test method calls
test_method_id_list = self.getTestMethodIdList()
if test_method_id_list:
......
......@@ -453,7 +453,7 @@ class DeliveryLine(Movement, XMLMatrix, ImmobilisationMovement):
delivery_dict.get(delivery_path, []) + \
[s_m]
for s_m_list_per_movement in delivery_dict.values():
for s_m_list_per_movement in list(delivery_dict.values()):
total_quantity = sum([quantity_dict.get(s_m, s_m.getQuantity()) \
for s_m in s_m_list_per_movement])
if total_quantity != 0.0:
......
......@@ -476,11 +476,11 @@ class Document(DocumentExtensibleTraversableMixin, XMLObject, UrlMixin,
tmp = {}
for match in rx_search.finditer(text):
group = match.group()
group_item_list = match.groupdict().items()
group_item_list = list(match.groupdict().items())
group_item_list.sort()
key = (group, tuple(group_item_list))
tmp[key] = None
for group, group_item_tuple in tmp.keys():
for group, group_item_tuple in list(tmp.keys()):
result.append((group, dict(group_item_tuple)))
return result
......@@ -581,7 +581,7 @@ class Document(DocumentExtensibleTraversableMixin, XMLObject, UrlMixin,
getRelatedList(self)
lista_latest = {}
for o in lista.keys():
for o in list(lista.keys()):
lista_latest[o.getLatestVersionValue()] = True # get latest versions avoiding duplicates again
# remove this document
......@@ -589,7 +589,7 @@ class Document(DocumentExtensibleTraversableMixin, XMLObject, UrlMixin,
# remove last version of document itself from related documents
lista_latest.pop(self.getLatestVersionValue(), None)
return lista_latest.keys()
return list(lista_latest.keys())
### Version and language getters - might be moved one day to a mixin class in base
security.declareProtected(Permissions.View, 'getLatestVersionValue')
......
......@@ -317,7 +317,7 @@ class ImmobilisableItem(Item, Amount):
Returns a list of dictionaries representing immobilisation periods for the object
from_date is included, to_date is excluded
"""
kw_key_list = kw.keys()
kw_key_list = list(kw.keys())
kw_key_list.sort()
if kw_key_list.count('immo_cache_dict'):
kw_key_list.remove('immo_cache_dict')
......@@ -337,7 +337,7 @@ class ImmobilisableItem(Item, Amount):
previous_period = period_list[-1]
if previous_period['stop_date'] == current_period['start_date']:
if len(keys) == 0:
for key in previous_period.keys():
for key in list(previous_period.keys()):
if key.split('_')[0] == prefix:
current_period[key] = previous_period[key]
else:
......@@ -568,7 +568,7 @@ class ImmobilisableItem(Item, Amount):
extra_cost_price = current_immo_period.get('start_extra_cost_price')
main_price = current_immo_period.get('start_main_price')
current_immo_period['start_price'] = (main_price or 0.) + (extra_cost_price or 0.)
key_list = current_immo_period.keys()
key_list = list(current_immo_period.keys())
for key in key_list:
value = current_immo_period[key]
if key.find('_') != -1:
......@@ -577,7 +577,7 @@ class ImmobilisableItem(Item, Amount):
else:
# A period wich is alone only copies start values to initial ones
# So it may be invalid later
key_list = current_immo_period.keys()
key_list = list(current_immo_period.keys())
for key in key_list:
value = current_immo_period[key]
if key.find('_') != -1:
......
......@@ -277,7 +277,7 @@ class ImmobilisationMovement(Movement, XMLObject):
if (split_char is not None) and (split_qty != 0):
new_parameter_dict = {}
for key in parameter_dict.keys():
for key in list(parameter_dict.keys()):
param_list = parameter_dict[key]
if param_list is None:
new_parameter_dict[key] = []
......
......@@ -291,11 +291,11 @@ class Inventory(Delivery):
# in new inventory
if len(not_used_inventory_dict):
inventory_uid = self.getUid()
for first_level_key in not_used_inventory_dict.keys():
for first_level_key in list(not_used_inventory_dict.keys()):
inventory_value = \
not_used_inventory_dict[tuple(first_level_key)]
# XXX-Aurel : this code does not work with only one level of variation
for second_level_key in inventory_value.keys():
for second_level_key in list(inventory_value.keys()):
diff_quantity = - inventory_value[tuple(second_level_key)]
kwd = {'uid': inventory_uid,
......
......@@ -286,7 +286,7 @@ class SimulationMovement(PropertyRecordableMixin, Movement, ExplainableMixin):
# applicable rule per reference. It indicates a configuration error.
applicable_rule_dict.setdefault(reference, rule)
applicable_rule_list = applicable_rule_dict.values()
applicable_rule_list = list(applicable_rule_dict.values())
for applied_rule in list(self.objectValues()):
rule = applied_rule.getSpecialiseValue()
try:
......
......@@ -21,7 +21,7 @@ class ComputedAttributeGetItemCompatibleMixin(ZSQLBrain):
"""A brain that supports accessing computed attributes using __getitem__
protocol.
"""
def __init__(self):
def __init__(self, *args, **kw):
# __getitem__ returns the computed attribute directly, but if we access
# brain['node_title'] we expect to have the attribute after computation,
# not the ComputedAttribute attribue instance. Defining a __getitem__
......@@ -41,7 +41,10 @@ class ComputedAttributeGetItemCompatibleMixin(ZSQLBrain):
# ComputedAttribute compatibility for __getitem__
# pylint: disable=E0102
def __getitem__(self, name):
item = self.__super__getitem__(name)
try:
item = self.__super__getitem__(name)
except KeyError:
item = self.__getattribute__(name)
if isinstance(item, ComputedAttribute):
return item.__of__(self)
return item
......
......@@ -41,7 +41,7 @@ from OFS.Image import Pdata, Image as OFSImage
from DateTime import DateTime
def makeSortedTuple(kw):
items = kw.items()
items = list(kw.items())
items.sort()
return tuple(items)
......
......@@ -116,7 +116,7 @@ class MailMessageMixin:
way of representing strings in ERP5.
"""
result = {}
for (name, value) in self._getMessage().items():
for (name, value) in list(self._getMessage().items()):
try:
decoded_header = decode_header(value)
except HeaderParseError as error_message:
......@@ -142,7 +142,7 @@ class MailMessageMixin:
result = []
for i, part in enumerate(self._getMessage().walk()):
if not part.is_multipart():
kw = dict(part.items())
kw = dict(list(part.items()))
kw['uid'] = 'part_%s' % i
kw['index'] = i
filename = part.get_filename()
......@@ -182,7 +182,7 @@ class MailMessageMixin:
if index == i:
# This part should be handled in skin script
# but it was a bit easier to access items here
kw = dict(part.items())
kw = dict(list(part.items()))
content_type = part.get_content_type()
if REQUEST is not None:
filename = part.get_filename()
......
......@@ -130,7 +130,7 @@ class MovementCollectionUpdaterMixin:
prevision_to_decision_map.append((None, no_group_list))
# Second, let us create small groups of movements
for tester_key in prevision_movement_dict.keys():
for tester_key in list(prevision_movement_dict.keys()):
for prevision_movement in prevision_movement_dict[tester_key]:
map_list = []
for decision_movement in decision_movement_dict.get(tester_key, ()):
......
......@@ -53,7 +53,7 @@ class SimulableMixin(Base):
"""
tv = getTransactionalVariable()
key = 'SimulableMixin.updateSimulation', self.getUid()
item_list = kw.items()
item_list = list(kw.items())
try:
kw, ignore = tv[key]
kw.update(item_list)
......
......@@ -120,7 +120,7 @@ def addToDate(date, to_add=None, **kw):
if 1 > return_value[key] % 1 > 0:
return_value[lesser_key_dict[key]] += return_value[key] % 1 * number_less_of_in_dict[key]
return_value[key] = int(return_value[key])
for local_key in return_value.keys():
for local_key in list(return_value.keys()):
if local_key not in ('day', 'year'):
treatPositiveValues(return_value, local_key)
......@@ -197,7 +197,7 @@ def getIntervalBetweenDates(from_date=None, to_date=None,
to_inverse = 0
diff_value = {}
for key in keys.keys():
for key in list(keys.keys()):
if key:
diff_value[key] = 0
......@@ -212,7 +212,7 @@ def getIntervalBetweenDates(from_date=None, to_date=None,
diff_value['day'] = round(to_date - from_date)
returned_value = {}
for key, value in diff_value.items():
for key, value in list(diff_value.items()):
if to_inverse:
returned_value[key] = -value
else:
......
......@@ -110,7 +110,7 @@ class MovementGroupNode:
Get property dict for the futur created object
"""
property_dict = getattr(self, '_property_dict', {}).copy()
for key in property_dict.keys():
for key in list(property_dict.keys()):
if key.startswith('_'):
del(property_dict[key])
return property_dict
......@@ -423,10 +423,10 @@ class FakeMovement:
"""
price_dict = self._getPriceDict()
if len(price_dict) == 1:
return price_dict.keys()[0]
return list(price_dict.keys())[0]
total_quantity = sum(price_dict.values())
return (total_quantity and
sum(price * quantity for price, quantity in price_dict.items())
sum(price * quantity for price, quantity in list(price_dict.items()))
/ float(total_quantity))
def getAddQuantity(self):
......@@ -455,7 +455,7 @@ class FakeMovement:
Return total price
"""
price_dict = self._getPriceDict()
return sum(price * quantity for price, quantity in price_dict.items())
return sum(price * quantity for price, quantity in list(price_dict.items()))
def recursiveReindexObject(self, *args, **kw):
"""
......
......@@ -51,7 +51,7 @@ class TextContent:
# this is probably not html code, try rfc822 parsing
message = email.message_from_string(text)
return {k.capitalize(): '\n'.join(message.get_all(k))
for k in message.keys()}
for k in list(message.keys())}
headers = collections.defaultdict(list)
for meta in tree.iterfind(".//meta"):
......
for k, v in kw.items():
for k, v in list(kw.items()):
if v:
if k == "str_object_path":
kw["path"] = v
......
......@@ -4,7 +4,7 @@ translation_list = [
newTempBase(context, 'property_domain_dict/'+k, uid=k,
property_name=v.getPropertyName(),
domain_name=v.getDomainName())
for k, v in context.getPropertyTranslationDomainDict().items()]
for k, v in list(context.getPropertyTranslationDomainDict().items())]
translation_list.sort(key=lambda x: x.getId())
return translation_list
......@@ -131,7 +131,7 @@ if len(listbox_id_list):
for listbox_id in listbox_id_list:
listbox_line_list = []
listbox = kw[listbox_id]
listbox_keys = listbox.keys()
listbox_keys = list(listbox.keys())
listbox_keys.sort()
for key in listbox_keys:
listbox_line = listbox[key]
......@@ -166,7 +166,7 @@ if listbox_uid is not None and 'list_selection_name' in kw:
listbox_uid, uids)
# Remove values which doesn't work with make_query.
clean_kw = {}
for k, v in kw.items() :
for k, v in list(kw.items()) :
if v not in (None, [], ()) :
clean_kw[k] = kw[k]
......
......@@ -60,12 +60,12 @@ def editListBox(listbox_field, listbox):
hidden_attribute_list = [x[0] for x in listbox_field.get_value('global_attributes')]
for hidden_attribute in hidden_attribute_list:
global_property_dict[hidden_attribute] = getattr(request, hidden_attribute, None)
for item_url, listbox_item_dict in listbox.items():
for item_url, listbox_item_dict in list(listbox.items()):
listbox_item_dict.update(global_property_dict)
# Form: '' -> ERP5: None
encapsulated_editor_list = []
cleaned_v = {}
for key, value in listbox_item_dict.items():
for key, value in list(listbox_item_dict.items()):
if hasattr(value, 'edit'):
encapsulated_editor_list.append(value)
else:
......@@ -157,7 +157,7 @@ def editMatrixBox(matrixbox_field, matrixbox):
if cell_range != matrixbox_cell_range:
matrix_context.setCellRange(base_id=cell_base_id, *matrixbox_cell_range)
for cell_index_tuple, cell_dict in matrixbox.items():
for cell_index_tuple, cell_dict in list(matrixbox.items()):
# Only update cells which still exist
if matrix_context.hasInRange(*cell_index_tuple, **k_dict):
cell = matrix_context.newCell(*cell_index_tuple, **k_dict)
......@@ -175,7 +175,7 @@ def editMatrixBox(matrixbox_field, matrixbox):
cell_dict[key] = variated_property
# Form: '' -> ERP5: None
cleaned_v = cell_dict.copy()
for key, value in cleaned_v.items():
for key, value in list(cleaned_v.items()):
if value == '':
cleaned_v[key] = None
cell.edit(edit_order=edit_order, **cleaned_v) # and update the cell specific values
......
......@@ -24,7 +24,7 @@ else:
request = container.REQUEST
request_form = request.form
for k in request_form.keys():
for k in list(request_form.keys()):
del request_form[k]
request.form.update(old_request)
......
......@@ -61,12 +61,12 @@ def getIDFromString(string=None):
# Replace odd chars by safe ascii
string = string.lower()
string = string.strip()
for (safe_char, char_list) in translation_map.items():
for (safe_char, char_list) in list(translation_map.items()):
for char in char_list:
string = string.replace(char, safe_char)
# Exclude all non alphanumeric chars
for char in string:
if char.isalnum() or char in translation_map.keys():
if char.isalnum() or char in list(translation_map.keys()):
clean_id += char
# Delete leading and trailing char which are not alpha-numerics
# This prevent having IDs with starting underscores
......@@ -99,7 +99,7 @@ else:
spreadsheet_list = parser.getSpreadsheetsMapping(no_empty_lines=True)
for table_name in spreadsheet_list.keys():
for table_name in list(spreadsheet_list.keys()):
sheet = spreadsheet_list[table_name]
if not sheet:
continue
......@@ -112,7 +112,7 @@ for table_name in spreadsheet_list.keys():
for column in columns_header:
column_id = getIDFromString(column)
# This give us the information that the path definition has started
path_def_started = 'path_0' in property_map.values()
path_def_started = 'path_0' in list(property_map.values())
# The path of the category has started to be expressed
if column_id == 'path':
property_map[column_index] = 'path_' + str(path_index)
......@@ -177,7 +177,7 @@ for table_name in spreadsheet_list.keys():
# Analyse every cell of the line
category_property_list = {}
cell_index = 0
for (property_id, cell_data) in line_data.items():
for (property_id, cell_data) in list(line_data.items()):
# Try to generate a cell id from cell data
cell_id = getIDFromString(cell_data)
......@@ -223,7 +223,7 @@ for table_name in spreadsheet_list.keys():
category_property_list['path'] = path
# Save the current raw path item value as title if no title column defined
if 'title' not in category_property_list.keys():
if 'title' not in list(category_property_list.keys()):
clean_title = cell_data.strip()
# Only set title if it look like a title
# (i.e. its tranformation to ID is not the same as the original value)
......@@ -280,7 +280,7 @@ for table_name in spreadsheet_list.keys():
# Proceed to next cell
cell_index += 1
line_index += 1
if len(category_property_list) > 0 and 'path' in category_property_list.keys():
if len(category_property_list) > 0 and 'path' in list(category_property_list.keys()):
category_list.append(category_property_list)
if error_list:
return {'error_list':error_list}
......
......@@ -31,4 +31,4 @@ for item in item_list:
# Return the list of subfield configuration.
return sub_field_dict.values()
return list(sub_field_dict.values())
......@@ -42,4 +42,4 @@ for item in item_list:
# Return the list of subfield configuration.
return sub_field_dict.values()
return list(sub_field_dict.values())
......@@ -21,7 +21,7 @@ for char in s.encode('iso8859_1'):
elif char.isspace() or char in ('+', '-'):
clean_id += '_'
else:
for (safe_char, char_list) in translation_map.items():
for (safe_char, char_list) in list(translation_map.items()):
if char in char_list:
clean_id += safe_char
break
......
......@@ -41,7 +41,7 @@ for workflow_item in workflow_item_list:
# XXX removing str method generate a strange bug
o = newTempBase(portal_object, str(i))
i += 1
for key, value in workflow_item.items():
for key, value in list(workflow_item.items()):
if key == 'serial' and not can_view_history:
continue
if key == wf_state_variable:
......
......@@ -114,7 +114,7 @@ def recurseSyntaxNode(node, criterion=DEFAULT_CRITERION_ALIAS):
result[criterion] = [node.getValue()]
else:
for subnode in node.getNodeList():
for criterion, value_list in recurseSyntaxNode(subnode, criterion=criterion).items():
for criterion, value_list in list(recurseSyntaxNode(subnode, criterion=criterion).items()):
result.setdefault(criterion, []).extend(value_list)
return result
......@@ -126,15 +126,15 @@ result = {}
if node is None:
result['searchabletext'] = searchstring
else:
for criterion, value_list in recurseSyntaxNode(node).items():
for criterion, value_list in list(recurseSyntaxNode(node).items()):
criterion, value_list = resolveCriterion(criterion, value_list)
result.setdefault(criterion, []).extend(value_list)
filtered_result = {}
for criterion, value_list in result.items():
for criterion, value_list in list(result.items()):
if len(value_list) > 0:
filtered_result[criterion] = value_list
result = filtered_result
for criterion, value_list in result.items():
for criterion, value_list in list(result.items()):
# XXX: yuck
if criterion == 'searchabletext':
result['searchabletext'] = ' '.join(value_list)
......
......@@ -41,7 +41,7 @@ erp5_role_dict = {
# Add ERP5 permissions
erp5_permission_dict = {}
for role,permission_list in erp5_role_dict.items():
for role,permission_list in list(erp5_role_dict.items()):
for permission in permission_list:
if permission not in erp5_permission_dict:
erp5_permission_dict[permission] = []
......
......@@ -4,7 +4,7 @@ if kw.get('update', False):
# Ensure ERP5JS correctly refresh the page
request.RESPONSE.setStatus(400)
for k in kw.keys():
for k in list(kw.keys()):
v = kw[k]
if k.endswith('listbox'):
listbox = {}
......
from Products.ERP5Type.Message import translateString
choosen = [choice for choice in editor.values() if choice['workflow_action']]
choosen = [choice for choice in list(editor.values()) if choice['workflow_action']]
if len(choosen) == 1:
return True
......
......@@ -13,7 +13,7 @@ from pprint import pformat
ret = '<html><body><table width=100%>\n'
property_dict = context.showDict().items()
property_dict = list(context.showDict().items())
property_dict.sort()
i = 0
for k,v in property_dict:
......
......@@ -35,7 +35,7 @@ if p.portal_templates.compareVersions(bt1.getVersion(), bt2.getVersion()) < 0:
else:
modified_object_list = getModifiedObjectList(bt1, bt2)
keys = modified_object_list.keys()
keys = list(modified_object_list.keys())
keys.sort()
i = 0
......
......@@ -155,12 +155,12 @@ for skin_folder_id in skin_id_list:
# The nice developper probably have a good reason not to do it.
modified_object_dict[field_path] = '0_keep_non_proxy_field'
for field_path, proxy_field_list in field_library_dict.items():
for field_path, proxy_field_list in list(field_library_dict.items()):
if not proxy_field_list:
modified_object_dict[field_path] = '0_unused_proxy_field'
i = 0
for key, value in modified_object_dict.items():
for key, value in list(modified_object_dict.items()):
line = newTempBase(context, 'tmp_install_%s' %(str(i)))
if isinstance(value, tuple):
value, template_id = value
......
......@@ -20,7 +20,7 @@ getModifiedObjectList = CachingMethod(getModifiedObjectList,
cache_id_generator=cache_id_generator)
modified_object_list = getModifiedObjectList(context)
keys = modified_object_list.keys()
keys = list(modified_object_list.keys())
keys.sort()
no_backup_list = ['Action', 'SiteProperty', 'Module', 'Document',
......
......@@ -27,7 +27,7 @@ for base_category_id in preferred_predicate_category_list:
# Add an empty record only if document does not have the category value and the category is enabled on the document.
category_parent_uid_item_dict[base_category_uid] = [[0, base_category_uid, 1]]
uid_item_list_list = category_parent_uid_item_dict.values()
uid_item_list_list = list(category_parent_uid_item_dict.values())
if uid_item_list_list:
return reduce(lambda a,b:a+b, uid_item_list_list)
return ()
......@@ -19,7 +19,7 @@ for error in error_list:
#print error
return_list.append(error)
for portal_type in nb_types.keys():
for portal_type in list(nb_types.keys()):
# Find the number of each portal type in the catalog
count_result = context.portal_catalog.countResults(portal_type=portal_type)
nb_catalog = count_result[0][0]
......
......@@ -24,7 +24,7 @@ else:
if len(filtered_uid_dict.keys()) > 0 :
selection_tool.checkAll(selection_name, uids, REQUEST=None)
selection_tool.setSelectionToIds(selection_name,
filtered_uid_dict.keys(), REQUEST=request)
list(filtered_uid_dict.keys()), REQUEST=request)
url = selection_tool.getSelectionListUrlFor(
selection_name, REQUEST=request)
......
......@@ -19,7 +19,7 @@ if hasattr(request, listbox_id):
# initialize the listbox
listbox=request[listbox_id]
keys_list = listbox.keys()
keys_list = list(listbox.keys())
if keys_list != []:
keys_list.sort(key=int)
......
......@@ -37,7 +37,7 @@ try:
hidden_attributes = [x[0] for x in listbox_field.get_value('global_attributes')]
for k in hidden_attributes:
gv[k] = getattr(request, k,None)
for property_, v in listbox.items():
for property_, v in list(listbox.items()):
v.update(gv)
context.setCriterion(property_, **v)
# Update basic attributes
......
......@@ -20,7 +20,7 @@ if statistics_criteria == 'total':
result = []
counter = 0
for cache_key,cache_key_memory in cache_plugin_stats_data.items():
for cache_key,cache_key_memory in list(cache_plugin_stats_data.items()):
obj = newTempBase(context,
'temp_translation_%d' %counter,
cache_key = cache_key,
......
......@@ -31,4 +31,4 @@ for item in item_list:
if item_value in value_list:
sub_field_dict[item_key]['value'] = item_value
return sub_field_dict.values()
return list(sub_field_dict.values())
......@@ -37,7 +37,7 @@ for skin_name, skin_path_list in skins_tool.getSkinPaths():
# leave only duplicating ones
duplicating_selection_name_dict = {}
for selection_name, field_list in selection_name_dict.items():
for selection_name, field_list in list(selection_name_dict.items()):
if len(field_list) > 1:
duplicating_selection_name_dict[selection_name] = field_list
......
......@@ -45,7 +45,7 @@ save_and_remove_title = Base_translateString('Backup And Remove')
for bt in bt_id_list:
bt_title, modified_object_list = bt_object_dict[bt]
keys = modified_object_list.keys()
keys = list(modified_object_list.keys())
keys.sort()
for i, object_id in enumerate(keys):
object_state, object_class = modified_object_list[object_id]
......
......@@ -143,7 +143,7 @@ class PortalPatch(Explicit):
diff_tree_list = []
# Flatten the list of DiffValues
for key, subset in tree_diff.items():
for key, subset in list(tree_diff.items()):
if isinstance(subset, set):
sublist = list(subset)
for item in sublist:
......
......@@ -336,7 +336,7 @@ class DomainTool(BaseTool):
mapped_value = self.getPortalObject().newContent(temp_object=True,
portal_type='Supply Cell', id='multivalued_mapped_value')
mapped_value._setMappedValuePropertyList(
mapped_value_property_dict.keys())
list(mapped_value_property_dict.keys()))
mapped_value.__dict__.update(mapped_value_property_dict)
return mapped_value
......
......@@ -145,7 +145,7 @@ class IntrospectionTool(LogMixin, BaseTool):
# Unlazyfy URLs and other lazy values so that it can be marshalled
result = {}
for key, action_list in erp5_menu_dict.items():
for key, action_list in list(erp5_menu_dict.items()):
result[key] = [ dict(action) for action in action_list ]
return result
......
......@@ -129,11 +129,11 @@ def buildEmailMessage(from_url, to_url, msg=None,
message.attach(MIMEText(msg, _charset='utf-8'))
if extra_headers:
for key, value in extra_headers.items():
for key, value in list(extra_headers.items()):
message.add_header('X-%s' % key, value)
if additional_headers:
for key, value in additional_headers.items():
for key, value in list(additional_headers.items()):
message.add_header(key, value)
if subject:
......
......@@ -232,7 +232,7 @@ class PasswordTool(BaseTool):
"""
current_date = DateTime()
password_request_dict = self._password_request_dict
for key, (_, date) in password_request_dict.items():
for key, (_, date) in list(password_request_dict.items()):
if date < current_date:
del password_request_dict[key]
......
......@@ -112,4 +112,4 @@ class RoundingTool(BaseTool):
Return the possible decimal rounding option item list which is provided
by python standard decimal module.
"""
return ROUNDING_OPTION_DICT.items()
return list(ROUNDING_OPTION_DICT.items())
......@@ -56,7 +56,7 @@ def remove_acquisition_wrapper(obj):
if isinstance(obj, collections.Mapping):
return obj.__class__({
remove_acquisition_wrapper(k): remove_acquisition_wrapper(v)
for k, v in obj.items()})
for k, v in list(obj.items())})
if isinstance(obj, (collections.Sequence, collections.Set)):
return obj.__class__([remove_acquisition_wrapper(o) for o in obj])
return obj
......@@ -70,7 +70,7 @@ def restore_acquisition_wrapper(obj, context):
if isinstance(obj, collections.Mapping):
return obj.__class__({
restore_acquisition_wrapper(k, context): restore_acquisition_wrapper(v, context)
for k, v in obj.items()})
for k, v in list(obj.items())})
if isinstance(obj, (collections.Sequence, collections.Set)):
return obj.__class__([restore_acquisition_wrapper(o, context) for o in obj])
return obj
......@@ -126,7 +126,7 @@ class Session(UserDict):
def edit(self, **kw):
""" Edit session object. """
for key, item in kw.items():
for key, item in list(kw.items()):
self.__setitem__(key, item)
def __setitem__(self, key, item):
......
......@@ -48,7 +48,12 @@ from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery, SimpleQuery
from Shared.DC.ZRDB.Results import Results
from Products.ERP5Type.Utils import mergeZRDBResults
from App.Extensions import getBrain
# pylint:disable=no-name-in-module
try: # BBB Zope 2.12
from App.Extensions import getBrain
except ImportError:
from Shared.DC.ZRDB.DA import getBrain
# pylint:enable=no-name-in-module
from MySQLdb import ProgrammingError
from MySQLdb.constants.ER import NO_SUCH_TABLE
......@@ -516,7 +521,7 @@ class SimulationTool(BaseTool):
)
from_table_dict[alias] = table
sql_kw.update(catalog_sql_kw)
sql_kw['from_table_list'] = from_table_dict.items()
sql_kw['from_table_list'] = list(from_table_dict.items())
return sql_kw
def _generateKeywordDict(self,
......@@ -1609,7 +1614,7 @@ class SimulationTool(BaseTool):
line_key = getInventoryListKey(line)
line_a = inventory_list_dict.get(line_key)
inventory_list_dict[line_key] = addLineValues(line_a, line)
sorted_inventory_list = inventory_list_dict.values()
sorted_inventory_list = list(inventory_list_dict.values())
# Sort results manually when required
sort_on = new_kw.get('sort_on')
if sort_on:
......
......@@ -120,7 +120,7 @@ def utf8Encode(chaine) :
if charsetSite.lower() in ("utf-8", "utf8"):
return chaine
else:
return unicode(chaine, charsetSite, errors).encode("utf-8", errors)
return str(chaine, charsetSite, errors).encode("utf-8", errors)
def utf8Decode(chaine) :
# because browser upload form is in utf-8 we need it
......@@ -129,7 +129,7 @@ def utf8Decode(chaine) :
return chaine
else:
try:
chaine = unicode(chaine, "utf-8", "strict").encode(charsetSite, "strict")
chaine = str(chaine, "utf-8", "strict").encode(charsetSite, "strict")
except:
chaine = chaine.encode(charsetSite, "strict")
return chaine
......
......@@ -93,7 +93,7 @@ def utf8Encode(chaine) :
if charsetSite.lower() in ("utf-8", "utf8"):
return chaine
else:
return unicode(chaine, charsetSite, errors).encode("utf-8", errors)
return str(chaine, charsetSite, errors).encode("utf-8", errors)
def utf8Decode(chaine) :
# because browser upload form is in utf-8 we need it
......@@ -102,7 +102,7 @@ def utf8Decode(chaine) :
return chaine
else:
try:
chaine = unicode(chaine, "utf-8", "strict").encode(charsetSite, "strict")
chaine = str(chaine, "utf-8", "strict").encode(charsetSite, "strict")
except:
chaine = chaine.encode(charsetSite, "strict")
return chaine
......
......@@ -120,7 +120,7 @@ def utf8Encode(chaine) :
if charsetSite.lower() in ("utf-8", "utf8"):
return chaine
else:
return unicode(chaine, charsetSite, errors).encode("utf-8", errors)
return str(chaine, charsetSite, errors).encode("utf-8", errors)
def utf8Decode(chaine) :
# because browser upload form is in utf-8 we need it
......@@ -129,7 +129,7 @@ def utf8Decode(chaine) :
return chaine
else:
try:
chaine = unicode(chaine, "utf-8", "strict").encode(charsetSite, "strict")
chaine = str(chaine, "utf-8", "strict").encode(charsetSite, "strict")
except:
chaine = chaine.encode(charsetSite, "strict")
return chaine
......
......@@ -68,7 +68,7 @@ if web_mode:
# Set properties to the new object
edit_kw = {}
property_id_list = new_object.propertyIds()
for (key, val) in form_data.items():
for (key, val) in list(form_data.items()):
if key in ACCEPTABLE_FORM_ID_LIST and key[len('clone_'):] in property_id_list:
edit_kw[key[len('clone_'):]] = val
new_object.edit(**edit_kw)
......
......@@ -8,7 +8,7 @@ The script must be called on the context of the document.
def filterDuplicateActions(actions):
new_actions = {}
for action_category, action_list in actions.items():
for action_category, action_list in list(actions.items()):
if action_category == 'object_onlyxhtml_view':
action_category = 'object_view'
......
......@@ -53,7 +53,7 @@ def addDialogIfNeeded(url):
if 'format' in parameter_kw:
# if format is passed in action url: remove it
target_format = parameter_kw.pop('format')
action = '%s?%s' % (action_id, '&'.join(['='.join(tuple_parameter) for tuple_parameter in parameter_kw.items()]))
action = '%s?%s' % (action_id, '&'.join(['='.join(tuple_parameter) for tuple_parameter in list(parameter_kw.items())]))
url = '%s/Base_viewOOoPrintDialog?dialog_action_url=%s&base_content_type=%s&field_your_format=%s' % (
context.absolute_url(),
url_quote('%s/%s' % (absolute_url, action)),
......
......@@ -20,7 +20,7 @@ request_form.update(kw)
request_form = context.ERP5Site_filterParameterList(request_form)
request_form.update(keep_items)
parameters = make_query(dict([(k, v) for k, v in request_form.items() if k and v is not None]))
parameters = make_query(dict([(k, v) for k, v in list(request_form.items()) if k and v is not None]))
if len(parameters):
if '?' in redirect_url:
separator = '&'
......
......@@ -20,7 +20,7 @@ keep_items.pop("portal_status_level", None)
if REQUEST is None:
REQUEST = context.REQUEST
for key, value in keep_items.items():
for key, value in list(keep_items.items()):
REQUEST.set(key, value)
return getattr(context, form_id)()
......@@ -10,4 +10,4 @@ kept_names = ('editable_mode', 'ignore_layout', # erp5_web
# Cancel url is always overwritten, except when rendering
# a dialog. So this is safe to propagate it.
return dict((item for item in parameter_list.items() if item[0] in kept_names))
return dict((item for item in list(parameter_list.items()) if item[0] in kept_names))
......@@ -564,7 +564,7 @@ for block_object in planning.content:
bot_list = []
center = ''
# recovering full string that will have to be displayed on the top & bottom line
for info_name in block_object.info.keys():
for info_name in list(block_object.info.keys()):
if 'top' in info_name:
top_string += block_object.info[info_name].info
top_list.append(info_name)
......@@ -604,7 +604,7 @@ for block_object in planning.content:
if block_dict['height'] < car_height:
# there is no room to display any text in the block
# escaping all text
for info_name in block_object.info.keys():
for info_name in list(block_object.info.keys()):
block_object.info[info_name].edit('')
else:
if block_dict['height'] < (car_height* lines):
......
......@@ -75,16 +75,16 @@ else:
# build list from dictionnary structure
# this list will e converted to a string afterwards
returned_list = []
for area_name in properties_structure.keys():
for area_name in list(properties_structure.keys()):
css_dict = properties_structure[area_name]
for class_name in css_dict.keys():
for class_name in list(css_dict.keys()):
if class_name == 'planning_content':
returned_list.append('.%s{' % class_name)
elif class_name == 'planning_box':
returned_list.append('.%s{' % class_name)
else:
returned_list.append('#%s{' % class_name)
for id_ in css_dict[class_name].keys():
for id_ in list(css_dict[class_name].keys()):
if same_type(css_dict[class_name][id_], ''):
returned_list.append('%s:%s;\n' % (id_, css_dict[class_name][id_]))
else:
......
......@@ -234,7 +234,11 @@ class PeriodicityMixin:
"""
returns something like ['Sunday','Monday',...]
"""
return DateTime._days
try:
from DateTime.DateTime import _DAYS
return _DAYS
except ImportError: # BBB DateTime 2.12
return DateTime._days
security.declareProtected(Permissions.AccessContentsInformation, 'getWeekDayItemList')
def getWeekDayItemList(self):
......
......@@ -93,7 +93,7 @@ class PropertyRecordableMixin:
Returns the list of property IDs which have
been recorded.
"""
return self._getRecordedPropertyDict({}).keys()
return list(self._getRecordedPropertyDict({}).keys())
security.declareProtected(Permissions.AccessContentsInformation,
'isPropertyRecorded')
......
......@@ -64,7 +64,7 @@ class ExtractMessageCatalog(TestXHTML):
result[i].update(messages)
f = file('%s.pot' % i, 'w')
for msgid in result[i].keys():
for msgid in list(result[i].keys()):
f.write('msgid "%s"\nmsgstr ""\n\n' % msgid)
......
......@@ -43,6 +43,7 @@ from MySQLdb import ProgrammingError
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5Type.tests.utils import reindex
from zExceptions import BadRequest
class InventoryAPITestCase(ERP5TypeTestCase):
"""Base class for Inventory API Tests {{{
......@@ -129,8 +130,14 @@ class InventoryAPITestCase(ERP5TypeTestCase):
'inventory_module',
self.folder.getId() ]:
folder = self.portal[module]
folder.manage_delObjects(list(folder.objectIds()))
self.portal.portal_skins.custom.manage_delObjects(list(self.portal.portal_skins.custom.objectIds()))
try:
folder.manage_delObjects(list(folder.objectIds()))
except BadRequest:
pass
try:
self.portal.portal_skins.custom.manage_delObjects(list(self.portal.portal_skins.custom.objectIds()))
except BadRequest:
pass
self.tic()
......
......@@ -98,7 +98,7 @@ class TestSecurityMixin(ERP5TypeTestCase):
continue
func_code = method.func_code
error_dict[(func_code.co_filename, func_code.co_firstlineno, method_id)] = True
error_list = error_dict.keys()
error_list = list(error_dict.keys())
if os.environ.get('erp5_debug_mode', None):
pass
else:
......
......@@ -133,7 +133,7 @@ class TestSpellChecking(ERP5TypeTestCase):
# check some suggestion are given for a small mistake
self.assertNotEquals(self.validate_spell('canceled'), {})
self.assertTrue('is misspelled' in \
self.validate_spell('canceled').values()[0])
list(self.validate_spell('canceled').values())[0])
def test_business_template_list_with_workflow_template_item(self):
"""
......
......@@ -121,7 +121,7 @@ class TestWorkflowStateTitleTranslation(ERP5TypeTestCase):
workflow = workflow_tool._getOb(workflow_id)
class_name = workflow.__class__.__name__
if class_name == 'DCWorkflowDefinition':
for state in workflow.states.items():
for state in list(workflow.states.items()):
state_title = state[1].title
state_id = state[0]
msgid = getMessageIdWithContext(state_title, 'state', workflow_id)
......@@ -134,14 +134,14 @@ class TestWorkflowStateTitleTranslation(ERP5TypeTestCase):
translation_dict[translated_state_title] = {state_id}
for key, value in translation_dict.items():
for key, value in list(translation_dict.items()):
if len(value) == 1:
translation_dict.pop(key)
if translation_dict != {}:
# State ID has multiple translation associated, and it leads to
# unexpected results for the user when using portal catalog.
rejected_key_list = translation_dict.keys()
rejected_key_list = list(translation_dict.keys())
result_dict = {x: [] for x in rejected_key_list}
error_dict = {x: [] for x in rejected_key_list}
error = 0
......@@ -151,7 +151,7 @@ class TestWorkflowStateTitleTranslation(ERP5TypeTestCase):
if workflow.__class__.__name__ == 'DCWorkflowDefinition':
workflow_id = workflow.id
workflow_dict = {}
for state_id, state in workflow.states._mapping.items():
for state_id, state in list(workflow.states._mapping.items()):
state_title = state.title
translated_state_title = \
self.portal.Localizer.erp5_ui.gettext(state_title, lang=self.lang)
......@@ -161,13 +161,13 @@ class TestWorkflowStateTitleTranslation(ERP5TypeTestCase):
# XXX To be improved
not_used_workflow_id_list = []
for key, item_list in result_dict.items():
for key, item_list in list(result_dict.items()):
wrong_state_id_list = [x[1] for x in item_list]
for workflow_id, wrong_state_id, state_title in item_list:
if workflow_id not in not_used_workflow_id_list:
workflow = self.portal.portal_workflow._getOb(workflow_id)
state_id_list = []
for state_id in workflow.states._mapping.keys():
for state_id in list(workflow.states._mapping.keys()):
if (state_id in wrong_state_id_list) and \
(state_id != wrong_state_id):
state_id_list.append(state_id)
......@@ -178,7 +178,7 @@ class TestWorkflowStateTitleTranslation(ERP5TypeTestCase):
error = 1
if error:
for key, item_list in error_dict.items():
for key, item_list in list(error_dict.items()):
if len(item_list) != 0:
self.logMessage("\n'%s'" % key.encode('utf-8'))
self.logMessage('\t### Conflicting workflow with common states (ie, what user can see) ###')
......
......@@ -186,7 +186,7 @@ class TestXHTMLMixin(ERP5TypeTestCase):
for portal_type in portal_types_module.contentValues(portal_type=\
'Base Type'):
if portal_type.getId().endswith('Module'):
for k, v in portal_type.getPropertyTranslationDomainDict().items():
for k, v in list(portal_type.getPropertyTranslationDomainDict().items()):
if k in ('title', 'short_title') and v.getDomainName() != 'erp5_ui':
error_list.append('"%s" should use erp5_ui for %s' % \
(portal_type.getId(), k))
......@@ -406,7 +406,7 @@ class TestXHTMLMixin(ERP5TypeTestCase):
for id_ in skin_folder.objectIds():
if id_.startswith('Preference_view'):
addPreferenceView(skin_folder.id, id_)
for view_id, location_list in preference_view_id_dict.items():
for view_id, location_list in list(preference_view_id_dict.items()):
if len(location_list) > 1:
error_list.extend(location_list)
self.assertEqual(error_list, [])
......@@ -712,7 +712,7 @@ def addTestMethodDynamically(
business_template_info_list.append(business_template_info)
for business_template_info in business_template_info_list:
for portal_type, action_information_list in business_template_info.actions.items():
for portal_type, action_information_list in list(business_template_info.actions.items()):
for action_information in action_information_list:
if (action_information['category'] in ('object_view', 'object_list') and
action_information['visible']==1 and
......
......@@ -774,7 +774,7 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
query = ComplexQuery(
[
SimpleQuery(**{key : value})
for key, value in local_role_column_dict.items()
for key, value in list(local_role_column_dict.items())
] + [query],
logical_operator='AND',
)
......@@ -1050,11 +1050,11 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
identity_criterion = getattr(object,'_identity_criterion',None)
range_criterion = getattr(object,'_range_criterion',None)
if identity_criterion is not None:
for property, value in identity_criterion.items():
for property, value in list(identity_criterion.items()):
if value is not None:
property_dict[property] = value
if range_criterion is not None:
for property, (min, max) in range_criterion.items():
for property, (min, max) in list(range_criterion.items()):
if min is not None:
property_dict['%s_range_min' % property] = min
if max is not None:
......@@ -1436,7 +1436,7 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
break
queries_by_connection_id = defaultdict(list)
for connection_id, method_list in method_list_by_connection_id.items():
for connection_id, method_list in list(method_list_by_connection_id.items()):
connection = connection_by_connection_id[connection_id]
db = connection()
with db.lock():
......@@ -1448,7 +1448,7 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
for query in queries_by_connection_id[connection_id]:
db.query(query)
return sum(queries_by_connection_id.values(), [])
return sum(list(queries_by_connection_id.values()), [])
security.declarePublic('getDocumentValueList')
def getDocumentValueList(self, sql_catalog_id=None,
......
......@@ -114,7 +114,7 @@ class NumericCaptchaProvider(object):
def generate(self, field):
# First step : generate the calculus. It is really simple.
terms = [str(random.randint(1, 20)), random.choice(self.operator_set.keys())]
terms = [str(random.randint(1, 20)), random.choice(list(self.operator_set.keys()))]
#XXX: Find a way to prevent too complex captchas (for instance 11*7*19...)
#terms += [str(random.randint(1, 20)), random.choice(operator_set.keys())]
terms.append(str(random.randint(1, 20)))
......@@ -128,7 +128,7 @@ class NumericCaptchaProvider(object):
def getHTML(self, field, captcha_key):
# Make the text harder to parse for a computer
calculus_text = captcha_key
for (operator, replacement) in self.operator_set.items():
for (operator, replacement) in list(self.operator_set.items()):
calculus_text = calculus_text.replace(operator, replacement)
return "<span class=\"%s\">%s</span>" % (field.get_value('css_class'), calculus_text)
......
......@@ -109,7 +109,7 @@ def isCacheable(value):
dic = getattr(value, '__dict__', None)
if dic is not None:
for i in dic.values():
for i in list(dic.values()):
jar = getattr(i, '_p_jar', None)
if jar is not None:
return False
......@@ -133,7 +133,7 @@ def getFieldDict(field, value_type):
else:
raise ValueError('value_type must be values or tales')
template_field = field.getRecursiveTemplateField()
for ui_field_id in template_field.form.fields.keys():
for ui_field_id in list(template_field.form.fields.keys()):
result[ui_field_id] = get_method(ui_field_id)
else:
if value_type=='values':
......@@ -142,7 +142,7 @@ def getFieldDict(field, value_type):
get_method = getattr(field, 'get_tales')
else:
raise ValueError('value_type must be values or tales')
for ui_field_id in field.form.fields.keys():
for ui_field_id in list(field.form.fields.keys()):
result[ui_field_id] = get_method(ui_field_id)
return result
......@@ -447,7 +447,7 @@ def initializeForm(field_registry, form_class=None):
if form_class is None: form_class = ERP5Form
meta_types = []
for meta_type, field in field_registry.get_field_classes().items():
for meta_type, field in list(field_registry.get_field_classes().items()):
# don't set up in form if this is a field for internal use only
if field.internal_field:
continue
......@@ -695,7 +695,7 @@ class ERP5Form(Base, ZMIForm, ZopePageTemplate):
# overriden to keep the order of a field after rename
groups = deepcopy(self.groups)
ret = ZMIForm.manage_renameObject(self, id, new_id, REQUEST=REQUEST)
for group_id, field_id_list in groups.items():
for group_id, field_id_list in list(groups.items()):
if id in field_id_list:
index = field_id_list.index(id)
field_id_list.pop(index)
......@@ -1045,7 +1045,7 @@ class ERP5Form(Base, ZMIForm, ZopePageTemplate):
# for skin_folder_id in self.getSimilarSkinFolderIdList():
for skin_folder_id in self.getPortalObject().portal_skins.objectIds():
iterate(getattr(skins_tool, skin_folder_id))
proxy_dict_list = proxy_dict.values()
proxy_dict_list = list(proxy_dict.values())
proxy_dict_list.sort(key=lambda x: x['short_path'])
for item in proxy_dict_list:
item['related_proxy_list'].sort(key=lambda x: x['short_path'])
......@@ -1091,14 +1091,14 @@ class ERP5Form(Base, ZMIForm, ZopePageTemplate):
return a==b
def remove_same_value(new_dict, target_dict):
for key, value in new_dict.items():
for key, value in list(new_dict.items()):
target_value = target_dict.get(key)
if force_delegate or is_equal(value, target_value):
del new_dict[key]
return new_dict
def get_group_and_position(field_id):
for i in self.groups.keys():
for i in list(self.groups.keys()):
if field_id in self.groups[i]:
return i, self.groups[i].index(field_id)
......@@ -1111,7 +1111,7 @@ class ERP5Form(Base, ZMIForm, ZopePageTemplate):
if field_dict is None:
return
for field_id in field_dict.keys():
for field_id in list(field_dict.keys()):
target = field_dict[field_id]
target_form_id, target_field_id = target.split('.')
......@@ -1138,7 +1138,7 @@ class ERP5Form(Base, ZMIForm, ZopePageTemplate):
getFieldDict(target_field, 'tales'))
if target_field.meta_type=='ProxyField':
for i in new_values.keys():
for i in list(new_values.keys()):
if not i in target_field.delegated_list:
# obsolete variable check
try:
......@@ -1150,7 +1150,7 @@ class ERP5Form(Base, ZMIForm, ZopePageTemplate):
if is_equal(target_field.get_recursive_orig_value(i),
new_values[i]):
del new_values[i]
for i in new_tales.keys():
for i in list(new_tales.keys()):
if not i in target_field.delegated_list:
# obsolete variable check
try:
......@@ -1211,14 +1211,14 @@ class ERP5Form(Base, ZMIForm, ZopePageTemplate):
return a==b
def remove_same_value(new_dict, target_dict):
for key, value in new_dict.items():
for key, value in list(new_dict.items()):
target_value = target_dict.get(key)
if is_equal(value, target_value):
del new_dict[key]
return new_dict
def get_group_and_position(field_id):
for i in self.groups.keys():
for i in list(self.groups.keys()):
if field_id in self.groups[i]:
return i, self.groups[i].index(field_id)
......@@ -1231,7 +1231,7 @@ class ERP5Form(Base, ZMIForm, ZopePageTemplate):
if field_dict is None:
return
for field_id in field_dict.keys():
for field_id in list(field_dict.keys()):
# keep current group and position.
group, position = get_group_and_position(field_id)
......
......@@ -115,7 +115,7 @@ class ImageFieldWidget(Widget.TextWidget):
# only add if it's True as conversion machine assume that if it is missing
# then conversion should happen "on the fly"
options['pre_converted_only'] = pre_converted_only
parameters = '&'.join(['%s=%s' % (k, v) for k, v in options.items() \
parameters = '&'.join(['%s=%s' % (k, v) for k, v in list(options.items()) \
if v])
if parameters:
image = '%s?%s' % (image, parameters)
......
......@@ -105,7 +105,7 @@ class CatalogMethodWrapper(MethodWrapper):
# XXX: I'm not sure if this filtering really belongs to here.
# It is probably needed at a more generic level (Forms ? Selection ?), or
# even a more specific one (limited to HTML ?)...
for key, value in kw.items():
for key, value in list(kw.items()):
if value == '':
kw.pop(key)
return getattr(self.context, self.method_name)(*args, **kw)
......@@ -1189,7 +1189,7 @@ class ListBoxRenderer:
params.setdefault(k, v)
search_prefix = 'search_%s_' % (self.getId(), )
for k, v in params.items():
for k, v in list(params.items()):
if k.startswith(search_prefix):
params[k[len(search_prefix):]] = v
......@@ -1218,12 +1218,12 @@ class ListBoxRenderer:
params.setdefault('meta_type', meta_type_list)
# Remove FileUpload parameters
for k, v in params.items():
for k, v in list(params.items()):
if k == "listbox":
# listbox can also contain useless parameters
new_list = []
for line in v:
for k1, v1 in line.items():
for k1, v1 in list(line.items()):
if hasattr(v1, 'read'):
del line[k1]
new_list.append(line)
......@@ -2619,7 +2619,7 @@ class ListBoxHTMLRenderer(ListBoxRenderer):
update_selection = False
form_dict = request.form
listbox_kw = selection.getParams()
listbox_arguments_list = [x for x in form_dict.keys() if x.startswith(field_id)]
listbox_arguments_list = [x for x in list(form_dict.keys()) if x.startswith(field_id)]
for original_listbox_argument in listbox_arguments_list:
listbox_argument = original_listbox_argument.replace('%s_' %field_id, '', 1)
listbox_argument_value = form_dict.get(original_listbox_argument, None)
......
......@@ -404,7 +404,7 @@ class OOoChartWidget(Widget.Widget):
position_legend=field.get_value('position_legend'),
)
for k, v in extra_argument_dict.items():
for k, v in list(extra_argument_dict.items()):
if REQUEST.get(k) is None:
REQUEST.form[k] = v
return extra_argument_dict
......@@ -467,7 +467,7 @@ class OOoChartWidget(Widget.Widget):
if render_format == 'html':
css_class = field.get_value('css_class')
format = field.get_value('image_format') or 'png'
query_dict = dict(REQUEST.form.items())
query_dict = dict(list(REQUEST.form.items()))
query_dict.update(render_format=format != 'raw' and format or '',
render_prefix=render_prefix,
display=field.get_value('image_display'))
......
......@@ -274,7 +274,7 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
# getting round_script if exists
round_script=getattr(context, field.get_value('round_script'), None)
# now processing activity updates
for activity_name in activity_dict.keys():
for activity_name in list(activity_dict.keys()):
# recovering list of moved blocks in the current activity
activity_block_moved_list = activity_dict[activity_name]
# recovering activity object from first moved block
......@@ -416,7 +416,7 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
"""
good_group_name = ''
# recovering group name
for axis_name in axis_groups.keys():
for axis_name in list(axis_groups.keys()):
if axis_groups[axis_name][group_position] < block_moved['center'] and \
axis_groups[axis_name][group_position] + \
axis_groups[axis_name][group_length] > block_moved['center']:
......@@ -555,7 +555,7 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
for axis_element in axis_group.axis_element_list:
for activity in axis_element.activity_list:
# for each activity, saving its properties into a dict
if activity.link in object_dict.keys():
if activity.link in list(object_dict.keys()):
object_dict[activity.link].append(
{ 'activity_name' : activity.name,
'axis_start': activity.lane_axis_start,
......@@ -605,7 +605,7 @@ class PlanningBoxEditor:
pass
def edit(self, context):
for url, kw in self.update_dict.items():
for url, kw in list(self.update_dict.items()):
context.restrictedTraverse(url).edit(**kw)
allow_class(PlanningBoxEditor)
......@@ -1103,7 +1103,7 @@ class BasicStructure:
if kw['portal_type'] in ['', []]:
del kw['portal_type']
# remove useless matter
for cname in self.params.keys():
for cname in list(self.params.keys()):
if self.params[cname] not in ['',None]:
kw[cname] = self.params[cname]
# try to get the method through acquisition
......
......@@ -226,14 +226,14 @@ class ProxyField(ZMIField):
This method is similar to manage_edit_xmlrpc, and it marks the properties
as not delegated.
"""
self._surcharged_edit(mapping, mapping.keys())
self._surcharged_edit(mapping, list(mapping.keys()))
def manage_tales_surcharged_xmlrpc(self, mapping):
"""Edit surcharged TALES
This method is similar to manage_tales_xmlrpc, and it marks the TALES
properties as not delegated.
"""
self._surcharged_tales(mapping, mapping.keys())
self._surcharged_tales(mapping, list(mapping.keys()))
def _surcharged_edit(self, result, surcharge_list):
......@@ -251,7 +251,7 @@ class ProxyField(ZMIField):
result = new_result
changed = []
for key, value in result.items():
for key, value in list(result.items()):
# XXX Remove old values
values.pop(key, None)
# store keys for which we want to notify change
......@@ -259,7 +259,7 @@ class ProxyField(ZMIField):
changed.append(key)
proxied_field = self.getTemplateField()
for key, value in result.items():
for key, value in list(result.items()):
if key not in surcharge_list:
result.pop(key)
if key in self.tales:
......@@ -333,12 +333,12 @@ class ProxyField(ZMIField):
tales = self.tales
changed = []
for key, value in result.items():
for key, value in list(result.items()):
# XXX Remove old values
tales.pop(key, None)
proxied_field = self.getTemplateField()
for key, value in result.items():
for key, value in list(result.items()):
if key not in surcharge_list:
result.pop(key)
if key in self.values:
......
......@@ -433,7 +433,7 @@ class SelectionTool( BaseTool, SimpleItem ):
selection_uid_dict[int(uid)] = 1
except (ValueError, TypeError):
selection_uid_dict[uid] = 1
self.setSelectionCheckedUidsFor(list_selection_name, selection_uid_dict.keys(), REQUEST=REQUEST)
self.setSelectionCheckedUidsFor(list_selection_name, list(selection_uid_dict.keys()), REQUEST=REQUEST)
if REQUEST is not None:
return self._redirectToOriginalForm(REQUEST=REQUEST, form_id=form_id,
query_string=query_string, no_reset=True)
......@@ -948,7 +948,7 @@ class SelectionTool( BaseTool, SimpleItem ):
def setDomainDictFromParam(self, selection_name, domain_dict):
domain_list = []
domain_path = []
for key, value in domain_dict.items():
for key, value in list(domain_dict.items()):
domain_path.append(key)
splitted_domain_list = value[1].split('/')[1:]
for i in range(len(splitted_domain_list)):
......@@ -1315,7 +1315,7 @@ class SelectionTool( BaseTool, SimpleItem ):
# Save the current REQUEST form
# We can't put FileUpload instances because we can't pickle them
saved_form_data = {key: value
for key, value in REQUEST.form.items()
for key, value in list(REQUEST.form.items())
if not isinstance(value, FileUpload)}
kw = {
......@@ -1537,7 +1537,7 @@ class SelectionTool( BaseTool, SimpleItem ):
def _getSelectionNameListFromContainer(self):
user_id = self._getUserId()
return list(set(self._getContainer().getSelectionNameList(user_id) +
self.getTemporarySelectionDict().keys()))
list(self.getTemporarySelectionDict().keys())))
def isAnonymous(self):
return self._getUserId() == 'Anonymous User'
......@@ -1602,7 +1602,7 @@ class TransactionalCacheContainer(MemcachedContainer):
class PersistentMappingContainer(BaseContainer):
def getSelectionNameList(self, user_id):
try:
return self._container[user_id].keys()
return list(self._container[user_id].keys())
except KeyError:
return []
......
......@@ -524,7 +524,7 @@ class ODFStrategy(Implicit):
return
def getNameAttribute(target_element):
attrib = target_element.attrib
for key in attrib.keys():
for key in list(attrib.keys()):
if key.endswith("}name"):
return key
return None
......@@ -839,7 +839,7 @@ class ODFStrategy(Implicit):
# if remaining these attribetes, the column shows its default value,
# such as '0.0', '$0'
attrib = column.attrib
for key in attrib.keys():
for key in list(attrib.keys()):
if 'office' in column.nsmap and key.startswith("{%s}" % column.nsmap['office']):
del attrib[key]
column.text = None
......@@ -847,7 +847,7 @@ class ODFStrategy(Implicit):
def _clearColumnValue(self, column):
attrib = column.attrib
for key in attrib.keys():
for key in list(attrib.keys()):
value_attribute = self._getColumnValueAttribute(column)
if value_attribute is not None:
column.set(value_attribute, '')
......@@ -861,7 +861,7 @@ class ODFStrategy(Implicit):
def _getColumnValueAttribute(self, column):
attrib = column.attrib
for key in attrib.keys():
for key in list(attrib.keys()):
if key.endswith("value"):
return key
return None
......
......@@ -390,7 +390,7 @@ class OOoParser(Implicit):
# Get all cells
find_path = './/{%s}table-cell' % line.nsmap['table']
cells = line.findall(find_path)
cell_index_range = range(len(cells))
cell_index_range = list(range(len(cells)))
for cell_index in cell_index_range:
cell = cells[cell_index]
......
......@@ -199,7 +199,7 @@ class TestIngestion(IngestionTestCase):
# Note : this code was taken from the CategoryTool_importCategoryFile python
# script (packaged in erp5_core).
for category in self.category_list:
keys = category.keys()
keys = list(category.keys())
if 'path' in keys:
base_path_obj = self.portal_categories
is_base_category = True
......@@ -379,7 +379,7 @@ class TestIngestion(IngestionTestCase):
Asserts that metadata of document ID document_id
is the same as expected_metadata
"""
for k, v in expected_metadata.items():
for k, v in list(expected_metadata.items()):
self.assertEqual(document.getProperty(k), v)
def receiveEmail(self, data,
......@@ -991,7 +991,7 @@ class TestIngestion(IngestionTestCase):
'ODT': 'Text',
'PDF': 'PDF',
'PPT': 'Presentation'}
for sub_reference, portal_type in extension_reference_portal_type_map.items():
for sub_reference, portal_type in list(extension_reference_portal_type_map.items()):
ingested_document = self.portal_catalog.getResultValue(
portal_type=portal_type,
reference='TEST%s' %sub_reference,
......@@ -1072,7 +1072,7 @@ class TestIngestion(IngestionTestCase):
'sxd' : 'Drawing',
'xxx' : 'File',
}
for type, portal_type in correct_type_mapping.items():
for type, portal_type in list(correct_type_mapping.items()):
filename = 'aaa.' + type
self.assertEqual(reg.findPortalTypeName(filename=filename),
portal_type)
......
......@@ -809,7 +809,7 @@ class TestOOoImport(TestOOoImportMixin):
# strings are encoded in UTF8
self.assertTrue(isinstance(region[1]['title'], str))
self.assertTrue(isinstance(region[1]['path'], str))
for k in region[1].keys():
for k in list(region[1].keys()):
self.assertTrue(isinstance(k, str), (k, type(k)))
def test_Base_getCategoriesSpreadSheetMapping_DuplicateIdsAtSameLevel(self):
......
......@@ -209,7 +209,7 @@ class WorkflowMethod(Method):
if valid_transition_list:
valid_invoke_once_item_list.append((wf_id, valid_transition_list))
candidate_transition_item_list = valid_invoke_once_item_list + \
self._invoke_always.get(portal_type, {}).items()
list(self._invoke_always.get(portal_type, {}).items())
#LOG('candidate_transition_item_list %s' % self.__name__, 0, str(candidate_transition_item_list))
......@@ -470,7 +470,7 @@ class PropertyHolder(object):
"""
Return a list of tuple (id, method) for every property of a class
"""
return self._getClassDict(klass, inherited=inherited, local=local).items()
return list(self._getClassDict(klass, inherited=inherited, local=local).items())
def getClassMethodItemList(self, klass, inherited=1, local=1):
"""
......@@ -1498,7 +1498,7 @@ class Base(
"""
if not kw:
return
key_list = kw.keys()
key_list = list(kw.keys())
modified_property_dict = self._v_modified_property_dict = {}
modified_object_dict = {}
......@@ -2451,7 +2451,7 @@ class Base(
method = self._getTypeBasedMethod('getIdTranslationDict')
if method is not None:
user_dict = method()
for k in user_dict.keys():
for k in list(user_dict.keys()):
if property_dict.get(k, None) is not None:
property_dict[k].update(user_dict[k])
else:
......@@ -2777,7 +2777,7 @@ class Base(
# Avoid copying a SESSION object, because it is newly created
# implicitly when not present, thus it may induce conflict errors.
# As ERP5 does not use Zope sessions, it is better to skip SESSION.
for k in REQUEST.keys():
for k in list(REQUEST.keys()):
if k != 'SESSION':
setattr(context, k, REQUEST[k])
# Set the original document
......@@ -3641,7 +3641,7 @@ class Base(
next_id = default
new_next_id = None if poison else next_id + count
id_generator_state[group].value = new_next_id
return range(next_id, new_next_id)
return list(range(next_id, new_next_id))
InitializeClass(Base)
......
......@@ -94,7 +94,7 @@ class RamCache(BaseCache):
## time to check for expired cache items
self._next_cache_expire_check_at = now + self.cache_expire_check_interval
cache = self.getCacheStorage()
for key, value in cache.items():
for key, value in list(cache.items()):
if value.isExpired():
try:
del cache[key]
......@@ -139,7 +139,7 @@ class RamCache(BaseCache):
def clearCacheForScope(self, scope):
cache = self.getCacheStorage()
for key in cache.keys():
for key in list(cache.keys()):
if key[0] == scope:
try:
del cache[key]
......
......@@ -54,7 +54,7 @@ class AttributeBlacklisted(PropertyExistence):
satisfied
"""
errors = PropertyExistence._checkConsistency(self, obj, fixit=fixit)
for attribute_name, expression_blacklisted_list in self.constraint_definition.items():
for attribute_name, expression_blacklisted_list in list(self.constraint_definition.items()):
message_id = None
mapping = dict(attribute_name=attribute_name)
#Evaluate expression_criterion_dict
......
......@@ -57,7 +57,7 @@ class AttributeEquality(PropertyExistence):
satisfied (equality)
"""
errors = PropertyExistence._checkConsistency(self, obj, fixit=fixit)
for attribute_name, expected_value in self.constraint_definition.items():
for attribute_name, expected_value in list(self.constraint_definition.items()):
message_id = None
mapping = {}
# If property does not exist, error will be raised by
......
......@@ -59,7 +59,7 @@ class AttributeUnicity(PropertyExistence):
This Constraint use portal_catalog
"""
errors = PropertyExistence._checkConsistency(self, obj, fixit=fixit)
for attribute_name, expression_criterion_dict in self.constraint_definition.items():
for attribute_name, expression_criterion_dict in list(self.constraint_definition.items()):
message_id = None
mapping = dict(attribute_name=attribute_name)
#Evaluate expression_criterion_dict
......
......@@ -65,7 +65,7 @@ class CategoryAcquiredMembershipState(Constraint):
state_var_list.pop('portal_type')
state_var_list.pop('base_category')
for workflow_variable, valid_state_list in state_var_list.items():
for workflow_variable, valid_state_list in list(state_var_list.items()):
for membership in membership_list:
current_state = membership.getProperty(workflow_variable)
if current_state not in valid_state_list:
......
......@@ -62,7 +62,7 @@ class CategoryExistence(Constraint):
error_list = []
portal_type = self.constraint_definition.get('portal_type', ())
# For each attribute name, we check if defined
for base_category in self.constraint_definition.keys():
for base_category in list(self.constraint_definition.keys()):
if base_category in ('portal_type', ):
continue
mapping = dict(base_category=base_category)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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