the use of the new io.* package introduced some incompatibilities on Py2k.
These should be resolved, due to the introduction of new adapter types
for translating from io.* to Py2k file types, StringIO types.
Thanks to Javier Santacruz for help with this.
return meta("%sBase" % meta.__name__, (base,), {})
################################################
+
+# produce a wrapper that allows encoded text to stream
+# into a given buffer, but doesn't close it.
+# not sure of a more idiomatic approach to this.
+class EncodedIO(io.TextIOWrapper):
+ def close(self):
+ pass
+
if py2k:
- def writable_buffer(file):
- return io.FileIO(file.fileno(), 'w')
-else:
- def writable_buffer(file):
- return file
+ # in Py2K, the io.* package is awkward because it does not
+ # easily wrap the file type (e.g. sys.stdout) and I can't
+ # figure out at all how to wrap StringIO.StringIO (used by nosetests)
+ # and also might be user specified too. So create a full
+ # adapter.
+
+ class ActLikePy3kIO(object):
+ """Produce an object capable of wrapping either
+ sys.stdout (e.g. file) *or* StringIO.StringIO().
+
+ """
+ def _false(self):
+ return False
+
+ def _true(self):
+ return True
+
+ readable = seekable = _false
+ writable = _true
+ closed = False
+
+ def __init__(self, file_):
+ self.file_ = file_
+
+ def write(self, text):
+ return self.file_.write(text)
+
+ def flush(self):
+ return self.file_.flush()
+
+ class EncodedIO(EncodedIO):
+ def __init__(self, file_, encoding):
+ super(EncodedIO, self).__init__(
+ ActLikePy3kIO(file_), encoding=encoding)
+
+
from sqlalchemy import create_engine
from sqlalchemy.engine import url as sqla_url
-from .compat import callable, writable_buffer
+from .compat import callable, EncodedIO
from . import ddl, util
log = logging.getLogger(__name__)
self._migrations_fn = opts.get('fn')
self.as_sql = as_sql
- self.output_buffer = opts.get("output_buffer", sys.stdout)
-
if "output_encoding" in opts:
- self.output_buffer = io.TextIOWrapper(
- opts.get("output_buffer") or writable_buffer(sys.stdout),
- opts.get('output_encoding')
+ self.output_buffer = EncodedIO(
+ opts.get("output_buffer") or sys.stdout,
+ opts['output_encoding']
)
+ else:
+ self.output_buffer = opts.get("output_buffer", sys.stdout)
self._user_compare_type = opts.get('compare_type', False)
self._user_compare_server_default = opts.get(
:version: 0.6.1
:released: no release date
+ .. change::
+ :tags: bug
+ :pullreq: 9
+
+ Fixes to Py3k in-place compatibity regarding output encoding and related;
+ the use of the new io.* package introduced some incompatibilities on Py2k.
+ These should be resolved, due to the introduction of new adapter types
+ for translating from io.* to Py2k file types, StringIO types.
+ Thanks to Javier Santacruz for help with this.
+
.. change::
:tags: bug
:tickets: 145
def setUp(self):
env = staging_env()
self.cfg = _no_sql_testing_config()
- self.cfg.output_buffer = io.StringIO()
global a, b, c
a, b, c = three_rev_fixture(self.cfg)
command.upgrade(self.cfg, a, sql=True)
command.downgrade(self.cfg, "%s:%s" % (b, a), sql=True)
command.current(self.cfg)
- # current seems to close the buffer (?)
- self.cfg.output_buffer = io.StringIO()
command.stamp(self.cfg, a)
def test_starting_rev_pre_context(self):