Skip to content

Commit efa4183

Browse files
authored
PLT-520 update GH actions, python support (#44)
1 parent af247c6 commit efa4183

23 files changed

+402
-234
lines changed

.github/workflows/test.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: Test
2+
3+
on: push
4+
5+
jobs:
6+
build:
7+
runs-on: ubuntu-latest
8+
strategy:
9+
matrix:
10+
python-version: [3.7, 3.8, 3.9]
11+
12+
steps:
13+
- uses: actions/checkout@v2
14+
15+
- name: Set up Python ${{ matrix.python-version }}
16+
uses: actions/setup-python@v2
17+
with:
18+
python-version: ${{ matrix.python-version }}
19+
20+
- name: Setup chromedriver
21+
uses: nanasess/setup-chromedriver@v1.0.5
22+
23+
- name: Install dependencies
24+
run: |
25+
python -m pip install --upgrade pip
26+
pip install tox tox-gh-actions
27+
28+
- name: Test with tox
29+
run: |
30+
tox -- -v --selenosis-driver=chrome-headless || \
31+
tox -- -v --selenosis-driver=chrome-headless || \
32+
tox -- -v --selenosis-driver=chrome-headless

.travis.yml

Lines changed: 0 additions & 47 deletions
This file was deleted.

README.rst

Lines changed: 113 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,125 @@ fields that use the `Select2 javascript
99
plugin <http://ivaynberg.github.com/select2/>`_. It was created by
1010
developers at `The Atlantic <http://www.theatlantic.com/>`_.
1111

12+
.. contents:: Table of Contents:
13+
1214
Support
1315
=======
1416

1517
Being that Django added select2 support in 2.0, we will support up to that version
1618
for compatibility purposes.
1719

18-
* ~=v2.0.2: Python ~=2.7,~=3.6 | Django >=1.8,<2.1
19-
* ~=v2.1: Python ~=2.7,>=3.6,<3.8 | Django >=1.11,<2.1
20-
* ~=v3.0: __Python >=3.6,<3.9 | Django >=2.0,<2.1 (future release)__
20+
* ~=v3.0: Python >=3.7,<3.9 | Django 2.2,3.1,3.2 (current release)
21+
22+
Local Development & Testing
23+
===========================
24+
25+
The following steps should only need to be done once when you first begin:
26+
27+
Install ``pyenv``
28+
-----------------
29+
30+
These instructions assume that you have `Homebrew <https://brew.sh/>`_ installed,
31+
but not ``pyenv``.
32+
33+
.. code:: bash
34+
35+
brew install pyenv
36+
touch ~/.bash_profile
37+
38+
Add the following line to your ``~/bash_profile`` or ``.zshrc``::
39+
40+
eval "$(pyenv init -)"
41+
42+
Reload your shell:
43+
44+
.. code:: bash
45+
46+
. ~/.bash_profile
47+
or
48+
49+
.. code:: bash
50+
51+
. ~/.zshrc
52+
53+
Python Repository Setup
54+
-----------------------
55+
56+
First, clone the repository and prep your Python environment:
57+
58+
.. code:: bash
59+
60+
git clone https://github.com/theatlantic/django-select2-forms.git
61+
pyenv install 3.7.2
62+
pyenv install 3.8.0
63+
pyenv install 3.9.0
64+
pyenv local 3.7.2 3.8.0 3.9.0
65+
python -V
66+
67+
The output of the previous command should be ``Python 3.7.2``.
68+
69+
Finally:
70+
71+
.. code:: bash
72+
73+
python -m venv venv
74+
75+
Activate Your Environment
76+
-------------------------
77+
78+
From the base directory:
79+
80+
.. code:: bash
81+
82+
deactivate # ignore: -bash: deactivate: command not found
83+
. venv/bin/activate
84+
pip install -U tox
85+
86+
Running tests
87+
-------------
88+
89+
If you have not already done so, set up your environment by chromedriver:
90+
91+
.. code:: bash
92+
93+
brew install --cask chromedriver
94+
95+
Run all tests:
96+
97+
.. code:: bash
98+
99+
tox -- --selenosis-driver=chrome-headless
100+
101+
Show all available ``tox`` commands:
102+
103+
.. code:: bash
104+
105+
tox -av
106+
107+
Run only a specific environment:
108+
109+
.. code:: bash
110+
111+
tox -e <environment-name> -- --selenosis-driver=chrome-headless # example: tox -e py37-django22
112+
113+
Only run a specific test:
114+
115+
.. code:: bash
116+
117+
tox -- pytest -k test_something --selenosis-driver=chrome-headless
118+
119+
Run an arbitrary command in a specific environment:
120+
121+
.. code:: bash
122+
123+
tox -e py37-django22 -- python # runs the Python REPL in that environment
124+
125+
Setup a development environment:
126+
127+
.. code:: bash
128+
129+
tox -e <pyXX-DjangoYY> --develop -r
130+
. .tox/<pyXX-DjangoYY>/bin/activate
21131
22132
Installation
23133
============

runtests.py

Lines changed: 0 additions & 20 deletions
This file was deleted.

select2/fields.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import django
22
from django import forms
33
from django.db import models
4-
from django.core.exceptions import ImproperlyConfigured, ValidationError
5-
from django.db.models.fields import FieldDoesNotExist
4+
from django.core.exceptions import ImproperlyConfigured, ValidationError, FieldDoesNotExist
65
from django.forms.models import ModelChoiceIterator
7-
from django.utils.encoding import force_text
6+
from django.utils.encoding import force_str
87
from django.utils.functional import Promise
9-
from django.utils import six
108
try:
119
from django.db.models.fields.related import lazy_related_operation
1210
except ImportError:
@@ -172,7 +170,7 @@ def clean(self, value):
172170
elif not self.required and not value:
173171
return []
174172

175-
if isinstance(value, six.string_types):
173+
if isinstance(value, str):
176174
value = value.split(',')
177175

178176
if not isinstance(value, (list, tuple)):
@@ -188,14 +186,14 @@ def clean(self, value):
188186
qs = self.queryset.filter(**{
189187
('%s__in' % key): value,
190188
})
191-
pks = set([force_text(getattr(o, key)) for o in qs])
189+
pks = set([force_str(getattr(o, key)) for o in qs])
192190

193191
# Create a dictionary for storing the original order of the items
194192
# passed from the form
195193
pk_positions = {}
196194

197195
for i, val in enumerate(value):
198-
pk = force_text(val)
196+
pk = force_str(val)
199197
if pk not in pks:
200198
raise ValidationError(self.error_messages['invalid_choice'] % val)
201199
pk_positions[pk] = i
@@ -209,7 +207,7 @@ def clean(self, value):
209207
sort_value_field_name = self.sort_field.name
210208
objs = []
211209
for i, obj in enumerate(qs):
212-
pk = force_text(getattr(obj, key))
210+
pk = force_str(getattr(obj, key))
213211
setattr(obj, sort_value_field_name, pk_positions[pk])
214212
objs.append(obj)
215213
return sorted(objs, key=lambda obj: getattr(obj, sort_value_field_name))
@@ -273,15 +271,15 @@ def contribute_to_related_class(self, cls, related):
273271
'field_name': self.name,
274272
'app_label': self.model._meta.app_label,
275273
'object_name': self.model._meta.object_name})
276-
if not callable(self.search_field) and not isinstance(self.search_field, six.string_types):
274+
if not callable(self.search_field) and not isinstance(self.search_field, str):
277275
raise TypeError(
278276
("keyword argument 'search_field' must be either callable or "
279277
"string on field '%(field_name)s' of model "
280278
"%(app_label)s.%(object_name)s") % {
281279
'field_name': self.name,
282280
'app_label': self.model._meta.app_label,
283281
'object_name': self.model._meta.object_name})
284-
if isinstance(self.search_field, six.string_types):
282+
if isinstance(self.search_field, str):
285283
try:
286284
opts = related.parent_model._meta
287285
except AttributeError:
@@ -354,7 +352,7 @@ def contribute_to_class(self, cls, name):
354352
def resolve_sort_field(field, model, cls):
355353
model._sort_field_name = field.sort_value_field_name
356354
field.sort_field = model._meta.get_field(field.sort_value_field_name)
357-
if isinstance(compat_rel(self).through, six.string_types):
355+
if isinstance(compat_rel(self).through, str):
358356
compat_add_lazy_relation(cls, self, compat_rel(self).through, resolve_sort_field)
359357
else:
360358
resolve_sort_field(self, compat_rel(self).through, cls)

select2/models/base.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import sys
33

44
from django.db import models
5-
from django.utils import six
65
from django.apps import apps
76
from django.db.models.base import ModelBase
87
from django.utils.functional import SimpleLazyObject
@@ -68,7 +67,7 @@ def _get_model():
6867
return super_new(cls, name, bases, attrs)
6968

7069

71-
class SortableThroughModel(six.with_metaclass(SortableThroughModelBase, models.Model)):
70+
class SortableThroughModel(models.Model, metaclass=SortableThroughModelBase):
7271

7372
class Meta:
7473
abstract = True

select2/tests/fixtures/select2-test-data.xml

Lines changed: 0 additions & 39 deletions
This file was deleted.

select2/tests/settings.py

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)