Skip to content

Commit

Permalink
dropped python 2; django 1.11/2.0/2.1 support. added django 3.0 to tox
Browse files Browse the repository at this point in the history
  • Loading branch information
roman-karpovich committed Jul 16, 2020
1 parent 33b2e20 commit de66531
Show file tree
Hide file tree
Showing 22 changed files with 139 additions and 55 deletions.
19 changes: 19 additions & 0 deletions .flake8
@@ -0,0 +1,19 @@
[flake8]
max-line-length = 120
ignore =
; PyFlakes errors
; F405 name may be undefined, or defined from star imports: module
; DUO130 insecure use of "hashlib" module
DUO130
F405
W503
S105
S107
S303
P103



exclude =
*/migrations
./.tox
10 changes: 10 additions & 0 deletions .isort.cfg
@@ -0,0 +1,10 @@
[settings]
line_length=120
multi_line_output=3
include_trailing_comma=true
balanced_wrapping=true
skip=.tox,migrations,deployer,wsgi.py

known_django=django
known_rest=rest_framework
sections=FUTURE,STDLIB,DJANGO,REST,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
3 changes: 2 additions & 1 deletion .travis.yml
Expand Up @@ -4,7 +4,8 @@ python:
- "2.7"
- "3.5"
- "3.6"
- "3.7-dev"
- "3.7"
- "3.8"
install:
- pip install .
- pip install tox tox-travis coverage coveralls
Expand Down
2 changes: 1 addition & 1 deletion drf_batch_example/urls.py
@@ -1,6 +1,6 @@
try:
from django.conf.urls import url
except:
except ImportError:
# django 2.0
from django.urls import re_path as url

Expand Down
1 change: 1 addition & 0 deletions drf_batch_example/views.py
@@ -1,4 +1,5 @@
from django.http import JsonResponse

from rest_framework.views import APIView


Expand Down
1 change: 1 addition & 0 deletions drf_batch_requests/backends/sync.py
@@ -1,4 +1,5 @@
from django.core.handlers.base import BaseHandler

from rest_framework.status import is_success

from drf_batch_requests.backends.base import RequestsConsumeBaseBackend
Expand Down
6 changes: 4 additions & 2 deletions drf_batch_requests/graph.py
Expand Up @@ -25,8 +25,10 @@ def fail(self, own_fail=True):

@property
def can_be_performed(self):
return self.status == RequestGraphNode.STATUS_NOT_STARTED and \
all(map(lambda parent: parent.status == RequestGraphNode.STATUS_COMPLETED, self.parents))
if not self.status == RequestGraphNode.STATUS_NOT_STARTED:
return False

return all(map(lambda parent: parent.status == RequestGraphNode.STATUS_COMPLETED, self.parents))

def __str__(self):
return self.name or super(RequestGraphNode, self).__str__()
Expand Down
19 changes: 10 additions & 9 deletions drf_batch_requests/request.py
@@ -1,12 +1,12 @@
import json
import re
from io import BytesIO
from urllib.parse import urlsplit

from django.http import HttpRequest
from django.http.request import QueryDict
from django.utils import six
from django.utils.encoding import force_text
from django.utils.six import BytesIO
from django.utils.six.moves.urllib.parse import urlsplit

from rest_framework.exceptions import ValidationError

from drf_batch_requests.exceptions import RequestAttributeError
Expand Down Expand Up @@ -67,15 +67,16 @@ def _prepare_formdata_body(self, data, files=None):
boundary = match.groupdict()['boundary']
body = ''
for key, value in data.items():
value = value if isinstance(value, six.string_types) else json.dumps(value)
value = value if isinstance(value, str) else json.dumps(value)
body += '--{}\r\nContent-Disposition: form-data; name="{}"\r\n\r\n{}\r\n'.format(boundary, key, value)

if files:
for key, attachment in files.items():
attachment.seek(0)
body += '--{}\r\nContent-Disposition: form-data; name="{}"; filename="{}"\r\n' \
'Content-Type: {}\r\n' \
'Content-Transfer-Encoding: binary\r\n\r\n{}\r\n'.format(
attachment_body_part = '--{0}\r\nContent-Disposition: form-data; name="{1}"; filename="{2}"\r\n' \
'Content-Type: {3}\r\n' \
'Content-Transfer-Encoding: binary\r\n\r\n{4}\r\n'
body += attachment_body_part.format(
boundary, key, attachment.name, attachment.content_type, attachment.read()
)

Expand Down Expand Up @@ -108,7 +109,7 @@ def _process_attr(self, attr):
raise RequestAttributeError('Empty result for {}'.format(url_param[2]))

if isinstance(result, list):
result = ','.join(map(six.text_type, result))
result = ','.join(map(str, result))

if attr == url_param[0]:
attr = result
Expand All @@ -126,7 +127,7 @@ def updated_obj(self, obj):
if isinstance(obj, dict):
for key, value in obj.items():
obj[key] = self.updated_obj(value)
elif isinstance(obj, six.string_types):
elif isinstance(obj, str):
return self._process_attr(obj)

return obj
Expand Down
5 changes: 2 additions & 3 deletions drf_batch_requests/serializers.py
@@ -1,7 +1,6 @@
import json

from django.core.files import File
from django.utils import six

from rest_framework import serializers
from rest_framework.exceptions import ValidationError
Expand Down Expand Up @@ -43,10 +42,10 @@ def validate(self, attrs):

if 'depends_on' in attrs:
value = attrs['depends_on']
if not isinstance(value, (six.string_types, list)):
if not isinstance(value, (str, list)):
raise ValidationError({'depends_on': 'Incorrect value provided'})

if isinstance(value, six.string_types):
if isinstance(value, str):
attrs['depends_on'] = [value]

return attrs
Expand Down
2 changes: 1 addition & 1 deletion drf_batch_requests/urls.py
@@ -1,6 +1,6 @@
try:
from django.conf.urls import url
except:
except ImportError:
# django 2.0
from django.urls import re_path as url

Expand Down
2 changes: 1 addition & 1 deletion drf_batch_requests/utils.py
Expand Up @@ -33,4 +33,4 @@ def callback():
else:
raise NotImplementedError

return callback
return callback
15 changes: 8 additions & 7 deletions drf_batch_requests/views.py
@@ -1,22 +1,23 @@
import json
from importlib import import_module

try:
from json import JSONDecodeError
except ImportError:
JSONDecodeError = ValueError

from django.db import transaction

from rest_framework.response import Response
from rest_framework.status import is_success
from rest_framework.views import APIView

from drf_batch_requests import settings as app_settings
from drf_batch_requests.exceptions import RequestAttributeError
from drf_batch_requests.graph import RequestGraph
from drf_batch_requests.request import BatchRequestsFactory
from drf_batch_requests import settings as app_settings
from drf_batch_requests.utils import generate_node_callback

try:
from json import JSONDecodeError
except ImportError:
JSONDecodeError = ValueError


class BatchView(APIView):
permission_classes = []
Expand Down Expand Up @@ -47,7 +48,7 @@ def post(self, request, *args, **kwargs):
for node in available_nodes:
try:
current_request = requests_factory.generate_request(node.request)
except RequestAttributeError as ex:
except RequestAttributeError:
# todo: set fail reason
node.fail()

Expand Down
27 changes: 22 additions & 5 deletions drf_batch_settings/settings.py
Expand Up @@ -23,13 +23,31 @@
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

TEMPLATE_DEBUG = True

ALLOWED_HOSTS = []


# Application definition
# Template configurations
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'OPTIONS': {

'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
'loaders': [
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
],
},
},
]

# Application definition
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
Expand All @@ -41,12 +59,11 @@
'drf_batch_example'
)

MIDDLEWARE_CLASSES = (
MIDDLEWARE = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
Expand Down
7 changes: 4 additions & 3 deletions drf_batch_settings/urls.py
@@ -1,8 +1,9 @@
try:
from django.conf.urls import url, include
except:
from django.conf.urls import include, url
except ImportError:
# django 2.0
from django.urls import re_path as url, include
from django.urls import include
from django.urls import re_path as url

urlpatterns = [
url(r'^batch/', include('drf_batch_requests.urls', namespace='drf_batch')),
Expand Down
1 change: 0 additions & 1 deletion runtests.py
Expand Up @@ -6,7 +6,6 @@
from django.conf import settings
from django.test.utils import get_runner


if __name__ == '__main__':
os.environ['DJANGO_SETTINGS_MODULE'] = 'tests.test_settings'
django.setup()
Expand Down
9 changes: 4 additions & 5 deletions setup.py
Expand Up @@ -10,7 +10,7 @@

setup(
name='drf-batch-requests',
version='0.8.11',
version='0.9.0',
packages=['drf_batch_requests', ],
include_package_data=True,
license='MIT License',
Expand All @@ -21,7 +21,7 @@
author='Roman Karpovich',
author_email='fpm.th13f@gmail.com',
install_requires=[
'django>=1.9',
'django>=2.2',
'djangorestframework',
],
classifiers=[
Expand All @@ -32,11 +32,10 @@
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Topic :: Internet :: WWW/HTTP',
'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
],
Expand Down
4 changes: 3 additions & 1 deletion tests/mixins.py
Expand Up @@ -3,7 +3,9 @@
except ImportError:
from django.core.urlresolvers import resolve

from rest_framework.test import APITestCase as OriginalAPITestCase, APIRequestFactory, force_authenticate
from rest_framework.test import APIRequestFactory
from rest_framework.test import APITestCase as OriginalAPITestCase
from rest_framework.test import force_authenticate


class APITestCase(OriginalAPITestCase):
Expand Down
31 changes: 29 additions & 2 deletions tests/test_settings.py
@@ -1,21 +1,48 @@
import os


BASE_DIR = os.path.dirname(os.path.abspath(__file__))


SECRET_KEY = 'secret-key'

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'OPTIONS': {

'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
'loaders': [
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
],
},
},
]

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',

'django.contrib.messages',
'drf_batch_requests',
'tests',
]

MIDDLEWARE = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)


DATABASES = {
'default': {
Expand Down
1 change: 1 addition & 0 deletions tests/test_view.py
@@ -1,6 +1,7 @@
import json

from django.core.files.uploadedfile import SimpleUploadedFile

from rest_framework import status

from tests.mixins import APITestCase
Expand Down
4 changes: 2 additions & 2 deletions tests/urls.py
@@ -1,6 +1,6 @@
try:
from django.conf.urls import url, include
except:
from django.conf.urls import include, url
except ImportError:
# django 2.0
from django.urls import re_path as url, include

Expand Down
1 change: 1 addition & 0 deletions tests/views.py
@@ -1,6 +1,7 @@
from django.http import JsonResponse
from django.http.response import HttpResponse as DjangoResponse
from django.views.generic import View

from rest_framework.response import Response
from rest_framework.views import APIView

Expand Down

0 comments on commit de66531

Please sign in to comment.