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

Remove py27 support #1050

Merged
merged 27 commits into from
Feb 16, 2017
Merged
Show file tree
Hide file tree
Changes from 17 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
13 changes: 3 additions & 10 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
dist: trusty
language: python
python: 2.7
python: 3.5
cache: pip
services: redis-server
addons:
postgresql: "9.5"
env:
- TOX_ENV=py27
- TOX_ENV=py34
- TOX_ENV=py27-raw
- TOX_ENV=py35
- TOX_ENV=py35-raw
- TOX_ENV=flake8
- TOX_ENV=docs
install:
Expand All @@ -31,9 +30,3 @@ matrix:
- python: 3.6
env:
- TOX_ENV=py36
- env: ACTION=loadtest_tutorial
before_script: echo 'Tutorial'
script: make loadtest-check-tutorial
- env: ACTION=loadtest_simulation
before_script: echo 'Simulation'
script: make loadtest-check-simulation
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ This document describes changes between each past release.

- Update the upsert query to use an INSERT or UPDATE on CONFLICT behavior (fixes #1055)
- Remove pypy supports. (#1049)
- Remove Python 2.7 support. (#1050)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a big breaking change!



5.3.2 (2017-01-31)
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
SERVER_CONFIG = config/kinto.ini

VIRTUALENV = virtualenv
VIRTUALENV = virtualenv --python=python3
SPHINX_BUILDDIR = docs/_build
VENV := $(shell echo $${VIRTUAL_ENV-.venv})
PYTHON = $(VENV)/bin/python
PYTHON = $(VENV)/bin/python3
DEV_STAMP = $(VENV)/.dev_env_installed.stamp
DOC_STAMP = $(VENV)/.doc_env_installed.stamp
INSTALL_STAMP = $(VENV)/.install.stamp
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,5 @@ Kinto is a minimalist JSON storage service with synchronisation and sharing abil
Requirements
------------

* **Python**: 2.7, 3.4+
* **Python**: 3.5+
* **Backends**: In-memory (development), Postgresql 9.5+ (production)
4 changes: 2 additions & 2 deletions docs/api/1.x/collections.rst
Original file line number Diff line number Diff line change
Expand Up @@ -598,14 +598,14 @@ Once a schema has been defined, the posted records must match it:
"code": 400,
"details": [
{
"description": "u'title' is a required property",
"description": "'title' is a required property",
"location": "body",
"name": "title"
}
],
"errno": 107,
"error": "Invalid parameters",
"message": "u'title' is a required property"
"message": "'title' is a required property"
}


Expand Down
17 changes: 8 additions & 9 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
#
# Kinto documentation build configuration file, created by
# sphinx-quickstart on Mon Feb 2 15:08:06 2015.
Expand Down Expand Up @@ -64,8 +63,8 @@
master_doc = 'index'

# General information about the project.
project = u'Kinto'
copyright = u'2015-2017 — Mozilla Services'
project = 'Kinto'
copyright = '2015-2017 — Mozilla Services'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
Expand Down Expand Up @@ -175,8 +174,8 @@ def setup(app):
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
('index', 'Kinto.tex', u'Kinto Documentation',
u'Mozilla Services — Da French Team', 'manual'),
('index', 'Kinto.tex', 'Kinto Documentation',
'Mozilla Services — Da French Team', 'manual'),
]


Expand All @@ -185,8 +184,8 @@ def setup(app):
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'kinto', u'Kinto Documentation',
[u'Mozilla Services — Da French Team'], 1)
('index', 'kinto', 'Kinto Documentation',
['Mozilla Services — Da French Team'], 1)
]


Expand All @@ -196,8 +195,8 @@ def setup(app):
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
('index', 'Kinto', u'Kinto Documentation',
u'Mozilla Services — Da French Team', 'Kinto',
('index', 'Kinto', 'Kinto Documentation',
'Mozilla Services — Da French Team', 'Kinto',
'A remote storage service with syncing and sharing abilities.',
'Miscellaneous'),
]
4 changes: 2 additions & 2 deletions docs/core/notifications.rst
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ Example, when deleting a collection with two records:
::

>>> event.impacted_records
[{'old': {'deleted': True, 'last_modified': 1447240896769, 'id': u'a1f4af60-ddf5-4c49-933f-4cfeff18ad07'}},
{'old': {'deleted': True, 'last_modified': 1447240896770, 'id': u'7a6916aa-0ea1-42a7-9741-c24fe13cb70b'}}]
[{'old': {'deleted': True, 'last_modified': 1447240896769, 'id': 'a1f4af60-ddf5-4c49-933f-4cfeff18ad07'}},
{'old': {'deleted': True, 'last_modified': 1447240896770, 'id': '7a6916aa-0ea1-42a7-9741-c24fe13cb70b'}}]


Event listeners
Expand Down
8 changes: 4 additions & 4 deletions docs/core/permission.rst
Original file line number Diff line number Diff line change
Expand Up @@ -294,15 +294,15 @@ on the resource during registration.
class MyViewSet(resource.ViewSet):

def get_view_arguments(self, endpoint_type, resource_cls, method):
args = super(MyViewSet, self).get_view_arguments(endpoint_type,
args = super().get_view_arguments(endpoint_type,
resource_cls,
method)
if method.lower() not in ('get', 'head'):
args['permission'] = 'publish'
return args

def get_service_arguments(self):
args = super(MyViewSet, self).get_service_arguments()
args = super().get_service_arguments()
args['factory'] = myapp.MyRootFactory
return args

Expand All @@ -323,7 +323,7 @@ For example, a simplistic example with the previous resource viewset:

from pyramid.security import IAuthorizationPolicy

class MyRootFactory(object):
class MyRootFactory:
def __init__(self, request):
self.current_resource = None
service = request.current_service
Expand All @@ -332,7 +332,7 @@ For example, a simplistic example with the previous resource viewset:


@implementer(IAuthorizationPolicy)
class AuthorizationPolicy(object):
class AuthorizationPolicy:
def permits(self, context, principals, permission):
if context.current_resource == BlogArticle:
if permission == 'publish':
Expand Down
6 changes: 3 additions & 3 deletions docs/core/resource.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Full example
schema = BookmarkSchema

def process_record(self, new, old=None):
new = super(Bookmark, self).process_record(new, old)
new = super().process_record(new, old)
if new['device'] != old['device']:
new['device'] = self.request.headers.get('User-Agent')

Expand Down Expand Up @@ -136,7 +136,7 @@ a custom model can be plugged-in:

class TrackedModel(resource.Model):
def create_record(self, record, parent_id=None):
record = super(TrackedModel, self).create_record(record, parent_id)
record = super().create_record(record, parent_id)
trackid = index.track(record)
record['trackid'] = trackid
return record
Expand Down Expand Up @@ -241,7 +241,7 @@ or at the resource level:
@resource.register()
class Mushroom(resource.UserResource):
def __init__(request):
super(Mushroom, self).__init__(request)
super().__init__(request)
self.model.id_generator = MsecId()


Expand Down
1 change: 0 additions & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@ kinto-redis
mock
webtest
cornice
enum
pyramid
2 changes: 1 addition & 1 deletion docs/tutorials/notifications-custom.rst
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,6 @@ But 2 seconds later, look at the worker output:

::

{u'resource_name': u'record', u'user_id': u'basicauth:fea1e21d339299506d89e60f048cefd5b424ea641ba48267c35a4ce921439fa4', u'timestamp': 1453459942672, u'uri': u'/buckets/c8c94a74-5bf6-9fb0-5b72-b0777da6718e/collections/assets/records', u'bucket_id': u'c8c94a74-5bf6-9fb0-5b72-b0777da6718e', u'action': u'create', u'collection_id': u'assets'}
{'resource_name': 'record', 'user_id': 'basicauth:fea1e21d339299506d89e60f048cefd5b424ea641ba48267c35a4ce921439fa4', 'timestamp': 1453459942672, 'uri': '/buckets/c8c94a74-5bf6-9fb0-5b72-b0777da6718e/collections/assets/records', 'bucket_id': 'c8c94a74-5bf6-9fb0-5b72-b0777da6718e', 'action': 'create', 'collection_id': 'assets'}

It worked!
2 changes: 1 addition & 1 deletion docs/tutorials/write-plugin.rst
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ It is a wrapper basically, and the code is kept simple for the simplicity of thi

import elasticsearch

class Indexer(object):
class Indexer:
def __init__(self, hosts):
self.client = elasticsearch.Elasticsearch(hosts)

Expand Down
1 change: 0 additions & 1 deletion kinto/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import sys
import logging
import logging.config
from six.moves import input

from kinto.core import scripts
from pyramid.scripts import pserve
Expand Down
3 changes: 1 addition & 2 deletions kinto/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ def init(config_file, backend, host='127.0.0.1'):
values['secret'] = core_utils.random_bytes_hex(32)

values['kinto_version'] = __version__
values['config_file_timestamp'] = core_utils._encoded(
strftime('%a, %d %b %Y %H:%M:%S %z'))
values['config_file_timestamp'] = str(strftime('%a, %d %b %Y %H:%M:%S %z'))

values['storage_backend'] = "kinto.core.storage.%s" % backend
values['cache_backend'] = "kinto.core.cache.%s" % backend
Expand Down
4 changes: 1 addition & 3 deletions kinto/core/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ class BasicAuthAuthenticationPolicy(base_auth.BasicAuthAuthenticationPolicy):
def __init__(self, *args, **kwargs):
def noop_check(*a):
return []
super(BasicAuthAuthenticationPolicy, self).__init__(noop_check,
*args,
**kwargs)
super().__init__(noop_check, *args, **kwargs)

def effective_principals(self, request):
# Bypass default Pyramid construction of principals because
Expand Down
10 changes: 4 additions & 6 deletions kinto/core/authorization.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import functools

import six
from pyramid.settings import aslist
from pyramid.security import IAuthorizationPolicy, Authenticated
from zope.interface import implementer
Expand Down Expand Up @@ -40,7 +39,7 @@ def groupfinder(userid, request):


@implementer(IAuthorizationPolicy)
class AuthorizationPolicy(object):
class AuthorizationPolicy:
"""Default authorization class, that leverages the permission backend
for shareable resources.
"""
Expand Down Expand Up @@ -107,7 +106,7 @@ def principals_allowed_by_permission(self, context, permission):
raise NotImplementedError() # PRAGMA NOCOVER


class RouteFactory(object):
class RouteFactory:
resource_name = None
on_collection = False
required_permission = None
Expand Down Expand Up @@ -209,8 +208,7 @@ def get_permission_object_id(self, request, object_id=None):
# With the current request on a collection, the record URI must
# be found out by inspecting the collection service and its sibling
# record service.
matchdict = request.matchdict.copy()
matchdict['id'] = object_id
matchdict = {**request.matchdict, 'id': object_id}
try:
object_uri = utils.instance_uri(request,
self.resource_name,
Expand Down Expand Up @@ -242,7 +240,7 @@ def _find_required_permission(self, request, service):
required_permission = self.method_permissions.get(method)

# For create permission, the object id is the plural endpoint.
collection_path = six.text_type(service.collection_path)
collection_path = str(service.collection_path)
collection_path = collection_path.format(**request.matchdict)

# In the case of a "PUT", check if the targetted record already
Expand Down
2 changes: 1 addition & 1 deletion kinto/core/cache/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
_HEARTBEAT_TTL_SECONDS = 3600


class CacheBase(object):
class CacheBase:

def __init__(self, *args, **kwargs):
self.prefix = kwargs['cache_prefix']
Expand Down
2 changes: 1 addition & 1 deletion kinto/core/cache/memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class Cache(CacheBase):
"""

def __init__(self, *args, **kwargs):
super(Cache, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self.flush()

def initialize_schema(self, dry_run=False):
Expand Down
2 changes: 1 addition & 1 deletion kinto/core/cache/postgresql/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class Cache(CacheBase):
:noindex:
""" # NOQA
def __init__(self, client, *args, **kwargs):
super(Cache, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self.client = client

def initialize_schema(self, dry_run=False):
Expand Down
8 changes: 4 additions & 4 deletions kinto/core/cache/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
from kinto.core.cache import heartbeat


class CacheTest(object):
class CacheTest:
backend = None
settings = {}

def setUp(self):
super(CacheTest, self).setUp()
super().setUp()
self.cache = self.backend.load_from_config(self._get_config())
self.cache.initialize_schema()
self.request = None
Expand All @@ -29,11 +29,11 @@ def _get_config(self, settings=None):

def tearDown(self):
mock.patch.stopall()
super(CacheTest, self).tearDown()
super().tearDown()
self.cache.flush()

def get_backend_prefix(self, prefix):
settings_prefix = self.settings.copy()
settings_prefix = {**self.settings}
settings_prefix['cache_prefix'] = prefix
config_prefix = self._get_config(settings=settings_prefix)

Expand Down
2 changes: 1 addition & 1 deletion kinto/core/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from pyramid.response import Response


class cache_forever(object):
class cache_forever:
def __init__(self, wrapped):
self.wrapped = wrapped
self.saved = None
Expand Down
11 changes: 5 additions & 6 deletions kinto/core/errors.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import six
from pyramid import httpexceptions
from enum import Enum

from kinto.core.logs import logger
from kinto.core.utils import json, reapply_cors, encode_header
from kinto.core.utils import json, reapply_cors


class ERRORS(Enum):
Expand Down Expand Up @@ -132,13 +131,13 @@ def json_error_handler(request):
(c.f. HTTP API).
"""
errors = request.errors
sorted_errors = sorted(errors, key=lambda x: six.text_type(x['name']))
sorted_errors = sorted(errors, key=lambda x: str(x['name']))
# In Cornice, we call error handler if at least one error was set.
error = sorted_errors[0]
name = error['name']
description = error['description']

if isinstance(description, six.binary_type):
if isinstance(description, bytes):
description = error['description'].decode('utf-8')

if name is not None:
Expand Down Expand Up @@ -185,8 +184,8 @@ def send_alert(request, message=None, url=None, code='soft-eol'):
if url is None:
url = request.registry.settings['project_docs']

request.response.headers['Alert'] = encode_header(json.dumps({
request.response.headers['Alert'] = json.dumps({
'code': code,
'message': message,
'url': url
}))
})
Loading