From be83a240fbec399d8f43a3b660b9c802dd024b23 Mon Sep 17 00:00:00 2001 From: Olivia Grubert Date: Thu, 3 Nov 2016 16:30:08 -0700 Subject: [PATCH] 2to3 python converstion with major version bump to 1.0.0-yr.alpha --- examples/blogserver/manage.py | 2 +- ez_setup.py | 552 ++++++++++---------- piston/authentication.py | 28 +- piston/decorator.py | 6 +- piston/doc.py | 6 +- piston/emitters.py | 37 +- piston/forms.py | 2 +- piston/handler.py | 11 +- piston/models.py | 22 +- piston/oauth.py | 34 +- piston/resource.py | 29 +- piston/signals.py | 2 +- piston/store.py | 6 +- piston/test.py | 2 +- piston/tests.py | 26 +- piston/utils.py | 14 +- piston/validate_jsonp.py | 20 +- setup.py | 4 +- tests/bootstrap.py | 6 +- tests/test_project/apps/testapp/handlers.py | 4 +- tests/test_project/apps/testapp/tests.py | 80 +-- 21 files changed, 446 insertions(+), 447 deletions(-) diff --git a/examples/blogserver/manage.py b/examples/blogserver/manage.py index 5e78ea9..8e08caf 100644 --- a/examples/blogserver/manage.py +++ b/examples/blogserver/manage.py @@ -1,7 +1,7 @@ #!/usr/bin/env python from django.core.management import execute_manager try: - import settings # Assumed to be in the same directory. + from . import settings # Assumed to be in the same directory. except ImportError: import sys sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) diff --git a/ez_setup.py b/ez_setup.py index d35213e..05eb693 100644 --- a/ez_setup.py +++ b/ez_setup.py @@ -1,276 +1,276 @@ -#!python -"""Bootstrap setuptools installation - -If you want to use setuptools in your package's setup.py, just include this -file in the same directory with it, and add this to the top of your setup.py:: - - from ez_setup import use_setuptools - use_setuptools() - -If you want to require a specific version of setuptools, set a download -mirror, or use an alternate download directory, you can do so by supplying -the appropriate options to ``use_setuptools()``. - -This file can also be run as a script to install or upgrade setuptools. -""" -import sys -DEFAULT_VERSION = "0.6c9" -DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3] - -md5_data = { - 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca', - 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb', - 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b', - 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a', - 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618', - 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac', - 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5', - 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4', - 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c', - 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b', - 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27', - 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277', - 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa', - 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e', - 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e', - 'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f', - 'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2', - 'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc', - 'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167', - 'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64', - 'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d', - 'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20', - 'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab', - 'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53', - 'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2', - 'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e', - 'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372', - 'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902', - 'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de', - 'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b', - 'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03', - 'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a', - 'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6', - 'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a', -} - -import sys, os -try: from hashlib import md5 -except ImportError: from md5 import md5 - -def _validate_md5(egg_name, data): - if egg_name in md5_data: - digest = md5(data).hexdigest() - if digest != md5_data[egg_name]: - print >>sys.stderr, ( - "md5 validation of %s failed! (Possible download problem?)" - % egg_name - ) - sys.exit(2) - return data - -def use_setuptools( - version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, - download_delay=15 -): - """Automatically find/download setuptools and make it available on sys.path - - `version` should be a valid setuptools version number that is available - as an egg for download under the `download_base` URL (which should end with - a '/'). `to_dir` is the directory where setuptools will be downloaded, if - it is not already available. If `download_delay` is specified, it should - be the number of seconds that will be paused before initiating a download, - should one be required. If an older version of setuptools is installed, - this routine will print a message to ``sys.stderr`` and raise SystemExit in - an attempt to abort the calling script. - """ - was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules - def do_download(): - egg = download_setuptools(version, download_base, to_dir, download_delay) - sys.path.insert(0, egg) - import setuptools; setuptools.bootstrap_install_from = egg - try: - import pkg_resources - except ImportError: - return do_download() - try: - pkg_resources.require("setuptools>="+version); return - except pkg_resources.VersionConflict, e: - if was_imported: - print >>sys.stderr, ( - "The required version of setuptools (>=%s) is not available, and\n" - "can't be installed while this script is running. Please install\n" - " a more recent version first, using 'easy_install -U setuptools'." - "\n\n(Currently using %r)" - ) % (version, e.args[0]) - sys.exit(2) - else: - del pkg_resources, sys.modules['pkg_resources'] # reload ok - return do_download() - except pkg_resources.DistributionNotFound: - return do_download() - -def download_setuptools( - version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, - delay = 15 -): - """Download setuptools from a specified location and return its filename - - `version` should be a valid setuptools version number that is available - as an egg for download under the `download_base` URL (which should end - with a '/'). `to_dir` is the directory where the egg will be downloaded. - `delay` is the number of seconds to pause before an actual download attempt. - """ - import urllib2, shutil - egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3]) - url = download_base + egg_name - saveto = os.path.join(to_dir, egg_name) - src = dst = None - if not os.path.exists(saveto): # Avoid repeated downloads - try: - from distutils import log - if delay: - log.warn(""" ---------------------------------------------------------------------------- -This script requires setuptools version %s to run (even to display -help). I will attempt to download it for you (from -%s), but -you may need to enable firewall access for this script first. -I will start the download in %d seconds. - -(Note: if this machine does not have network access, please obtain the file - - %s - -and place it in this directory before rerunning this script.) ----------------------------------------------------------------------------""", - version, download_base, delay, url - ); from time import sleep; sleep(delay) - log.warn("Downloading %s", url) - src = urllib2.urlopen(url) - # Read/write all in one block, so we don't create a corrupt file - # if the download is interrupted. - data = _validate_md5(egg_name, src.read()) - dst = open(saveto,"wb"); dst.write(data) - finally: - if src: src.close() - if dst: dst.close() - return os.path.realpath(saveto) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -def main(argv, version=DEFAULT_VERSION): - """Install or upgrade setuptools and EasyInstall""" - try: - import setuptools - except ImportError: - egg = None - try: - egg = download_setuptools(version, delay=0) - sys.path.insert(0,egg) - from setuptools.command.easy_install import main - return main(list(argv)+[egg]) # we're done here - finally: - if egg and os.path.exists(egg): - os.unlink(egg) - else: - if setuptools.__version__ == '0.0.1': - print >>sys.stderr, ( - "You have an obsolete version of setuptools installed. Please\n" - "remove it from your system entirely before rerunning this script." - ) - sys.exit(2) - - req = "setuptools>="+version - import pkg_resources - try: - pkg_resources.require(req) - except pkg_resources.VersionConflict: - try: - from setuptools.command.easy_install import main - except ImportError: - from easy_install import main - main(list(argv)+[download_setuptools(delay=0)]) - sys.exit(0) # try to force an exit - else: - if argv: - from setuptools.command.easy_install import main - main(argv) - else: - print "Setuptools version",version,"or greater has been installed." - print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)' - -def update_md5(filenames): - """Update our built-in md5 registry""" - - import re - - for name in filenames: - base = os.path.basename(name) - f = open(name,'rb') - md5_data[base] = md5(f.read()).hexdigest() - f.close() - - data = [" %r: %r,\n" % it for it in md5_data.items()] - data.sort() - repl = "".join(data) - - import inspect - srcfile = inspect.getsourcefile(sys.modules[__name__]) - f = open(srcfile, 'rb'); src = f.read(); f.close() - - match = re.search("\nmd5_data = {\n([^}]+)}", src) - if not match: - print >>sys.stderr, "Internal error!" - sys.exit(2) - - src = src[:match.start(1)] + repl + src[match.end(1):] - f = open(srcfile,'w') - f.write(src) - f.close() - - -if __name__=='__main__': - if len(sys.argv)>2 and sys.argv[1]=='--md5update': - update_md5(sys.argv[2:]) - else: - main(sys.argv[1:]) - - - - - - +#!python +"""Bootstrap setuptools installation + +If you want to use setuptools in your package's setup.py, just include this +file in the same directory with it, and add this to the top of your setup.py:: + + from ez_setup import use_setuptools + use_setuptools() + +If you want to require a specific version of setuptools, set a download +mirror, or use an alternate download directory, you can do so by supplying +the appropriate options to ``use_setuptools()``. + +This file can also be run as a script to install or upgrade setuptools. +""" +import sys +DEFAULT_VERSION = "0.6c9" +DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3] + +md5_data = { + 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca', + 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb', + 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b', + 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a', + 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618', + 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac', + 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5', + 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4', + 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c', + 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b', + 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27', + 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277', + 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa', + 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e', + 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e', + 'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f', + 'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2', + 'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc', + 'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167', + 'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64', + 'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d', + 'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20', + 'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab', + 'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53', + 'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2', + 'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e', + 'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372', + 'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902', + 'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de', + 'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b', + 'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03', + 'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a', + 'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6', + 'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a', +} + +import sys, os +try: from hashlib import md5 +except ImportError: from md5 import md5 + +def _validate_md5(egg_name, data): + if egg_name in md5_data: + digest = md5(data).hexdigest() + if digest != md5_data[egg_name]: + print(( + "md5 validation of %s failed! (Possible download problem?)" + % egg_name + ), file=sys.stderr) + sys.exit(2) + return data + +def use_setuptools( + version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, + download_delay=15 +): + """Automatically find/download setuptools and make it available on sys.path + + `version` should be a valid setuptools version number that is available + as an egg for download under the `download_base` URL (which should end with + a '/'). `to_dir` is the directory where setuptools will be downloaded, if + it is not already available. If `download_delay` is specified, it should + be the number of seconds that will be paused before initiating a download, + should one be required. If an older version of setuptools is installed, + this routine will print a message to ``sys.stderr`` and raise SystemExit in + an attempt to abort the calling script. + """ + was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules + def do_download(): + egg = download_setuptools(version, download_base, to_dir, download_delay) + sys.path.insert(0, egg) + import setuptools; setuptools.bootstrap_install_from = egg + try: + import pkg_resources + except ImportError: + return do_download() + try: + pkg_resources.require("setuptools>="+version); return + except pkg_resources.VersionConflict as e: + if was_imported: + print(( + "The required version of setuptools (>=%s) is not available, and\n" + "can't be installed while this script is running. Please install\n" + " a more recent version first, using 'easy_install -U setuptools'." + "\n\n(Currently using %r)" + ) % (version, e.args[0]), file=sys.stderr) + sys.exit(2) + else: + del pkg_resources, sys.modules['pkg_resources'] # reload ok + return do_download() + except pkg_resources.DistributionNotFound: + return do_download() + +def download_setuptools( + version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, + delay = 15 +): + """Download setuptools from a specified location and return its filename + + `version` should be a valid setuptools version number that is available + as an egg for download under the `download_base` URL (which should end + with a '/'). `to_dir` is the directory where the egg will be downloaded. + `delay` is the number of seconds to pause before an actual download attempt. + """ + import urllib.request, urllib.error, urllib.parse, shutil + egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3]) + url = download_base + egg_name + saveto = os.path.join(to_dir, egg_name) + src = dst = None + if not os.path.exists(saveto): # Avoid repeated downloads + try: + from distutils import log + if delay: + log.warn(""" +--------------------------------------------------------------------------- +This script requires setuptools version %s to run (even to display +help). I will attempt to download it for you (from +%s), but +you may need to enable firewall access for this script first. +I will start the download in %d seconds. + +(Note: if this machine does not have network access, please obtain the file + + %s + +and place it in this directory before rerunning this script.) +---------------------------------------------------------------------------""", + version, download_base, delay, url + ); from time import sleep; sleep(delay) + log.warn("Downloading %s", url) + src = urllib.request.urlopen(url) + # Read/write all in one block, so we don't create a corrupt file + # if the download is interrupted. + data = _validate_md5(egg_name, src.read()) + dst = open(saveto,"wb"); dst.write(data) + finally: + if src: src.close() + if dst: dst.close() + return os.path.realpath(saveto) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +def main(argv, version=DEFAULT_VERSION): + """Install or upgrade setuptools and EasyInstall""" + try: + import setuptools + except ImportError: + egg = None + try: + egg = download_setuptools(version, delay=0) + sys.path.insert(0,egg) + from setuptools.command.easy_install import main + return main(list(argv)+[egg]) # we're done here + finally: + if egg and os.path.exists(egg): + os.unlink(egg) + else: + if setuptools.__version__ == '0.0.1': + print(( + "You have an obsolete version of setuptools installed. Please\n" + "remove it from your system entirely before rerunning this script." + ), file=sys.stderr) + sys.exit(2) + + req = "setuptools>="+version + import pkg_resources + try: + pkg_resources.require(req) + except pkg_resources.VersionConflict: + try: + from setuptools.command.easy_install import main + except ImportError: + from easy_install import main + main(list(argv)+[download_setuptools(delay=0)]) + sys.exit(0) # try to force an exit + else: + if argv: + from setuptools.command.easy_install import main + main(argv) + else: + print("Setuptools version",version,"or greater has been installed.") + print('(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)') + +def update_md5(filenames): + """Update our built-in md5 registry""" + + import re + + for name in filenames: + base = os.path.basename(name) + f = open(name,'rb') + md5_data[base] = md5(f.read()).hexdigest() + f.close() + + data = [" %r: %r,\n" % it for it in list(md5_data.items())] + data.sort() + repl = "".join(data) + + import inspect + srcfile = inspect.getsourcefile(sys.modules[__name__]) + f = open(srcfile, 'rb'); src = f.read(); f.close() + + match = re.search("\nmd5_data = {\n([^}]+)}", src) + if not match: + print("Internal error!", file=sys.stderr) + sys.exit(2) + + src = src[:match.start(1)] + repl + src[match.end(1):] + f = open(srcfile,'w') + f.write(src) + f.close() + + +if __name__=='__main__': + if len(sys.argv)>2 and sys.argv[1]=='--md5update': + update_md5(sys.argv[2:]) + else: + main(sys.argv[1:]) + + + + + + diff --git a/piston/authentication.py b/piston/authentication.py index a11e260..2308852 100644 --- a/piston/authentication.py +++ b/piston/authentication.py @@ -1,6 +1,6 @@ import binascii -import oauth +from . import oauth from django.http import HttpResponse, HttpResponseRedirect from django.contrib.auth.models import User, AnonymousUser from django.contrib.auth.decorators import login_required @@ -70,7 +70,7 @@ def challenge(self): return resp def __repr__(self): - return u'' % self.realm + return '' % self.realm class HttpBasicSimple(HttpBasicAuthentication): def __init__(self, realm, username, password): @@ -94,13 +94,13 @@ def load_data_store(): try: mod = __import__(module, {}, {}, attr) - except ImportError, e: - raise ImproperlyConfigured, 'Error importing OAuth data store %s: "%s"' % (module, e) + except ImportError as e: + raise ImproperlyConfigured('Error importing OAuth data store %s: "%s"' % (module, e)) try: cls = getattr(mod, attr) except AttributeError: - raise ImproperlyConfigured, 'Module %s does not define a "%s" OAuth data store' % (module, attr) + raise ImproperlyConfigured('Module %s does not define a "%s" OAuth data store' % (module, attr)) return cls @@ -113,7 +113,7 @@ def initialize_server_request(request): """ # c.f. http://www.mail-archive.com/oauth@googlegroups.com/msg01556.html if (request.method == 'POST' and request.FILES == {}): - params = dict(request.REQUEST.items()) + params = dict(list(request.REQUEST.items())) else: params = {} @@ -145,7 +145,7 @@ def send_oauth_error(err=None): realm = 'OAuth' header = oauth.build_authenticate_header(realm=realm) - for k, v in header.iteritems(): + for k, v in header.items(): response[k] = v return response @@ -159,7 +159,7 @@ def oauth_request_token(request): token = oauth_server.fetch_request_token(oauth_request) response = HttpResponse(token.to_string()) - except oauth.OAuthError, err: + except oauth.OAuthError as err: response = send_oauth_error(err) return response @@ -183,7 +183,7 @@ def oauth_user_auth(request): try: token = oauth_server.fetch_request_token(oauth_request) - except oauth.OAuthError, err: + except oauth.OAuthError as err: return send_oauth_error(err) try: @@ -214,7 +214,7 @@ def oauth_user_auth(request): response = HttpResponseRedirect(callback+args) - except oauth.OAuthError, err: + except oauth.OAuthError as err: response = send_oauth_error(err) else: response = HttpResponse('Action not allowed.') @@ -230,7 +230,7 @@ def oauth_access_token(request): try: token = oauth_server.fetch_access_token(oauth_request, required=True) return HttpResponse(token.to_string()) - except oauth.OAuthError, err: + except oauth.OAuthError as err: return send_oauth_error(err) INVALID_PARAMS_RESPONSE = send_oauth_error(oauth.OAuthError('Invalid request parameters.')) @@ -254,8 +254,8 @@ def is_authenticated(self, request): if self.is_valid_request(request): try: consumer, token, parameters = self.validate_token(request) - except oauth.OAuthError, err: - print send_oauth_error(err) + except oauth.OAuthError as err: + print(send_oauth_error(err)) return False if consumer and token: @@ -281,7 +281,7 @@ def challenge(self, request=None): response.status_code = 401 realm = 'API' - for k, v in self.builder(realm=realm).iteritems(): + for k, v in self.builder(realm=realm).items(): response[k] = v tmpl = loader.render_to_string('oauth/challenge.html', { 'MEDIA_URL': settings.MEDIA_URL }) diff --git a/piston/decorator.py b/piston/decorator.py index f8dc3b8..81f2de4 100755 --- a/piston/decorator.py +++ b/piston/decorator.py @@ -54,9 +54,9 @@ def getinfo(func): signature = inspect.formatargspec(regargs, varargs, varkwargs, defaults, formatvalue=lambda value: "")[1:-1] return dict(name=func.__name__, argnames=argnames, signature=signature, - defaults = func.func_defaults, doc=func.__doc__, + defaults = func.__defaults__, doc=func.__doc__, module=func.__module__, dict=func.__dict__, - globals=func.func_globals, closure=func.func_closure) + globals=func.__globals__, closure=func.__closure__) # akin to functools.update_wrapper def update_wrapper(wrapper, model, infodict=None): @@ -68,7 +68,7 @@ def update_wrapper(wrapper, model, infodict=None): wrapper.__doc__ = infodict['doc'] wrapper.__module__ = infodict['module'] wrapper.__dict__.update(infodict['dict']) - wrapper.func_defaults = infodict['defaults'] + wrapper.__defaults__ = infodict['defaults'] wrapper.undecorated = model return wrapper diff --git a/piston/doc.py b/piston/doc.py index 0f3b71e..2a962f3 100644 --- a/piston/doc.py +++ b/piston/doc.py @@ -89,7 +89,7 @@ def get_methods(self, include_default=False): if not met: continue - stale = inspect.getmodule(met.im_func) is not inspect.getmodule(self.handler) + stale = inspect.getmodule(met.__func__) is not inspect.getmodule(self.handler) if not self.handler.is_anonymous: if met and (not stale or include_default): @@ -140,7 +140,7 @@ def get_resource_uri_template(self): def _convert(template, params=[]): """URI template converter""" paths = template % dict([p, "{%s}" % p] for p in params) - return u'%s%s' % (get_script_prefix(), paths) + return '%s%s' % (get_script_prefix(), paths) try: resource_uri = self.handler.resource_uri() @@ -171,7 +171,7 @@ def _convert(template, params=[]): resource_uri_template = property(get_resource_uri_template) def __repr__(self): - return u'' % self.name + return '' % self.name def documentation_view(request): """ diff --git a/piston/emitters.py b/piston/emitters.py index 4b18225..b1c317c 100644 --- a/piston/emitters.py +++ b/piston/emitters.py @@ -1,7 +1,8 @@ -from __future__ import generators + import decimal, re, inspect import copy +import collections try: # yaml isn't standard with python. It shouldn't be required if it @@ -34,16 +35,16 @@ def any(iterable): except ImportError: import json as simplejson -from utils import HttpStatusCode, Mimer -from validate_jsonp import is_valid_jsonp_callback_value +from .utils import HttpStatusCode, Mimer +from .validate_jsonp import is_valid_jsonp_callback_value try: - import cStringIO as StringIO + import io as StringIO except ImportError: - import StringIO + import io try: - import cPickle as pickle + import pickle as pickle except ImportError: import pickle @@ -86,7 +87,7 @@ def method_fields(self, handler, fields): for field in fields - Emitter.RESERVED_FIELDS: t = getattr(handler, str(field), None) - if t and callable(t): + if t and isinstance(t, collections.Callable): ret[field] = t return ret @@ -182,7 +183,7 @@ def _model(data, fields=()): # sets can be negated. for exclude in exclude_fields: - if isinstance(exclude, basestring): + if isinstance(exclude, str): get_fields.discard(exclude) elif isinstance(exclude, re._pattern_type): @@ -221,7 +222,7 @@ def _model(data, fields=()): if inst: if hasattr(inst, 'all'): ret[model] = _related(inst, fields) - elif callable(inst): + elif isinstance(inst, collections.Callable): if len(inspect.getargspec(inst)[0]) == 1: ret[model] = _any(inst(), fields) else: @@ -236,7 +237,7 @@ def _model(data, fields=()): else: maybe = getattr(data, maybe_field, None) if maybe is not None: - if callable(maybe): + if isinstance(maybe, collections.Callable): if len(inspect.getargspec(maybe)[0]) <= 1: ret[maybe_field] = _any(maybe()) else: @@ -253,10 +254,10 @@ def _model(data, fields=()): ret[f.attname] = _any(getattr(data, f.attname)) if hasattr(data, "_piston"): - for f,v in data._piston['fields'].items(): + for f,v in list(data._piston['fields'].items()): ret[f] = _any(v) - fields = dir(data.__class__) + ret.keys() + fields = dir(data.__class__) + list(ret.keys()) add_ons = [k for k in dir(data) if k not in fields] for k in add_ons: @@ -271,7 +272,7 @@ def _model(data, fields=()): try: ret['resource_uri'] = reverser( lambda: (url_id, fields) )() - except NoReverseMatch, e: + except NoReverseMatch as e: pass if hasattr(data, 'get_api_url') and 'resource_uri' not in ret: @@ -301,13 +302,13 @@ def _dict(data, fields=()): """ Dictionaries. """ - return dict([ (k, _any(v, fields)) for k, v in data.iteritems() ]) + return dict([ (k, _any(v, fields)) for k, v in data.items() ]) # Kickstart the seralizin'. return _any(self.data, self.fields) def in_typemapper(self, model, anonymous): - for klass, (km, is_anon) in self.typemapper.iteritems(): + for klass, (km, is_anon) in self.typemapper.items(): if model is km and is_anon is anonymous: return klass @@ -332,7 +333,7 @@ def get(cls, format): """ Gets an emitter, returns the class and a content-type. """ - if cls.EMITTERS.has_key(format): + if format in cls.EMITTERS: return cls.EMITTERS.get(format) raise ValueError("No emitters found for type %s" % format) @@ -365,7 +366,7 @@ def _to_xml(self, xml, data): self._to_xml(xml, item) xml.endElement("resource") elif isinstance(data, dict): - for key, value in data.iteritems(): + for key, value in data.items(): xml.startElement(key, {}) self._to_xml(xml, value) xml.endElement(key) @@ -373,7 +374,7 @@ def _to_xml(self, xml, data): xml.characters(smart_unicode(data)) def render(self, request): - stream = StringIO.StringIO() + stream = io.StringIO() xml = SimplerXMLGenerator(stream, "utf-8") xml.startDocument() diff --git a/piston/forms.py b/piston/forms.py index 90f03ff..e0f5650 100644 --- a/piston/forms.py +++ b/piston/forms.py @@ -16,7 +16,7 @@ class ModelForm(forms.ModelForm): """ def merge_from_initial(self): self.data._mutable = True - filt = lambda v: v not in self.data.keys() + filt = lambda v: v not in list(self.data.keys()) for field in filter(filt, getattr(self.Meta, 'fields', ())): self.data[field] = self.initial.get(field, None) diff --git a/piston/handler.py b/piston/handler.py index 11161fe..3895947 100644 --- a/piston/handler.py +++ b/piston/handler.py @@ -1,6 +1,6 @@ import warnings -from utils import rc +from .utils import rc from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned from django.conf import settings @@ -16,7 +16,7 @@ def __new__(cls, name, bases, attrs): new_cls = type.__new__(cls, name, bases, attrs) def already_registered(model, anon): - for k, (m, a) in typemapper.iteritems(): + for k, (m, a) in typemapper.items(): if model == m and anon == a: return k @@ -35,7 +35,7 @@ def already_registered(model, anon): return new_cls -class BaseHandler(object): +class BaseHandler(object, metaclass=HandlerMetaClass): """ Basehandler that gives you CRUD for free. You are supposed to subclass this for specific @@ -45,7 +45,6 @@ class BaseHandler(object): receive a request as the first argument from the resource. Use this for checking `request.user`, etc. """ - __metaclass__ = HandlerMetaClass allowed_methods = ('GET', 'POST', 'PUT', 'DELETE') anonymous = is_anonymous = False @@ -53,7 +52,7 @@ class BaseHandler(object): fields = ( ) def flatten_dict(self, dct): - return dict([ (str(k), dct.get(k)) for k in dct.keys() ]) + return dict([ (str(k), dct.get(k)) for k in list(dct.keys()) ]) def has_model(self): return hasattr(self, 'model') or hasattr(self, 'queryset') @@ -127,7 +126,7 @@ def update(self, request, *args, **kwargs): return rc.BAD_REQUEST attrs = self.flatten_dict(request.data) - for k,v in attrs.iteritems(): + for k,v in attrs.items(): setattr( inst, k, v ) inst.save() diff --git a/piston/models.py b/piston/models.py index b7c7504..bd1b5c9 100644 --- a/piston/models.py +++ b/piston/models.py @@ -1,4 +1,4 @@ -import urllib, time, urlparse +import urllib.request, urllib.parse, urllib.error, time, urllib.parse # Django imports from django.db.models.signals import post_save, post_delete @@ -7,8 +7,8 @@ from django.core.mail import send_mail, mail_admins # Piston imports -from managers import TokenManager, ConsumerManager, ResourceManager -from signals import consumer_post_save, consumer_post_delete +from .managers import TokenManager, ConsumerManager, ResourceManager +from .signals import consumer_post_save, consumer_post_delete KEY_SIZE = 18 SECRET_SIZE = 32 @@ -33,7 +33,7 @@ class Meta: app_label = 'piston' def __unicode__(self): - return u"Nonce %s for %s" % (self.key, self.consumer_key) + return "Nonce %s for %s" % (self.key, self.consumer_key) class Consumer(models.Model): @@ -52,7 +52,7 @@ class Meta: app_label = 'piston' def __unicode__(self): - return u"Consumer %s with key %s" % (self.name, self.key) + return "Consumer %s with key %s" % (self.name, self.key) def generate_random_codes(self): """ @@ -79,13 +79,13 @@ def generate_random_codes(self): class Token(models.Model): REQUEST = 1 ACCESS = 2 - TOKEN_TYPES = ((REQUEST, u'Request'), (ACCESS, u'Access')) + TOKEN_TYPES = ((REQUEST, 'Request'), (ACCESS, 'Access')) key = models.CharField(max_length=KEY_SIZE) secret = models.CharField(max_length=SECRET_SIZE) verifier = models.CharField(max_length=VERIFIER_SIZE) token_type = models.IntegerField(choices=TOKEN_TYPES) - timestamp = models.IntegerField(default=long(time.time())) + timestamp = models.IntegerField(default=int(time.time())) is_approved = models.BooleanField(default=False) user = models.ForeignKey(User, null=True, blank=True, related_name='tokens') @@ -100,7 +100,7 @@ class Meta: app_label = 'piston' def __unicode__(self): - return u"%s Token %s for %s" % (self.get_token_type_display(), self.key, self.consumer) + return "%s Token %s for %s" % (self.get_token_type_display(), self.key, self.consumer) def to_string(self, only_key=False): token_dict = { @@ -115,7 +115,7 @@ def to_string(self, only_key=False): if only_key: del token_dict['oauth_token_secret'] - return urllib.urlencode(token_dict) + return urllib.parse.urlencode(token_dict) def generate_random_codes(self): key = User.objects.make_random_password(length=KEY_SIZE) @@ -133,13 +133,13 @@ def generate_random_codes(self): def get_callback_url(self): if self.callback and self.verifier: # Append the oauth_verifier. - parts = urlparse.urlparse(self.callback) + parts = urllib.parse.urlparse(self.callback) scheme, netloc, path, params, query, fragment = parts[:6] if query: query = '%s&oauth_verifier=%s' % (query, self.verifier) else: query = 'oauth_verifier=%s' % self.verifier - return urlparse.urlunparse((scheme, netloc, path, params, + return urllib.parse.urlunparse((scheme, netloc, path, params, query, fragment)) return self.callback diff --git a/piston/oauth.py b/piston/oauth.py index cdce7ee..60687f2 100644 --- a/piston/oauth.py +++ b/piston/oauth.py @@ -23,10 +23,10 @@ """ import cgi -import urllib +import urllib.request, urllib.parse, urllib.error import time import random -import urlparse +import urllib.parse import hmac import binascii @@ -47,11 +47,11 @@ def build_authenticate_header(realm=''): def escape(s): """Escape a URL including any /.""" - return urllib.quote(s, safe='~') + return urllib.parse.quote(s, safe='~') def _utf8_str(s): """Convert unicode to utf-8.""" - if isinstance(s, unicode): + if isinstance(s, str): return s.encode("utf-8") else: return str(s) @@ -115,13 +115,13 @@ def set_verifier(self, verifier=None): def get_callback_url(self): if self.callback and self.verifier: # Append the oauth_verifier. - parts = urlparse.urlparse(self.callback) + parts = urllib.parse.urlparse(self.callback) scheme, netloc, path, params, query, fragment = parts[:6] if query: query = '%s&oauth_verifier=%s' % (query, self.verifier) else: query = 'oauth_verifier=%s' % self.verifier - return urlparse.urlunparse((scheme, netloc, path, params, + return urllib.parse.urlunparse((scheme, netloc, path, params, query, fragment)) return self.callback @@ -132,7 +132,7 @@ def to_string(self): } if self.callback_confirmed is not None: data['oauth_callback_confirmed'] = self.callback_confirmed - return urllib.urlencode(data) + return urllib.parse.urlencode(data) def from_string(s): """ Returns a token from something like: @@ -193,7 +193,7 @@ def _get_timestamp_nonce(self): def get_nonoauth_parameters(self): """Get any non-OAuth parameters.""" parameters = {} - for k, v in self.parameters.iteritems(): + for k, v in self.parameters.items(): # Ignore oauth parameters. if k.find('oauth_') < 0: parameters[k] = v @@ -204,7 +204,7 @@ def to_header(self, realm=''): auth_header = 'OAuth realm="%s"' % realm # Add the oauth parameters. if self.parameters: - for k, v in self.parameters.iteritems(): + for k, v in self.parameters.items(): if k[:6] == 'oauth_': auth_header += ', %s="%s"' % (k, escape(str(v))) return {'Authorization': auth_header} @@ -212,7 +212,7 @@ def to_header(self, realm=''): def to_postdata(self): """Serialize as post data for a POST request.""" return '&'.join(['%s=%s' % (escape(str(k)), escape(str(v))) \ - for k, v in self.parameters.iteritems()]) + for k, v in self.parameters.items()]) def to_url(self): """Serialize as a URL for a GET request.""" @@ -228,7 +228,7 @@ def get_normalized_parameters(self): pass # Escape key values before sorting. key_values = [(escape(_utf8_str(k)), escape(_utf8_str(v))) \ - for k,v in params.items()] + for k,v in list(params.items())] # Sort lexicographically, first after key, then after value. key_values.sort() # Combine key value pairs into a string. @@ -240,7 +240,7 @@ def get_normalized_http_method(self): def get_normalized_http_url(self): """Parses the URL and rebuilds it to be scheme://host/path.""" - parts = urlparse.urlparse(self.http_url) + parts = urllib.parse.urlparse(self.http_url) scheme, netloc, path = parts[:3] # Exclude default port numbers. if scheme == 'http' and netloc[-3:] == ':80': @@ -288,7 +288,7 @@ def from_request(http_method, http_url, headers=None, parameters=None, parameters.update(query_params) # URL parameters. - param_str = urlparse.urlparse(http_url)[4] # query + param_str = urllib.parse.urlparse(http_url)[4] # query url_params = OAuthRequest._split_url_string(param_str) parameters.update(url_params) @@ -352,15 +352,15 @@ def _split_header(header): # Split key-value. param_parts = param.split('=', 1) # Remove quotes and unescape the value. - params[param_parts[0]] = urllib.unquote(param_parts[1].strip('\"')) + params[param_parts[0]] = urllib.parse.unquote(param_parts[1].strip('\"')) return params _split_header = staticmethod(_split_header) def _split_url_string(param_str): """Turn URL string into parameters.""" parameters = cgi.parse_qs(param_str, keep_blank_values=False) - for k, v in parameters.iteritems(): - parameters[k] = urllib.unquote(v[0]) + for k, v in parameters.items(): + parameters[k] = urllib.parse.unquote(v[0]) return parameters _split_url_string = staticmethod(_split_url_string) @@ -471,7 +471,7 @@ def _get_signature_method(self, oauth_request): # Get the signature method object. signature_method = self.signature_methods[signature_method] except: - signature_method_names = ', '.join(self.signature_methods.keys()) + signature_method_names = ', '.join(list(self.signature_methods.keys())) raise OAuthError('Signature method %s not supported try one of the ' 'following: %s' % (signature_method, signature_method_names)) diff --git a/piston/resource.py b/piston/resource.py index 3ba6c7e..91530cc 100644 --- a/piston/resource.py +++ b/piston/resource.py @@ -9,12 +9,13 @@ from django.db.models.query import QuerySet from django.http import Http404 -from emitters import Emitter -from handler import typemapper -from doc import HandlerMethod -from authentication import NoAuthentication -from utils import coerce_put_post, FormValidationError, HttpStatusCode -from utils import rc, format_error, translate_mime, MimerDataException +from .emitters import Emitter +from .handler import typemapper +from .doc import HandlerMethod +from .authentication import NoAuthentication +from .utils import coerce_put_post, FormValidationError, HttpStatusCode +from .utils import rc, format_error, translate_mime, MimerDataException +import collections CHALLENGE = object() @@ -30,8 +31,8 @@ class Resource(object): 'PUT': 'update', 'DELETE': 'delete' } def __init__(self, handler, authentication=None): - if not callable(handler): - raise AttributeError, "Handler not callable." + if not isinstance(handler, collections.Callable): + raise AttributeError("Handler not callable.") self.handler = handler() self.csrf_exempt = getattr(self.handler, 'csrf_exempt', True) @@ -86,10 +87,10 @@ def anonymous(self): if hasattr(self.handler, 'anonymous'): anon = self.handler.anonymous - if callable(anon): + if isinstance(anon, collections.Callable): return anon - for klass in typemapper.keys(): + for klass in list(typemapper.keys()): if anon == klass.__name__: return klass @@ -162,7 +163,7 @@ def __call__(self, request, *args, **kwargs): try: result = meth(request, *args, **kwargs) - except Exception, e: + except Exception as e: result = self.error_handler(e, request, meth, em_format) try: @@ -208,7 +209,7 @@ def __call__(self, request, *args, **kwargs): resp.streaming = self.stream return resp - except HttpStatusCode, e: + except HttpStatusCode as e: return e.response @staticmethod @@ -220,10 +221,10 @@ def cleanup_request(request): for method_type in ('GET', 'PUT', 'POST', 'DELETE'): block = getattr(request, method_type, { }) - if True in [ k.startswith("oauth_") for k in block.keys() ]: + if True in [ k.startswith("oauth_") for k in list(block.keys()) ]: sanitized = block.copy() - for k in sanitized.keys(): + for k in list(sanitized.keys()): if k.startswith("oauth_"): sanitized.pop(k) diff --git a/piston/signals.py b/piston/signals.py index 133be13..8296465 100644 --- a/piston/signals.py +++ b/piston/signals.py @@ -2,7 +2,7 @@ import django.dispatch # Piston imports -from utils import send_consumer_mail +from .utils import send_consumer_mail def consumer_post_save(sender, instance, created, **kwargs): send_consumer_mail(instance) diff --git a/piston/store.py b/piston/store.py index b7207b7..c00b8f7 100644 --- a/piston/store.py +++ b/piston/store.py @@ -1,7 +1,7 @@ -import oauth +from . import oauth -from models import Nonce, Token, Consumer -from models import generate_random, VERIFIER_SIZE +from .models import Nonce, Token, Consumer +from .models import generate_random, VERIFIER_SIZE class DataStore(oauth.OAuthDataStore): """Layer between Python OAuth and Django database.""" diff --git a/piston/test.py b/piston/test.py index 57eda72..f6a7f61 100644 --- a/piston/test.py +++ b/piston/test.py @@ -8,7 +8,7 @@ from piston.models import Consumer, Token # 3rd/Python party imports -import httplib2, urllib, cgi +import httplib2, urllib.request, urllib.parse, urllib.error, cgi URLENCODED_FORM_CONTENT = 'application/x-www-form-urlencoded' diff --git a/piston/tests.py b/piston/tests.py index 946c974..0eefb63 100644 --- a/piston/tests.py +++ b/piston/tests.py @@ -11,11 +11,11 @@ import json as simplejson # Piston imports -from test import TestCase -from models import Consumer -from handler import BaseHandler -from utils import rc -from resource import Resource +from .test import TestCase +from .models import Consumer +from .handler import BaseHandler +from .utils import rc +from .resource import Resource class ConsumerTest(TestCase): fixtures = ['models.json'] @@ -51,12 +51,12 @@ def test_create_pending(self): # If it's pending we should have two messages in the outbox; one # to the consumer and one to the site admins. if len(settings.ADMINS): - self.assertEquals(len(mail.outbox), 2) + self.assertEqual(len(mail.outbox), 2) else: - self.assertEquals(len(mail.outbox), 1) + self.assertEqual(len(mail.outbox), 1) expected = "Your API Consumer for example.com is awaiting approval." - self.assertEquals(mail.outbox[0].subject, expected) + self.assertEqual(mail.outbox[0].subject, expected) def test_delete_consumer(self): """ Ensure deleting a Consumer sends a cancel email """ @@ -71,9 +71,9 @@ def test_delete_consumer(self): if not self._pre_test_email(): return - self.assertEquals(len(mail.outbox), 1) + self.assertEqual(len(mail.outbox), 1) expected = "Your API Consumer for example.com has been canceled." - self.assertEquals(mail.outbox[0].subject, expected) + self.assertEqual(mail.outbox[0].subject, expected) class CustomResponseWithStatusCodeTest(TestCase): @@ -103,12 +103,12 @@ def create(self, request): request.method = 'POST' response = resource(request, emitter_format='json') - self.assertEquals(201, response.status_code) + self.assertEqual(201, response.status_code) self.assertTrue(response._is_string, "Expected response content to be a string") # compare the original data dict with the json response # converted to a dict - self.assertEquals(response_data, simplejson.loads(response.content)) + self.assertEqual(response_data, simplejson.loads(response.content)) class ErrorHandlerTest(TestCase): @@ -154,7 +154,7 @@ def error_handler(self, error, request, meth, em_format): request.method = 'GET' response = resource(request, emitter_format='json') - self.assertEquals(401, response.status_code) + self.assertEqual(401, response.status_code) # verify the content we got back can be converted back to json # and examine the dictionary keys all exist as expected diff --git a/piston/utils.py b/piston/utils.py index 1c1482b..63a6171 100644 --- a/piston/utils.py +++ b/piston/utils.py @@ -10,7 +10,7 @@ from django.conf import settings from django.utils.translation import ugettext as _ from django.template import loader, TemplateDoesNotExist -from decorator import decorator +from .decorator import decorator from datetime import datetime, timedelta @@ -20,7 +20,7 @@ def get_version(): return __version__ def format_error(error): - return u"Piston/%s (Django %s) crash report:\n\n%s" % \ + return "Piston/%s (Django %s) crash report:\n\n%s" % \ (get_version(), django_version(), error) class rc_factory(object): @@ -73,7 +73,7 @@ def _set_content(self, content): self['Content-Type'] = 'application/json' is_string = False - if not isinstance(content, basestring) and hasattr(content, '__iter__'): + if not isinstance(content, str) and hasattr(content, '__iter__'): self._container = content else: self._container = [content] @@ -235,7 +235,7 @@ def loader_for_type(self, ctype): Gets a function ref to deserialize content for a certain mimetype. """ - for loadee, mimes in Mimer.TYPES.iteritems(): + for loadee, mimes in Mimer.TYPES.items(): for mime in mimes: if ctype.startswith(mime): return loadee @@ -359,7 +359,7 @@ def send_consumer_mail(consumer): mail_admins(_(subject), body, fail_silently=True) if settings.DEBUG and consumer.user: - print "Mail being sent, to=%s" % consumer.user.email - print "Subject: %s" % _(subject) - print body + print("Mail being sent, to=%s" % consumer.user.email) + print("Subject: %s" % _(subject)) + print(body) diff --git a/piston/validate_jsonp.py b/piston/validate_jsonp.py index 10fba21..d371c3e 100644 --- a/piston/validate_jsonp.py +++ b/piston/validate_jsonp.py @@ -60,9 +60,9 @@ def is_valid_javascript_identifier(identifier, escape=r'\u', ucd_cat=category): if not identifier: return False - if not isinstance(identifier, unicode): + if not isinstance(identifier, str): try: - identifier = unicode(identifier, 'utf-8') + identifier = str(identifier, 'utf-8') except UnicodeDecodeError: return False @@ -76,12 +76,12 @@ def is_valid_javascript_identifier(identifier, escape=r'\u', ucd_cat=category): if len(segment) < 4: return False try: - add_char(unichr(int('0x' + segment[:4], 16))) + add_char(chr(int('0x' + segment[:4], 16))) except Exception: return False add_char(segment[4:]) - identifier = u''.join(new) + identifier = ''.join(new) if is_reserved_js_word(identifier): return False @@ -103,11 +103,11 @@ def is_valid_javascript_identifier(identifier, escape=r'\u', ucd_cat=category): def is_valid_jsonp_callback_value(value): """Return whether the given ``value`` can be used as a JSON-P callback.""" - for identifier in value.split(u'.'): + for identifier in value.split('.'): while '[' in identifier: if not has_valid_array_index(identifier): return False - identifier = replace_array_index(u'', identifier) + identifier = replace_array_index('', identifier) if not is_valid_javascript_identifier(identifier): return False @@ -140,16 +140,16 @@ def test(): >>> is_valid_javascript_identifier('$210') True - >>> is_valid_javascript_identifier(u'Stra\u00dfe') + >>> is_valid_javascript_identifier(u'Stra\\u00dfe') True - >>> is_valid_javascript_identifier(r'\u0062') # u'b' + >>> is_valid_javascript_identifier(r'\\u0062') # u'b' True - >>> is_valid_javascript_identifier(r'\u62') + >>> is_valid_javascript_identifier(r'\\u62') False - >>> is_valid_javascript_identifier(r'\u0020') + >>> is_valid_javascript_identifier(r'\\u0020') False >>> is_valid_javascript_identifier('_bar') diff --git a/setup.py b/setup.py index e304cfd..52bbf50 100644 --- a/setup.py +++ b/setup.py @@ -8,11 +8,9 @@ ez_setup.use_setuptools() from setuptools import setup, find_packages -import os - setup( name = "django-piston", - version = "0.2.3.sm12", + version = "1.0.0-yr.alpha", # version 1.0.0 supports python3 url = 'http://bitbucket.org/jespern/django-piston/wiki/Home', download_url = 'http://bitbucket.org/jespern/django-piston/downloads/', license = 'BSD', diff --git a/tests/bootstrap.py b/tests/bootstrap.py index c262f93..3752920 100644 --- a/tests/bootstrap.py +++ b/tests/bootstrap.py @@ -20,7 +20,7 @@ $Id$ """ -import os, shutil, sys, tempfile, urllib2 +import os, shutil, sys, tempfile, urllib.request, urllib.error, urllib.parse tmpeggs = tempfile.mkdtemp() @@ -30,8 +30,8 @@ import pkg_resources except ImportError: ez = {} - exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py' - ).read() in ez + exec(urllib.request.urlopen('http://peak.telecommunity.com/dist/ez_setup.py' + ).read(), ez) ez['use_setuptools'](to_dir=tmpeggs, download_delay=0) import pkg_resources diff --git a/tests/test_project/apps/testapp/handlers.py b/tests/test_project/apps/testapp/handlers.py index f8a7231..e81fe62 100644 --- a/tests/test_project/apps/testapp/handlers.py +++ b/tests/test_project/apps/testapp/handlers.py @@ -3,8 +3,8 @@ from piston.handler import BaseHandler from piston.utils import rc, validate -from models import TestModel, ExpressiveTestModel, Comment, InheritedModel, PlainOldObject, Issue58Model, ListFieldsModel -from forms import EchoForm +from .models import TestModel, ExpressiveTestModel, Comment, InheritedModel, PlainOldObject, Issue58Model, ListFieldsModel +from .forms import EchoForm from test_project.apps.testapp import signals class EntryHandler(BaseHandler): diff --git a/tests/test_project/apps/testapp/tests.py b/tests/test_project/apps/testapp/tests.py index c7417db..e8815a2 100644 --- a/tests/test_project/apps/testapp/tests.py +++ b/tests/test_project/apps/testapp/tests.py @@ -14,10 +14,10 @@ try: import yaml except ImportError: - print "Can't run YAML testsuite" + print("Can't run YAML testsuite") yaml = None -import urllib, base64 +import urllib.request, urllib.parse, urllib.error, base64 from test_project.apps.testapp.models import TestModel, ExpressiveTestModel, Comment, InheritedModel, Issue58Model, ListFieldsModel from test_project.apps.testapp import signals @@ -70,7 +70,7 @@ def test_handshake(self): self.assertEqual(token.secret, oatoken.secret) # Simulate user authentication... - self.failUnless(self.client.login(username='admin', password='admin')) + self.assertTrue(self.client.login(username='admin', password='admin')) request = oauth.OAuthRequest.from_token_and_callback(token=oatoken, callback='http://printer.example.com/request_token_ready', http_url='http://testserver/api/oauth/authorize') @@ -92,8 +92,8 @@ def test_handshake(self): # Response should be a redirect... self.assertEqual(302, response.status_code) - self.failUnless(response['Location'].startswith("http://printer.example.com/request_token_ready?")) - self.failUnless(('oauth_token='+oatoken.key in response['Location'])) + self.assertTrue(response['Location'].startswith("http://printer.example.com/request_token_ready?")) + self.assertTrue(('oauth_token='+oatoken.key in response['Location'])) # Actually we can't test this last part, since it's 1.0a. # Obtain access token... @@ -110,25 +110,25 @@ class BasicAuthTest(MainTests): def test_invalid_auth_header(self): response = self.client.get('/api/entries/') - self.assertEquals(response.status_code, 401) + self.assertEqual(response.status_code, 401) # no space bad_auth_string = 'Basic%s' % base64.encodestring('admin:admin').rstrip() response = self.client.get('/api/entries/', HTTP_AUTHORIZATION=bad_auth_string) - self.assertEquals(response.status_code, 401) + self.assertEqual(response.status_code, 401) # no colon bad_auth_string = 'Basic %s' % base64.encodestring('adminadmin').rstrip() response = self.client.get('/api/entries/', HTTP_AUTHORIZATION=bad_auth_string) - self.assertEquals(response.status_code, 401) + self.assertEqual(response.status_code, 401) # non base64 data bad_auth_string = 'Basic FOOBARQ!' response = self.client.get('/api/entries/', HTTP_AUTHORIZATION=bad_auth_string) - self.assertEquals(response.status_code, 401) + self.assertEqual(response.status_code, 401) class TestMultipleAuthenticators(MainTests): def test_both_authenticators(self): @@ -142,7 +142,7 @@ def test_both_authenticators(self): response = self.client.get('/api/multiauth/', HTTP_AUTHORIZATION=auth_string) - self.assertEquals(response.status_code, 200, 'Failed with combo of %s:%s' % (username, password)) + self.assertEqual(response.status_code, 200, 'Failed with combo of %s:%s' % (username, password)) class MultiXMLTests(MainTests): def init_delegate(self): @@ -155,14 +155,14 @@ def test_multixml(self): expected = '\nNoneNoneNoneNone' result = self.client.get('/api/entries.xml', HTTP_AUTHORIZATION=self.auth_string).content - self.assertEquals(expected, result) + self.assertEqual(expected, result) def test_singlexml(self): obj = TestModel.objects.all()[0] expected = '\nNoneNone' result = self.client.get('/api/entry-%d.xml' % (obj.pk,), HTTP_AUTHORIZATION=self.auth_string).content - self.assertEquals(expected, result) + self.assertEqual(expected, result) class AbstractBaseClassTests(MainTests): def init_delegate(self): @@ -188,7 +188,7 @@ def test_field_presence(self): } ]""" - self.assertEquals(result, expected) + self.assertEqual(result, expected) def test_specific_id(self): ids = (1, 2) @@ -204,7 +204,7 @@ def test_specific_id(self): expected = be % id_ - self.assertEquals(result, expected) + self.assertEqual(result, expected) class IncomingExpressiveTests(MainTests): def init_delegate(self): @@ -234,12 +234,12 @@ def test_incoming_json(self): result = self.client.get('/api/expressive.json', HTTP_AUTHORIZATION=self.auth_string).content - self.assertEquals(result, expected) + self.assertEqual(result, expected) resp = self.client.post('/api/expressive.json', outgoing, content_type='application/json', HTTP_AUTHORIZATION=self.auth_string) - self.assertEquals(resp.status_code, 201) + self.assertEqual(resp.status_code, 201) expected = """[ { @@ -269,14 +269,14 @@ def test_incoming_json(self): result = self.client.get('/api/expressive.json', HTTP_AUTHORIZATION=self.auth_string).content - self.assertEquals(result, expected) + self.assertEqual(result, expected) def test_incoming_invalid_json(self): resp = self.client.post('/api/expressive.json', 'foo', HTTP_AUTHORIZATION=self.auth_string, content_type='application/json') - self.assertEquals(resp.status_code, 400) + self.assertEqual(resp.status_code, 400) def test_incoming_yaml(self): if not yaml: @@ -290,7 +290,7 @@ def test_incoming_yaml(self): title: foo2 """ - self.assertEquals(self.client.get('/api/expressive.yaml', + self.assertEqual(self.client.get('/api/expressive.yaml', HTTP_AUTHORIZATION=self.auth_string).content, expected) outgoing = yaml.dump({ 'title': 'test', 'content': 'test', @@ -300,7 +300,7 @@ def test_incoming_yaml(self): resp = self.client.post('/api/expressive.json', outgoing, content_type='application/x-yaml', HTTP_AUTHORIZATION=self.auth_string) - self.assertEquals(resp.status_code, 201) + self.assertEqual(resp.status_code, 201) expected = """- comments: [] content: bar @@ -314,7 +314,7 @@ def test_incoming_yaml(self): content: test title: test """ - self.assertEquals(self.client.get('/api/expressive.yaml', + self.assertEqual(self.client.get('/api/expressive.yaml', HTTP_AUTHORIZATION=self.auth_string).content, expected) def test_incoming_invalid_yaml(self): @@ -322,7 +322,7 @@ def test_incoming_invalid_yaml(self): ' 8**sad asj lja foo', HTTP_AUTHORIZATION=self.auth_string, content_type='application/x-yaml') - self.assertEquals(resp.status_code, 400) + self.assertEqual(resp.status_code, 400) class Issue36RegressionTests(MainTests): """ @@ -352,7 +352,7 @@ def test_simple(self): try: response = self.client.post('/api/entries.xml', {'file':fp}, HTTP_AUTHORIZATION=self.auth_string) - self.assertEquals(1, len(self.request.FILES), 'request.FILES on POST is empty when it should contain 1 file') + self.assertEqual(1, len(self.request.FILES), 'request.FILES on POST is empty when it should contain 1 file') finally: fp.close() @@ -366,29 +366,29 @@ def test_simple(self): try: response = self.client.put('/api/entry-%d.xml' % self.data.pk, {'file': fp}, HTTP_AUTHORIZATION=self.auth_string) - self.assertEquals(1, len(self.request.FILES), 'request.FILES on PUT is empty when it should contain 1 file') + self.assertEqual(1, len(self.request.FILES), 'request.FILES on PUT is empty when it should contain 1 file') finally: fp.close() class ValidationTest(MainTests): def test_basic_validation_fails(self): resp = self.client.get('/api/echo') - self.assertEquals(resp.status_code, 400) - self.assertEquals(resp.content, 'Bad Request
    ' + self.assertEqual(resp.status_code, 400) + self.assertEqual(resp.content, 'Bad Request
      ' '
    • msg
      • This field is required.
      • ' '
    ') def test_basic_validation_succeeds(self): data = {'msg': 'donuts!'} resp = self.client.get('/api/echo', data) - self.assertEquals(resp.status_code, 200) - self.assertEquals(data, simplejson.loads(resp.content)) + self.assertEqual(resp.status_code, 200) + self.assertEqual(data, simplejson.loads(resp.content)) class PlainOldObject(MainTests): def test_plain_object_serialization(self): resp = self.client.get('/api/popo') - self.assertEquals(resp.status_code, 200) - self.assertEquals({'type': 'plain', 'field': 'a field'}, simplejson.loads(resp.content)) + self.assertEqual(resp.status_code, 200) + self.assertEqual({'type': 'plain', 'field': 'a field'}, simplejson.loads(resp.content)) class ListFieldsTest(MainTests): def init_delegate(self): @@ -404,8 +404,8 @@ def test_single_item(self): "variety": "apple" }''' resp = self.client.get('/api/list_fields/1') - self.assertEquals(resp.status_code, 200) - self.assertEquals(resp.content, expect) + self.assertEqual(resp.status_code, 200) + self.assertEqual(resp.content, expect) def test_multiple_items(self): @@ -424,22 +424,22 @@ def test_multiple_items(self): } ]''' resp = self.client.get('/api/list_fields') - self.assertEquals(resp.status_code, 200) - self.assertEquals(resp.content, expect) + self.assertEqual(resp.status_code, 200) + self.assertEqual(resp.content, expect) class ErrorHandlingTests(MainTests): """Test proper handling of errors by Resource""" def test_response_not_allowed(self): resp = self.client.post('/api/echo') - self.assertEquals(resp.status_code, 405) - self.assertEquals(resp['Allow'], 'GET, HEAD') + self.assertEqual(resp.status_code, 405) + self.assertEqual(resp['Allow'], 'GET, HEAD') def test_not_found_because_of_unexpected_http_method(self): # not using self.client.head because it is not present in Django 1.0 resp = self.client.get('/api/echo', REQUEST_METHOD='HEAD') - self.assertEquals(resp.status_code, 404) - self.assertEquals(resp.content, '') + self.assertEqual(resp.status_code, 404) + self.assertEqual(resp.content, '') class Issue58ModelTests(MainTests): @@ -471,9 +471,9 @@ def test_incoming_json(self): # test GET result = self.client.get('/api/issue58.json', HTTP_AUTHORIZATION=self.auth_string).content - self.assertEquals(result, expected) + self.assertEqual(result, expected) # test POST resp = self.client.post('/api/issue58.json', outgoing, content_type='application/json', HTTP_AUTHORIZATION=self.auth_string) - self.assertEquals(resp.status_code, 201) + self.assertEqual(resp.status_code, 201)