From a34d514d66267b90a9f75fd820bd41bad0ee82f1 Mon Sep 17 00:00:00 2001 From: Scott Sanderson Date: Sat, 25 Oct 2014 17:46:25 -0400 Subject: [PATCH] BUG: Fix str/unicode warnings from SQLAlchemy on python 2. When running with `reset_db=True` on python 2, several SQLAlchemy operations were performed with bytes where unicode was expected, resulting in warnings like the following. ``` /home/ssanderson/.virtualenvs/jupyterhub/local/lib/python2.7/site-packages/sqlalchemy/engine/default.py:573: SAWarning: Unicode type received non-unicodebind param value. param.append(processors[key](compiled_params[key])) ``` Fixes a few stray non-unicode literals and adds a unicode safe wrapper for `getpass.getuser`. --- jupyterhub/app.py | 15 +++++++-------- jupyterhub/tests/conftest.py | 4 ++-- jupyterhub/utils.py | 11 +++++++++++ 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/jupyterhub/app.py b/jupyterhub/app.py index 4b14c3bd..0ce8cfca 100644 --- a/jupyterhub/app.py +++ b/jupyterhub/app.py @@ -4,7 +4,6 @@ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. -import getpass import io import logging import os @@ -41,7 +40,7 @@ from . import orm from ._data import DATA_FILES_PATH from .utils import ( url_path_join, random_hex, TimeoutError, - ISO8601_ms, ISO8601_s, + ISO8601_ms, ISO8601_s, getuser_unicode, ) # classes for config from .auth import Authenticator, PAMAuthenticator @@ -353,7 +352,7 @@ class JupyterHubApp(Application): """More informative log messages for failed filesystem access""" path = os.path.abspath(path) parent, fname = os.path.split(path) - user = getpass.getuser() + user = getuser_unicode() if not os.path.isdir(parent): self.log.error("Directory %s does not exist", parent) if os.path.exists(parent) and not os.access(parent, os.W_OK): @@ -385,7 +384,7 @@ class JupyterHubApp(Application): port=self.hub_port, base_url=self.hub_prefix, cookie_secret=self.cookie_secret, - cookie_name='jupyter-hub-token', + cookie_name=u'jupyter-hub-token', ) ) self.db.add(self.hub) @@ -400,13 +399,13 @@ class JupyterHubApp(Application): def init_users(self): """Load users into and from the database""" db = self.db - + if not self.admin_users: # add current user as admin if there aren't any others admins = db.query(orm.User).filter(orm.User.admin==True) if admins.first() is None: - self.admin_users.add(getpass.getuser()) - + self.admin_users.add(getuser_unicode()) + for name in self.admin_users: # ensure anyone specified as admin in config is admin in db user = orm.User.find(db, name) @@ -511,7 +510,7 @@ class JupyterHubApp(Application): self.proxy.public_server.port = self.port self.proxy.api_server.ip = self.proxy_api_ip self.proxy.api_server.port = self.proxy_api_port - self.proxy.api_server.base_url = '/api/routes/' + self.proxy.api_server.base_url = u'/api/routes/' if self.proxy.auth_token is None: self.proxy.auth_token = self.proxy_auth_token self.db.commit() diff --git a/jupyterhub/tests/conftest.py b/jupyterhub/tests/conftest.py index d8a4a5a5..fe569048 100644 --- a/jupyterhub/tests/conftest.py +++ b/jupyterhub/tests/conftest.py @@ -3,13 +3,13 @@ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. -import getpass import logging from pytest import fixture from tornado import ioloop from .. import orm +from ..utils import getuser_unicode from .mocking import MockHubApp @@ -24,7 +24,7 @@ def db(): if _db is None: _db = orm.new_session('sqlite:///:memory:', echo=True) user = orm.User( - name=getpass.getuser(), + name=getuser_unicode(), server=orm.Server(), ) hub = orm.Hub( diff --git a/jupyterhub/utils.py b/jupyterhub/utils.py index 7c7a7065..8c52aade 100644 --- a/jupyterhub/utils.py +++ b/jupyterhub/utils.py @@ -4,9 +4,12 @@ # Distributed under the terms of the Modified BSD License. import binascii +import getpass import errno import os import socket + +from six import text_type from tornado import web, gen, ioloop from tornado.httpclient import AsyncHTTPClient, HTTPError from tornado.log import app_log @@ -21,6 +24,14 @@ except NameError: class TimeoutError(Exception): pass + +def getuser_unicode(): + """ + Call getpass.getuser, ensuring that the output is returned as unicode. + """ + return text_type(getpass.getuser()) + + def random_port(): """get a single random port""" sock = socket.socket()