diff --git a/bt5/erp5_access_token/TestTemplateItem/portal_components/test.erp5.testERP5AccessToken.py b/bt5/erp5_access_token/TestTemplateItem/portal_components/test.erp5.testERP5AccessToken.py
index 17d048311136d7aad38444c62c73534a1d319b04..2ca7026732fc54ccaa1067368184a4b8e1636d12 100644
--- a/bt5/erp5_access_token/TestTemplateItem/portal_components/test.erp5.testERP5AccessToken.py
+++ b/bt5/erp5_access_token/TestTemplateItem/portal_components/test.erp5.testERP5AccessToken.py
@@ -34,7 +34,7 @@ from DateTime import DateTime
 import urllib
 import httplib
 import base64
-import StringIO
+from six.moves import cStringIO as StringIO
 import mock
 from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
 from Products.ERP5Security.ERP5DumbHTTPExtractionPlugin import ERP5DumbHTTPExtractionPlugin
@@ -438,7 +438,7 @@ class TestERP5DumbHTTPExtractionPlugin(AccessTokenTestCase):
     env['GATEWAY_INTERFACE']='CGI/1.1 '
     env['SCRIPT_NAME']='Main'
     env.update(headers)
-    return HTTPRequest(StringIO.StringIO(), env, HTTPResponse())
+    return HTTPRequest(StringIO(), env, HTTPResponse())
 
   def test_working_authentication(self):
     request = self.do_fake_request("GET", {"HTTP_AUTHORIZATION": "Basic " + base64.b64encode("login:password")})
diff --git a/bt5/erp5_accounting/TestTemplateItem/portal_components/test.erp5.testAccounting.py b/bt5/erp5_accounting/TestTemplateItem/portal_components/test.erp5.testAccounting.py
index 836133d773ddcb06ea757a7c8b4cce3bae32be63..c78709c6048ba405c14a9fb6a9529f91f675a670 100644
--- a/bt5/erp5_accounting/TestTemplateItem/portal_components/test.erp5.testAccounting.py
+++ b/bt5/erp5_accounting/TestTemplateItem/portal_components/test.erp5.testAccounting.py
@@ -30,7 +30,7 @@
 
 """
 
-from StringIO import StringIO
+from six.moves import cStringIO as StringIO
 import lxml
 
 from DateTime import DateTime
diff --git a/bt5/erp5_accounting_l10n_fr/SkinTemplateItem/portal_skins/erp5_accounting_l10n_fr/AccountingTransactionModule_aggregateFrenchAccountingTransactionFile.py b/bt5/erp5_accounting_l10n_fr/SkinTemplateItem/portal_skins/erp5_accounting_l10n_fr/AccountingTransactionModule_aggregateFrenchAccountingTransactionFile.py
index 09d6b04a20732ae84a2b6565574a971f9672eaf9..dc43ac6d19db33963a2ce243d06fdea5f8306f22 100644
--- a/bt5/erp5_accounting_l10n_fr/SkinTemplateItem/portal_skins/erp5_accounting_l10n_fr/AccountingTransactionModule_aggregateFrenchAccountingTransactionFile.py
+++ b/bt5/erp5_accounting_l10n_fr/SkinTemplateItem/portal_skins/erp5_accounting_l10n_fr/AccountingTransactionModule_aggregateFrenchAccountingTransactionFile.py
@@ -1,4 +1,4 @@
-from cStringIO import StringIO
+from six.moves import cStringIO as StringIO
 import zipfile
 from Products.ERP5Type.Message import translateString
 
diff --git a/bt5/erp5_accounting_l10n_fr/TestTemplateItem/portal_components/test.erp5.testAccounting_l10n_fr.py b/bt5/erp5_accounting_l10n_fr/TestTemplateItem/portal_components/test.erp5.testAccounting_l10n_fr.py
index f72b596b90e3cf4b3fa353b5ac6e937748d01132..fbf07bb21c073490f54b85a133307a1b2af1d60e 100644
--- a/bt5/erp5_accounting_l10n_fr/TestTemplateItem/portal_components/test.erp5.testAccounting_l10n_fr.py
+++ b/bt5/erp5_accounting_l10n_fr/TestTemplateItem/portal_components/test.erp5.testAccounting_l10n_fr.py
@@ -34,7 +34,7 @@ import unittest
 import zipfile
 import email
 import os.path
-from cStringIO import StringIO
+from six.moves import cStringIO as StringIO
 from DateTime import DateTime
 
 from lxml import etree
diff --git a/bt5/erp5_administration/SkinTemplateItem/portal_skins/erp5_administration/ERP5Site_profileContext.py b/bt5/erp5_administration/SkinTemplateItem/portal_skins/erp5_administration/ERP5Site_profileContext.py
index 1000f9998df8e482c8f8856d115aba796405eca0..43a8a390d38a9ecfb88dcd29a80da96e7f2f4d2d 100644
--- a/bt5/erp5_administration/SkinTemplateItem/portal_skins/erp5_administration/ERP5Site_profileContext.py
+++ b/bt5/erp5_administration/SkinTemplateItem/portal_skins/erp5_administration/ERP5Site_profileContext.py
@@ -20,7 +20,7 @@ zipfile (bool)
   When true, the result is a zip file containing profiling result along with the python code (and, when not possible, the disassembled bytecode) of all files which appear in the profiling result.
   When false, the result is a bare profiling result (cachegrind file format).
 """
-from StringIO import StringIO
+from six.moves import cStringIO as StringIO
 portal = context.getPortalObject()
 if statistic:
   profiler, retriever = portal.ERP5Site_getStatisticalProfilerAndThread(single=True)
diff --git a/bt5/erp5_administration/SkinTemplateItem/portal_skins/erp5_administration/ERP5Site_profileProcess.py b/bt5/erp5_administration/SkinTemplateItem/portal_skins/erp5_administration/ERP5Site_profileProcess.py
index 9cb715a74c7af286cfb2707fa74047caf44329a6..a84d3c2f7c481ccf60737c4619debda4e5349c41 100644
--- a/bt5/erp5_administration/SkinTemplateItem/portal_skins/erp5_administration/ERP5Site_profileProcess.py
+++ b/bt5/erp5_administration/SkinTemplateItem/portal_skins/erp5_administration/ERP5Site_profileProcess.py
@@ -18,7 +18,7 @@ zipfile (bool)
   When false, the result is a bare profiling result (cachegrind file format).
 """
 from time import sleep
-from StringIO import StringIO
+from six.moves import cStringIO as StringIO
 profiler, thread = context.ERP5Site_getStatisticalProfilerAndThread(single=False)
 with thread:
   sleep(duration)
diff --git a/bt5/erp5_authentication_policy/TestTemplateItem/portal_components/test.erp5.testAuthenticationPolicy.py b/bt5/erp5_authentication_policy/TestTemplateItem/portal_components/test.erp5.testAuthenticationPolicy.py
index 503f623a157142d5fe7750abc9406f26b4d57e2e..bd682ccd7de3a875e239e538897558c57921a49a 100644
--- a/bt5/erp5_authentication_policy/TestTemplateItem/portal_components/test.erp5.testAuthenticationPolicy.py
+++ b/bt5/erp5_authentication_policy/TestTemplateItem/portal_components/test.erp5.testAuthenticationPolicy.py
@@ -30,9 +30,8 @@
 
 from functools import partial
 import unittest
-import urllib
-import urlparse
-from StringIO import StringIO
+import six.moves.urllib.parse
+from six.moves import cStringIO as StringIO
 import time
 import httplib
 import mock
diff --git a/bt5/erp5_base/DocumentTemplateItem/portal_components/document.erp5.Image.py b/bt5/erp5_base/DocumentTemplateItem/portal_components/document.erp5.Image.py
index 21392199de83f567bb1ab4bbc124cbd58a0b8037..072b4fd22fb59d84c9be9734673c26229c7561f6 100644
--- a/bt5/erp5_base/DocumentTemplateItem/portal_components/document.erp5.Image.py
+++ b/bt5/erp5_base/DocumentTemplateItem/portal_components/document.erp5.Image.py
@@ -32,7 +32,7 @@
 
 import os
 import subprocess
-from cStringIO import StringIO
+from six.moves import cStringIO as StringIO
 
 from AccessControl import ClassSecurityInfo
 from Acquisition import aq_base
diff --git a/bt5/erp5_base/DocumentTemplateItem/portal_components/document.erp5.OOoDocument.py b/bt5/erp5_base/DocumentTemplateItem/portal_components/document.erp5.OOoDocument.py
index 560ea632a7ec9565fed40911b258f94dfe993295..6333890fbbd4486d6ae9092f8839b6dfcff5fbf9 100644
--- a/bt5/erp5_base/DocumentTemplateItem/portal_components/document.erp5.OOoDocument.py
+++ b/bt5/erp5_base/DocumentTemplateItem/portal_components/document.erp5.OOoDocument.py
@@ -27,7 +27,8 @@
 #
 ##############################################################################
 
-import re, zipfile, cStringIO
+import re, zipfile
+from six.moves import cStringIO as StringIO
 from warnings import warn
 from AccessControl import ClassSecurityInfo
 from OFS.Image import Pdata
diff --git a/bt5/erp5_base/ExtensionTemplateItem/portal_components/extension.erp5.BarcodeUtils.py b/bt5/erp5_base/ExtensionTemplateItem/portal_components/extension.erp5.BarcodeUtils.py
index 6b9117cdaf07a4e8a5470d13b0673ce46db74add..6fbd82eac27b00b12b276db47a42b0993ea7e7bd 100644
--- a/bt5/erp5_base/ExtensionTemplateItem/portal_components/extension.erp5.BarcodeUtils.py
+++ b/bt5/erp5_base/ExtensionTemplateItem/portal_components/extension.erp5.BarcodeUtils.py
@@ -22,7 +22,7 @@ def generateBarcodeImage(self, barcode_type, data, REQUEST=None):
     output = encoder.get_imagedata()
   elif barcode_type == 'qrcode':
     import qrcode
-    from cStringIO import StringIO
+    from six.moves import cStringIO as StringIO
     fp = StringIO()
     img = qrcode.make(data)
     img.save(fp, 'png')
diff --git a/bt5/erp5_big_file/DocumentTemplateItem/portal_components/document.erp5.BigFile.py b/bt5/erp5_big_file/DocumentTemplateItem/portal_components/document.erp5.BigFile.py
index 1cddc70a9d335e9be00e6c38c6b5a3ec5fc72a67..803a747f2eb8e5c9c445049f4701cdef5f3790ed 100644
--- a/bt5/erp5_big_file/DocumentTemplateItem/portal_components/document.erp5.BigFile.py
+++ b/bt5/erp5_big_file/DocumentTemplateItem/portal_components/document.erp5.BigFile.py
@@ -14,7 +14,7 @@
 #
 ##############################################################################
 
-from cStringIO import StringIO
+from six.moves import cStringIO as StringIO
 from AccessControl import ClassSecurityInfo
 from Products.ERP5Type import Permissions, PropertySheet
 from Products.ERP5Type.Base import removeIContentishInterface
diff --git a/bt5/erp5_big_file/TestTemplateItem/portal_components/test.erp5.testBigFile.py b/bt5/erp5_big_file/TestTemplateItem/portal_components/test.erp5.testBigFile.py
index f0d8171c508a3f5b9d17c32070834063eed89df7..e76b4db1ef04d200895af5d28611495ffd2b7d17 100644
--- a/bt5/erp5_big_file/TestTemplateItem/portal_components/test.erp5.testBigFile.py
+++ b/bt5/erp5_big_file/TestTemplateItem/portal_components/test.erp5.testBigFile.py
@@ -24,7 +24,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
-from cStringIO import StringIO
+from six.moves import cStringIO as StringIO
 
 from ZPublisher.HTTPRequest import HTTPRequest
 from ZPublisher.HTTPResponse import HTTPResponse
diff --git a/bt5/erp5_configurator/DocumentTemplateItem/portal_components/document.erp5.CategoriesSpreadsheetConfiguratorItem.py b/bt5/erp5_configurator/DocumentTemplateItem/portal_components/document.erp5.CategoriesSpreadsheetConfiguratorItem.py
index b3686f590d9e95023bf4458f9cce857a41c1ef73..c6d256a9aebeb4526de5c9b70181de8a377c1060 100644
--- a/bt5/erp5_configurator/DocumentTemplateItem/portal_components/document.erp5.CategoriesSpreadsheetConfiguratorItem.py
+++ b/bt5/erp5_configurator/DocumentTemplateItem/portal_components/document.erp5.CategoriesSpreadsheetConfiguratorItem.py
@@ -27,7 +27,7 @@
 ##############################################################################
 
 import zope.interface
-from StringIO import StringIO
+from six.moves import cStringIO as StringIO
 from Acquisition import aq_base
 from AccessControl import ClassSecurityInfo
 from Products.ERP5Type import Permissions, PropertySheet
diff --git a/bt5/erp5_configurator/ExtensionTemplateItem/portal_components/extension.erp5.ConfigurationTemplate_readOOoCalcFile.py b/bt5/erp5_configurator/ExtensionTemplateItem/portal_components/extension.erp5.ConfigurationTemplate_readOOoCalcFile.py
index 66604f6937a46019ee77f114fa1e010a9ddb0fe6..084b8f94a4e993a8bcccefa4d4289df7200bdb40 100644
--- a/bt5/erp5_configurator/ExtensionTemplateItem/portal_components/extension.erp5.ConfigurationTemplate_readOOoCalcFile.py
+++ b/bt5/erp5_configurator/ExtensionTemplateItem/portal_components/extension.erp5.ConfigurationTemplate_readOOoCalcFile.py
@@ -30,17 +30,17 @@
 # This extension should be replaced by a clever parser provided by
 # ERP5OOo or probably by CloudOOo itself.
 
-import StringIO
+from io import BytesIO
 
 def read(self, filename, data):
   """
-  Return a OOCalc as a StringIO
+  Return a OOCalc as a BytesIO
   """
   if data is None:
     oo_template_file = getattr(self, filename)
-    fp = StringIO.StringIO(oo_template_file)
+    fp = BytesIO(oo_template_file)
   else:
-    fp = StringIO.StringIO(data)
+    fp = BytesIO(data)
   fp.filename = filename
   return fp
 
diff --git a/bt5/erp5_core_test/TestTemplateItem/portal_components/test.erp5.testAutoLogout.py b/bt5/erp5_core_test/TestTemplateItem/portal_components/test.erp5.testAutoLogout.py
index 3f1181b2834a0a101d652affc66b3b20321da2c5..ae76a696b91ef78c2a5f47585354f45500a57101 100644
--- a/bt5/erp5_core_test/TestTemplateItem/portal_components/test.erp5.testAutoLogout.py
+++ b/bt5/erp5_core_test/TestTemplateItem/portal_components/test.erp5.testAutoLogout.py
@@ -29,7 +29,7 @@
 ##############################################################################
 
 from functools import partial
-from StringIO import StringIO
+from six.moves import cStringIO as StringIO
 import unittest
 import urllib
 from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
diff --git a/bt5/erp5_core_test/TestTemplateItem/portal_components/test.erp5.testCookieCrumbler.py b/bt5/erp5_core_test/TestTemplateItem/portal_components/test.erp5.testCookieCrumbler.py
index 72e678c9efcc97bf499bd83cb2342c96c1b6f7ce..b9db2cdd1e0ba3d7a2ff1418dae950151cf559b8 100644
--- a/bt5/erp5_core_test/TestTemplateItem/portal_components/test.erp5.testCookieCrumbler.py
+++ b/bt5/erp5_core_test/TestTemplateItem/portal_components/test.erp5.testCookieCrumbler.py
@@ -12,7 +12,7 @@
 ##############################################################################
 
 import base64
-from cStringIO import StringIO
+from six.moves import cStringIO as StringIO
 import unittest
 import urllib
 
diff --git a/bt5/erp5_core_test/TestTemplateItem/portal_components/test.erp5.testRestrictedPythonSecurity.py b/bt5/erp5_core_test/TestTemplateItem/portal_components/test.erp5.testRestrictedPythonSecurity.py
index 75ce72b15b6feec4ab431d6eb55f7f001bc24bf1..b129420ac92a4386e016ca2b8a6bdee34c9a9d7d 100644
--- a/bt5/erp5_core_test/TestTemplateItem/portal_components/test.erp5.testRestrictedPythonSecurity.py
+++ b/bt5/erp5_core_test/TestTemplateItem/portal_components/test.erp5.testRestrictedPythonSecurity.py
@@ -448,6 +448,8 @@ class TestRestrictedPythonSecurity(ERP5TypeTestCase):
     )
 
   def test_StringIO(self):
+    if six.PY3:
+      return # Python 3's StringIO is cStringIO, thus we just test in test_cStringIO.
     self.createAndRunScript('''
         import StringIO
         s = StringIO.StringIO()
@@ -465,16 +467,16 @@ class TestRestrictedPythonSecurity(ERP5TypeTestCase):
 
   def test_cStringIO(self):
     self.createAndRunScript('''
-        import cStringIO
-        s = cStringIO.StringIO()
+        from six.moves import cStringIO as StringIO
+        s = StringIO()
         s.write("ok")
         return s.getvalue()
         ''',
         expected="ok"
     )
     self.createAndRunScript('''
-        import cStringIO
-        return cStringIO.StringIO("ok").getvalue()
+        from six.moves import cStringIO as StringIO
+        return StringIO("ok").getvalue()
         ''',
         expected="ok"
     )
@@ -685,7 +687,7 @@ class TestRestrictedPythonSecurity(ERP5TypeTestCase):
     for pandas_read_function in ("read_json", "read_csv", "read_fwf"):
       for preparation, prohibited_input in (
         ('', 100),
-        ('from StringIO import StringIO', 'StringIO("[1, 2, 3]")'),
+        ('from six.moves import cStringIO as StringIO', 'StringIO("[1, 2, 3]")'),
       ):
         self.assertRaises(
           ZopeGuardsUnauthorized,
diff --git a/bt5/erp5_core_test/TestTemplateItem/portal_components/test.erp5.testXMLPickle.py b/bt5/erp5_core_test/TestTemplateItem/portal_components/test.erp5.testXMLPickle.py
index 53b977e9ac3faf193681990d5e0176425b152271..26536d96da179267003408547478d03a11968477 100644
--- a/bt5/erp5_core_test/TestTemplateItem/portal_components/test.erp5.testXMLPickle.py
+++ b/bt5/erp5_core_test/TestTemplateItem/portal_components/test.erp5.testXMLPickle.py
@@ -30,7 +30,7 @@ import unittest
 import pickle
 import re
 import xml.sax
-from StringIO import StringIO
+from six.moves import cStringIO as StringIO
 
 from Products.ERP5Type.XMLExportImport import ppml
 
diff --git a/bt5/erp5_data_notebook/ExtensionTemplateItem/portal_components/extension.erp5.JupyterCompile.py b/bt5/erp5_data_notebook/ExtensionTemplateItem/portal_components/extension.erp5.JupyterCompile.py
index ab681d647fba6f36eb0a7e48543d7a6d80e0cde5..ba64b0e40a38a169724121120c0b1c7011a064f4 100644
--- a/bt5/erp5_data_notebook/ExtensionTemplateItem/portal_components/extension.erp5.JupyterCompile.py
+++ b/bt5/erp5_data_notebook/ExtensionTemplateItem/portal_components/extension.erp5.JupyterCompile.py
@@ -2,7 +2,7 @@
 from matplotlib.figure import Figure
 from IPython.core.display import DisplayObject
 from IPython.lib.display import IFrame
-from cStringIO import StringIO
+from six.moves import cStringIO as StringIO
 from erp5.portal_type import Image
 from types import ModuleType
 from ZODB.serialize import ObjectWriter
diff --git a/bt5/erp5_dms/TestTemplateItem/portal_components/test.erp5.testDms.py b/bt5/erp5_dms/TestTemplateItem/portal_components/test.erp5.testDms.py
index e2c4adeb1c35aabf8566f6fbfa4fb7d8560db31a..7c06f9c99ec9bd700383fbd56a4d6553ed656a62 100644
--- a/bt5/erp5_dms/TestTemplateItem/portal_components/test.erp5.testDms.py
+++ b/bt5/erp5_dms/TestTemplateItem/portal_components/test.erp5.testDms.py
@@ -47,7 +47,7 @@
 
 import unittest
 import time
-import StringIO
+from six.moves import cStringIO as StringIO
 from subprocess import Popen, PIPE
 from unittest import expectedFailure
 
@@ -1720,7 +1720,7 @@ class TestDocument(TestDocumentMixin):
     # as it is done in reality
 
     # Mimic the behaviour of a FileUpload from WebPage_view
-    file_like = StringIO.StringIO()
+    file_like = StringIO()
     file_like.write(html_content)
     setattr(file_like, 'filename', 'something.htm')
     web_page.edit(file=file_like)
@@ -2009,7 +2009,7 @@ document.write('<sc'+'ript type="text/javascript" src="http://somosite.bg/utb.ph
     self.assertEqual(document.asText(), 'ERP5 is a free software.')
 
   def test_broken_pdf_asText(self):
-    class StringIOWithFilename(StringIO.StringIO):
+    class StringIOWithFilename(StringIO):
       filename = 'broken.pdf'
     document = self.portal.document_module.newContent(
         portal_type='PDF',
@@ -2022,7 +2022,7 @@ document.write('<sc'+'ript type="text/javascript" src="http://somosite.bg/utb.ph
     pdf_writer = PyPDF2.PdfFileWriter()
     pdf_writer.addPage(pdf_reader.getPage(0))
     pdf_writer.encrypt('secret')
-    encrypted_pdf_stream = StringIO.StringIO()
+    encrypted_pdf_stream = StringIO()
     pdf_writer.write(encrypted_pdf_stream)
     document = self.portal.document_module.newContent(
         portal_type='PDF',
diff --git a/bt5/erp5_dms/TestTemplateItem/portal_components/test.erp5.testERP5WebWithDms.py b/bt5/erp5_dms/TestTemplateItem/portal_components/test.erp5.testERP5WebWithDms.py
index f50283d0b1f0ddba3af3bd7842d383f2622c5ff9..3cc8a5c95761170d9e856d171add737fb1c467b9 100644
--- a/bt5/erp5_dms/TestTemplateItem/portal_components/test.erp5.testERP5WebWithDms.py
+++ b/bt5/erp5_dms/TestTemplateItem/portal_components/test.erp5.testERP5WebWithDms.py
@@ -31,7 +31,7 @@ import unittest
 import os
 import quopri
 import functools
-from StringIO import StringIO
+from six.moves import cStringIO as StringIO
 from lxml import etree
 from base64 import b64decode, b64encode
 from email.parser import Parser as EmailParser
diff --git a/bt5/erp5_dms/TestTemplateItem/portal_components/test.erp5.testWebDavSupport.py b/bt5/erp5_dms/TestTemplateItem/portal_components/test.erp5.testWebDavSupport.py
index 3202eea205290ccb5d1108fd1a6608e2a61f56ec..4237b9e21d9c2d84e0960e49561c912eb8ccdf26 100644
--- a/bt5/erp5_dms/TestTemplateItem/portal_components/test.erp5.testWebDavSupport.py
+++ b/bt5/erp5_dms/TestTemplateItem/portal_components/test.erp5.testWebDavSupport.py
@@ -34,8 +34,8 @@ from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
 from Products.ERP5Type.tests.utils import FileUpload
 from unittest import expectedFailure
 
-import httplib
-from StringIO import StringIO
+import six.moves.http_client
+from six.moves import cStringIO as StringIO
 from DateTime import DateTime
 
 from lxml import etree
diff --git a/bt5/erp5_document_scanner/SkinTemplateItem/portal_skins/erp5_document_scanner/Base_uploadDocumentFromCamera.py b/bt5/erp5_document_scanner/SkinTemplateItem/portal_skins/erp5_document_scanner/Base_uploadDocumentFromCamera.py
index 417ac6fa1ba0d9df03b30849b779576747885571..6b543e36d43ab899705050ed85fd998a0168c251 100644
--- a/bt5/erp5_document_scanner/SkinTemplateItem/portal_skins/erp5_document_scanner/Base_uploadDocumentFromCamera.py
+++ b/bt5/erp5_document_scanner/SkinTemplateItem/portal_skins/erp5_document_scanner/Base_uploadDocumentFromCamera.py
@@ -1,4 +1,4 @@
-from StringIO import StringIO
+from six.moves import cStringIO as StringIO
 
 class StringIOWithFileName(StringIO):
   filename =  "{}.pdf".format(
diff --git a/bt5/erp5_forge/ExtensionTemplateItem/portal_components/extension.erp5.Glossary.py b/bt5/erp5_forge/ExtensionTemplateItem/portal_components/extension.erp5.Glossary.py
index 0e2a815fb2cb7be770bec62b53ac1a26d7b1da03..d9f0e1a49f1f85d8ede820d638e4ce8770d5f208 100644
--- a/bt5/erp5_forge/ExtensionTemplateItem/portal_components/extension.erp5.Glossary.py
+++ b/bt5/erp5_forge/ExtensionTemplateItem/portal_components/extension.erp5.Glossary.py
@@ -53,7 +53,7 @@ def getActionTitleListFromAllActionProvider(portal):
   return result
 
 
-from StringIO import StringIO
+from six.moves import cStringIO as StringIO
 from zope.tal.htmltalparser import HTMLTALParser
 from zope.tal.talparser import TALParser
 from zope.tal.talgenerator import TALGenerator
diff --git a/bt5/erp5_hal_json_style/TestTemplateItem/portal_components/test.erp5.testHalJsonStyle.py b/bt5/erp5_hal_json_style/TestTemplateItem/portal_components/test.erp5.testHalJsonStyle.py
index 31f15be870323f163f06d04c5c67724d0a222e83..233823a412b68fbc15ef50b55f2824ab519907ea 100644
--- a/bt5/erp5_hal_json_style/TestTemplateItem/portal_components/test.erp5.testHalJsonStyle.py
+++ b/bt5/erp5_hal_json_style/TestTemplateItem/portal_components/test.erp5.testHalJsonStyle.py
@@ -11,7 +11,7 @@ from ZPublisher.HTTPResponse import HTTPResponse
 
 import base64
 import DateTime
-import StringIO
+from six.moves import cStringIO as StringIO
 import json
 import re
 import urllib
@@ -116,7 +116,7 @@ def do_fake_request(request_method, headers=None, data=()):
   env['GATEWAY_INTERFACE']='CGI/1.1 '
   env['SCRIPT_NAME']='Main'
   env.update(headers)
-  body_stream = StringIO.StringIO()
+  body_stream = StringIO()
 
   # for some mysterious reason QUERY_STRING does not get parsed into data fields
   if data and request_method.upper() == 'GET':
diff --git a/bt5/erp5_officejs_appstore_base/SkinTemplateItem/portal_skins/erp5_officejs_appstore_base/SoftwarePublication_submitSoftwarePublication.py b/bt5/erp5_officejs_appstore_base/SkinTemplateItem/portal_skins/erp5_officejs_appstore_base/SoftwarePublication_submitSoftwarePublication.py
index c46766ecc53d5b0f65f96d65844eaee57cc17583..834c6307e7e1c4190dcee9d842103658de3f97f8 100644
--- a/bt5/erp5_officejs_appstore_base/SkinTemplateItem/portal_skins/erp5_officejs_appstore_base/SoftwarePublication_submitSoftwarePublication.py
+++ b/bt5/erp5_officejs_appstore_base/SkinTemplateItem/portal_skins/erp5_officejs_appstore_base/SoftwarePublication_submitSoftwarePublication.py
@@ -60,7 +60,7 @@ if not zip_file:
   rejectSoftwarePublication(software_publication)
   return
 
-from cStringIO import StringIO
+from six.moves import cStringIO as StringIO
 import zipfile
 from zipfile import BadZipfile
 
diff --git a/bt5/erp5_officejs_support_request_ui_test/TestTemplateItem/portal_components/test.erp5.testSupportRequest.py b/bt5/erp5_officejs_support_request_ui_test/TestTemplateItem/portal_components/test.erp5.testSupportRequest.py
index d41a5c7d075230df9d066a7ea97103969645c7da..a77a00c4b55919b400750e9001b49eeefa03b0f8 100644
--- a/bt5/erp5_officejs_support_request_ui_test/TestTemplateItem/portal_components/test.erp5.testSupportRequest.py
+++ b/bt5/erp5_officejs_support_request_ui_test/TestTemplateItem/portal_components/test.erp5.testSupportRequest.py
@@ -25,9 +25,9 @@
 #
 ##############################################################################
 import json
-from StringIO import StringIO
-import urlparse
-import httplib
+from six.moves import cStringIO as StringIO
+import six.moves.urllib.parse
+import six.moves.http_client
 
 import feedparser
 from DateTime import DateTime
diff --git a/bt5/erp5_pdf_merge/ExtensionTemplateItem/portal_components/extension.erp5.ERP5PDFMerge.py b/bt5/erp5_pdf_merge/ExtensionTemplateItem/portal_components/extension.erp5.ERP5PDFMerge.py
index 9e855d311e43444df04af631c88b886323686cc2..a2f440dae664b777af040da8307839a460ec91ac 100644
--- a/bt5/erp5_pdf_merge/ExtensionTemplateItem/portal_components/extension.erp5.ERP5PDFMerge.py
+++ b/bt5/erp5_pdf_merge/ExtensionTemplateItem/portal_components/extension.erp5.ERP5PDFMerge.py
@@ -35,7 +35,7 @@ def mergePDFList(self, pdf_data_list, start_on_recto=False):
   to have each PDF as the recto page. This is useful if you have to print the
   merged pdf in recto/verso mode.
   """
-  from StringIO import StringIO
+  from six.moves import cStringIO as StringIO
   from PyPDF2 import PdfFileWriter, PdfFileReader
 
   output = PdfFileWriter()
diff --git a/bt5/erp5_receipt_recognition/ExtensionTemplateItem/portal_components/extension.erp5.ReceiptRecognition.py b/bt5/erp5_receipt_recognition/ExtensionTemplateItem/portal_components/extension.erp5.ReceiptRecognition.py
index 4ec6cff22404ab4f47e19fe5cc18ce8c8695a74e..e346f97e47afbb4f70c938827b71999c96130bab 100644
--- a/bt5/erp5_receipt_recognition/ExtensionTemplateItem/portal_components/extension.erp5.ReceiptRecognition.py
+++ b/bt5/erp5_receipt_recognition/ExtensionTemplateItem/portal_components/extension.erp5.ReceiptRecognition.py
@@ -11,7 +11,7 @@ https://github.com/tmbdev/ocropy
 
 import numpy as np
 import scipy.ndimage as ndi
-import StringIO
+from six.moves import cStringIO as StringIO
 from matplotlib import pylab
 import matplotlib.image as mpimg
 import scipy.stats as stats
@@ -38,7 +38,7 @@ def getReceiptValue(self, image_data, model_name = "en-default.pyrnn"):
   This function look for euros only and return a price with a two digit
   precison like "135.79" or "43,89".
   """
-  image_as_string = StringIO.StringIO(image_data)
+  image_as_string = StringIO(image_data)
   image_as_array = mpimg.imread(image_as_string, format = 'JPG')
   line_list, cleared = getLinesFromPicture(image_as_array)
 
diff --git a/bt5/erp5_safeimage/ExtensionTemplateItem/portal_components/extension.erp5.ERP5ZoomifyImage.py b/bt5/erp5_safeimage/ExtensionTemplateItem/portal_components/extension.erp5.ERP5ZoomifyImage.py
index 288c4621fd6ee3c1b356df8b45ae8ae04ff22df1..7db9e4d2e7607f29c790acdabda91bf91ece0557 100644
--- a/bt5/erp5_safeimage/ExtensionTemplateItem/portal_components/extension.erp5.ERP5ZoomifyImage.py
+++ b/bt5/erp5_safeimage/ExtensionTemplateItem/portal_components/extension.erp5.ERP5ZoomifyImage.py
@@ -17,7 +17,7 @@
 ##############################################################################
 
 import os, sys, shutil, tempfile
-from cStringIO import StringIO
+from six.moves import cStringIO as StringIO
 from zLOG import LOG,ERROR,INFO,WARNING
 from OFS.Image import File, Image
 import os, transaction
diff --git a/bt5/erp5_safeimage/SkinTemplateItem/portal_skins/erp5_safeimage/SeleniumSafeImage_uploadFile.py b/bt5/erp5_safeimage/SkinTemplateItem/portal_skins/erp5_safeimage/SeleniumSafeImage_uploadFile.py
index 4182231cd6e3f783a9dc629066121e0e77da8f4e..da535c19a1bbb013486ddc7b29100103b60ef4f2 100644
--- a/bt5/erp5_safeimage/SkinTemplateItem/portal_skins/erp5_safeimage/SeleniumSafeImage_uploadFile.py
+++ b/bt5/erp5_safeimage/SkinTemplateItem/portal_skins/erp5_safeimage/SeleniumSafeImage_uploadFile.py
@@ -1,5 +1,5 @@
 #from Products.ERP5.Document.TileImageTransformed import TileImageTransformed
-#from cStringIO import StringIO
+#from six.moves import cStringIO as StringIO
 
 
 portal = context.getPortalObject()
diff --git a/bt5/erp5_simplified_invoicing/TestTemplateItem/portal_components/test.erp5.testInvoice.py b/bt5/erp5_simplified_invoicing/TestTemplateItem/portal_components/test.erp5.testInvoice.py
index a396eb464a9708effba4fedebfbf2f4ee2078297..441a148335b115e4faa02d14a16c67e378c3f6ca 100644
--- a/bt5/erp5_simplified_invoicing/TestTemplateItem/portal_components/test.erp5.testInvoice.py
+++ b/bt5/erp5_simplified_invoicing/TestTemplateItem/portal_components/test.erp5.testInvoice.py
@@ -560,8 +560,8 @@ class TestInvoice(TestInvoiceMixin):
     invoice.confirm()
     self.tic()
     odt = invoice.Invoice_viewAsODT()
-    import cStringIO
-    output = cStringIO.StringIO()
+    from io import BytesIO
+    output = BytesIO()
     output.write(odt)
     m = OpenDocumentTextFile(output)
     text_content=m.toString().encode('ascii','replace')
diff --git a/bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.ERP5ShopOrderConduit.py b/bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.ERP5ShopOrderConduit.py
index a737bdba01c456f205f583bf2f6ee937a4eeb9ed..0c51dbcbf078df6a1e2d7f96356d442843dee548 100644
--- a/bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.ERP5ShopOrderConduit.py
+++ b/bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.ERP5ShopOrderConduit.py
@@ -29,7 +29,7 @@
 
 from xml.dom.ext import PrettyPrint
 import random
-from cStringIO import StringIO
+from six.moves import cStringIO as StringIO
 
 from AccessControl import ClassSecurityInfo
 from zLOG import LOG
diff --git a/bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.SyncMLUtils.py b/bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.SyncMLUtils.py
index daeab1481d164ed1c97fd34553ebf37fa6028c0b..6ef9f9b0b207510f363b63323259ac2e1792de7c 100644
--- a/bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.SyncMLUtils.py
+++ b/bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.SyncMLUtils.py
@@ -37,7 +37,7 @@ from hashlib import md5
 
 from ZPublisher.HTTPRequest import FileUpload
 from OFS.Image import Pdata
-from StringIO import StringIO
+from six.moves import cStringIO as StringIO
 import transaction
 
 class PdataHelper(persistent.Persistent):
diff --git a/bt5/erp5_ui_test/TestTemplateItem/portal_components/test.erp5.testListBox.py b/bt5/erp5_ui_test/TestTemplateItem/portal_components/test.erp5.testListBox.py
index edd165832191bd963f655cbe6300a8850c0cf011..a2dd6000f08628e13668b5198ce74785ee866542 100644
--- a/bt5/erp5_ui_test/TestTemplateItem/portal_components/test.erp5.testListBox.py
+++ b/bt5/erp5_ui_test/TestTemplateItem/portal_components/test.erp5.testListBox.py
@@ -39,7 +39,7 @@ from Testing import ZopeTestCase
 from Products.ERP5Type.Globals import get_request
 from Products.ERP5Type.tests.utils import createZODBPythonScript
 from ZPublisher.HTTPRequest import FileUpload
-from StringIO import StringIO
+from six.moves import cStringIO as StringIO
 from Products.ERP5Form.Selection import Selection
 from Products.Formulator.TALESField import TALESMethod
 from Products.ERP5Form.ListBox import ListBoxHTMLRenderer
diff --git a/bt5/erp5_ui_test/TestTemplateItem/portal_components/test.erp5.testPlanningBox.py b/bt5/erp5_ui_test/TestTemplateItem/portal_components/test.erp5.testPlanningBox.py
index 664a9c5268445f203e68f35bb8b89ab31e4e3d97..8daf2912d339b63cf0ff98e43a056a398cf68a90 100644
--- a/bt5/erp5_ui_test/TestTemplateItem/portal_components/test.erp5.testPlanningBox.py
+++ b/bt5/erp5_ui_test/TestTemplateItem/portal_components/test.erp5.testPlanningBox.py
@@ -30,7 +30,7 @@ from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
 from AccessControl.SecurityManagement import newSecurityManager
 from Products.ERP5Type.tests.Sequence import SequenceList
 from Products.ERP5Type.Globals import get_request
-from StringIO import StringIO
+from six.moves import cStringIO as StringIO
 from DateTime import DateTime
 
 class DummyFieldStorage:
diff --git a/bt5/erp5_web/TestTemplateItem/portal_components/test.erp5.testERP5Web.py b/bt5/erp5_web/TestTemplateItem/portal_components/test.erp5.testERP5Web.py
index e71467c95e2fcf0389a97f81142c222ce376513a..280fdab77baa5056265c9558faba8928f49af833 100644
--- a/bt5/erp5_web/TestTemplateItem/portal_components/test.erp5.testERP5Web.py
+++ b/bt5/erp5_web/TestTemplateItem/portal_components/test.erp5.testERP5Web.py
@@ -31,8 +31,8 @@
 import re
 import time
 from unittest import expectedFailure, skip
-from StringIO import StringIO
-from urllib import urlencode
+from six.moves import cStringIO as StringIO
+from six.moves.urllib.parse import urlencode
 from AccessControl import Unauthorized
 from Testing import ZopeTestCase
 from DateTime import DateTime
diff --git a/bt5/erp5_web_renderjs_ui_test/TestTemplateItem/portal_components/test.erp5.testRJSUpgrader.py b/bt5/erp5_web_renderjs_ui_test/TestTemplateItem/portal_components/test.erp5.testRJSUpgrader.py
index c8c255fc49a3d59abe2119e4e6bfbf1b29341cc5..7be1867a7674b493c5e83e3fc5f372a2c4315945 100644
--- a/bt5/erp5_web_renderjs_ui_test/TestTemplateItem/portal_components/test.erp5.testRJSUpgrader.py
+++ b/bt5/erp5_web_renderjs_ui_test/TestTemplateItem/portal_components/test.erp5.testRJSUpgrader.py
@@ -25,7 +25,7 @@
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #
 ##############################################################################
-import StringIO
+from six.moves import cStringIO as StringIO
 import textwrap
 import time
 
@@ -332,7 +332,7 @@ class TestRenderUpdateTranslationData(RenderJSUpgradeTestCase):
   def test_WebSite_getTranslationDataTextContent_extract_from_file(self):
     self.portal.portal_skins.custom.manage_addProduct['OFS'].manage_addFile(
         'test_portal_skins_gadget.html',
-        file=StringIO.StringIO(textwrap.dedent('''
+        file=StringIO(textwrap.dedent('''
           <html>
           <!--
            data-i18n=Message from file
diff --git a/erp5/util/benchmark/result.py b/erp5/util/benchmark/result.py
index 30cd0bc410596b5dc067acf5f807e82631e07082..f51be7244dfd5133ec78bbcacfc4057c25ffc2dd 100644
--- a/erp5/util/benchmark/result.py
+++ b/erp5/util/benchmark/result.py
@@ -332,7 +332,7 @@ class CSVBenchmarkResult(BenchmarkResult):
       self.logger.error(logged_msg)
       raise RuntimeError(msg)
 
-from cStringIO import StringIO
+from six.moves import cStringIO as StringIO
 
 from six.moves import xmlrpc_client as xmlrpclib
 import datetime
diff --git a/product/ERP5OOo/tests/testIngestion.py b/product/ERP5OOo/tests/testIngestion.py
index 2cb16f010142b96d3ab84256e78fe09e6ffbd446..ba3152a4971a9e87937c7282d9ed7cc3d8360595 100644
--- a/product/ERP5OOo/tests/testIngestion.py
+++ b/product/ERP5OOo/tests/testIngestion.py
@@ -31,7 +31,7 @@
 
 import unittest
 import os
-import StringIO
+from six.moves import cStringIO as StringIO
 from cgi import FieldStorage
 from lxml import etree
 from AccessControl.SecurityManagement import newSecurityManager
@@ -2108,7 +2108,7 @@ class Base_contributeMixin:
     """
     person = self.portal.person_module.newContent(portal_type='Person')
     empty_file_upload = ZPublisher.HTTPRequest.FileUpload(FieldStorage(
-                            fp=StringIO.StringIO(),
+                            fp=StringIO(),
                             environ=dict(REQUEST_METHOD='PUT'),
                             headers={"content-disposition":
                               "attachment; filename=empty;"}))
diff --git a/product/ERP5Type/Pandas.py b/product/ERP5Type/Pandas.py
index edb685b80e92a46a007ff3ebce26c08281f5b10a..fce23faa7cbbca7b3f911e7d83e45966dd46ec57 100644
--- a/product/ERP5Type/Pandas.py
+++ b/product/ERP5Type/Pandas.py
@@ -37,10 +37,7 @@ from pandas import *
 import six as _six
 from AccessControl.ZopeGuards import Unauthorized as _ZopeGuardsUnauthorized
 
-if _six.PY2:
-  from StringIO import StringIO as _StringIO
-else:
-  from io import StringIO as _StringIO
+from six.moves import cStringIO as _StringIO
 
 
 def _addRestrictedPandasReadFunction(function_name):
diff --git a/product/ERP5Type/patches/urllib_opener.py b/product/ERP5Type/patches/urllib_opener.py
index 24ebc02afc42601d5bc53318b51e1c546ff11d71..298601c6fa42959bdb00805e5797863d70164642 100644
--- a/product/ERP5Type/patches/urllib_opener.py
+++ b/product/ERP5Type/patches/urllib_opener.py
@@ -29,9 +29,8 @@
 
 # Install openers
 # -> testTemplateTool.TestTemplateTool.test_getBusinessTemplateUrl
-import urllib
-import urllib2
-import cStringIO
+import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error
+from six.moves import cStringIO as StringIO
 import socket
 import os
 import dircache
@@ -61,7 +60,7 @@ class DirectoryFileHandler(urllib2.FileHandler):
         size = stats.st_size
         modified = formatdate(stats.st_mtime, usegmt=True)
         mtype = mimetypes.guess_type(file)[0]
-        headers = mimetools.Message(cStringIO.StringIO(
+        headers = mimetools.Message(StringIO(
             'Content-type: %s\nContent-length: %d\nLast-modified: %s\n' %
             (mtype or 'text/plain', size, modified)))
         if host:
@@ -70,14 +69,14 @@ class DirectoryFileHandler(urllib2.FileHandler):
            (not port and socket.gethostbyname(host) in self.get_names()):
             try:
               file_list = dircache.listdir(localfile)
-              s = cStringIO.StringIO()
+              s = StringIO()
               s.write('<html><head><base href="%s"/></head><body>' % ('file:' + file))
               s.write('<p>Directory Content:</p>')
               for f in file_list:
                 s.write('<p><a href="%s">%s</a></p>\n' % (urllib.quote(f), f))
               s.write('</body></html>')
               s.seek(0)
-              headers = mimetools.Message(cStringIO.StringIO(
+              headers = mimetools.Message(StringIO(
                   'Content-type: %s\nContent-length: %d\nLast-modified: %s\n' %
                   ('text/html', size, modified)))
               return urllib2.addinfourl(s, headers, 'file:' + file)
diff --git a/product/ERP5Type/tests/ERP5TypeLiveTestCase.py b/product/ERP5Type/tests/ERP5TypeLiveTestCase.py
index 5727bdd113d8e24f02d629458fee086193a9250f..ab05ab2ff0efdb0109bb3a5977b89f7b1f641300 100644
--- a/product/ERP5Type/tests/ERP5TypeLiveTestCase.py
+++ b/product/ERP5Type/tests/ERP5TypeLiveTestCase.py
@@ -253,7 +253,7 @@ class ERP5TypeTestReLoader(ERP5TypeTestLoader):
 
 def runLiveTest(test_list, verbosity=1, stream=None, request_server_url=None, **kw):
   from Products.ERP5Type.tests.runUnitTest import DebugTestResult
-  from StringIO import StringIO
+  from six.moves import cStringIO as StringIO
   # Add path of the TestTemplateItem folder of the instance
   path = kw.get('path', None)
   if path is not None and path not in sys.path:
diff --git a/product/ERP5Type/tests/testUpgradeInstanceWithOldDataFs.py b/product/ERP5Type/tests/testUpgradeInstanceWithOldDataFs.py
index 411580c9e44b1956ff9742f365fa586663d1e37b..341b6dc7bd8d184f371f9f29516a1fa666b40a74 100644
--- a/product/ERP5Type/tests/testUpgradeInstanceWithOldDataFs.py
+++ b/product/ERP5Type/tests/testUpgradeInstanceWithOldDataFs.py
@@ -27,7 +27,7 @@
 ##############################################################################
 from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
 from Products.ERP5Type import WITH_LEGACY_WORKFLOW
-import StringIO
+from six.moves import cStringIO as StringIO
 import unittest
 import urllib
 import httplib
@@ -120,7 +120,7 @@ class TestUpgradeInstanceWithOldDataFs(ERP5TypeTestCase):
     ret = self.publish(
       '%s/portal_alarms/promise_check_upgrade' % self.portal.getPath(),
       basic='%s:current' % self.id(),
-      stdin=StringIO.StringIO(urllib.urlencode({
+      stdin=StringIO(urllib.urlencode({
         'Base_callDialogMethod:method': '',
         'dialog_id': 'Alarm_viewSolveDialog',
         'dialog_method': 'Alarm_solve',