From 367e92d47170d6e3d0373959fc7cea05d27185bd Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Mon, 18 Jun 2018 00:50:47 +0000 Subject: [PATCH 44/54] Python 3 preparation: StringIO. --- frontends/roundup.cgi | 5 +++-- roundup/anypy/strings.py | 6 ++++++ roundup/cgi/PageTemplates/PageTemplate.py | 1 - roundup/cgi/TAL/TALInterpreter.py | 16 ++-------------- roundup/cgi/engine_chameleon.py | 2 +- roundup/cgi/engine_zopetal.py | 2 +- roundup/cgi/templating.py | 8 ++------ roundup/mailer.py | 2 -- roundup/mailgw.py | 19 ++++++++++--------- roundup/roundupdb.py | 2 +- roundup/scripts/roundup_mailgw.py | 2 +- roundup/scripts/roundup_server.py | 8 ++++---- scripts/roundup-reminder | 5 +++-- test/test_cgi.py | 11 ++++++----- test/test_mailgw.py | 2 +- test/test_mailsplit.py | 2 +- test/test_multipart.py | 2 +- 17 files changed, 43 insertions(+), 52 deletions(-) diff --git a/frontends/roundup.cgi b/frontends/roundup.cgi index 7054ba0..2c72756 100755 --- a/frontends/roundup.cgi +++ b/frontends/roundup.cgi @@ -71,12 +71,13 @@ LOG = DevNull() # Set up the error handler # try: - import traceback, StringIO, cgi + import traceback, cgi + from roundup.anypy.strings import StringIO from roundup.cgi import cgitb except: print("Content-Type: text/plain\n") print(_("Failed to import cgitb!\n\n")) - s = StringIO.StringIO() + s = StringIO() traceback.print_exc(None, s) print(s.getvalue()) diff --git a/roundup/anypy/strings.py b/roundup/anypy/strings.py index e3b0dd3..2b90fb4 100644 --- a/roundup/anypy/strings.py +++ b/roundup/anypy/strings.py @@ -7,6 +7,12 @@ import sys _py3 = sys.version_info[0] > 2 +import io +if _py3: + StringIO = io.StringIO +else: + StringIO = io.BytesIO + def b2s(b): """Convert a UTF-8 encoded bytes object to the internal string format.""" if _py3: diff --git a/roundup/cgi/PageTemplates/PageTemplate.py b/roundup/cgi/PageTemplates/PageTemplate.py index 285fe6e..44e9a32 100644 --- a/roundup/cgi/PageTemplates/PageTemplate.py +++ b/roundup/cgi/PageTemplates/PageTemplate.py @@ -25,7 +25,6 @@ import sys from roundup.cgi.TAL.TALParser import TALParser from roundup.cgi.TAL.HTMLTALParser import HTMLTALParser from roundup.cgi.TAL.TALGenerator import TALGenerator -# Do not use cStringIO here! It's not unicode aware. :( from roundup.cgi.TAL.TALInterpreter import TALInterpreter, FasterStringIO from .Expressions import getEngine diff --git a/roundup/cgi/TAL/TALInterpreter.py b/roundup/cgi/TAL/TALInterpreter.py index e8bd490..c7bf960 100644 --- a/roundup/cgi/TAL/TALInterpreter.py +++ b/roundup/cgi/TAL/TALInterpreter.py @@ -22,8 +22,7 @@ import getopt import re from types import ListType from cgi import escape -# Do not use cStringIO here! It's not unicode aware. :( -from StringIO import StringIO +from roundup.anypy.strings import StringIO #from DocumentTemplate.DT_Util import ustr ustr = str @@ -758,18 +757,7 @@ class FasterStringIO(StringIO): This let's us have a much faster write() method. """ - def close(self): - if not self.closed: - self.write = _write_ValueError - StringIO.close(self) - - def seek(self, pos, mode=0): - raise RuntimeError("FasterStringIO.seek() not allowed") - - def write(self, s): - #assert self.pos == self.len - self.buflist.append(s) - self.len = self.pos = self.pos + len(s) + pass def _write_ValueError(s): diff --git a/roundup/cgi/engine_chameleon.py b/roundup/cgi/engine_chameleon.py index db6b09c..4a9aeac 100644 --- a/roundup/cgi/engine_chameleon.py +++ b/roundup/cgi/engine_chameleon.py @@ -5,7 +5,7 @@ __docformat__ = 'restructuredtext' import os.path import chameleon -from roundup.cgi.templating import StringIO, context, TALLoaderBase +from roundup.cgi.templating import context, TALLoaderBase from roundup.anypy.strings import s2u class Loader(TALLoaderBase): diff --git a/roundup/cgi/engine_zopetal.py b/roundup/cgi/engine_zopetal.py index 949b3e7..5f093c0 100644 --- a/roundup/cgi/engine_zopetal.py +++ b/roundup/cgi/engine_zopetal.py @@ -86,7 +86,7 @@ class RoundupPageTemplate(PageTemplate.PageTemplate): c.update({'options': options}) # and go - output = StringIO.StringIO() + output = StringIO() TALInterpreter.TALInterpreter(self._v_program, self.macros, getEngine().getContext(c), output, tal=1, strictinsert=0)() return output.getvalue() diff --git a/roundup/cgi/templating.py b/roundup/cgi/templating.py index 79ebd4b..6fb6cbd 100644 --- a/roundup/cgi/templating.py +++ b/roundup/cgi/templating.py @@ -29,7 +29,7 @@ from roundup.anypy import urllib_ from roundup import hyperdb, date, support from roundup import i18n from roundup.i18n import _ -from roundup.anypy.strings import is_us, us2s, s2u, u2s +from roundup.anypy.strings import is_us, us2s, s2u, u2s, StringIO from .KeywordsExpr import render_keywords_expression_editor @@ -44,10 +44,6 @@ try: except ImportError: import pickle try: - import cStringIO as StringIO -except ImportError: - import StringIO -try: from StructuredText.StructuredText import HTML as StructuredText except ImportError: try: # older version @@ -647,7 +643,7 @@ class HTMLClass(HTMLInputMixin, HTMLPermissions): """ Return the items of this class as a chunk of CSV text. """ props = self.propnames() - s = StringIO.StringIO() + s = StringIO() writer = csv.writer(s) writer.writerow(props) check = self._client.db.security.hasPermission diff --git a/roundup/mailer.py b/roundup/mailer.py index 3e8953a..5462cc2 100644 --- a/roundup/mailer.py +++ b/roundup/mailer.py @@ -4,8 +4,6 @@ __docformat__ = 'restructuredtext' import time, quopri, os, socket, smtplib, re, sys, traceback, email, logging -from cStringIO import StringIO - from roundup import __version__ from roundup.date import get_timezone, Date diff --git a/roundup/mailgw.py b/roundup/mailgw.py index 0432b58..00e0048 100644 --- a/roundup/mailgw.py +++ b/roundup/mailgw.py @@ -95,7 +95,7 @@ explanatory message given in the exception. from __future__ import print_function __docformat__ = 'restructuredtext' -import string, re, os, mimetools, cStringIO, smtplib, socket, binascii, quopri +import string, re, os, mimetools, smtplib, socket, binascii, quopri import time, random, sys, logging import codecs import traceback @@ -108,6 +108,7 @@ from roundup import configuration, hyperdb, date, password, exceptions from roundup.mailer import Mailer, MessageSendError from roundup.i18n import _ from roundup.hyperdb import iter_roles +from roundup.anypy.strings import StringIO try: import pyme, pyme.core, pyme.constants, pyme.constants.sigsum @@ -223,7 +224,7 @@ class Message(mimetools.Message): ''' boundary = self.getparam('boundary') mid, end = '--'+boundary, '--'+boundary+'--' - s = cStringIO.StringIO() + s = StringIO() while 1: line = self.fp.readline() if not line: @@ -303,7 +304,7 @@ class Message(mimetools.Message): # the subject of the actual e-mail embedded here # we add a '.eml' extension like other email software does it self.fp.seek(0) - s = cStringIO.StringIO(self.getbody()) + s = StringIO(self.getbody()) name = Message(s).getheader('subject') if name: name = name + '.eml' @@ -329,7 +330,7 @@ class Message(mimetools.Message): data = binascii.a2b_base64(self.fp.read()) elif encoding == 'quoted-printable': # the quopri module wants to work with files - decoded = cStringIO.StringIO() + decoded = StringIO() quopri.decode(self.fp, decoded) data = decoded.getvalue() elif encoding == 'uuencoded': @@ -449,7 +450,7 @@ class Message(mimetools.Message): attachments = [] html_part = False elif unpack_rfc822 and content_type == 'message/rfc822': - s = cStringIO.StringIO(self.getbody()) + s = StringIO(self.getbody()) m = Message(s) ig = ignore_alternatives and not content new_content, attachments, html_part = m.extract_content(m.gettype(), ig, @@ -527,7 +528,7 @@ class Message(mimetools.Message): # pyme.core.Data implements a seek method with a different signature # than roundup can handle. So we'll put the data in a container that # the Message class can work with. - c = cStringIO.StringIO() + c = StringIO() c.write(plaintext.read()) c.seek(0) return Message(c) @@ -1328,7 +1329,7 @@ class MailGW: XXX: we may want to read this into a temporary file instead... """ - s = cStringIO.StringIO() + s = StringIO() s.write(sys.stdin.read()) s.seek(0) self.main(s) @@ -1424,7 +1425,7 @@ class MailGW: server.store(str(i), '+FLAGS', r'(\Deleted)') # process the message - s = cStringIO.StringIO(data[0][1]) + s = StringIO(data[0][1]) s.seek(0) self.handle_Message(Message(s)) server.close() @@ -1493,7 +1494,7 @@ class MailGW: # [ array of message lines ], # number of octets ] lines = server.retr(i)[1] - s = cStringIO.StringIO('\n'.join(lines)) + s = StringIO('\n'.join(lines)) s.seek(0) self.handle_Message(Message(s)) # delete the message diff --git a/roundup/roundupdb.py b/roundup/roundupdb.py index 70f44ec..868bfd7 100644 --- a/roundup/roundupdb.py +++ b/roundup/roundupdb.py @@ -21,7 +21,7 @@ __docformat__ = 'restructuredtext' import re, os, smtplib, socket, time, random -import cStringIO, base64, mimetypes +import base64, mimetypes import os.path import logging from email import Encoders diff --git a/roundup/scripts/roundup_mailgw.py b/roundup/scripts/roundup_mailgw.py index d3c16b7..9697990 100644 --- a/roundup/scripts/roundup_mailgw.py +++ b/roundup/scripts/roundup_mailgw.py @@ -37,7 +37,7 @@ if (osp.exists(thisdir + '/__init__.py') and from roundup import version_check from roundup import __version__ as roundup_version -import sys, os, re, cStringIO, getopt, socket, netrc +import sys, os, re, getopt, socket, netrc from roundup import mailgw from roundup.i18n import _ diff --git a/roundup/scripts/roundup_server.py b/roundup/scripts/roundup_server.py index 623a31a..a408d40 100644 --- a/roundup/scripts/roundup_server.py +++ b/roundup/scripts/roundup_server.py @@ -36,8 +36,7 @@ if (osp.exists(thisdir + '/__init__.py') and # --/ -import errno, cgi, getopt, os, socket, sys, traceback, time -import StringIO +import errno, cgi, getopt, io, os, socket, sys, traceback, time try: # Python 3. @@ -64,6 +63,7 @@ from roundup import __version__ as roundup_version # Roundup modules of use here from roundup.anypy import http_, urllib_ +from roundup.anypy.strings import StringIO from roundup.cgi import cgitb, client from roundup.cgi.PageTemplates.PageTemplate import PageTemplate import roundup.instance @@ -240,7 +240,7 @@ class RoundupRequestHandler(http_.server.BaseHTTPRequestHandler): self.wfile.write(cgitb.breaker()) self.wfile.write(cgitb.html()) except: - s = StringIO.StringIO() + s = StringIO() traceback.print_exc(None, s) self.wfile.write("
")
                         self.wfile.write(cgi.escape(s.getvalue()))
@@ -311,7 +311,7 @@ class RoundupRequestHandler(http_.server.BaseHTTPRequestHandler):
 
 
             if favicon_fileobj is None:
-                favicon_fileobj = StringIO.StringIO(favico)
+                favicon_fileobj = io.BytesIO(favico)
 
             self.send_response(200)
             self.send_header('Content-Type', 'image/x-icon')
diff --git a/scripts/roundup-reminder b/scripts/roundup-reminder
index cf35494..2acc778 100755
--- a/scripts/roundup-reminder
+++ b/scripts/roundup-reminder
@@ -28,9 +28,10 @@ TODO: possibly make this more general and configurable...
 '''
 
 from __future__ import print_function
-import sys, cStringIO, MimeWriter, smtplib
+import sys, MimeWriter, smtplib
 from roundup import instance, date
 from roundup.mailer import SMTPConnection
+from roundup.anypy.strings import StringIO
 
 # open the instance
 if len(sys.argv) != 2:
@@ -71,7 +72,7 @@ for user_id in db.user.list():
         continue
 
     # generate the email message
-    message = cStringIO.StringIO()
+    message = StringIO()
     writer = MimeWriter.MimeWriter(message)
     writer.addheader('Subject', 'Your active %s issues'%db.config.TRACKER_NAME)
     writer.addheader('To', address)
diff --git a/test/test_cgi.py b/test/test_cgi.py
index fa312dd..b0ae2c2 100644
--- a/test/test_cgi.py
+++ b/test/test_cgi.py
@@ -9,7 +9,7 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 from __future__ import print_function
-import unittest, os, shutil, errno, sys, difflib, cgi, re, StringIO
+import unittest, os, shutil, errno, sys, difflib, cgi, re
 
 from roundup.cgi import client, actions, exceptions
 from roundup.cgi.exceptions import FormError, NotFound
@@ -18,6 +18,7 @@ from roundup.cgi.templating import HTMLItem, HTMLRequest, NoTemplate
 from roundup.cgi.templating import HTMLProperty, _HTMLItem, anti_csrf_nonce
 from roundup.cgi.form_parser import FormParser
 from roundup import init, instance, password, hyperdb, date
+from roundup.anypy.strings import StringIO
 
 # For testing very simple rendering
 from roundup.cgi.engine_zopetal import RoundupPageTemplate
@@ -1458,7 +1459,7 @@ class FormTestCase(FormTestParent, unittest.TestCase):
         cl = self._make_client({'@columns': 'id,name'}, nodeid=None,
             userid='1')
         cl.classname = 'status'
-        output = StringIO.StringIO()
+        output = StringIO()
         cl.request = MockNull()
         cl.request.wfile = output
         actions.ExportCSVAction(cl).handle()
@@ -1471,7 +1472,7 @@ class FormTestCase(FormTestParent, unittest.TestCase):
         cl = self._make_client({'@columns': 'falseid,name'}, nodeid=None,
             userid='1')
         cl.classname = 'status'
-        output = StringIO.StringIO()
+        output = StringIO()
         cl.request = MockNull()
         cl.request.wfile = output
         self.assertRaises(exceptions.NotFound,
@@ -1481,7 +1482,7 @@ class FormTestCase(FormTestParent, unittest.TestCase):
         cl = self._make_client({'@columns': 'id,email,password'}, nodeid=None,
             userid='2')
         cl.classname = 'user'
-        output = StringIO.StringIO()
+        output = StringIO()
         cl.request = MockNull()
         cl.request.wfile = output
         # used to be self.assertRaises(exceptions.Unauthorised,
@@ -1496,7 +1497,7 @@ class FormTestCase(FormTestParent, unittest.TestCase):
         cl = self._make_client({'@columns': 'id,address,password'}, nodeid=None,
             userid='2')
         cl.classname = 'user'
-        output = StringIO.StringIO()
+        output = StringIO()
         cl.request = MockNull()
         cl.request.wfile = output
         # used to be self.assertRaises(exceptions.Unauthorised,
diff --git a/test/test_mailgw.py b/test/test_mailgw.py
index 5ffcfd3..99e70e0 100644
--- a/test/test_mailgw.py
+++ b/test/test_mailgw.py
@@ -28,7 +28,7 @@ except ImportError:
         reason="Skipping PGP tests: 'pyme' not installed"))
 
 
-from cStringIO import StringIO
+from roundup.anypy.strings import StringIO
 
 if 'SENDMAILDEBUG' not in os.environ:
     os.environ['SENDMAILDEBUG'] = 'mail-test.log'
diff --git a/test/test_mailsplit.py b/test/test_mailsplit.py
index dc18bf9..bd25a7f 100644
--- a/test/test_mailsplit.py
+++ b/test/test_mailsplit.py
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 
-import unittest, cStringIO
+import unittest
 
 from roundup.mailgw import parseContent
 
diff --git a/test/test_multipart.py b/test/test_multipart.py
index 09aa76c..232a95b 100644
--- a/test/test_multipart.py
+++ b/test/test_multipart.py
@@ -16,7 +16,7 @@
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 
 import unittest
-from cStringIO import StringIO
+from roundup.anypy.strings import StringIO
 
 from roundup.mailgw import Message
 
-- 
2.7.4