From 614273039986e69e60d0d74e7867c25893432ed3 Mon Sep 17 00:00:00 2001 From: "luca.ebach" Date: Wed, 11 Nov 2020 15:22:58 +0100 Subject: [PATCH] make python3 compatible --- flask_negotiation/__init__.py | 12 ++++++----- flask_negotiation/decorators.py | 8 ++++--- flask_negotiation/media_type.py | 32 ++++++++++++++++----------- flask_negotiation/renderers.py | 9 +++++--- setup.py | 3 ++- tests/test_negotiation.py | 38 ++++++++++++++++----------------- 6 files changed, 58 insertions(+), 44 deletions(-) diff --git a/flask_negotiation/__init__.py b/flask_negotiation/__init__.py index 1429139..5e30c90 100644 --- a/flask_negotiation/__init__.py +++ b/flask_negotiation/__init__.py @@ -3,11 +3,13 @@ Provides better content-negotiation for flask. """ +from __future__ import absolute_import + from flask import Response, request, abort -from renderers import TemplateRenderer -from decorators import provides -from media_type import acceptable_media_types, best_renderer, MediaType +from .renderers import TemplateRenderer +from .decorators import provides +from .media_type import acceptable_media_types, best_renderer, MediaType __all__ = ('Render', 'MediaType', 'provides') @@ -74,5 +76,5 @@ def content_view(): if renderer is None: abort(406) body = renderer.render(data, template, ctx) - return Response(body, status, headers, unicode(rendered_media_type), - content_type=unicode(rendered_media_type)) + return Response(body, status, headers, str(rendered_media_type), + content_type=str(rendered_media_type)) diff --git a/flask_negotiation/decorators.py b/flask_negotiation/decorators.py index b306df2..930b00b 100644 --- a/flask_negotiation/decorators.py +++ b/flask_negotiation/decorators.py @@ -1,13 +1,15 @@ """:mod:`decorators` --- Decorators for Flask views =================================================== """ +from __future__ import absolute_import + from functools import wraps from flask import request from werkzeug.exceptions import NotAcceptable -from renderers import Renderer -from media_type import acceptable_media_types, MediaType, choose_media_type +from .renderers import Renderer +from .media_type import acceptable_media_types, MediaType, choose_media_type def provides(media_type, *args, **kwargs): @@ -58,7 +60,7 @@ def handle_type(provide_type): if isinstance(media_type, MediaType): media_types.append(media_type) elif isinstance(media_type, type) and issubclass(media_type, Renderer): - media_types += map(MediaType, media_type.__media_types__) + media_types += list(map(MediaType, media_type.__media_types__)) elif isinstance(media_type, Renderer): media_types += media_type.media_types else: diff --git a/flask_negotiation/media_type.py b/flask_negotiation/media_type.py index c4200ba..09dff6a 100644 --- a/flask_negotiation/media_type.py +++ b/flask_negotiation/media_type.py @@ -4,6 +4,7 @@ HTTP media type """ +from functools import cmp_to_key def parse_header(s): """Parses parameter header @@ -47,7 +48,7 @@ def __init__(self, raw): self.main_type, sep, self.sub_type = self.media_type.partition('/') def __contains__(self, other): - for k, v in self.params.iteritems(): + for k, v in self.params.items(): if k != 'q' and other.params.get(k, None) != v: return False if self.main_type == '*' and self.sub_type == '*': @@ -59,8 +60,8 @@ def __contains__(self, other): return self == other def __eq__(self, other): - if isinstance(other, basestring): - return unicode(self) == other + if isinstance(other, str): + return str(self) == other return (self.main_type == other.main_type and self.sub_type == other.sub_type) @@ -68,16 +69,15 @@ def __repr__(self): return '' def __str__(self): - return unicode(self).encode('utf-8') + return '; '.join(['%s/%s' % (self.main_type, self.sub_type)] + + ['%s=%s' % (k, v) + for k, v in self.params.items()]) - def __unicode__(self): - return u'; '.join([u'%s/%s' % (self.main_type, self.sub_type)] + - [u'%s=%s' % (k, v) - for k, v in self.params.iteritems()]) + def __lt__(self, other): + return float(self.quality) < float(other.quality) - def __cmp__(self, other): - return cmp(float(self.quality), - float(other.quality)) + def __gt__(self, other): + return float(self.quality) > float(other.quality) @property def quality(self): @@ -110,6 +110,9 @@ def best_renderer(renderers, media_types): if not choosen_items: return None, None + def cmp(first, second): + return first - second + def cmp_types(first, second): renderer1, choosen1, media_type1 = first renderer2, choosen2, media_type2 = second @@ -120,7 +123,7 @@ def cmp_types(first, second): media_types.index(media_type1)) return cmp(media_type1.quality, media_type2.quality) - return tuple(sorted(choosen_items, cmp=cmp_types)[-1][:2]) + return tuple(sorted(choosen_items, key=cmp_to_key(cmp_types))[-1][:2]) def choose_media_type(acceptables, media_types): @@ -138,6 +141,9 @@ def choose_media_type(acceptables, media_types): if not choosen: return None + def cmp(first, second): + return first - second + def cmp_types(first, second): acceptable1, media_type1 = first acceptable2, media_type2 = second @@ -146,7 +152,7 @@ def cmp_types(first, second): acceptables.index(acceptable1)) return cmp(acceptable.quality, acceptable.quality) - return sorted(choosen, cmp=cmp_types)[-1][0] + return sorted(choosen, key=cmp_to_key(cmp_types))[-1][0] def can_accept(acceptables, media_types): diff --git a/flask_negotiation/renderers.py b/flask_negotiation/renderers.py index 4abc482..aa17d9d 100644 --- a/flask_negotiation/renderers.py +++ b/flask_negotiation/renderers.py @@ -3,17 +3,20 @@ Renderers """ +from __future__ import absolute_import + import json +import six from abc import ABCMeta, abstractmethod from flask import render_template from functools import wraps -from media_type import MediaType +from .media_type import MediaType +@six.add_metaclass(ABCMeta) class Renderer(object): """Base renderer class. """ - __metaclass__ = ABCMeta __media_types__ = () """A collection of supporting media-type :class:`string`s, subclasses must @@ -90,7 +93,7 @@ class FunctionRenderer(Renderer): def __init__(self, fn, media_types): super(FunctionRenderer, self).__init__() self.fn = fn - self.__media_types__ = map(unicode, media_types) + self.__media_types__ = list(map(str, media_types)) def render(self, data, template=None, ctx=None): return self.fn(data, template=template, ctx=ctx) diff --git a/setup.py b/setup.py index d9e78f9..dab9385 100644 --- a/setup.py +++ b/setup.py @@ -9,10 +9,11 @@ requires = [ 'Flask', + 'six' ] setup(name='Flask-Negotiation', - version='0.1.9', + version='0.1.10', url='http://blog.hardtack.me/', author='GunWoo Choi', author_email='6566gun@gmail.com', diff --git a/tests/test_negotiation.py b/tests/test_negotiation.py index a6a30f9..0f0eec6 100644 --- a/tests/test_negotiation.py +++ b/tests/test_negotiation.py @@ -95,14 +95,14 @@ def second(): } rv = client.get('/render', headers=headers) assert 200 == rv.status_code - assert 'value' == rv.data + assert b'value' == rv.data headers = { 'Accept': 'application/json; q=0.7, text/html; q=0.8' } rv = client.get('/render', headers=headers) assert 200 == rv.status_code - assert 'value' == rv.data + assert b'value' == rv.data headers = { 'Accept': 'application/json; q=0.7, text/html; q=0.8' @@ -187,12 +187,12 @@ def fifth(provide_type): headers = { 'Accept': 'application/json' } - assert 'application/json' == client.get('/5', headers=headers).data + assert b'application/json' == client.get('/5', headers=headers).data headers = { 'Accept': 'text/html' } - assert 'text/html' == client.get('/5', headers=headers).data + assert b'text/html' == client.get('/5', headers=headers).data def test_media_type(): @@ -229,7 +229,7 @@ def test_acceptablility(): assert can_accept(acceptables, media_types) # Partitial wildcard - media_types = map(MediaType, ['text/*']) + media_types = list(map(MediaType, ['text/*'])) acceptables = map(MediaType, ['application/json']) assert not can_accept(acceptables, media_types) @@ -237,31 +237,31 @@ def test_acceptablility(): assert can_accept(acceptables, media_types) # Multiple acceptables - media_types = map(MediaType, ['text/html']) - acceptables = map(MediaType, ['application/json', 'text/html']) + media_types = list(map(MediaType, ['text/html'])) + acceptables = list(map(MediaType, ['application/json', 'text/html'])) assert can_accept(acceptables, media_types) - media_types = map(MediaType, ['image/jpeg']) - acceptables = map(MediaType, ['application/json', 'text/html']) + media_types = list(map(MediaType, ['image/jpeg'])) + acceptables = list(map(MediaType, ['application/json', 'text/html'])) assert not can_accept(acceptables, media_types) # Multiple media types - media_types = map(MediaType, ['text/*', 'application/json']) - acceptables = map(MediaType, ['application/json']) + media_types = list(map(MediaType, ['text/*', 'application/json'])) + acceptables = list(map(MediaType, ['application/json'])) assert can_accept(acceptables, media_types) - acceptables = map(MediaType, ['text/html']) + acceptables = list(map(MediaType, ['text/html'])) assert can_accept(acceptables, media_types) - acceptables = map(MediaType, ['image/jpeg']) + acceptables = list(map(MediaType, ['image/jpeg'])) assert not can_accept(acceptables, media_types) # Multiple both - media_types = map(MediaType, ['text/html', 'application/*']) - acceptables = map(MediaType, ['application/json', 'image/jpeg']) + media_types = list(map(MediaType, ['text/html', 'application/*'])) + acceptables = list(map(MediaType, ['application/json', 'image/jpeg'])) assert can_accept(acceptables, media_types) - media_types = map(MediaType, ['text/html', 'application/*']) - acceptables = map(MediaType, ['image/png', 'image/jpeg']) + media_types = list(map(MediaType, ['text/html', 'application/*'])) + acceptables = list(map(MediaType, ['image/png', 'image/jpeg'])) assert not can_accept(acceptables, media_types) @@ -278,10 +278,10 @@ def test_choosing(): assert png_type == choose_media_type( [png_type, jpeg_type], - map(MediaType, ['text/html', 'application/*', 'image/*']) + list(map(MediaType, ['text/html', 'application/*', 'image/*'])) ) assert html_type == choose_media_type( [json_type, html_type], - map(MediaType, ['text/html', 'application/*']) + list(map(MediaType, ['text/html', 'application/*'])) )