Pull requests

#9 Merged
Repository
taric-dev taric-dev
Branch
fix_python2_sql_output
Repository
zzzeek zzzeek
Branch
fix_python2_sql_output

Fixes stdout --sql output in python2

Author
  1. taric-dev
Reviewers
Description

We have just noticed a python2 bug when using the --sql option.

$ alembic upgrade head --sql > test.sql

Traceback (most recent call last):
  File "/home/user/.virtualenvs/alembic2/bin/alembic", line 9, in <module>
    load_entry_point('alembic==0.5.0', 'console_scripts', 'alembic')()
  File "/home/user/projects/alembic/alembic/config.py", line 269, in main
    CommandLine(prog=prog).main(argv=argv)
  File "/home/user/projects/alembic/alembic/config.py", line 264, in main
    self.run_cmd(cfg, options)
  File "/home/user/projects/alembic/alembic/config.py", line 251, in run_cmd
    **dict((k, getattr(options, k)) for k in kwarg)
  File "/home/user/projects/alembic/alembic/command.py", line 124, in upgrade
    script.run_env()
  File "/home/user/projects/alembic/alembic/script.py", line 194, in run_env
    util.load_python_file(self.dir, 'env.py')
  File "/home/user/projects/alembic/alembic/util.py", line 188, in load_python_file
    module = imp.load_source(module_id, path, open(path, 'rb'))
  File "alembic/env.py", line 74, in <module>
    run_migrations_offline()
  File "alembic/env.py", line 46, in run_migrations_offline
    context.configure(url=url, output_encoding='utf-8')
  File "<string>", line 7, in configure
  File "/home/user/projects/alembic/alembic/environment.py", line 514, in configure
    opts=opts
  File "/home/user/projects/alembic/alembic/migration.py", line 144, in configure
    return MigrationContext(dialect, connection, opts)
  File "/home/user/projects/alembic/alembic/migration.py", line 78, in __init__
    opts['output_encoding']
AttributeError: readable

The problem seems to be that using output_encoding in python2 is broken due to the use of io.TextIOWrapper, which does not like to get a file object, which is exactly what python2 sys.stdout is. This problem is not displayed in python3 due to the fact of sys.stdout being a io.TextIOWrapper instance.

This behaviour starts at revision ff285f7 which introduces the buffer wrapping for the output_encoding parameter.

The proposed solution is to manually create a writable io.FileIO instance from the stdout file descriptor. This works for both python2 and python3.

  • Learn about pull requests

Comments (2)

  1. Mike Bayer repo owner

    OK this is merged but I had to modify the approach considerably, as nose uses StringIO which has more difficult wrapping needs than sys.stdout. Also the FileIO wrapper was closing the stream as it needed closefd=False, but the new approach just replaces all that anyway. thanks for the help!