Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Work in Progress: python 3 compatability #5

Merged
merged 4 commits into from
Mar 9, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
language: python
python:
- "2.7"
- "3.3"
- "3.4"
install:
- pip install -e . --use-mirrors
- pip install coveralls --use-mirrors
Expand Down
48 changes: 25 additions & 23 deletions ipydb/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@
:copyright: (c) 2012 by Jay Sweeney.
:license: see LICENSE for more details.
"""
from __future__ import print_function

import logging
import os

__title__ = 'ipydb'
__version__ = '0.0.2'
__author__ = 'Jay Sweeney'
__license__ = 'Apache 2.0'
__copyright__ = 'Copyright 2012 Jay Sweeney'

import logging
import os

PLUGIN_NAME = 'ipydb'
_loaded = False
_backup_prompt1 = ''
Expand All @@ -29,7 +31,7 @@

def load_ipython_extension(ip):
"""Load the ipydb into the active ipython session"""
from plugin import SqlPlugin
from .plugin import SqlPlugin
global _loaded
if not _loaded:
plugin = SqlPlugin(shell=ip, config=ip.config)
Expand Down Expand Up @@ -60,34 +62,34 @@ def configure_prompt(ipydb):


def ipydb_help():
msg = "Welcome to ipydb %s!" % __version__
print msg
print
msg2 = 'ipydb has added the following `magic` ' \
msg = u"Welcome to ipydb %s!" % __version__
print(msg)
print()
msg2 = u'ipydb has added the following `magic` ' \
'commands to your ipython session:'
print msg2
print(msg2)
helps = get_brief_help()
maxname = max(map(len, (r[0] for r in helps)))
print '-' * (maxname + 5)
print('-' * (maxname + 5))
for magic, doc in helps:
print (" %%%-" + str(maxname) + "s %s") % (magic, doc)
print '-' * (maxname + 5)
print
print "You can get detailed usage information " \
"for any of the above commands "
print "by typing %magic_command_name? For example, " \
"to get help on %connect, type"
print
print " %connect?"
print
print "Get started by connecting to a database " \
"using %connect_url or %connect"
print((u" %%%-" + str(maxname) + "s %s") % (magic, doc))
print('-' * (maxname + 5))
print()
print("You can get detailed usage information "
"for any of the above commands ")
print("by typing %magic_command_name? For example, "
"to get help on %connect, type")
print()
print(" %connect?")
print()
print("Get started by connecting to a database "
"using %connect_url or %connect")


def get_brief_help():
"""return a list of (magic_name, first_line_of_docstring)
for all the magic methods ipydb defines"""
from magic import SqlMagics
from .magic import SqlMagics
docs = []
magics = {}
magic_thing = SqlMagics.magics
Expand Down
28 changes: 14 additions & 14 deletions ipydb/asciitable.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# -*- coding: utf-8 -*-
from future.standard_library import install_aliases
install_aliases()

"""Draw ascii tables."""
import itertools
import sys

from utils import termsize
from past.builtins import basestring

from .utils import termsize


class FakedResult(object):
Expand Down Expand Up @@ -39,7 +43,7 @@ def keys(self):


def isublists(l, n):
return itertools.izip_longest(*[iter(l)] * n)
return itertools.zip_longest(*[iter(l)] * n)


def draw(cursor, out=sys.stdout, paginate=True, max_fieldsize=100):
Expand All @@ -58,15 +62,15 @@ def draw(cursor, out=sys.stdout, paginate=True, max_fieldsize=100):

def heading_line(sizes):
for size in sizes:
out.write('+' + '-' * (size + 2))
out.write('+\n')
out.write(u'+' + '-' * (size + 2))
out.write(u'+\n')

def draw_headings(headings, sizes):
heading_line(sizes)
for idx, size in enumerate(sizes):
fmt = '| %%-%is ' % size
fmt = u'| %%-%is ' % size
out.write((fmt % headings[idx]))
out.write('|\n')
out.write(u'|\n')
heading_line(sizes)

cols, lines = termsize()
Expand All @@ -76,7 +80,7 @@ def draw_headings(headings, sizes):
cursor = isublists(cursor, lines - 4)
# else we assume cursor arrive here pre-paginated
for screenrows in cursor:
sizes = heading_sizes[:]
sizes = list(heading_sizes)
for row in screenrows:
if row is None:
break
Expand All @@ -90,7 +94,7 @@ def draw_headings(headings, sizes):
if rw is None:
break # from isublists impl
for idx, size in enumerate(sizes):
fmt = '| %%-%is ' % size
fmt = u'| %%-%is ' % size
value = rw[idx]
if not isinstance(value, basestring):
value = str(value)
Expand All @@ -99,12 +103,8 @@ def draw_headings(headings, sizes):
value = value.replace('\n', '^')
value = value.replace('\r', '^').replace('\t', ' ')
value = fmt % value
try:
value = value.encode('utf-8', 'replace')
except UnicodeDecodeError:
value = fmt % '?'
out.write(value)
out.write('|\n')
out.write(u'|\n')
if not paginate:
heading_line(sizes)
out.write('\n')
out.write(u'\n')
13 changes: 7 additions & 6 deletions ipydb/completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
This module provides functionality for readline-style
tab-completion of SQL statements and other ipydb commands.
"""
from __future__ import print_function
import itertools
import logging
import re
Expand Down Expand Up @@ -38,14 +39,14 @@ def ipydb_complete(self, event):
try:
if sqlplugin:
if sqlplugin.debug:
print 'complete: sym=[%s] line=[%s] tuc=[%s]' % (
event.symbol, event.line, event.text_until_cursor)
print('complete: sym=[%s] line=[%s] tuc=[%s]' % (
event.symbol, event.line, event.text_until_cursor))
completions = sqlplugin.completer.complete(event)
if sqlplugin.debug:
print 'completions:', completions
print('completions:', completions)
return completions
except Exception, e:
print repr(e)
except Exception as e:
print(repr(e))
if sqlplugin and sqlplugin.debug:
import traceback
traceback.print_exc()
Expand Down Expand Up @@ -215,7 +216,7 @@ def expand_join_expression(self, expr):
for tbl in reversed(tables):
joins = self.db.get_joins(tbl, tail)
if joins:
join = iter(joins).next() # XXX: take a punt
join = next(iter(joins)) # XXX: take a punt
joinstr = 'inner join %s on ' % (tail)
sep = ''
for idx, col in enumerate(join.columns):
Expand Down
9 changes: 6 additions & 3 deletions ipydb/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

"""Functions to help create an SQLalchemy connection based upon
a 'connection configuration file'"""
import urlparse
from ConfigParser import ConfigParser, DuplicateSectionError
from future.standard_library import install_aliases
install_aliases()

from urllib import parse
from configparser import ConfigParser, DuplicateSectionError

import sqlalchemy as sa

Expand Down Expand Up @@ -101,7 +104,7 @@ def make_connection_url(config):
password=config.get('password'), host=config.get('host'),
port=config.get('port') or None,
database=config.get('database'),
query=dict(urlparse.parse_qsl(config.get('query', ''))))
query=dict(parse.parse_qsl(config.get('query', ''))))


def save_connection(name, engine, overwrite=False):
Expand Down
31 changes: 16 additions & 15 deletions ipydb/magic.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
:copyright: (c) 2012 by Jay Sweeney.
:license: see LICENSE for more details.
"""
from __future__ import print_function
import logging

from IPython.core.magic import Magics, magics_class, \
Expand Down Expand Up @@ -78,8 +79,8 @@ def set_reflection(self, arg):
self.ipydb.do_reflection = False
else:
self.ipydb.do_reflection = True
print 'Schema reflection: %s' % (
'on' if self.ipydb.do_reflection else 'off')
print('Schema reflection: %s' % (
'on' if self.ipydb.do_reflection else 'off'))

@line_magic
def engine(self, arg):
Expand All @@ -97,7 +98,7 @@ def debug(self, arg):
self.ipydb.debug = True
root_logger = logging.getLogger()
root_logger.setLevel(logging.DEBUG)
print "ipydb debugging is", 'on' if self.ipydb.debug else 'off'
print("ipydb debugging is", 'on' if self.ipydb.debug else 'off')

@line_magic
def begin(self, arg):
Expand Down Expand Up @@ -178,7 +179,7 @@ def sql(self, args='', cell=None):
if args.ret:
return sqlstr
else:
print "\n%s" % sqlstr
print("\n%s" % sqlstr)
return
if args.params:
params = self.shell.user_ns.get(args.params, {})
Expand All @@ -198,7 +199,7 @@ def sql(self, args='', cell=None):
elif result and not result.returns_rows:
# XXX: do all drivers support this?
s = 's' if result.rowcount != 1 else ''
print "%i row%s affected" % (result.rowcount, s)
print("%i row%s affected" % (result.rowcount, s))
sql.__description__ = 'Run an sql statement against ' \
'the current ipydb connection.'

Expand Down Expand Up @@ -272,7 +273,7 @@ def showsql(self, param=''):
level = logging.INFO
self.ipydb.show_sql = True
logging.getLogger('sqlalchemy.engine').setLevel(level)
print 'SQL logging %s' % ('on' if self.ipydb.show_sql else 'off')
print('SQL logging %s' % ('on' if self.ipydb.show_sql else 'off'))

@line_magic
def references(self, param=""):
Expand All @@ -288,7 +289,7 @@ def references(self, param=""):
: shows all fields having a foreign key referencing person.id
"""
if not param.strip() or len(param.split()) != 1:
print "Usage: %references TABLE_NAME[.FIELD_NAME]"
print("Usage: %references TABLE_NAME[.FIELD_NAME]")
return
self.ipydb.what_references(param)

Expand All @@ -304,7 +305,7 @@ def joins(self, param=""):
Usage: %joins TABLE_NAME
"""
if not param.strip() or len(param.split()) != 1:
print "Usage: %show_joins TABLE_NAME"
print("Usage: %show_joins TABLE_NAME")
return
self.ipydb.show_joins(param)

Expand All @@ -315,7 +316,7 @@ def fks(self, param=""):
Usage: %fks TABLE_NAME
"""
if not param.strip() or len(param.split()) != 1:
print "Usage: %show_fks TABLE_NAME"
print("Usage: %show_fks TABLE_NAME")
return
self.ipydb.show_fks(param)

Expand All @@ -324,10 +325,10 @@ def sqlformat(self, param=None):
"""Change the output format."""
from ipydb.plugin import SQLFORMATS
if not param or param not in SQLFORMATS:
print self.sqlformat.__doc__
print(self.sqlformat.__doc__)
else:
self.ipydb.sqlformat = param
print "output format: %s" % self.ipydb.sqlformat
print("output format: %s" % self.ipydb.sqlformat)

@line_magic
def connect(self, param):
Expand Down Expand Up @@ -393,7 +394,7 @@ def flushmetadata(self, arg):
def rereflect(self, arg):
"""Force re-loading of completion metadata."""
if not self.ipydb.connected:
print self.ipydb.not_connected_message
print(self.ipydb.not_connected_message)
return
self.ipydb.metadata_accessor.get_metadata(
self.ipydb.engine, force=True, noisy=True)
Expand All @@ -411,10 +412,10 @@ def saveconnection(self, arg):
with the current engine's connection parameters.
"""
if not self.ipydb.connected:
print self.ipydb.not_connected_message
print(self.ipydb.not_connected_message)
return
if not len(arg.strip()):
print "Usage: %saveconnection NICKNAME. \n\n" + \
"Please supply a NICKNAME to store the connection against."
print("Usage: %saveconnection NICKNAME. \n\n"
"Please supply a NICKNAME to store the connection against.")
return
self.ipydb.save_connection(arg)
9 changes: 5 additions & 4 deletions ipydb/metadata/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
:copyright: (c) 2012 by Jay Sweeney.
:license: see LICENSE for more details.
"""
from __future__ import print_function

import base64
from collections import defaultdict
Expand Down Expand Up @@ -49,7 +50,7 @@ def get_metadata_engine(other_engine):
if not os.path.exists(path):
os.makedirs(path)
dbfilename = get_db_filename(other_engine)
dburl = 'sqlite:////%s' % os.path.join(path, dbfilename)
dburl = u'sqlite:////%s' % os.path.join(path, dbfilename)
return dbfilename, sa.create_engine(dburl)


Expand All @@ -60,7 +61,7 @@ def get_db_filename(engine):
url = engine.url
url = str(URL(url.drivername, url.username, host=url.host,
port=url.port, database=url.database))
return base64.urlsafe_b64encode(url)
return str(base64.urlsafe_b64encode(url.encode('utf-8')))


@contextmanager
Expand Down Expand Up @@ -126,7 +127,7 @@ def get_metadata(self, engine, noisy=False, force=False):
db = self.read_expunge(ipydb_engine)
self.databases[db_key] = db
if noisy:
print "ipydb is fetching database metadata"
print("ipydb is fetching database metadata")
self.spawn_reflection_thread(db_key, db, engine.url)
return db
if db.age > MAX_CACHE_AGE:
Expand All @@ -140,7 +141,7 @@ def get_metadata(self, engine, noisy=False, force=False):
# Spawn a thread to do the slow sqlalchemy reflection,
# return whatever we have
if noisy:
print "ipydb is fetching database metadata"
print("ipydb is fetching database metadata")
self.spawn_reflection_thread(db_key, db, engine.url)
return db

Expand Down
Loading