Commit 0cfb1586 authored by Jérome Perrin's avatar Jérome Perrin

More python3 support

See merge request !1863
parents 2e8ef0bb 7fc1e3b0
"""Resets grouping reference on this line and all related lines.
This runs by default asynchronously, but can be call with `async=False` to
run synchronously and returns the list of ungrouped lines. With `async=True`,
This runs by default asynchronoushronously, but can be call with `asynchronous=False` to
run synchronously and returns the list of ungrouped lines. With `asynchronous=True`,
the returned list is always empty.
"""
......@@ -13,7 +13,7 @@ if not context.getGroupingReference():
portal = context.getPortalObject()
resetGroupingReference = portal.ERP5Site_resetAccountingTransactionLineGroupingReference
if async:
if asynchronous:
resetGroupingReference = portal.portal_simulation.activate(
activity='SQLQueue',
after_tag='accounting_grouping_reference'
......
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>async=True</string> </value>
<value> <string>asynchronous=True</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -121,7 +121,7 @@ else:
if line.getGroupingReference():
# Call AccountingTransactionLine_resetGroupingReference synchronously
# to know the number of ungrouped lines.
ungrouped_line_list.extend(line.AccountingTransactionLine_resetGroupingReference(async=False))
ungrouped_line_list.extend(line.AccountingTransactionLine_resetGroupingReference(asynchronous=False))
portal_status_message = Base_translateString('${ungrouped_line_count} lines ungrouped.',
mapping=dict(ungrouped_line_count=len(ungrouped_line_list)))
......
......@@ -3907,7 +3907,7 @@ class TestTransactions(AccountingTestCase):
# reset from the payment line, the invoice line from the same group will be
# ungrouped
payment_line.AccountingTransactionLine_resetGroupingReference(async=False)
payment_line.AccountingTransactionLine_resetGroupingReference(asynchronous=False)
self.assertFalse(payment_line.getGroupingReference())
self.assertFalse(payment_line.getGroupingDate())
self.assertFalse(invoice_line.getGroupingReference())
......
......@@ -27,6 +27,10 @@ from mimetools import choose_boundary
from Products.CMFCore.utils import _setCacheHeaders, _ViewEmulator
from DateTime import DateTime
import re
import six
if six.PY3:
long = int # pylint:disable=redefined-builtin
class BigFile(File):
"""
......
......@@ -33,6 +33,7 @@ from random import randint
import sys
import threading
import traceback
import unittest
import six
from AccessControl import getSecurityManager
from AccessControl.SecurityManagement import newSecurityManager
......@@ -48,6 +49,9 @@ from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery, SimpleQuery
from Testing import ZopeTestCase
from zLOG import LOG
if six.PY3:
long = int # pylint:disable=redefined-builtin
def format_stack(thread=None):
frame_dict = sys._current_frames()
if thread is not None:
......@@ -588,7 +592,7 @@ class TestERP5Catalog(ERP5TypeTestCase, LogInterceptor):
uid_dict = {}
for _ in xrange(UID_BUFFER_SIZE * 3):
uid = portal_catalog.newUid()
self.assertTrue(isinstance(uid, long))
self.assertIsInstance(uid, long)
self.assertNotIn(uid, uid_dict)
uid_dict[uid] = None
......@@ -1647,6 +1651,9 @@ class TestERP5Catalog(ERP5TypeTestCase, LogInterceptor):
portal_type='Organisation',**catalog_kw)])
def test_54_FixIntUid(self):
if six.PY3:
return unittest.skipTest(
"Python3 does not have different types for int and long")
portal = self.getPortal()
module = portal.getDefaultModule('Organisation')
......
......@@ -34,7 +34,7 @@ import unittest
def get_Z2_log_last_line():
z2_log_path = os.path.join(log_directory, 'Z2.log')
f = open(z2_log_path, 'rb')
f = open(z2_log_path, 'r')
try:
f.seek(-256, os.SEEK_END) # Assumes last line is not longer than 256 chars (it should be about 130)
except IOError: # too short
......
......@@ -34,7 +34,7 @@ import unittest
from AccessControl.SecurityManagement import newSecurityManager
from Testing import ZopeTestCase
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from DocumentTemplate.DT_Util import html_quote
from DocumentTemplate.html_quote import html_quote
class TestEditorField(ERP5TypeTestCase, ZopeTestCase.Functional):
"""
......
# export_only : allow to disable the uid column and the id of columns
import six
result = ''
request = context.REQUEST
......@@ -9,7 +10,7 @@ listboxline_list = context.get_value('default', render_format='list', REQUEST=re
def encode(value):
if isinstance(value, bool):
return '"%s"' % value
if isinstance(value, (int, long, float)):
if isinstance(value, six.integer_types + (float,)):
return str(value)
else:
if isinstance(value, str):
......
......@@ -238,7 +238,7 @@
error python: value[2]"
class="DataA" align="left"
tal:attributes="class python: error and (css + 'Error') or css;
align python: isinstance(original_value, (float, int, long)) and 'right' or 'left'">
align python: isinstance(original_value, modules['six'].integer_types + (float,)) and 'right' or 'left'">
<input tal:condition="not: repeat/value/index"
type="hidden" value="1" name="listbox_uid:list"
tal:attributes="value python: line.getUid() or '';
......@@ -268,7 +268,7 @@
<tal:block tal:repeat="value here/getStatValueList">
<td class="Data" align="left"
tal:define="original_value python: value[0]; processed_value python: value[1]"
tal:attributes="align python: isinstance(original_value, (float, int, long)) and 'right' or 'left'"
tal:attributes="align python: isinstance(original_value, modules['six'].integer_types + (float,)) and 'right' or 'left'"
tal:content="structure processed_value" />
</tal:block>
</tr>
......
......@@ -15,16 +15,17 @@ There are runtime values hidden in every dialog form (injected by getHateoas Scr
from erp5.component.module.Log import log, WARNING
from Products.Formulator.Errors import FormValidationError
import json
import six
# http://stackoverflow.com/a/13105359
def byteify(value):
if isinstance(value, dict):
return {byteify(key): byteify(value) for key, value in value.iteritems()}
return {byteify(key): byteify(value) for key, value in six.iteritems(value)}
elif isinstance(value, list):
return [byteify(element) for element in value]
elif isinstance(value, tuple):
return tuple(byteify(element) for element in value)
elif isinstance(value, unicode):
elif six.PY2 and isinstance(value, six.text_type):
return value.encode('utf-8')
else:
return value
......
......@@ -6,8 +6,9 @@ Return JSON with message to be displayed and set according HTTP STATUS for messa
"""
import json
from erp5.component.module.Log import WARNING, ERROR
import six
if isinstance(level, (str, unicode)):
if isinstance(level, (str, six.text_type)):
if level.lower() == "error":
response_code = 500
elif level.lower().startswith("warn"):
......
......@@ -3,6 +3,7 @@ from Products.Formulator.Errors import FormValidationError
from Products.ERP5Type.Core.Workflow import ValidationFailed
from Products.ERP5Type.Message import translateString
from erp5.component.module.Log import WARNING
import six
portal = context.getPortalObject()
request = REQUEST or context.REQUEST
......@@ -43,7 +44,7 @@ for f in form.get_fields():
listbox = request.get('listbox') # XXX: hardcoded field name
if listbox is not None:
listbox_line_list = []
for key, value in sorted(listbox.iteritems()):
for key, value in sorted(six.iteritems(listbox)):
value['listbox_key'] = key
listbox_line_list.append(value)
doaction_param_list['listbox'] = tuple(listbox_line_list)
......
......@@ -273,9 +273,9 @@
</span>
<span style="color: green;">&nbsp;:&nbsp;</span>
<tal:block tal:condition="show_search_line">
<span tal:condition="python: isinstance(original_value,(float, int, long))"
<span tal:condition="python: isinstance(original_value, modules['six'].integer_types + (float,))"
id="data_short" tal:content="python: original_value" />
<span tal:condition="python: not isinstance(original_value,(float, int, long))"
<span tal:condition="python: not isinstance(original_value, modules['six'].integer_types + (float,))"
id="data_short" tal:content="data_short" />
</tal:block>
<tal:block tal:condition="not:show_search_line">
......@@ -302,7 +302,7 @@
<tal:block tal:condition="python: original_value is not None">
<span align="right"
tal:define="original_value python: valueZ[0]; processed_value python: valueZ[1]"
tal:attributes="align python: isinstance(original_value, (float, int, long)) and 'right' or 'left'"
tal:attributes="align python: isinstance(original_value, modules['six'].integer_types + (float,)) and 'right' or 'left'"
tal:content="structure processed_value" />
</tal:block>
</div>
......
......@@ -100,7 +100,7 @@
-->
<tal:block metal:define-macro="cell_value">
<tal:block tal:define="is_list python:same_type(value, []) or same_type(value, ());
is_float python: isinstance(value, (int, long, float));">
is_float python: isinstance(value, modules['six'].integer_types + (float,));">
<tal:block tal:condition="python: is_list">
......@@ -116,7 +116,7 @@
</tal:block>
<tal:block tal:condition="python: value is not None and not is_list">
<tal:block tal:condition="is_float">
<tal:block tal:condition="python: isinstance(value, (int, long))">
<tal:block tal:condition="python: isinstance(value, modules['six'].integer_types)">
<table:table-cell tal:define="field python: editable_fields.get(column_id, None)"
tal:attributes="office:value value;
table:style-name string:${style_prefix}figure"
......
......@@ -18,7 +18,7 @@
<tal:block tal:condition="not:listboxline/isTitleLine">
<table:table-row tal:attributes="table:style-name python: listboxline.isStatLine() and 'listbox_stat_row' or 'listbox_data_row'">
<tal:block tal:condition="python: listboxline.isDataLine()">
<tal:block tal:repeat="empty_index python: xrange(0, max_section_depth)">
<tal:block tal:repeat="empty_index python: range(0, max_section_depth)">
<table:table-cell table:style-name='report-column-title'
table:number-columns-spanned='1'
office:value-type='string'>
......@@ -36,7 +36,7 @@
</tal:block>
<tal:block tal:condition="python: listboxline.isStatLine() or listboxline.isSummaryLine()">
<tal:block tal:repeat="empty_index python: xrange(0, listboxline.getSectionDepth())">
<tal:block tal:repeat="empty_index python: range(0, listboxline.getSectionDepth())">
<table:table-cell table:style-name='report-column-title'
table:number-columns-spanned='1'
office:value-type='string'>
......@@ -48,7 +48,7 @@
office:value-type='string'>
<text:p tal:content="listboxline/getSectionName"/>
</table:table-cell>
<tal:block tal:repeat="empty_index python: xrange(listboxline.getSectionDepth()+1, max_section_depth)">
<tal:block tal:repeat="empty_index python: range(listboxline.getSectionDepth()+1, max_section_depth)">
<table:table-cell table:style-name='report-column-title'
table:number-columns-spanned='1'
office:value-type='string'>
......
......@@ -70,7 +70,7 @@
<tal:block tal:condition="not:display_header">
<table:table-row table:style-name='listbox_header_row'>
<tal:block tal:repeat="empty_index python: xrange(0, max_section_depth)">
<tal:block tal:repeat="empty_index python: range(0, max_section_depth)">
<table:table-cell table:style-name='report-column-title'
table:number-columns-spanned='1'
office:value-type='string'>
......
......@@ -110,7 +110,7 @@
<style:style style:name="date_with_time" style:family="table-cell" style:parent-style-name="Default" style:data-style-name="date_style">
<style:table-cell-properties style:vertical-align='middle' style:repeat-content='false' style:text-align-source='fix' fo:border-right='0.002cm solid #000000' />
</style:style>
<tal:block tal:repeat="precision python: xrange(0,here.Base_getODSMaximumSupportedPrecision())">
<tal:block tal:repeat="precision python: range(0,here.Base_getODSMaximumSupportedPrecision())">
<tal:block tal:define="figure_data_precision_style_name string:figure_data_precision_${precision}">
<number:number-style style:name="figure_data_precision_X" tal:attributes="style:name figure_data_precision_style_name">
<number:number number:decimal-places="X" number:min-integer-digits="1" number:grouping="true" tal:attributes="number:decimal-places precision"/>
......
......@@ -118,11 +118,11 @@
column_id python: column_item[0]">
<tal:block tal:condition="python: column_property is not None">
<table:table-cell table:style-name='listbox-table.A1' office:value-type='string'>
<tal:block tal:condition="python: untranslatable_columns_dict.has_key(column_id)">
<tal:block tal:condition="python: column_id in untranslatable_columns_dict">
<text:p text:style-name='listbox-header'
tal:content="python: column_property"/>
</tal:block>
<tal:block tal:condition="python: not(untranslatable_columns_dict.has_key(column_id))">
<tal:block tal:condition="python: column_id not in untranslatable_columns_dict">
<text:p text:style-name='listbox-header'
tal:content="python: here.Base_translateString(column_property)"/>
</tal:block>
......
......@@ -139,34 +139,6 @@
<td>2000</td>
<td></td>
</tr>
<!-- Second loader while updating the page -->
<!--
<tr>
<td>waitForElementPresent</td>
<td>//h1[@class="ui-title"]//a[contains(@class, "ui-icon-spinner")]</td>
<td></td>
</tr>
<!-- Save Button is disabled -->
<!--
<tr>
<td>verifyElementPresent</td>
<td>//button[@data-i18n="Save"][contains(@class, "ui-disabled")]</td>
<td></td>
</tr>
<tr>
<td>waitForElementNotPresent</td>
<td>//h1[@class="ui-title"]//a[contains(@class, "ui-icon-spinner")]</td>
<td></td>
</tr>
<tr>
<td>verifyElementPresent</td>
<td>//button[@data-i18n="Save"][contains(@class, "ui-icon-check")]</td>
<td></td>
</tr>
<tr>
<td colspan="3"><p></p></td>
</tr>
<-->
</tal:block>
<tal:block metal:define-macro="click_to_align_center">
<tr>
......
......@@ -3,6 +3,7 @@ import datetime
import time
import json
from DateTime import DateTime
import six
response = container.REQUEST.RESPONSE
start = time.time()
......@@ -32,7 +33,7 @@ for line in results.tuples():
v = v.isoformat()
elif isinstance(v, Decimal):
v = float(v)
elif isinstance(v, (long, int, float)) and not isSafeInteger(v):
elif isinstance(v, six.integer_types + (float,)) and not isSafeInteger(v):
# if numbers are too large to be handled by javascript, we simply return them
# as string, this will still not work for pivot table, but at least the spreadsheet
# will not display truncated values.
......
......@@ -40,6 +40,10 @@ from lxml import etree
from zLOG import LOG, ERROR, INFO
from erp5.component.tool.WebServiceTool import ConnectionError
from Products.ERP5Type.Cache import CachingMethod
import six
if six.PY3:
long = int
ID_SEPARATOR="-"
......
......@@ -11,11 +11,7 @@ import socket
import sys
from tempfile import TemporaryFile
import time
from six.moves.urllib.parse import quote
try:
from urllib import splitport
except ImportError: # six.PY3
from urllib.parse import splitport
from six.moves.urllib.parse import quote, urlsplit
from waitress.server import create_server
import ZConfig
......@@ -268,8 +264,7 @@ def runwsgi():
new_limit = (cur_limit[1], cur_limit[1])
resource.setrlimit(resource.RLIMIT_NOFILE, new_limit)
ip, port = splitport(args.address)
port = int(port)
port = urlsplit('//' + args.address).port
createServer(
app_wrapper(
large_file_threshold=args.large_file_threshold,
......
......@@ -9,7 +9,7 @@
cell_number python: len(module_category_list);
row_number python: (cell_number/max_per_line+1)"
class="access_tab_table">
<tr tal:repeat="row python: xrange(row_number)">
<tr tal:repeat="row python: range(row_number)">
<tal:block tal:repeat="module_category python: module_category_list[(row*max_per_line):((row+1)*max_per_line)]">
<td>
<div style="width:25%; min-width:150px; float:left;"
......
......@@ -330,7 +330,7 @@
error python: value[2]"
class="DataA" align="left"
tal:attributes="class python: error and (css + 'Error') or css;
align python: isinstance(original_value, (float, int, long)) and 'right' or 'left'">
align python: isinstance(original_value, modules['six'].integer_types + (float,)) and 'right' or 'left'">
<input tal:condition="not: repeat/value/index"
type="hidden" value="1" name="listbox_uid:list"
tal:attributes="value python: line.getUid() or '';
......@@ -348,7 +348,7 @@
<tal:block tal:repeat="value here/getStatValueList">
<td class="Data" align="left"
tal:define="original_value python: value[0]; processed_value python: value[1]"
tal:attributes="align python: isinstance(original_value, (float, int, long)) and 'right' or 'left'"
tal:attributes="align python: isinstance(original_value, modules['six'].integer_types + (float,)) and 'right' or 'left'"
tal:content="structure processed_value" />
</tal:block>
</tr>
......
......@@ -38,7 +38,7 @@ import os
import sys
import tempfile
import zipfile
import popen2
import subprocess
from six.moves import urllib
from six.moves import cStringIO as StringIO
......@@ -93,8 +93,12 @@ elif odfpy:
fd, file_name = tempfile.mkstemp()
os.write(fd, odf_file_content)
os.close(fd)
stdout, stdin = popen2.popen4('odflint %s' % file_name)
stdin.close()
process = subprocess.Popen(
['odflint', file_name],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
stdout, _ = process.communicate()
error_list = ''
for line in stdout:
if line.startswith('Error: '):
......
......@@ -567,6 +567,8 @@ def checkPythonSourceCode(source_code_str, portal_type=None):
if str is bytes:
bytes2str = str2bytes = lambda s: s
def str2unicode(s):
return s.decode('utf-8')
def unicode2str(s):
return s.encode('utf-8')
else:
......@@ -574,6 +576,8 @@ else:
return s.decode()
def str2bytes(s):
return s.encode()
def str2unicode(s):
return s
def unicode2str(s):
return s
......
......@@ -189,7 +189,7 @@ ModuleSecurityInfo('Products.ERP5Type.Utils').declarePublic(
'int2letter', 'getMessageIdWithContext', 'getTranslationStringWithContext',
'Email_parseAddressHeader', 'guessEncodingFromText',
'isValidTALESExpression',
'ensure_list', 'bytes2str', 'str2bytes', 'unicode2str',
'ensure_list', 'bytes2str', 'str2bytes', 'str2unicode', 'unicode2str',
)
allow_module('Products.ERP5Type.Message')
......
......@@ -61,8 +61,7 @@ ACQUIRE_LOCAL_ROLE_GETTER_DICT = {
for acquire_local_role in (False, True)
}
if six.PY3:
StandardError = Exception
def _importFilesystemClass(classpath):
try:
module_path, class_name = classpath.rsplit('.', 1)
......@@ -74,7 +73,7 @@ def _importFilesystemClass(classpath):
InitializeClass(klass)
return klass
except StandardError:
except Exception as e:
raise ImportError('Could not import document class ' + classpath)
def _importComponentClass(component_package, name):
......
......@@ -32,6 +32,7 @@ import math
from DateTime.DateTime import _calcSD, _calcDependentSecond, _calcYMDHMS,\
getDefaultDateFormat, _correctYear, _calcHMS, _calcDependentSecond2, DateTimeError,\
SyntaxError, DateError, TimeError, localtime, time
from Products.ERP5Type import IS_ZOPE2
STATE_KEY = 'str'
......@@ -297,12 +298,13 @@ DateTimeKlass.SyntaxError = SyntaxError
DateTimeKlass.DateError = DateError
DateTimeKlass.TimeError = TimeError
# BBB undo patch from DateTime 2.12 , which patches
# copy_reg._reconstructor with a function that appears as
# `DateTime.DateTime._dt_reconstructor` in pickles.
# See https://github.com/zopefoundation/DateTime/blob/2.12.8/src/DateTime/DateTime.py#L1863-L1874
# This patch is no longer needed once we are using DateTime >= 3 so
# it is not needed on python3 (copy_reg does not exist on python3)
import copy_reg
copy_reg._reconstructor.__module__ = 'copy_reg'
copy_reg._reconstructor.__name__ = '_reconstructor'
if IS_ZOPE2: # BBB Zope2
# BBB undo patch from DateTime 2.12 , which patches
# copy_reg._reconstructor with a function that appears as
# `DateTime.DateTime._dt_reconstructor` in pickles.
# See https://github.com/zopefoundation/DateTime/blob/2.12.8/src/DateTime/DateTime.py#L1863-L1874
# This patch is no longer needed once we are using DateTime >= 3 so
# it is not needed on python3 (copy_reg does not exist on python3)
import copy_reg
copy_reg._reconstructor.__module__ = 'copy_reg'
copy_reg._reconstructor.__name__ = '_reconstructor'
......@@ -80,6 +80,9 @@ add_builtins(Ellipsis=Ellipsis, NotImplemented=NotImplemented,
dict=dict, list=list)
if "set" not in safe_builtins: # BBB
add_builtins(set=set, frozenset=frozenset, slice=slice)
if "bytes" not in safe_builtins: # BBB Zope2
assert six.PY2
add_builtins(bytes=str)
add_builtins(bin=bin, classmethod=classmethod, format=format, object=object,
property=property, staticmethod=staticmethod,
......
......@@ -1356,7 +1356,7 @@ class ERP5TypeCommandLineTestCase(ERP5TypeTestCaseMixin):
try:
portal_activities = self.portal.portal_activities
message_list = portal_activities.getMessageList()
except StandardError: # AttributeError, TransactionFailedError ...
except Exception: # AttributeError, TransactionFailedError ...
pass
else:
for m in message_list:
......
......@@ -4,9 +4,8 @@ from six import unichr
from six.moves import xrange
import string
from .DummyField import fields
from DocumentTemplate.DT_Util import html_quote
from DocumentTemplate.html_quote import html_quote
from DateTime import DateTime, Timezones
from Products.PythonScripts.standard import html_quote
import types
from DocumentTemplate.ustr import ustr
from six.moves.urllib.parse import urljoin
......
# -*- coding: utf-8 -*-
import unittest, re
from lxml import etree
from DateTime import DateTime
import Zope2
......@@ -122,9 +123,12 @@ class FormTestCase(unittest.TestCase):
.manage_addField('date_time','Test Field','DateTimeField')
field = self.form.date_time
field._edit({'timezone_style': 0})
self.assertNotIn('<select size="1" name="subfield_field_date_time_timezone" >', field.render())
parser = etree.HTMLParser()
e = etree.fromstring(field.render(), parser=parser)
self.assertFalse(e.xpath('//select[@size="1"][@name="subfield_field_date_time_timezone"]'))
field._edit({'timezone_style': 1})
self.assertIn('<select size="1" name="subfield_field_date_time_timezone" >', field.render())
e = etree.fromstring(field.render(), parser=parser)
self.assertTrue(e.xpath('//select[@size="1"][@name="subfield_field_date_time_timezone"]'))
def test_datetime_css_class_rendering(self):
......@@ -181,13 +185,18 @@ class FormTestCase(unittest.TestCase):
.manage_addField('date_time','Test Field','DateTimeField')
field = self.form.date_time
field._edit({'input_style': 'number'})
self.assertIn('<input name="subfield_field_date_time_year" value="" maxlength="4" type="number" size="4" min="0" max="9999" />', field.render())
parser = etree.HTMLParser()
e = etree.fromstring(field.render(), parser=parser)
self.assertTrue(e.xpath('//input[@name="subfield_field_date_time_year"][@value=""][@maxlength="4"][@type="number"][@size="4"][@min="0"][@max="9999"]'))
field._edit({'start_datetime': DateTime('1900/01/01'), 'end_datetime': None})
self.assertIn('<input name="subfield_field_date_time_year" value="" maxlength="4" type="number" size="4" min="1900" max="9999" />', field.render())
e = etree.fromstring(field.render(), parser=parser)
self.assertTrue(e.xpath('//input[@name="subfield_field_date_time_year"][@value=""][@maxlength="4"][@type="number"][@size="4"][@min="1900"][@max="9999"]'))
field._edit({'start_datetime': None, 'end_datetime': DateTime('2099/12/31')})
self.assertIn('<input name="subfield_field_date_time_year" value="" maxlength="4" type="number" size="4" min="0" max="2099" />', field.render())
e = etree.fromstring(field.render(), parser=parser)
self.assertTrue(e.xpath('//input[@name="subfield_field_date_time_year"][@value=""][@maxlength="4"][@type="number"][@size="4"][@min="0"][@max="2099"]'))
field._edit({'start_datetime': DateTime('1900/01/01'), 'end_datetime': DateTime('2099/12/31')})
self.assertIn('<input name="subfield_field_date_time_year" value="" maxlength="4" type="number" size="4" min="1900" max="2099" />', field.render())
e = etree.fromstring(field.render(), parser=parser)
self.assertTrue(e.xpath('//input[@name="subfield_field_date_time_year"][@value=""][@maxlength="4"][@type="number"][@size="4"][@min="1900"][@max="2099"]'))
def test_suite():
......
......@@ -26,7 +26,8 @@ from App.Common import package_home
ph = package_home(globals())
# Initializes a list with the charsets
charsets = [ x.strip() for x in open(ph + '/charsets.txt').readlines() ]
with open(ph + '/charsets.txt') as f:
charsets = [ x.strip() for x in f.readlines() ]
......
......@@ -20,7 +20,7 @@ from six.moves import cStringIO as StringIO
from Products.PortalTransforms.interfaces import ITransform
from zope.interface import implementer
from DocumentTemplate.DT_Util import html_quote
from DocumentTemplate.html_quote import html_quote
## Python Source Parser #####################################################
......
from Products.PortalTransforms.interfaces import ITransform
from zope.interface import implementer
from DocumentTemplate.DT_Util import html_quote
from DocumentTemplate.html_quote import html_quote
__revision__ = '$Id: text_pre_to_html.py 3658 2005-02-23 16:29:54Z tiran $'
......
from Products.PortalTransforms.interfaces import ITransform
from zope.interface import implementer
from DocumentTemplate.DT_Util import html_quote
from DocumentTemplate.html_quote import html_quote
__revision__ = '$Id: text_to_html.py 4787 2005-08-19 21:43:41Z dreamcatcher $'
......
......@@ -25,8 +25,11 @@ from OFS.Folder import Folder
from DateTime import DateTime
from Acquisition import Implicit, aq_base
from Persistence import Persistent
from DocumentTemplate.DT_Util import InstanceDict, TemplateDict
from DocumentTemplate.DT_Util import Eval
from DocumentTemplate.DT_Util import Eval, TemplateDict
try:
from DocumentTemplate._DocumentTemplate import InstanceDict
except ImportError: # BBB
from DocumentTemplate.DT_Util import InstanceDict
from AccessControl.Permission import pname
from AccessControl.Permissions import import_export_objects, \
manage_zcatalog_entries
......
......@@ -69,7 +69,9 @@ def _makeFile(filename, prefix=None, id=None):
if id is None:
id = os.path.split( path )[ 1 ]
return File( id=id, title='', file=open(path).read() )
with open(path, 'rb') as f:
data = f.read()
return File( id=id, title='', file=data )
def registerFiles(directory, prefix):
......
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