Skip to content

Commit 5967940

Browse files
committed
Inject base class in favor of separate new metho
1 parent 4df350a commit 5967940

File tree

5 files changed

+24
-21
lines changed

5 files changed

+24
-21
lines changed

s3file/apps.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ def ready(self):
1111

1212
if isinstance(default_storage, S3Boto3Storage):
1313
from django import forms
14-
from .forms import S3FileInput
14+
from .forms import S3FileInputMixin
1515

16-
forms.ClearableFileInput.__new__ = \
17-
lambda cls, *args, **kwargs: object.__new__(S3FileInput)
16+
if S3FileInputMixin not in forms.ClearableFileInput.__bases__:
17+
forms.ClearableFileInput.__bases__ = \
18+
(S3FileInputMixin,) + forms.ClearableFileInput.__bases__

s3file/forms.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
logger = logging.getLogger('s3file')
1111

1212

13-
class S3FileInput(ClearableFileInput):
13+
class S3FileInputMixin:
1414
"""FileInput that uses JavaScript to directly upload to Amazon S3."""
1515

1616
needs_multipart_form = False
@@ -26,7 +26,7 @@ def client(self):
2626
return default_storage.connection.meta.client
2727

2828
def build_attrs(self, *args, **kwargs):
29-
attrs = super(S3FileInput, self).build_attrs(*args, **kwargs)
29+
attrs = super().build_attrs(*args, **kwargs)
3030

3131
mime_type = attrs.get('accept', None)
3232
response = self.client.generate_presigned_post(
@@ -75,5 +75,4 @@ def upload_folder(self):
7575
class Media:
7676
js = (
7777
's3file/js/s3file.js',
78-
7978
)

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
setup(
55
name='django-s3file',
6-
version='3.0.0',
6+
version='3.0.1',
77
description='A lightweight file uploader input for Django and Amazon S3',
88
author='codingjoe',
99
url='https://github.com/codingjoe/django-s3file',

tests/test_apps.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
from django import forms
44

55
from s3file.apps import S3FileConfig
6-
from s3file.forms import S3FileInput
6+
from s3file.forms import S3FileInputMixin
77

88

99
class TestS3FileConfig:
1010
def test_ready(self, settings):
1111
app = S3FileConfig('s3file', importlib.import_module('tests.testapp'))
1212
app.ready()
13-
assert not isinstance(forms.ClearableFileInput(), S3FileInput)
13+
assert not isinstance(forms.ClearableFileInput(), S3FileInputMixin)
1414
settings.DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
1515
app.ready()
16-
assert isinstance(forms.ClearableFileInput(), S3FileInput)
16+
assert isinstance(forms.ClearableFileInput(), S3FileInputMixin)

tests/test_forms.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from selenium.webdriver.support.expected_conditions import staleness_of
88
from selenium.webdriver.support.wait import WebDriverWait
99

10-
from s3file.forms import S3FileInput
10+
from s3file.forms import S3FileInputMixin
1111
from tests.testapp.forms import UploadForm
1212

1313
try:
@@ -33,13 +33,15 @@ def url(self):
3333

3434
@pytest.fixture(autouse=True)
3535
def patch(self):
36-
ClearableFileInput.__new__ = \
37-
lambda cls, *args, **kwargs: object.__new__(S3FileInput)
36+
if S3FileInputMixin not in ClearableFileInput.__bases__:
37+
ClearableFileInput.__bases__ = \
38+
(S3FileInputMixin,) + ClearableFileInput.__bases__
39+
pass
3840

3941
@pytest.fixture
4042
def freeze(self, monkeypatch):
4143
"""Freeze datetime and UUID."""
42-
monkeypatch.setattr('s3file.forms.S3FileInput.upload_folder', 'tmp')
44+
monkeypatch.setattr('s3file.forms.S3FileInputMixin.upload_folder', 'tmp')
4345

4446
def test_value_from_datadict(self, client, upload_file):
4547
with open(upload_file) as f:
@@ -78,7 +80,7 @@ def test_clear(self, filemodel):
7880
assert not form.cleaned_data['file']
7981

8082
def test_build_attr(self):
81-
assert set(S3FileInput().build_attrs({}).keys()) == {
83+
assert set(ClearableFileInput().build_attrs({}).keys()) == {
8284
'class',
8385
'data-url',
8486
'data-fields-x-amz-algorithm',
@@ -88,11 +90,12 @@ def test_build_attr(self):
8890
'data-fields-policy',
8991
'data-fields-key',
9092
}
91-
assert S3FileInput().build_attrs({})['class'] == 's3file'
92-
assert S3FileInput().build_attrs({'class': 'my-class'})['class'] == 'my-class s3file'
93+
assert ClearableFileInput().build_attrs({})['class'] == 's3file'
94+
assert ClearableFileInput().build_attrs(
95+
{'class': 'my-class'})['class'] == 'my-class s3file'
9396

9497
def test_get_conditions(self, freeze):
95-
conditions = S3FileInput().get_conditions(None)
98+
conditions = ClearableFileInput().get_conditions(None)
9699
assert all(condition in conditions for condition in [
97100
{"bucket": 'test-bucket'},
98101
{"success_action_status": "201"},
@@ -101,15 +104,15 @@ def test_get_conditions(self, freeze):
101104
]), conditions
102105

103106
def test_accept(self):
104-
widget = S3FileInput()
107+
widget = ClearableFileInput()
105108
assert 'accept' not in widget.render(name='file', value='test.jpg')
106109
assert ["starts-with", "$Content-Type", ""] in widget.get_conditions(None)
107110

108-
widget = S3FileInput(attrs={'accept': 'image/*'})
111+
widget = ClearableFileInput(attrs={'accept': 'image/*'})
109112
assert 'accept="image/*"' in widget.render(name='file', value='test.jpg')
110113
assert ["starts-with", "$Content-Type", "image/"] in widget.get_conditions('image/*')
111114

112-
widget = S3FileInput(attrs={'accept': 'image/jpeg'})
115+
widget = ClearableFileInput(attrs={'accept': 'image/jpeg'})
113116
assert 'accept="image/jpeg"' in widget.render(name='file', value='test.jpg')
114117
assert {"Content-Type": 'image/jpeg'} in widget.get_conditions('image/jpeg')
115118

0 commit comments

Comments
 (0)