From 8cb00e011662113e6f9d5875890df34850c20a06 Mon Sep 17 00:00:00 2001 From: Alex Tomkins Date: Fri, 28 Jul 2017 21:03:29 +0100 Subject: [PATCH 01/37] Fix haystack.__version__ __name__ for django-haystack is haystack, but the installed module is django-haystack - so we need to use that instead. --- haystack/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/haystack/__init__.py b/haystack/__init__.py index 12362df40..65dcec23a 100644 --- a/haystack/__init__.py +++ b/haystack/__init__.py @@ -13,7 +13,7 @@ __author__ = 'Daniel Lindsley' try: - __version__ = get_distribution(__name__).version + __version__ = get_distribution('django-haystack').version except DistributionNotFound: __version__ = (0, 0, 'dev0') From 7b6e799b1df4c92b1cda0e379c91a4a7529cccca Mon Sep 17 00:00:00 2001 From: Alex Tomkins Date: Sat, 29 Jul 2017 12:52:54 +0100 Subject: [PATCH 02/37] Change fallback __version__ to be a string For consistency, this will match the version from get_distribution --- haystack/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/haystack/__init__.py b/haystack/__init__.py index 65dcec23a..7316dc8cd 100644 --- a/haystack/__init__.py +++ b/haystack/__init__.py @@ -15,7 +15,7 @@ try: __version__ = get_distribution('django-haystack').version except DistributionNotFound: - __version__ = (0, 0, 'dev0') + __version__ = '0.0.dev0' default_app_config = 'haystack.apps.HaystackConfig' From 11d3a134e0fff06a596b3662f651dbf616853bb2 Mon Sep 17 00:00:00 2001 From: Erik Cederstrand Date: Mon, 30 Sep 2019 12:52:32 +0200 Subject: [PATCH 03/37] Python installs setuptools by default already Also removes unused imports --- setup.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/setup.py b/setup.py index 887956047..c762b9d40 100755 --- a/setup.py +++ b/setup.py @@ -1,16 +1,7 @@ #!/usr/bin/env python # encoding: utf-8 -# n.b. we can't have unicode_literals here due to http://bugs.python.org/setuptools/issue152 -from __future__ import absolute_import, division, print_function - -try: - from setuptools import setup -except ImportError: - from ez_setup import use_setuptools - - use_setuptools() - from setuptools import setup +from setuptools import setup install_requires = ["Django>=1.11"] From a5bb8dfce8df836c0cf136836855baf5ecb5fd69 Mon Sep 17 00:00:00 2001 From: Erik Cederstrand Date: Mon, 30 Sep 2019 12:55:27 +0200 Subject: [PATCH 04/37] Add setuptools_scm to setup.cfg instead --- setup.cfg | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/setup.cfg b/setup.cfg index 8cfac863d..5e3dd1772 100644 --- a/setup.cfg +++ b/setup.cfg @@ -11,3 +11,7 @@ ignore = E203, E501, W503 line_length=88 default_section=THIRDPARTY known_first_party=haystack + +[options] +setup_requires = + setuptools_scm From 5fbddccb8aba9d8cba6cbc08c62f34d5744a9007 Mon Sep 17 00:00:00 2001 From: Erik Cederstrand Date: Mon, 30 Sep 2019 12:56:04 +0200 Subject: [PATCH 05/37] setup_requires in setup.py is not fully supported by pip --- setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.py b/setup.py index c762b9d40..3c1747b98 100755 --- a/setup.py +++ b/setup.py @@ -54,5 +54,4 @@ install_requires=install_requires, tests_require=tests_require, test_suite="test_haystack.run_tests.run_all", - setup_requires=["setuptools_scm"], ) From ee127012d18b2c231b39e411503f5f6322736efc Mon Sep 17 00:00:00 2001 From: the5fire Date: Fri, 11 Oct 2019 22:44:06 +0800 Subject: [PATCH 06/37] using six replace django six --- haystack/backends/__init__.py | 5 ++++- haystack/backends/elasticsearch_backend.py | 2 +- haystack/backends/simple_backend.py | 2 +- haystack/backends/solr_backend.py | 2 +- haystack/backends/whoosh_backend.py | 2 +- haystack/fields.py | 3 ++- haystack/indexes.py | 2 +- haystack/inputs.py | 3 ++- haystack/management/commands/clear_index.py | 2 +- haystack/models.py | 2 +- haystack/panels.py | 2 +- haystack/query.py | 2 +- haystack/templatetags/highlight.py | 2 +- haystack/utils/__init__.py | 2 +- haystack/utils/loading.py | 2 +- setup.py | 2 +- test_haystack/test_indexes.py | 4 ++-- test_haystack/test_views.py | 2 +- 18 files changed, 24 insertions(+), 19 deletions(-) diff --git a/haystack/backends/__init__.py b/haystack/backends/__init__.py index 87355b531..77c0668f3 100644 --- a/haystack/backends/__init__.py +++ b/haystack/backends/__init__.py @@ -1,12 +1,15 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals + import copy from copy import deepcopy from time import time + +import six + from django.conf import settings from django.db.models import Q from django.db.models.base import ModelBase -from django.utils import six from django.utils import tree from django.utils.encoding import force_text diff --git a/haystack/backends/elasticsearch_backend.py b/haystack/backends/elasticsearch_backend.py index 3b023b9d1..deaa1c675 100644 --- a/haystack/backends/elasticsearch_backend.py +++ b/haystack/backends/elasticsearch_backend.py @@ -6,9 +6,9 @@ import warnings from datetime import datetime, timedelta +import six from django.conf import settings from django.core.exceptions import ImproperlyConfigured -from django.utils import six import haystack from haystack.backends import BaseEngine, BaseSearchBackend, BaseSearchQuery, log_query diff --git a/haystack/backends/simple_backend.py b/haystack/backends/simple_backend.py index abbd8fb1a..6eebecebe 100644 --- a/haystack/backends/simple_backend.py +++ b/haystack/backends/simple_backend.py @@ -7,8 +7,8 @@ from warnings import warn +import six from django.db.models import Q -from django.utils import six from haystack import connections from haystack.backends import ( diff --git a/haystack/backends/solr_backend.py b/haystack/backends/solr_backend.py index d1f4cc664..308ca3556 100644 --- a/haystack/backends/solr_backend.py +++ b/haystack/backends/solr_backend.py @@ -4,9 +4,9 @@ import warnings +import six from django.conf import settings from django.core.exceptions import ImproperlyConfigured -from django.utils import six import haystack from haystack.backends import ( diff --git a/haystack/backends/whoosh_backend.py b/haystack/backends/whoosh_backend.py index 702251c52..5163c441d 100644 --- a/haystack/backends/whoosh_backend.py +++ b/haystack/backends/whoosh_backend.py @@ -9,9 +9,9 @@ import threading import warnings +import six from django.conf import settings from django.core.exceptions import ImproperlyConfigured -from django.utils import six from django.utils.datetime_safe import datetime from django.utils.encoding import force_text diff --git a/haystack/fields.py b/haystack/fields.py index 023df08e3..b81112ad8 100644 --- a/haystack/fields.py +++ b/haystack/fields.py @@ -4,8 +4,9 @@ import re from inspect import ismethod +import six from django.template import loader -from django.utils import datetime_safe, six +from django.utils import datetime_safe from haystack.exceptions import SearchFieldError from haystack.utils import get_model_ct_tuple diff --git a/haystack/indexes.py b/haystack/indexes.py index f77cbf183..dea404e80 100644 --- a/haystack/indexes.py +++ b/haystack/indexes.py @@ -8,7 +8,7 @@ from django.core.exceptions import ImproperlyConfigured from django.utils.encoding import force_text -from django.utils.six import with_metaclass +from six import with_metaclass from haystack import connection_router, connections from haystack.constants import Indexable # NOQA — exposed as a public export diff --git a/haystack/inputs.py b/haystack/inputs.py index e2d79a337..d990cbddf 100644 --- a/haystack/inputs.py +++ b/haystack/inputs.py @@ -5,7 +5,8 @@ import re import warnings -from django.utils.encoding import force_text, python_2_unicode_compatible +from django.utils.encoding import force_text +from six import python_2_unicode_compatible @python_2_unicode_compatible diff --git a/haystack/management/commands/clear_index.py b/haystack/management/commands/clear_index.py index f2639f330..25011faa4 100644 --- a/haystack/management/commands/clear_index.py +++ b/haystack/management/commands/clear_index.py @@ -2,8 +2,8 @@ from __future__ import absolute_import, division, print_function, unicode_literals +import six from django.core.management.base import BaseCommand -from django.utils import six from haystack import connections diff --git a/haystack/models.py b/haystack/models.py index aa4f65895..dab9519ca 100644 --- a/haystack/models.py +++ b/haystack/models.py @@ -4,8 +4,8 @@ from __future__ import absolute_import, division, print_function, unicode_literals +import six from django.core.exceptions import ObjectDoesNotExist -from django.utils import six from django.utils.encoding import force_text from django.utils.text import capfirst diff --git a/haystack/panels.py b/haystack/panels.py index 08fff1a33..bdb9a7e4b 100644 --- a/haystack/panels.py +++ b/haystack/panels.py @@ -4,9 +4,9 @@ import datetime +import six from debug_toolbar.panels import DebugPanel from django.template.loader import render_to_string -from django.utils import six from django.utils.translation import ugettext_lazy as _ from haystack import connections diff --git a/haystack/query.py b/haystack/query.py index 390b099d6..93f6ee1fd 100644 --- a/haystack/query.py +++ b/haystack/query.py @@ -5,7 +5,7 @@ import operator import warnings -from django.utils import six +import six from haystack import connection_router, connections from haystack.backends import SQ diff --git a/haystack/templatetags/highlight.py b/haystack/templatetags/highlight.py index 2853b83ae..3013b7368 100644 --- a/haystack/templatetags/highlight.py +++ b/haystack/templatetags/highlight.py @@ -2,10 +2,10 @@ from __future__ import absolute_import, division, print_function, unicode_literals +import six from django import template from django.conf import settings from django.core.exceptions import ImproperlyConfigured -from django.utils import six from haystack.utils import importlib diff --git a/haystack/utils/__init__.py b/haystack/utils/__init__.py index 17b10123c..fcbed04b4 100644 --- a/haystack/utils/__init__.py +++ b/haystack/utils/__init__.py @@ -5,8 +5,8 @@ import importlib import re +import six from django.conf import settings -from django.utils import six from haystack.constants import ID, DJANGO_CT, DJANGO_ID from haystack.utils.highlighting import Highlighter diff --git a/haystack/utils/loading.py b/haystack/utils/loading.py index 985dfecc6..b817e0001 100644 --- a/haystack/utils/loading.py +++ b/haystack/utils/loading.py @@ -8,9 +8,9 @@ import warnings from collections import OrderedDict +import six from django.conf import settings from django.core.exceptions import ImproperlyConfigured -from django.utils import six from django.utils.module_loading import module_has_submodule from haystack import constants diff --git a/setup.py b/setup.py index 887956047..26ab9c9f4 100755 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ use_setuptools() from setuptools import setup -install_requires = ["Django>=1.11"] +install_requires = ["Django>=1.11", "six==1.12.0"] tests_require = [ "pysolr>=3.7.0", diff --git a/test_haystack/test_indexes.py b/test_haystack/test_indexes.py index 40f558e37..376a88355 100644 --- a/test_haystack/test_indexes.py +++ b/test_haystack/test_indexes.py @@ -7,7 +7,7 @@ from threading import Thread from django.test import TestCase -from django.utils.six.moves import queue +from six.moves import queue from test_haystack.core.models import ( AFifthMockModel, AnotherMockModel, @@ -17,7 +17,7 @@ MockModel, ) -from haystack import connection_router, connections, indexes +from haystack import connections, indexes from haystack.exceptions import SearchFieldError from haystack.utils.loading import UnifiedIndex diff --git a/test_haystack/test_views.py b/test_haystack/test_views.py index 256c3d4eb..a5acaee21 100644 --- a/test_haystack/test_views.py +++ b/test_haystack/test_views.py @@ -9,7 +9,7 @@ from django.http import HttpRequest, QueryDict from django.test import TestCase, override_settings from django.urls import reverse -from django.utils.six.moves import queue +from six.moves import queue from test_haystack.core.models import AnotherMockModel, MockModel from haystack import connections, indexes From aaf7944c13dae7857516088344d79ae8e369758b Mon Sep 17 00:00:00 2001 From: Asyncinfo Date: Tue, 15 Oct 2019 09:37:35 +0800 Subject: [PATCH 07/37] Update tutorial.rst add the settings of the Elasticsearch 5.x --- docs/tutorial.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/tutorial.rst b/docs/tutorial.rst index a8133d7d7..578c3d923 100644 --- a/docs/tutorial.rst +++ b/docs/tutorial.rst @@ -157,7 +157,16 @@ Example (ElasticSearch 2.x):: 'INDEX_NAME': 'haystack', }, } + +Example (ElasticSearch 5.x):: + HAYSTACK_CONNECTIONS = { + 'default': { + 'ENGINE': 'haystack.backends.elasticsearch5_backend.Elasticsearch5SearchEngine', + 'URL': 'http://127.0.0.1:9200/', + 'INDEX_NAME': 'haystack', + }, + } Whoosh ~~~~~~ From 79ec0a3284e5873078546b352b3343260ed1b91b Mon Sep 17 00:00:00 2001 From: Andreas Neumeier Date: Mon, 2 Dec 2019 14:40:21 +0100 Subject: [PATCH 08/37] Update loading.py --- haystack/utils/loading.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/haystack/utils/loading.py b/haystack/utils/loading.py index 985dfecc6..1d5b4f9d3 100644 --- a/haystack/utils/loading.py +++ b/haystack/utils/loading.py @@ -10,7 +10,6 @@ from django.conf import settings from django.core.exceptions import ImproperlyConfigured -from django.utils import six from django.utils.module_loading import module_has_submodule from haystack import constants @@ -163,7 +162,7 @@ def _for_action(self, action, many, **hints): connection_to_use = action_callable(**hints) if connection_to_use is not None: - if isinstance(connection_to_use, six.string_types): + if isinstance(connection_to_use, str): conns.append(connection_to_use) else: conns.extend(connection_to_use) From 4d0334681bdb453bc6460834c8318cddc6ce7311 Mon Sep 17 00:00:00 2001 From: Andreas Neumeier Date: Mon, 2 Dec 2019 14:51:31 +0100 Subject: [PATCH 09/37] Update .travis.yml Remove Python 2.7, which is end of life. (https://pythonclock.org/) Add Python 3.7 to the test-matrix. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 11c9233c4..0436163e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,10 @@ sudo: required dist: trusty language: python python: - - 2.7 - 3.4 - 3.5 - 3.6 + - 3.7 - pypy cache: From 5af8aceaf08957928b164c1cf244dc1088cbd859 Mon Sep 17 00:00:00 2001 From: "Mr.Kio" <38723412+MrKioZ@users.noreply.github.com> Date: Sun, 19 Jan 2020 12:00:29 +0200 Subject: [PATCH 10/37] Update __init__.py --- haystack/utils/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/haystack/utils/__init__.py b/haystack/utils/__init__.py index 17b10123c..d17189162 100644 --- a/haystack/utils/__init__.py +++ b/haystack/utils/__init__.py @@ -6,7 +6,6 @@ import re from django.conf import settings -from django.utils import six from haystack.constants import ID, DJANGO_CT, DJANGO_ID from haystack.utils.highlighting import Highlighter @@ -22,7 +21,7 @@ def default_get_identifier(obj_or_string): If not overridden, uses ... """ - if isinstance(obj_or_string, six.string_types): + if type(obj_or_string) == str:: if not IDENTIFIER_REGEX.match(obj_or_string): raise AttributeError( "Provided string '%s' is not a valid identifier." % obj_or_string From d4494a6a091e5bba7a8b4391cc8b00e3c38786c1 Mon Sep 17 00:00:00 2001 From: "Mr.Kio" <38723412+MrKioZ@users.noreply.github.com> Date: Sun, 19 Jan 2020 12:01:06 +0200 Subject: [PATCH 11/37] Update __init__.py --- haystack/utils/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/haystack/utils/__init__.py b/haystack/utils/__init__.py index d17189162..6a697dfd7 100644 --- a/haystack/utils/__init__.py +++ b/haystack/utils/__init__.py @@ -21,7 +21,7 @@ def default_get_identifier(obj_or_string): If not overridden, uses ... """ - if type(obj_or_string) == str:: + if type(obj_or_string) == str: if not IDENTIFIER_REGEX.match(obj_or_string): raise AttributeError( "Provided string '%s' is not a valid identifier." % obj_or_string From c3c68e36293a9f750431da62c56cf54f43d7babf Mon Sep 17 00:00:00 2001 From: "Mr.Kio" <38723412+MrKioZ@users.noreply.github.com> Date: Sun, 19 Jan 2020 12:03:40 +0200 Subject: [PATCH 12/37] Update __init__.py --- haystack/utils/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/haystack/utils/__init__.py b/haystack/utils/__init__.py index 6a697dfd7..36e13d99e 100644 --- a/haystack/utils/__init__.py +++ b/haystack/utils/__init__.py @@ -3,6 +3,7 @@ from __future__ import unicode_literals import importlib +import six import re from django.conf import settings @@ -21,7 +22,7 @@ def default_get_identifier(obj_or_string): If not overridden, uses ... """ - if type(obj_or_string) == str: + if isinstance(obj_or_string, six.string_types): if not IDENTIFIER_REGEX.match(obj_or_string): raise AttributeError( "Provided string '%s' is not a valid identifier." % obj_or_string From e1b4f5a19def0ff04ba67822e21a74200f184940 Mon Sep 17 00:00:00 2001 From: "Mr.Kio" <38723412+MrKioZ@users.noreply.github.com> Date: Sun, 19 Jan 2020 12:06:22 +0200 Subject: [PATCH 13/37] Update setup.py --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 3c1747b98..553f7d9b2 100755 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from setuptools import setup -install_requires = ["Django>=1.11"] +install_requires = ["Django>=1.11", "six"] tests_require = [ "pysolr>=3.7.0", From a2b27a4cabc984c97a46e1695f4687d34b933808 Mon Sep 17 00:00:00 2001 From: Chris Adams Date: Tue, 3 Dec 2019 13:43:35 -0500 Subject: [PATCH 14/37] Travis CI: upgrade to running on Xenial --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0436163e6..dcf9598ec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ sudo: required -dist: trusty +dist: xenial language: python python: - 3.4 From 57bf3f07bdd0af1b7bc30bf6f3a72353703814c0 Mon Sep 17 00:00:00 2001 From: Chris Adams Date: Tue, 3 Dec 2019 13:48:04 -0500 Subject: [PATCH 15/37] Upgrade package versions --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index dcf9598ec..bcc85da08 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,10 +19,10 @@ addons: - binutils - default-jdk - gdal-bin - - libgdal1h - - libgeos-c1 + - libgdal1i + - libgeos-c1v5 - libproj-dev - - libxapian22 + - libxapian22v5 - python-xapian - wajig From d631eec074d310fde3b345fe71ead31cc92b5648 Mon Sep 17 00:00:00 2001 From: Chris Adams Date: Tue, 3 Dec 2019 13:56:22 -0500 Subject: [PATCH 16/37] Upgrade to Ubuntu 18.04 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index bcc85da08..0ff9e7db7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ sudo: required -dist: xenial +dist: bionic language: python python: - 3.4 @@ -17,7 +17,7 @@ cache: addons: apt_packages: - binutils - - default-jdk + - openjdk11 - gdal-bin - libgdal1i - libgeos-c1v5 From 74d497860aa70e932108edd83d36bc06610f88e6 Mon Sep 17 00:00:00 2001 From: Alexander Clausen Date: Fri, 24 Jan 2020 17:25:42 +0100 Subject: [PATCH 17/37] Update packages for bionic Remove libxapian, should be installed as dependency of python-xapian --- .travis.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0ff9e7db7..014db1ddc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,12 +17,11 @@ cache: addons: apt_packages: - binutils - - openjdk11 + - openjdk-11-jdk - gdal-bin - - libgdal1i + - libgdal20 - libgeos-c1v5 - libproj-dev - - libxapian22v5 - python-xapian - wajig From ecbce6ffaecd718d33d01c86bbd27731347bd325 Mon Sep 17 00:00:00 2001 From: Alexander Clausen Date: Fri, 24 Jan 2020 17:32:35 +0100 Subject: [PATCH 18/37] Remove Python 3.4 --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 014db1ddc..1d25eaf3b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,6 @@ sudo: required dist: bionic language: python python: - - 3.4 - 3.5 - 3.6 - 3.7 From 1d6c9af6da39739c21c3f169269cedb260126ca1 Mon Sep 17 00:00:00 2001 From: Alexander Clausen Date: Fri, 24 Jan 2020 17:47:29 +0100 Subject: [PATCH 19/37] solr downloader: catch ConnectionError and try next mirror --- test_haystack/solr_tests/server/get-solr-download-url.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test_haystack/solr_tests/server/get-solr-download-url.py b/test_haystack/solr_tests/server/get-solr-download-url.py index d2e4b207c..14569b708 100755 --- a/test_haystack/solr_tests/server/get-solr-download-url.py +++ b/test_haystack/solr_tests/server/get-solr-download-url.py @@ -52,9 +52,12 @@ if not test_url.endswith(tarball): test_url = urljoin(test_url, dist_path) - if requests.head(test_url, allow_redirects=True).status_code == 200: - download_url = test_url - break + try: + if requests.head(test_url, allow_redirects=True).status_code == 200: + download_url = test_url + break + except requests.exceptions.ConnectionError: + continue else: print("None of the Apache mirrors have %s" % dist_path, file=sys.stderr) sys.exit(1) From 8d5b73f888688e8ff967fc015a2c0d66d2bf9ba2 Mon Sep 17 00:00:00 2001 From: Alexander Clausen Date: Fri, 24 Jan 2020 17:55:09 +0100 Subject: [PATCH 20/37] travis: remove obsolete excludes --- .travis.yml | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1d25eaf3b..cc627c080 100644 --- a/.travis.yml +++ b/.travis.yml @@ -78,24 +78,6 @@ matrix: allow_failures: - python: 'pypy' exclude: - - python: 2.7 - env: DJANGO_VERSION=">=2.0,<2.1" VERSION_ES=">=5.0.0,<6.0.0" - - python: 2.7 - env: DJANGO_VERSION=">=2.0,<2.1" VERSION_ES=">=2.0.0,<3.0.0" - - python: 2.7 - env: DJANGO_VERSION=">=2.0,<2.1" VERSION_ES=">=1.0.0,<2.0.0" - - python: 2.7 - env: DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=5.0.0,<6.0.0" - - python: 2.7 - env: DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=2.0.0,<3.0.0" - - python: 2.7 - env: DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=1.0.0,<2.0.0" - - python: 3.4 - env: DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=5.0.0,<6.0.0" - - python: 3.4 - env: DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=2.0.0,<3.0.0" - - python: 3.4 - env: DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=1.0.0,<2.0.0" - python: pypy env: DJANGO_VERSION=">=2.0,<2.1" VERSION_ES=">=5.0.0,<6.0.0" - python: pypy From 9ed236de1067e20b7ca72743e21ebbf7712abf91 Mon Sep 17 00:00:00 2001 From: Alexander Clausen Date: Fri, 24 Jan 2020 18:03:12 +0100 Subject: [PATCH 21/37] travis: downgrade to openjdk 8 The version of solr used in the tests is not compatible with the more current openjdk 11. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cc627c080..8fc32a958 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ cache: addons: apt_packages: - binutils - - openjdk-11-jdk + - openjdk-8-jdk - gdal-bin - libgdal20 - libgeos-c1v5 From 087861efa268f891f02f631c27318dcb641c6c83 Mon Sep 17 00:00:00 2001 From: Alexander Clausen Date: Fri, 24 Jan 2020 18:42:53 +0100 Subject: [PATCH 22/37] point JAVA_HOME to openjdk-8 --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 8fc32a958..f21fb6d58 100644 --- a/.travis.yml +++ b/.travis.yml @@ -64,6 +64,8 @@ after_success: - codecov env: + global: + - JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 matrix: - DJANGO_VERSION=">=1.11,<2.0" VERSION_ES=">=1.0.0,<2.0.0" - DJANGO_VERSION=">=2.0,<2.1" VERSION_ES=">=1.0.0,<2.0.0" From e6b91ee0981913eaee850195c67e88b72018d3cb Mon Sep 17 00:00:00 2001 From: Alexander Clausen Date: Fri, 24 Jan 2020 19:20:46 +0100 Subject: [PATCH 23/37] travis: add debugging output for elasticsearch service --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index f21fb6d58..113e855e0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -46,6 +46,8 @@ before_install: sudo apt-get -qy --allow-downgrades install elasticsearch=1.7.6 fi - sudo service elasticsearch restart + - sudo systemctl status elasticsearch + - sudo journalctl --unit elasticsearch install: - pip install --upgrade setuptools From 42cc4d0f7d8ae2e46164070ecf3c9ae3edc3aaaf Mon Sep 17 00:00:00 2001 From: Alexander Clausen Date: Fri, 24 Jan 2020 20:23:42 +0100 Subject: [PATCH 24/37] try to run elasticsearch via docker --- .travis.yml | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index 113e855e0..61fd96716 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,8 @@ python: - 3.6 - 3.7 - pypy +services: + - docker cache: apt: true @@ -25,29 +27,17 @@ addons: - wajig before_install: - - sudo apt-get install -qy default-jre - mkdir -p $HOME/download-cache - # See https://www.elastic.co/guide/en/elasticsearch/reference/current/deb.html#deb-repo - - wget -qO - https://packages.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add - - > if [[ $VERSION_ES == '>=2.0.0,<3.0.0' ]]; then - echo "deb http://packages.elastic.co/elasticsearch/2.x/debian stable main" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-2.x.list - sudo apt-get update - sudo apt-get -qy --allow-downgrades install elasticsearch=2.4.6 + docker run -d -p 9200:9200 elasticsearch:2.4.6-alpine elif [[ $VERSION_ES == '>=5.0.0,<6.0.0' ]]; then - echo "deb https://artifacts.elastic.co/packages/5.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-5.x.list - sudo apt-get update -qy - sudo apt-get -y --allow-downgrades install elasticsearch=5.6.10 + docker run -d -p 9200:9200 elasticsearch:5.6.10-alpine else - echo "deb http://packages.elastic.co/elasticsearch/1.7/debian stable main" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-1.7.list - sudo apt-get update -qy - sudo apt-get -qy --allow-downgrades install elasticsearch=1.7.6 + docker run -d -p 9200:9200 elasticsearch:1.7.6-alpine fi - - sudo service elasticsearch restart - - sudo systemctl status elasticsearch - - sudo journalctl --unit elasticsearch install: - pip install --upgrade setuptools From f8238eee452f5032cad76f17b2713caefd4c0ba6 Mon Sep 17 00:00:00 2001 From: Alexander Clausen Date: Fri, 24 Jan 2020 20:52:28 +0100 Subject: [PATCH 25/37] Travis: try to test w/ pypy3 Plain 'pypy' gives a 404 --- .travis.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 61fd96716..d12cafeef 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ python: - 3.5 - 3.6 - 3.7 - - pypy + - pypy3 services: - docker @@ -70,19 +70,19 @@ env: - DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=5.0.0,<6.0.0" matrix: allow_failures: - - python: 'pypy' + - python: 'pypy3' exclude: - - python: pypy + - python: pypy3 env: DJANGO_VERSION=">=2.0,<2.1" VERSION_ES=">=5.0.0,<6.0.0" - - python: pypy + - python: pypy3 env: DJANGO_VERSION=">=2.0,<2.1" VERSION_ES=">=2.0.0,<3.0.0" - - python: pypy + - python: pypy3 env: DJANGO_VERSION=">=2.0,<2.1" VERSION_ES=">=1.0.0,<2.0.0" - - python: pypy + - python: pypy3 env: DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=5.0.0,<6.0.0" - - python: pypy + - python: pypy3 env: DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=2.0.0,<3.0.0" - - python: pypy + - python: pypy3 env: DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=1.0.0,<2.0.0" notifications: From 07967f30de173d7aafd8216612161d6bed48fd10 Mon Sep 17 00:00:00 2001 From: Alexander Clausen Date: Fri, 24 Jan 2020 20:57:04 +0100 Subject: [PATCH 26/37] Travis: fix linting errors, warnings See: https://config.travis-ci.com/explore --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index d12cafeef..839dc068a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -sudo: required +os: linux dist: bionic language: python python: @@ -58,7 +58,7 @@ after_success: env: global: - JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 - matrix: + jobs: - DJANGO_VERSION=">=1.11,<2.0" VERSION_ES=">=1.0.0,<2.0.0" - DJANGO_VERSION=">=2.0,<2.1" VERSION_ES=">=1.0.0,<2.0.0" - DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=1.0.0,<2.0.0" @@ -68,7 +68,7 @@ env: - DJANGO_VERSION=">=1.11,<2.0" VERSION_ES=">=5.0.0,<6.0.0" - DJANGO_VERSION=">=2.0,<2.1" VERSION_ES=">=5.0.0,<6.0.0" - DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=5.0.0,<6.0.0" -matrix: +jobs: allow_failures: - python: 'pypy3' exclude: From 037eed7a4f9e5265b57eab36f14e4fe1af56dbae Mon Sep 17 00:00:00 2001 From: Alexander Clausen Date: Fri, 24 Jan 2020 22:07:53 +0100 Subject: [PATCH 27/37] Run solr via docker --- .../server/get-solr-download-url.py | 65 ----------------- test_haystack/solr_tests/server/solr-setup.sh | 23 ++++++ .../server/start-solr-test-server.sh | 71 ++----------------- 3 files changed, 28 insertions(+), 131 deletions(-) delete mode 100755 test_haystack/solr_tests/server/get-solr-download-url.py create mode 100755 test_haystack/solr_tests/server/solr-setup.sh diff --git a/test_haystack/solr_tests/server/get-solr-download-url.py b/test_haystack/solr_tests/server/get-solr-download-url.py deleted file mode 100755 index 14569b708..000000000 --- a/test_haystack/solr_tests/server/get-solr-download-url.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - -import sys -from itertools import chain - -import requests - -# Try to import urljoin from the Python 3 reorganized stdlib first: -try: - from urllib.parse import urljoin -except ImportError: - from urlparse import urljoin - - -if len(sys.argv) != 2: - print("Usage: %s SOLR_VERSION" % sys.argv[0], file=sys.stderr) - sys.exit(1) - -solr_version = sys.argv[1] -tarball = "solr-{0}.tgz".format(solr_version) -dist_path = "lucene/solr/{0}/{1}".format(solr_version, tarball) - -download_url = urljoin("https://archive.apache.org/dist/", dist_path) -mirror_response = requests.get( - "https://www.apache.org/dyn/mirrors/mirrors.cgi/%s?asjson=1" % dist_path -) - -if not mirror_response.ok: - print( - "Apache mirror request returned HTTP %d" % mirror_response.status_code, - file=sys.stderr, - ) - sys.exit(1) - -mirror_data = mirror_response.json() - -# Since the Apache mirrors are often unreliable and releases may disappear without notice we'll -# try the preferred mirror, all of the alternates and backups, and fall back to the main Apache -# archive server: -for base_url in chain( - (mirror_data["preferred"],), - mirror_data["http"], - mirror_data["backup"], - ("https://archive.apache.org/dist/",), -): - test_url = urljoin(base_url, mirror_data["path_info"]) - - # The Apache mirror script's response format has recently changed to exclude the actual file paths: - if not test_url.endswith(tarball): - test_url = urljoin(test_url, dist_path) - - try: - if requests.head(test_url, allow_redirects=True).status_code == 200: - download_url = test_url - break - except requests.exceptions.ConnectionError: - continue -else: - print("None of the Apache mirrors have %s" % dist_path, file=sys.stderr) - sys.exit(1) - -print(download_url) diff --git a/test_haystack/solr_tests/server/solr-setup.sh b/test_haystack/solr_tests/server/solr-setup.sh new file mode 100755 index 000000000..f9cef556e --- /dev/null +++ b/test_haystack/solr_tests/server/solr-setup.sh @@ -0,0 +1,23 @@ +#!/bin/bash +set -e + +# this script is run in the container as setup + +CONFDEST=/opt/solr/server/solr/configsets/collection1/conf/ +BASIC_CONFIGS=/opt/solr/server/solr/configsets/basic_configs/conf/ + +# put configuration in place: +mkdir -p $CONFDEST +cp -r /confdir/* $CONFDEST + + +# borrow some files from the basic_configs configset: +cp -r $BASIC_CONFIGS/lang $CONFDEST +cp -r $BASIC_CONFIGS/*.txt $CONFDEST +cp -r $BASIC_CONFIGS/{currency,elevate}.xml $CONFDEST + +ls -la $CONFDEST/ + +precreate-core collection1 $CONFDEST/../ +precreate-core mgmnt +exec solr-foreground diff --git a/test_haystack/solr_tests/server/start-solr-test-server.sh b/test_haystack/solr_tests/server/start-solr-test-server.sh index 9bd57ea5f..c5204f27e 100755 --- a/test_haystack/solr_tests/server/start-solr-test-server.sh +++ b/test_haystack/solr_tests/server/start-solr-test-server.sh @@ -2,73 +2,12 @@ set -e -SOLR_VERSION=6.6.4 -SOLR_DIR=solr - - -SOLR_PORT=9001 - -cd $(dirname $0) - -export TEST_ROOT=$(pwd) - -export SOLR_ARCHIVE="${SOLR_VERSION}.tgz" - -if [ -d "${HOME}/download-cache/" ]; then - export SOLR_ARCHIVE="${HOME}/download-cache/${SOLR_ARCHIVE}" -fi - -if [ -f ${SOLR_ARCHIVE} ]; then - # If the tarball doesn't extract cleanly, remove it so it'll download again: - tar -tf ${SOLR_ARCHIVE} > /dev/null || rm ${SOLR_ARCHIVE} -fi - -if [ ! -f ${SOLR_ARCHIVE} ]; then - SOLR_DOWNLOAD_URL=$(python get-solr-download-url.py $SOLR_VERSION) - curl -Lo $SOLR_ARCHIVE ${SOLR_DOWNLOAD_URL} || (echo "Unable to download ${SOLR_DOWNLOAD_URL}"; exit 2) -fi - -echo "Extracting Solr ${SOLR_ARCHIVE} to ${TEST_ROOT}/${SOLR_DIR}" -rm -rf ${SOLR_DIR} -mkdir ${SOLR_DIR} -FULL_SOLR_DIR=$(readlink -f ./${SOLR_DIR}) -tar -C ${SOLR_DIR} -xf ${SOLR_ARCHIVE} --strip-components=1 - -# These tuning options will break on Java 10 and for testing we don't care about -# production server optimizations: -export GC_LOG_OPTS="" -export GC_TUNE="" - -export SOLR_LOGS_DIR="${FULL_SOLR_DIR}/logs" - -install -d ${SOLR_LOGS_DIR} - -echo "Changing into ${FULL_SOLR_DIR} " - -cd ${FULL_SOLR_DIR} - -echo "Creating Solr Core" -./bin/solr start -p ${SOLR_PORT} -./bin/solr create -c collection1 -p ${SOLR_PORT} -n basic_config -./bin/solr create -c mgmnt -p ${SOLR_PORT} - -echo "Solr system information:" -curl --fail --silent 'http://localhost:9001/solr/admin/info/system?wt=json&indent=on' | python -m json.tool -./bin/solr stop -p ${SOLR_PORT} - -CONF_DIR=${TEST_ROOT}/confdir -CORE_DIR=${FULL_SOLR_DIR}/server/solr/collection1 -mv ${CORE_DIR}/conf/managed-schema ${CORE_DIR}/conf/managed-schema.old -cp ${CONF_DIR}/* ${CORE_DIR}/conf/ - -echo 'Starting server' -cd server -# We use exec to allow process monitors to correctly kill the -# actual Java process rather than this launcher script: -export CMD="java -Djetty.port=${SOLR_PORT} -Djava.awt.headless=true -Dapple.awt.UIElement=true -jar start.jar --module=http -Dsolr.install.dir=${FULL_SOLR_DIR} -Dsolr.log.dir=${SOLR_LOGS_DIR}" +SOLR_VERSION=6.6.6 if [ -z "${BACKGROUND_SOLR}" ]; then - exec $CMD + ARGS="" else - exec $CMD >/dev/null & + ARGS="-d" fi + +docker run ${ARGS} -p 9001:8983 -v $PWD/solr-setup.sh:/solr-setup.sh -v $PWD/confdir:/confdir:ro solr:${SOLR_VERSION}-slim bash -c "/solr-setup.sh" From 2219d11d8358dc518071110741dc6632832364c0 Mon Sep 17 00:00:00 2001 From: Alexander Clausen Date: Fri, 24 Jan 2020 22:17:11 +0100 Subject: [PATCH 28/37] make solr start script callable from other directories --- test_haystack/solr_tests/server/start-solr-test-server.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test_haystack/solr_tests/server/start-solr-test-server.sh b/test_haystack/solr_tests/server/start-solr-test-server.sh index c5204f27e..07c9c2b06 100755 --- a/test_haystack/solr_tests/server/start-solr-test-server.sh +++ b/test_haystack/solr_tests/server/start-solr-test-server.sh @@ -10,4 +10,7 @@ else ARGS="-d" fi -docker run ${ARGS} -p 9001:8983 -v $PWD/solr-setup.sh:/solr-setup.sh -v $PWD/confdir:/confdir:ro solr:${SOLR_VERSION}-slim bash -c "/solr-setup.sh" +# https://stackoverflow.com/a/246128/540644 +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +docker run ${ARGS} -p 9001:8983 -v $DIR/solr-setup.sh:/solr-setup.sh -v $DIR/confdir:/confdir:ro solr:${SOLR_VERSION}-slim bash -c "/solr-setup.sh" From 4b84faa404a55f97b0b3bb2cffd6a3f1f645b66e Mon Sep 17 00:00:00 2001 From: Alexander Clausen Date: Fri, 24 Jan 2020 22:31:23 +0100 Subject: [PATCH 29/37] test_build_schema: properly restore monkey patched settings --- .../test_solr_management_commands.py | 113 +++++++++--------- 1 file changed, 57 insertions(+), 56 deletions(-) diff --git a/test_haystack/solr_tests/test_solr_management_commands.py b/test_haystack/solr_tests/test_solr_management_commands.py index f368f8ddc..b9119c423 100644 --- a/test_haystack/solr_tests/test_solr_management_commands.py +++ b/test_haystack/solr_tests/test_solr_management_commands.py @@ -227,62 +227,63 @@ def test_build_schema(self): oldui = connections["solr"].get_unified_index() oldurl = settings.HAYSTACK_CONNECTIONS["solr"]["URL"] - needle = "Th3S3cr3tK3y" - constants.DOCUMENT_FIELD = ( - needle - ) # Force index to use new key for document_fields - settings.HAYSTACK_CONNECTIONS["solr"]["URL"] = ( - settings.HAYSTACK_CONNECTIONS["solr"]["URL"].rsplit("/", 1)[0] + "/mgmnt" - ) - - ui = UnifiedIndex() - ui.build(indexes=[SolrMockSecretKeySearchIndex()]) - connections["solr"]._index = ui - - rendered_file = StringIO() - - script_dir = os.path.realpath(os.path.dirname(__file__)) - conf_dir = os.path.join( - script_dir, "server", "solr", "server", "solr", "mgmnt", "conf" - ) - schema_file = os.path.join(conf_dir, "schema.xml") - solrconfig_file = os.path.join(conf_dir, "solrconfig.xml") - - self.assertTrue( - os.path.isdir(conf_dir), msg="Expected %s to be a directory" % conf_dir - ) - - call_command("build_solr_schema", using="solr", stdout=rendered_file) - contents = rendered_file.getvalue() - self.assertGreater(contents.find('name="%s' % needle), -1) - - call_command("build_solr_schema", using="solr", configure_directory=conf_dir) - with open(schema_file) as s: - self.assertGreater(s.read().find('name="%s' % needle), -1) - with open(solrconfig_file) as s: - self.assertGreater(s.read().find('name="df">%s' % needle), -1) - - self.assertTrue(os.path.isfile(os.path.join(conf_dir, "managed-schema.old"))) - - call_command("build_solr_schema", using="solr", reload_core=True) - - os.rename(schema_file, "%s.bak" % schema_file) - self.assertRaises( - CommandError, - call_command, - "build_solr_schema", - using="solr", - reload_core=True, - ) - - call_command("build_solr_schema", using="solr", filename=schema_file) - with open(schema_file) as s: - self.assertGreater(s.read().find('name="%s' % needle), -1) - - # reset - constants.DOCUMENT_FIELD = oldhdf - connections["solr"]._index = oldui - settings.HAYSTACK_CONNECTIONS["solr"]["URL"] = oldurl + try: + needle = "Th3S3cr3tK3y" + constants.DOCUMENT_FIELD = ( + needle + ) # Force index to use new key for document_fields + settings.HAYSTACK_CONNECTIONS["solr"]["URL"] = ( + settings.HAYSTACK_CONNECTIONS["solr"]["URL"].rsplit("/", 1)[0] + "/mgmnt" + ) + + ui = UnifiedIndex() + ui.build(indexes=[SolrMockSecretKeySearchIndex()]) + connections["solr"]._index = ui + + rendered_file = StringIO() + + script_dir = os.path.realpath(os.path.dirname(__file__)) + conf_dir = os.path.join( + script_dir, "server", "solr", "server", "solr", "mgmnt", "conf" + ) + schema_file = os.path.join(conf_dir, "schema.xml") + solrconfig_file = os.path.join(conf_dir, "solrconfig.xml") + + self.assertTrue( + os.path.isdir(conf_dir), msg="Expected %s to be a directory" % conf_dir + ) + + call_command("build_solr_schema", using="solr", stdout=rendered_file) + contents = rendered_file.getvalue() + self.assertGreater(contents.find('name="%s' % needle), -1) + + call_command("build_solr_schema", using="solr", configure_directory=conf_dir) + with open(schema_file) as s: + self.assertGreater(s.read().find('name="%s' % needle), -1) + with open(solrconfig_file) as s: + self.assertGreater(s.read().find('name="df">%s' % needle), -1) + + self.assertTrue(os.path.isfile(os.path.join(conf_dir, "managed-schema.old"))) + + call_command("build_solr_schema", using="solr", reload_core=True) + + os.rename(schema_file, "%s.bak" % schema_file) + self.assertRaises( + CommandError, + call_command, + "build_solr_schema", + using="solr", + reload_core=True, + ) + + call_command("build_solr_schema", using="solr", filename=schema_file) + with open(schema_file) as s: + self.assertGreater(s.read().find('name="%s' % needle), -1) + finally: + # reset + constants.DOCUMENT_FIELD = oldhdf + connections["solr"]._index = oldui + settings.HAYSTACK_CONNECTIONS["solr"]["URL"] = oldurl class AppModelManagementCommandTestCase(TestCase): From 1e8ac2035dfb66107070edc4eaa12376795981ff Mon Sep 17 00:00:00 2001 From: Alexander Clausen Date: Fri, 24 Jan 2020 23:44:45 +0100 Subject: [PATCH 30/37] add linebreaks to make docker command readable --- test_haystack/solr_tests/server/start-solr-test-server.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test_haystack/solr_tests/server/start-solr-test-server.sh b/test_haystack/solr_tests/server/start-solr-test-server.sh index 07c9c2b06..96cd583c0 100755 --- a/test_haystack/solr_tests/server/start-solr-test-server.sh +++ b/test_haystack/solr_tests/server/start-solr-test-server.sh @@ -13,4 +13,7 @@ fi # https://stackoverflow.com/a/246128/540644 DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -docker run ${ARGS} -p 9001:8983 -v $DIR/solr-setup.sh:/solr-setup.sh -v $DIR/confdir:/confdir:ro solr:${SOLR_VERSION}-slim bash -c "/solr-setup.sh" +docker run --rm ${ARGS} -p 9001:8983 \ + -v $DIR/solr-setup.sh:/solr-setup.sh \ + -v $DIR/confdir:/confdir:ro \ + --name haystack_solr solr:${SOLR_VERSION}-slim bash -c "/solr-setup.sh" From 6c1381fd73fd3f1991b5f376f7bfe83c8dc506aa Mon Sep 17 00:00:00 2001 From: Alexander Clausen Date: Fri, 24 Jan 2020 23:45:12 +0100 Subject: [PATCH 31/37] Update tox.ini to match Python versions in travis --- tox.ini | 105 ++++++++++++++++++++++++++------------------------------ 1 file changed, 49 insertions(+), 56 deletions(-) diff --git a/tox.ini b/tox.ini index 7539c6cc2..c2786ea69 100644 --- a/tox.ini +++ b/tox.ini @@ -1,26 +1,25 @@ [tox] envlist = docs, - py27-django1.11-es1.x, - py34-django1.11-es1.x, - py34-django2.0-es1.x, py35-django1.11-es1.x, py35-django2.0-es1.x, py35-django2.1-es1.x, pypy-django1.11-es1.x, - py27-django1.11-es2.x, - py34-django1.11-es2.x, - py34-django2.0-es2.x, py35-django1.11-es2.x, py35-django2.0-es2.x, py35-django2.1-es2.x, py36-django1.11-es2.x, py36-django2.0-es2.x, py36-django2.1-es2.x, + py37-django1.11-es2.x, + py37-django2.0-es2.x, + py37-django2.1-es2.x, pypy-django1.11-es2.x, - py27-django1.11-es5.x, py36-django1.11-es5.x, py36-django2.0-es5.x, py36-django2.1-es5.x, + py37-django1.11-es5.x, + py37-django2.0-es5.x, + py37-django2.1-es5.x, pypy-django1.11-es5.x, [base] @@ -61,28 +60,6 @@ deps = {[django1.11]deps} {[base]deps} -[testenv:py27-django1.11-es1.x] -basepython = python2.7 -setenv = VERSION_ES=>=1.0.0,<2.0.0 -deps = - {[es1.x]deps} - {[django1.11]deps} - {[base]deps} - -[testenv:py34-django1.11-es1.x] -basepython = python3.4 -setenv = VERSION_ES=>=1.0.0,<2.0.0 -deps = - {[django1.11]deps} - {[base]deps} - -[testenv:py34-django2.0-es1.x] -basepython = python3.4 -setenv = VERSION_ES=>=1.0.0,<2.0.0 -deps = - {[django2.0]deps} - {[base]deps} - [testenv:py35-django1.11-es1.x] basepython = python3.5 setenv = VERSION_ES=>=1.0.0,<2.0.0 @@ -114,72 +91,72 @@ deps = {[django1.11]deps} {[base]deps} -[testenv:py27-django1.11-es2.x] -basepython = python2.7 +[testenv:py35-django1.11-es2.x] +basepython = python3.5 setenv = VERSION_ES=>=2.0.0,<3.0.0 deps = {[es2.x]deps} {[django1.11]deps} {[base]deps} -[testenv:py34-django1.11-es2.x] -basepython = python3.4 +[testenv:py35-django2.0-es2.x] +basepython = python3.5 setenv = VERSION_ES=>=2.0.0,<3.0.0 deps = {[es2.x]deps} - {[django1.11]deps} + {[django2.0]deps} {[base]deps} -[testenv:py34-django2.0-es2.x] -basepython = python3.4 +[testenv:py35-django2.1-es2.x] +basepython = python3.5 setenv = VERSION_ES=>=2.0.0,<3.0.0 deps = {[es2.x]deps} - {[django2.0]deps} + {[django2.1]deps} {[base]deps} -[testenv:py35-django1.11-es2.x] -basepython = python3.5 +[testenv:py36-django1.11-es2.x] +basepython = python3.6 setenv = VERSION_ES=>=2.0.0,<3.0.0 deps = {[es2.x]deps} {[django1.11]deps} {[base]deps} -[testenv:py35-django2.0-es2.x] -basepython = python3.5 +[testenv:py36-django2.0-es2.x] +basepython = python3.6 setenv = VERSION_ES=>=2.0.0,<3.0.0 deps = {[es2.x]deps} {[django2.0]deps} {[base]deps} -[testenv:py35-django2.1-es2.x] -basepython = python3.5 +[testenv:py36-django2.1-es2.x] +basepython = python3.6 setenv = VERSION_ES=>=2.0.0,<3.0.0 deps = {[es2.x]deps} {[django2.1]deps} {[base]deps} -[testenv:py36-django1.11-es2.x] -basepython = python3.6 +[testenv:py37-django1.11-es2.x] +basepython = python3.7 setenv = VERSION_ES=>=2.0.0,<3.0.0 deps = {[es2.x]deps} {[django1.11]deps} {[base]deps} -[testenv:py36-django2.0-es2.x] -basepython = python3.6 +[testenv:py37-django2.0-es2.x] +basepython = python3.7 setenv = VERSION_ES=>=2.0.0,<3.0.0 deps = {[es2.x]deps} {[django2.0]deps} {[base]deps} -[testenv:py36-django2.1-es2.x] -basepython = python3.6 +[testenv:py37-django2.1-es2.x] +basepython = python3.7 setenv = VERSION_ES=>=2.0.0,<3.0.0 deps = {[es2.x]deps} @@ -193,32 +170,48 @@ deps = {[django1.11]deps} {[base]deps} -[testenv:py27-django1.11-es5.x] -basepython = python2.7 +[testenv:py36-django1.11-es5.x] +basepython = python3.6 setenv = VERSION_ES=>=5.0.0,<6.0.0 deps = {[es5.x]deps} {[django1.11]deps} {[base]deps} -[testenv:py36-django1.11-es5.x] +[testenv:py36-django2.0-es5.x] basepython = python3.6 setenv = VERSION_ES=>=5.0.0,<6.0.0 deps = {[es5.x]deps} - {[django1.11]deps} + {[django2.0]deps} {[base]deps} -[testenv:py36-django2.0-es5.x] +[testenv:py36-django2.1-es5.x] basepython = python3.6 setenv = VERSION_ES=>=5.0.0,<6.0.0 +deps = + {[es5.x]deps} + {[django2.1]deps} + {[base]deps} + +[testenv:py37-django1.11-es5.x] +basepython = python3.7 +setenv = VERSION_ES=>=5.0.0,<6.0.0 +deps = + {[es5.x]deps} + {[django1.11]deps} + {[base]deps} + +[testenv:py37-django2.0-es5.x] +basepython = python3.7 +setenv = VERSION_ES=>=5.0.0,<6.0.0 deps = {[es5.x]deps} {[django2.0]deps} {[base]deps} -[testenv:py36-django2.1-es5.x] -basepython = python3.6 +[testenv:py37-django2.1-es5.x] +basepython = python3.7 setenv = VERSION_ES=>=5.0.0,<6.0.0 deps = {[es5.x]deps} From 2423f9d2dec14f0dc0e7232de095e2923cdde8a5 Mon Sep 17 00:00:00 2001 From: Alexander Clausen Date: Mon, 27 Jan 2020 10:51:09 +0100 Subject: [PATCH 32/37] Revert "Run solr via docker" This reverts commit 037eed7a4f9e5265b57eab36f14e4fe1af56dbae. --- .../server/get-solr-download-url.py | 65 ++++++++++++++++ test_haystack/solr_tests/server/solr-setup.sh | 23 ------ .../server/start-solr-test-server.sh | 77 ++++++++++++++++--- 3 files changed, 131 insertions(+), 34 deletions(-) create mode 100755 test_haystack/solr_tests/server/get-solr-download-url.py delete mode 100755 test_haystack/solr_tests/server/solr-setup.sh diff --git a/test_haystack/solr_tests/server/get-solr-download-url.py b/test_haystack/solr_tests/server/get-solr-download-url.py new file mode 100755 index 000000000..14569b708 --- /dev/null +++ b/test_haystack/solr_tests/server/get-solr-download-url.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +# encoding: utf-8 + +from __future__ import absolute_import, division, print_function, unicode_literals + +import sys +from itertools import chain + +import requests + +# Try to import urljoin from the Python 3 reorganized stdlib first: +try: + from urllib.parse import urljoin +except ImportError: + from urlparse import urljoin + + +if len(sys.argv) != 2: + print("Usage: %s SOLR_VERSION" % sys.argv[0], file=sys.stderr) + sys.exit(1) + +solr_version = sys.argv[1] +tarball = "solr-{0}.tgz".format(solr_version) +dist_path = "lucene/solr/{0}/{1}".format(solr_version, tarball) + +download_url = urljoin("https://archive.apache.org/dist/", dist_path) +mirror_response = requests.get( + "https://www.apache.org/dyn/mirrors/mirrors.cgi/%s?asjson=1" % dist_path +) + +if not mirror_response.ok: + print( + "Apache mirror request returned HTTP %d" % mirror_response.status_code, + file=sys.stderr, + ) + sys.exit(1) + +mirror_data = mirror_response.json() + +# Since the Apache mirrors are often unreliable and releases may disappear without notice we'll +# try the preferred mirror, all of the alternates and backups, and fall back to the main Apache +# archive server: +for base_url in chain( + (mirror_data["preferred"],), + mirror_data["http"], + mirror_data["backup"], + ("https://archive.apache.org/dist/",), +): + test_url = urljoin(base_url, mirror_data["path_info"]) + + # The Apache mirror script's response format has recently changed to exclude the actual file paths: + if not test_url.endswith(tarball): + test_url = urljoin(test_url, dist_path) + + try: + if requests.head(test_url, allow_redirects=True).status_code == 200: + download_url = test_url + break + except requests.exceptions.ConnectionError: + continue +else: + print("None of the Apache mirrors have %s" % dist_path, file=sys.stderr) + sys.exit(1) + +print(download_url) diff --git a/test_haystack/solr_tests/server/solr-setup.sh b/test_haystack/solr_tests/server/solr-setup.sh deleted file mode 100755 index f9cef556e..000000000 --- a/test_haystack/solr_tests/server/solr-setup.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -set -e - -# this script is run in the container as setup - -CONFDEST=/opt/solr/server/solr/configsets/collection1/conf/ -BASIC_CONFIGS=/opt/solr/server/solr/configsets/basic_configs/conf/ - -# put configuration in place: -mkdir -p $CONFDEST -cp -r /confdir/* $CONFDEST - - -# borrow some files from the basic_configs configset: -cp -r $BASIC_CONFIGS/lang $CONFDEST -cp -r $BASIC_CONFIGS/*.txt $CONFDEST -cp -r $BASIC_CONFIGS/{currency,elevate}.xml $CONFDEST - -ls -la $CONFDEST/ - -precreate-core collection1 $CONFDEST/../ -precreate-core mgmnt -exec solr-foreground diff --git a/test_haystack/solr_tests/server/start-solr-test-server.sh b/test_haystack/solr_tests/server/start-solr-test-server.sh index 96cd583c0..9bd57ea5f 100755 --- a/test_haystack/solr_tests/server/start-solr-test-server.sh +++ b/test_haystack/solr_tests/server/start-solr-test-server.sh @@ -2,18 +2,73 @@ set -e -SOLR_VERSION=6.6.6 +SOLR_VERSION=6.6.4 +SOLR_DIR=solr -if [ -z "${BACKGROUND_SOLR}" ]; then - ARGS="" -else - ARGS="-d" + +SOLR_PORT=9001 + +cd $(dirname $0) + +export TEST_ROOT=$(pwd) + +export SOLR_ARCHIVE="${SOLR_VERSION}.tgz" + +if [ -d "${HOME}/download-cache/" ]; then + export SOLR_ARCHIVE="${HOME}/download-cache/${SOLR_ARCHIVE}" +fi + +if [ -f ${SOLR_ARCHIVE} ]; then + # If the tarball doesn't extract cleanly, remove it so it'll download again: + tar -tf ${SOLR_ARCHIVE} > /dev/null || rm ${SOLR_ARCHIVE} fi -# https://stackoverflow.com/a/246128/540644 -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +if [ ! -f ${SOLR_ARCHIVE} ]; then + SOLR_DOWNLOAD_URL=$(python get-solr-download-url.py $SOLR_VERSION) + curl -Lo $SOLR_ARCHIVE ${SOLR_DOWNLOAD_URL} || (echo "Unable to download ${SOLR_DOWNLOAD_URL}"; exit 2) +fi + +echo "Extracting Solr ${SOLR_ARCHIVE} to ${TEST_ROOT}/${SOLR_DIR}" +rm -rf ${SOLR_DIR} +mkdir ${SOLR_DIR} +FULL_SOLR_DIR=$(readlink -f ./${SOLR_DIR}) +tar -C ${SOLR_DIR} -xf ${SOLR_ARCHIVE} --strip-components=1 + +# These tuning options will break on Java 10 and for testing we don't care about +# production server optimizations: +export GC_LOG_OPTS="" +export GC_TUNE="" -docker run --rm ${ARGS} -p 9001:8983 \ - -v $DIR/solr-setup.sh:/solr-setup.sh \ - -v $DIR/confdir:/confdir:ro \ - --name haystack_solr solr:${SOLR_VERSION}-slim bash -c "/solr-setup.sh" +export SOLR_LOGS_DIR="${FULL_SOLR_DIR}/logs" + +install -d ${SOLR_LOGS_DIR} + +echo "Changing into ${FULL_SOLR_DIR} " + +cd ${FULL_SOLR_DIR} + +echo "Creating Solr Core" +./bin/solr start -p ${SOLR_PORT} +./bin/solr create -c collection1 -p ${SOLR_PORT} -n basic_config +./bin/solr create -c mgmnt -p ${SOLR_PORT} + +echo "Solr system information:" +curl --fail --silent 'http://localhost:9001/solr/admin/info/system?wt=json&indent=on' | python -m json.tool +./bin/solr stop -p ${SOLR_PORT} + +CONF_DIR=${TEST_ROOT}/confdir +CORE_DIR=${FULL_SOLR_DIR}/server/solr/collection1 +mv ${CORE_DIR}/conf/managed-schema ${CORE_DIR}/conf/managed-schema.old +cp ${CONF_DIR}/* ${CORE_DIR}/conf/ + +echo 'Starting server' +cd server +# We use exec to allow process monitors to correctly kill the +# actual Java process rather than this launcher script: +export CMD="java -Djetty.port=${SOLR_PORT} -Djava.awt.headless=true -Dapple.awt.UIElement=true -jar start.jar --module=http -Dsolr.install.dir=${FULL_SOLR_DIR} -Dsolr.log.dir=${SOLR_LOGS_DIR}" + +if [ -z "${BACKGROUND_SOLR}" ]; then + exec $CMD +else + exec $CMD >/dev/null & +fi From 47a5352ac14a7a3a8d547d645eae766424f1904b Mon Sep 17 00:00:00 2001 From: Samir Shah Date: Wed, 12 Feb 2020 10:44:45 +0300 Subject: [PATCH 33/37] Drop support for Python 2 and old versions of Django. Add support for Django 3. --- .travis.yml | 38 +-- README.rst | 2 +- docs/conf.py | 2 - docs/searchindex_api.rst | 4 +- example_project/bare_bones_app/models.py | 5 +- .../bare_bones_app/search_indexes.py | 3 - example_project/regular_app/models.py | 7 +- example_project/regular_app/search_indexes.py | 3 - example_project/settings.py | 3 - haystack/__init__.py | 3 - haystack/admin.py | 7 +- haystack/apps.py | 2 - haystack/backends/__init__.py | 20 +- haystack/backends/elasticsearch2_backend.py | 2 - haystack/backends/elasticsearch5_backend.py | 2 - haystack/backends/elasticsearch_backend.py | 16 +- haystack/backends/simple_backend.py | 9 +- haystack/backends/solr_backend.py | 14 +- haystack/backends/whoosh_backend.py | 34 ++- haystack/constants.py | 3 - haystack/exceptions.py | 3 - haystack/fields.py | 15 +- haystack/forms.py | 3 - haystack/generic_views.py | 3 - haystack/indexes.py | 10 +- haystack/inputs.py | 9 +- .../management/commands/build_solr_schema.py | 3 - haystack/management/commands/clear_index.py | 6 +- haystack/management/commands/haystack_info.py | 3 - haystack/management/commands/rebuild_index.py | 2 - haystack/management/commands/update_index.py | 6 +- haystack/manager.py | 3 - haystack/models.py | 16 +- haystack/panels.py | 6 +- haystack/query.py | 10 +- haystack/routers.py | 3 - haystack/signals.py | 3 - haystack/templatetags/highlight.py | 10 +- haystack/templatetags/more_like_this.py | 3 - haystack/urls.py | 3 - haystack/utils/__init__.py | 7 +- haystack/utils/app_loading.py | 2 - haystack/utils/geo.py | 3 - haystack/utils/highlighting.py | 3 - haystack/utils/loading.py | 4 - haystack/utils/log.py | 3 - haystack/views.py | 3 - setup.py | 13 +- test_haystack/__init__.py | 2 - test_haystack/core/admin.py | 3 - test_haystack/core/custom_identifier.py | 3 - test_haystack/core/models.py | 20 +- test_haystack/core/urls.py | 3 - test_haystack/discovery/models.py | 7 +- test_haystack/discovery/search_indexes.py | 3 - .../elasticsearch2_tests/test_backend.py | 2 - .../elasticsearch2_tests/test_inputs.py | 3 - .../elasticsearch2_tests/test_query.py | 2 - .../elasticsearch5_tests/test_backend.py | 2 - .../elasticsearch5_tests/test_inputs.py | 3 - .../elasticsearch5_tests/test_query.py | 2 - .../test_elasticsearch_backend.py | 2 - .../test_elasticsearch_query.py | 3 - .../elasticsearch_tests/test_inputs.py | 3 - test_haystack/mocks.py | 3 - test_haystack/multipleindex/__init__.py | 3 - test_haystack/multipleindex/models.py | 7 +- test_haystack/multipleindex/routers.py | 3 - test_haystack/multipleindex/search_indexes.py | 3 - test_haystack/multipleindex/tests.py | 3 - test_haystack/results_per_page_urls.py | 3 - test_haystack/run_tests.py | 3 - test_haystack/settings.py | 9 +- test_haystack/simple_tests/search_indexes.py | 3 - .../simple_tests/test_simple_backend.py | 2 - .../simple_tests/test_simple_query.py | 3 - .../server/get-solr-download-url.py | 3 - test_haystack/solr_tests/server/wait-for-solr | 2 - test_haystack/solr_tests/test_admin.py | 3 - test_haystack/solr_tests/test_inputs.py | 3 - test_haystack/solr_tests/test_solr_backend.py | 4 +- .../test_solr_management_commands.py | 5 +- test_haystack/solr_tests/test_solr_query.py | 3 - test_haystack/solr_tests/test_templatetags.py | 4 +- test_haystack/spatial/__init__.py | 3 - test_haystack/spatial/models.py | 3 - test_haystack/spatial/search_indexes.py | 3 - test_haystack/spatial/test_spatial.py | 3 - test_haystack/test_altered_internal_names.py | 3 - test_haystack/test_app_loading.py | 2 - .../test_app_using_appconfig/__init__.py | 3 - .../test_app_using_appconfig/apps.py | 2 - .../migrations/0001_initial.py | 2 - .../test_app_using_appconfig/models.py | 3 - .../search_indexes.py | 3 - .../test_app_using_appconfig/tests.py | 3 - .../django/hierarchal_app_django/models.py | 3 - test_haystack/test_app_without_models/urls.py | 3 - .../test_app_without_models/views.py | 3 - test_haystack/test_backends.py | 3 - test_haystack/test_discovery.py | 3 - test_haystack/test_fields.py | 5 +- test_haystack/test_forms.py | 2 - test_haystack/test_generic_views.py | 3 - test_haystack/test_indexes.py | 5 +- test_haystack/test_inputs.py | 3 - test_haystack/test_loading.py | 3 - test_haystack/test_management_commands.py | 4 +- test_haystack/test_managers.py | 3 - test_haystack/test_models.py | 9 +- test_haystack/test_query.py | 2 - test_haystack/test_templatetags.py | 2 - test_haystack/test_utils.py | 3 - test_haystack/test_views.py | 5 +- test_haystack/utils.py | 3 - test_haystack/whoosh_tests/test_forms.py | 2 - test_haystack/whoosh_tests/test_inputs.py | 3 - .../whoosh_tests/test_whoosh_backend.py | 3 - .../whoosh_tests/test_whoosh_query.py | 3 - test_haystack/whoosh_tests/testcases.py | 3 - tox.ini | 224 ++---------------- 121 files changed, 138 insertions(+), 672 deletions(-) diff --git a/.travis.yml b/.travis.yml index 839dc068a..660cb0f07 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ python: - 3.5 - 3.6 - 3.7 + - 3.8 - pypy3 services: - docker @@ -29,10 +30,10 @@ addons: before_install: - mkdir -p $HOME/download-cache - > - if [[ $VERSION_ES == '>=2.0.0,<3.0.0' ]]; + if [[ $VERSION_ES == '>=2,<3' ]]; then docker run -d -p 9200:9200 elasticsearch:2.4.6-alpine - elif [[ $VERSION_ES == '>=5.0.0,<6.0.0' ]]; + elif [[ $VERSION_ES == '>=5,<6' ]]; then docker run -d -p 9200:9200 elasticsearch:5.6.10-alpine else @@ -59,31 +60,34 @@ env: global: - JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 jobs: - - DJANGO_VERSION=">=1.11,<2.0" VERSION_ES=">=1.0.0,<2.0.0" - - DJANGO_VERSION=">=2.0,<2.1" VERSION_ES=">=1.0.0,<2.0.0" - - DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=1.0.0,<2.0.0" - - DJANGO_VERSION=">=1.11,<2.0" VERSION_ES=">=2.0.0,<3.0.0" - - DJANGO_VERSION=">=2.0,<2.1" VERSION_ES=">=2.0.0,<3.0.0" - - DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=2.0.0,<3.0.0" - - DJANGO_VERSION=">=1.11,<2.0" VERSION_ES=">=5.0.0,<6.0.0" - - DJANGO_VERSION=">=2.0,<2.1" VERSION_ES=">=5.0.0,<6.0.0" - - DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=5.0.0,<6.0.0" + - DJANGO_VERSION=">=2.2,<3.0" VERSION_ES=">=1,<2" + - DJANGO_VERSION=">=3.0,<3.1" VERSION_ES=">=1,<2" + - DJANGO_VERSION=">=2.2,<3.0" VERSION_ES=">=2,<3" + - DJANGO_VERSION=">=3.0,<3.1" VERSION_ES=">=2,<3" + - DJANGO_VERSION=">=2.2,<3.0" VERSION_ES=">=5,<6" + - DJANGO_VERSION=">=3.0,<3.1" VERSION_ES=">=5,<6" jobs: allow_failures: - python: 'pypy3' exclude: - python: pypy3 - env: DJANGO_VERSION=">=2.0,<2.1" VERSION_ES=">=5.0.0,<6.0.0" + env: DJANGO_VERSION=">=2.2,<3.0" VERSION_ES=">=5,<6" - python: pypy3 - env: DJANGO_VERSION=">=2.0,<2.1" VERSION_ES=">=2.0.0,<3.0.0" + env: DJANGO_VERSION=">=2.2,<3.0" VERSION_ES=">=2,<3" - python: pypy3 - env: DJANGO_VERSION=">=2.0,<2.1" VERSION_ES=">=1.0.0,<2.0.0" + env: DJANGO_VERSION=">=2.2,<3.0" VERSION_ES=">=1,<2" - python: pypy3 - env: DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=5.0.0,<6.0.0" + env: DJANGO_VERSION=">=3.0,<3.1" VERSION_ES=">=5,<6" - python: pypy3 - env: DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=2.0.0,<3.0.0" + env: DJANGO_VERSION=">=3.0,<3.1" VERSION_ES=">=2,<3" - python: pypy3 - env: DJANGO_VERSION=">=2.1,<2.2" VERSION_ES=">=1.0.0,<2.0.0" + env: DJANGO_VERSION=">=3.0,<3.1" VERSION_ES=">=1,<2" + - python: 3.5 + env: DJANGO_VERSION=">=3.0,<3.1" VERSION_ES=">=1,<2" + - python: 3.5 + env: DJANGO_VERSION=">=3.0,<3.1" VERSION_ES=">=2,<3" + - python: 3.5 + env: DJANGO_VERSION=">=3.0,<3.1" VERSION_ES=">=5,<6" notifications: irc: 'irc.freenode.org#haystack' diff --git a/README.rst b/README.rst index 4a1af4033..1eb90f0a4 100644 --- a/README.rst +++ b/README.rst @@ -50,7 +50,7 @@ Requirements Haystack has a relatively easily-met set of requirements. -* Python 2.7+ or Python 3.3+ +* Python 3.5+ * A supported version of Django: https://www.djangoproject.com/download/#supported-versions Additionally, each backend has its own requirements. You should refer to diff --git a/docs/conf.py b/docs/conf.py index 022e40b2a..2ff433372 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -11,8 +11,6 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from __future__ import absolute_import, division, print_function, unicode_literals - import os import sys diff --git a/docs/searchindex_api.rst b/docs/searchindex_api.rst index 4dd234832..c8da131ed 100644 --- a/docs/searchindex_api.rst +++ b/docs/searchindex_api.rst @@ -332,7 +332,6 @@ object and write its ``prepare`` method to populate/alter the data any way you choose. For instance, a (naive) user-created ``GeoPointField`` might look something like:: - from django.utils import six from haystack import indexes class GeoPointField(indexes.CharField): @@ -341,7 +340,7 @@ something like:: super(GeoPointField, self).__init__(**kwargs) def prepare(self, obj): - return six.text_type("%s-%s" % (obj.latitude, obj.longitude)) + return "%s-%s" % (obj.latitude, obj.longitude) The ``prepare`` method simply returns the value to be used for that field. It's entirely possible to include data that's not directly referenced to the object @@ -615,4 +614,3 @@ For the impatient:: def index_queryset(self, using=None): "Used when the entire index for model is updated." return Note.objects.filter(pub_date__lte=datetime.datetime.now()) - diff --git a/example_project/bare_bones_app/models.py b/example_project/bare_bones_app/models.py index 47739369e..aac17e9c9 100644 --- a/example_project/bare_bones_app/models.py +++ b/example_project/bare_bones_app/models.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import datetime from django.db import models @@ -14,7 +11,7 @@ class Cat(models.Model): created = models.DateTimeField(default=datetime.datetime.now) updated = models.DateTimeField(default=datetime.datetime.now) - def __unicode__(self): + def __str__(self): return self.name @models.permalink diff --git a/example_project/bare_bones_app/search_indexes.py b/example_project/bare_bones_app/search_indexes.py index ab93b8e29..09d8bf789 100644 --- a/example_project/bare_bones_app/search_indexes.py +++ b/example_project/bare_bones_app/search_indexes.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from bare_bones_app.models import Cat from haystack import indexes diff --git a/example_project/regular_app/models.py b/example_project/regular_app/models.py index 66025f31a..bbbb80d7a 100644 --- a/example_project/regular_app/models.py +++ b/example_project/regular_app/models.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import datetime from django.db import models @@ -25,7 +22,7 @@ class Dog(models.Model): created = models.DateTimeField(default=datetime.datetime.now) updated = models.DateTimeField(default=datetime.datetime.now) - def __unicode__(self): + def __str__(self): return self.full_name() @models.permalink @@ -43,5 +40,5 @@ class Toy(models.Model): dog = models.ForeignKey(Dog, related_name="toys") name = models.CharField(max_length=60) - def __unicode__(self): + def __str__(self): return "%s's %s" % (self.dog.name, self.name) diff --git a/example_project/regular_app/search_indexes.py b/example_project/regular_app/search_indexes.py index 60dbb2136..60dcb95ba 100644 --- a/example_project/regular_app/search_indexes.py +++ b/example_project/regular_app/search_indexes.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from regular_app.models import Dog from haystack import indexes diff --git a/example_project/settings.py b/example_project/settings.py index bd1341c2d..beb96c418 100644 --- a/example_project/settings.py +++ b/example_project/settings.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import os from django.conf import settings diff --git a/haystack/__init__.py b/haystack/__init__.py index 812a949a3..d25dcfec3 100644 --- a/haystack/__init__.py +++ b/haystack/__init__.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.conf import settings from django.core.exceptions import ImproperlyConfigured from pkg_resources import DistributionNotFound, get_distribution, parse_version diff --git a/haystack/admin.py b/haystack/admin.py index cfbe13092..390672393 100644 --- a/haystack/admin.py +++ b/haystack/admin.py @@ -1,13 +1,10 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.contrib.admin.options import ModelAdmin, csrf_protect_m from django.contrib.admin.views.main import SEARCH_VAR, ChangeList from django.core.exceptions import PermissionDenied from django.core.paginator import InvalidPage, Paginator from django.shortcuts import render -from django.utils.encoding import force_text +from django.utils.encoding import force_str from django.utils.translation import ungettext from haystack import connections @@ -135,7 +132,7 @@ def changelist_view(self, request, extra_context=None): ) context = { - "module_name": force_text(self.model._meta.verbose_name_plural), + "module_name": force_str(self.model._meta.verbose_name_plural), "selection_note": selection_note % {"count": len(changelist.result_list)}, "selection_note_all": selection_note_all % {"total_count": changelist.result_count}, diff --git a/haystack/apps.py b/haystack/apps.py index 239e83b60..579518637 100644 --- a/haystack/apps.py +++ b/haystack/apps.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import logging from django.apps import AppConfig diff --git a/haystack/backends/__init__.py b/haystack/backends/__init__.py index 77c0668f3..9cc0f8385 100644 --- a/haystack/backends/__init__.py +++ b/haystack/backends/__init__.py @@ -1,17 +1,13 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals - import copy from copy import deepcopy from time import time -import six - from django.conf import settings from django.db.models import Q from django.db.models.base import ModelBase from django.utils import tree -from django.utils.encoding import force_text +from django.utils.encoding import force_str from haystack.constants import VALID_FILTERS, FILTER_SEPARATOR, DEFAULT_ALIAS from haystack.exceptions import MoreLikeThisError, FacetingError @@ -163,7 +159,7 @@ def prep_value(self, value): Hook to give the backend a chance to prep an attribute value before sending it to the search engine. By default, just force it to unicode. """ - return force_text(value) + return force_str(value) def more_like_this( self, model_instance, additional_query_string=None, result_class=None @@ -315,9 +311,6 @@ def __bool__(self): """ return bool(self.children) - def __nonzero__(self): # Python 2 compatibility - return type(self).__bool__(self) - def __contains__(self, other): """ Returns True is 'other' is a direct child of this instance. @@ -407,12 +400,7 @@ def __repr__(self): ) def _repr_query_fragment_callback(self, field, filter_type, value): - if six.PY3: - value = force_text(value) - else: - value = force_text(value).encode("utf8") - - return "%s%s%s=%s" % (field, FILTER_SEPARATOR, filter_type, value) + return "%s%s%s=%s" % (field, FILTER_SEPARATOR, filter_type, force_str(value)) def as_query_string(self, query_fragment_callback): """ @@ -785,7 +773,7 @@ def clean(self, query_fragment): A basic (override-able) implementation is provided. """ - if not isinstance(query_fragment, six.string_types): + if not isinstance(query_fragment, str): return query_fragment words = query_fragment.split() diff --git a/haystack/backends/elasticsearch2_backend.py b/haystack/backends/elasticsearch2_backend.py index 5d149565d..ed28e52f4 100644 --- a/haystack/backends/elasticsearch2_backend.py +++ b/haystack/backends/elasticsearch2_backend.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import, division, print_function, unicode_literals - import datetime from django.conf import settings diff --git a/haystack/backends/elasticsearch5_backend.py b/haystack/backends/elasticsearch5_backend.py index 6574c37d1..1b1c20c7d 100644 --- a/haystack/backends/elasticsearch5_backend.py +++ b/haystack/backends/elasticsearch5_backend.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import, division, print_function, unicode_literals - import datetime import warnings diff --git a/haystack/backends/elasticsearch_backend.py b/haystack/backends/elasticsearch_backend.py index deaa1c675..582fec6ae 100644 --- a/haystack/backends/elasticsearch_backend.py +++ b/haystack/backends/elasticsearch_backend.py @@ -1,12 +1,8 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import re import warnings from datetime import datetime, timedelta -import six from django.conf import settings from django.core.exceptions import ImproperlyConfigured @@ -813,9 +809,9 @@ def _from_python(self, value): iso = self._iso_datetime(value) if iso: return iso - elif isinstance(value, six.binary_type): + elif isinstance(value, bytes): # TODO: Be stricter. - return six.text_type(value, errors="replace") + return str(value, errors="replace") elif isinstance(value, set): return list(value) return value @@ -825,7 +821,7 @@ def _to_python(self, value): if isinstance(value, (int, float, complex, list, tuple, bool)): return value - if isinstance(value, six.string_types): + if isinstance(value, str): possible_datetime = DATETIME_REGEX.search(value) if possible_datetime: @@ -894,7 +890,7 @@ def build_query_fragment(self, field, filter_type, value): if hasattr(value, "values_list"): value = list(value) - if isinstance(value, six.string_types): + if isinstance(value, str): # It's not an ``InputType``. Assume ``Clean``. value = Clean(value) else: @@ -945,7 +941,7 @@ def build_query_fragment(self, field, filter_type, value): # Iterate over terms & incorportate the converted form of each into the query. terms = [] - if isinstance(prepared_value, six.string_types): + if isinstance(prepared_value, str): for possible_value in prepared_value.split(" "): terms.append( filter_types[filter_type] @@ -1002,7 +998,7 @@ def build_alt_parser_query(self, parser_name, query_string="", **kwargs): kwarg_bits = [] for key in sorted(kwargs.keys()): - if isinstance(kwargs[key], six.string_types) and " " in kwargs[key]: + if isinstance(kwargs[key], str) and " " in kwargs[key]: kwarg_bits.append("%s='%s'" % (key, kwargs[key])) else: kwarg_bits.append("%s=%s" % (key, kwargs[key])) diff --git a/haystack/backends/simple_backend.py b/haystack/backends/simple_backend.py index 6eebecebe..2cadd1951 100644 --- a/haystack/backends/simple_backend.py +++ b/haystack/backends/simple_backend.py @@ -2,12 +2,9 @@ """ A very basic, ORM-based backend for simple search during tests. """ - -from __future__ import absolute_import, division, print_function, unicode_literals - +from functools import reduce from warnings import warn -import six from django.db.models import Q from haystack import connections @@ -71,7 +68,7 @@ def search(self, query_string, **kwargs): if queries: qs = model.objects.filter( - six.moves.reduce(lambda x, y: x | y, queries) + reduce(lambda x, y: x | y, queries) ) else: qs = [] @@ -128,7 +125,7 @@ def _build_sub_query(self, search_node): term_list.append(value.prepare(self)) - return (" ").join(map(six.text_type, term_list)) + return (" ").join(map(str, term_list)) class SimpleEngine(BaseEngine): diff --git a/haystack/backends/solr_backend.py b/haystack/backends/solr_backend.py index 308ca3556..ca12df11c 100644 --- a/haystack/backends/solr_backend.py +++ b/haystack/backends/solr_backend.py @@ -1,10 +1,6 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import warnings -import six from django.conf import settings from django.core.exceptions import ImproperlyConfigured @@ -518,7 +514,7 @@ def _process_results( if spelling_suggestions: # Maintain compatibility with older versions of Haystack which returned a single suggestion: spelling_suggestion = spelling_suggestions[-1] - assert isinstance(spelling_suggestion, six.string_types) + assert isinstance(spelling_suggestion, str) else: spelling_suggestion = None @@ -609,7 +605,7 @@ def extract_spelling_suggestions(self, raw_results): if isinstance(collations, dict): # Solr 6.5 collation_values = collations["collation"] - if isinstance(collation_values, six.string_types): + if isinstance(collation_values, str): collation_values = [collation_values] elif isinstance(collation_values, dict): # spellcheck.collateExtendedResults changes the format to a dictionary: @@ -634,7 +630,7 @@ def extract_spelling_suggestions(self, raw_results): spelling_suggestions.append(j["word"]) else: spelling_suggestions.append(j) - elif isinstance(suggestions[0], six.string_types) and isinstance( + elif isinstance(suggestions[0], str) and isinstance( suggestions[1], dict ): # Solr 6.4 uses a list of paired (word, dictionary) pairs: @@ -761,7 +757,7 @@ def build_query_fragment(self, field, filter_type, value): if hasattr(value, "values_list"): value = list(value) - if isinstance(value, six.string_types): + if isinstance(value, str): # It's not an ``InputType``. Assume ``Clean``. value = Clean(value) else: @@ -863,7 +859,7 @@ def build_alt_parser_query(self, parser_name, query_string="", **kwargs): kwarg_bits = [] for key in sorted(kwargs.keys()): - if isinstance(kwargs[key], six.string_types) and " " in kwargs[key]: + if isinstance(kwargs[key], str) and " " in kwargs[key]: kwarg_bits.append("%s='%s'" % (key, kwargs[key])) else: kwarg_bits.append("%s=%s" % (key, kwargs[key])) diff --git a/haystack/backends/whoosh_backend.py b/haystack/backends/whoosh_backend.py index 5163c441d..d4bc9053e 100644 --- a/haystack/backends/whoosh_backend.py +++ b/haystack/backends/whoosh_backend.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import json import os import re @@ -9,11 +6,10 @@ import threading import warnings -import six from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.utils.datetime_safe import datetime -from django.utils.encoding import force_text +from django.utils.encoding import force_str from haystack.backends import ( BaseEngine, @@ -428,7 +424,7 @@ def search( if len(query_string) == 0: return {"results": [], "hits": 0} - query_string = force_text(query_string) + query_string = force_str(query_string) # A one-character query (non-wildcard) gets nabbed by a stopwords # filter and should yield zero results. @@ -514,7 +510,7 @@ def search( for nq in narrow_queries: recent_narrowed_results = narrow_searcher.search( - self.parser.parse(force_text(nq)), limit=None + self.parser.parse(force_str(nq)), limit=None ) if len(recent_narrowed_results) <= 0: @@ -642,7 +638,7 @@ def more_like_this( for nq in narrow_queries: recent_narrowed_results = narrow_searcher.search( - self.parser.parse(force_text(nq)), limit=None + self.parser.parse(force_str(nq)), limit=None ) if len(recent_narrowed_results) <= 0: @@ -793,7 +789,7 @@ def create_spelling_suggestion(self, query_string): spelling_suggestion = None reader = self.index.reader() corrector = reader.corrector(self.content_field_name) - cleaned_query = force_text(query_string) + cleaned_query = force_str(query_string) if not query_string: return spelling_suggestion @@ -833,12 +829,12 @@ def _from_python(self, value): else: value = "false" elif isinstance(value, (list, tuple)): - value = ",".join([force_text(v) for v in value]) - elif isinstance(value, (six.integer_types, float)): + value = ",".join([force_str(v) for v in value]) + elif isinstance(value, (int, float)): # Leave it alone. pass else: - value = force_text(value) + value = force_str(value) return value def _to_python(self, value): @@ -852,7 +848,7 @@ def _to_python(self, value): elif value == "false": return False - if value and isinstance(value, six.string_types): + if value and isinstance(value, str): possible_datetime = DATETIME_REGEX.search(value) if possible_datetime: @@ -877,7 +873,7 @@ def _to_python(self, value): # Try to handle most built-in types. if isinstance( converted_value, - (list, tuple, set, dict, six.integer_types, float, complex), + (list, tuple, set, dict, int, float, complex), ): return converted_value except: @@ -891,9 +887,9 @@ def _to_python(self, value): class WhooshSearchQuery(BaseSearchQuery): def _convert_datetime(self, date): if hasattr(date, "hour"): - return force_text(date.strftime("%Y%m%d%H%M%S")) + return force_str(date.strftime("%Y%m%d%H%M%S")) else: - return force_text(date.strftime("%Y%m%d000000")) + return force_str(date.strftime("%Y%m%d000000")) def clean(self, query_fragment): """ @@ -934,7 +930,7 @@ def build_query_fragment(self, field, filter_type, value): if hasattr(value, "strftime"): is_datetime = True - if isinstance(value, six.string_types) and value != " ": + if isinstance(value, str) and value != " ": # It's not an ``InputType``. Assume ``Clean``. value = Clean(value) else: @@ -985,7 +981,7 @@ def build_query_fragment(self, field, filter_type, value): # Iterate over terms & incorportate the converted form of each into the query. terms = [] - if isinstance(prepared_value, six.string_types): + if isinstance(prepared_value, str): possible_values = prepared_value.split(" ") else: if is_datetime is True: @@ -1030,7 +1026,7 @@ def build_query_fragment(self, field, filter_type, value): if is_datetime is True: pv = self._convert_datetime(pv) - if isinstance(pv, six.string_types) and not is_datetime: + if isinstance(pv, str) and not is_datetime: in_options.append('"%s"' % pv) else: in_options.append("%s" % pv) diff --git a/haystack/constants.py b/haystack/constants.py index 24ad98d64..63491c63c 100644 --- a/haystack/constants.py +++ b/haystack/constants.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.conf import settings DEFAULT_ALIAS = "default" diff --git a/haystack/exceptions.py b/haystack/exceptions.py index 251559ee4..a1c038c34 100644 --- a/haystack/exceptions.py +++ b/haystack/exceptions.py @@ -1,8 +1,5 @@ # encoding: utf-8 -from __future__ import absolute_import, division, print_function, unicode_literals - - class HaystackError(Exception): """A generic exception for all others to extend.""" diff --git a/haystack/fields.py b/haystack/fields.py index b81112ad8..a12eab0dc 100644 --- a/haystack/fields.py +++ b/haystack/fields.py @@ -1,10 +1,7 @@ # encoding: utf-8 -from __future__ import absolute_import, division, print_function, unicode_literals - import re from inspect import ismethod -import six from django.template import loader from django.utils import datetime_safe @@ -241,7 +238,7 @@ def convert(self, value): if value is None: return None - return six.text_type(value) + return str(value) class LocationField(SearchField): @@ -270,7 +267,7 @@ def convert(self, value): value = ensure_point(value) return value - if isinstance(value, six.string_types): + if isinstance(value, str): lat, lng = value.split(",") elif isinstance(value, (list, tuple)): # GeoJSON-alike @@ -353,7 +350,7 @@ def convert(self, value): if value is None: return None - return six.text_type(value) + return str(value) class BooleanField(SearchField): @@ -391,7 +388,7 @@ def convert(self, value): if value is None: return None - if isinstance(value, six.string_types): + if isinstance(value, str): match = DATE_REGEX.search(value) if match: @@ -424,7 +421,7 @@ def convert(self, value): if value is None: return None - if isinstance(value, six.string_types): + if isinstance(value, str): match = DATETIME_REGEX.search(value) if match: @@ -469,7 +466,7 @@ def convert(self, value): if value is None: return None - if hasattr(value, "__iter__") and not isinstance(value, six.text_type): + if hasattr(value, "__iter__") and not isinstance(value, str): return value return [value] diff --git a/haystack/forms.py b/haystack/forms.py index 099f94817..27a784045 100644 --- a/haystack/forms.py +++ b/haystack/forms.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django import forms from django.utils.encoding import smart_text from django.utils.text import capfirst diff --git a/haystack/generic_views.py b/haystack/generic_views.py index 74cdfc9c9..5319ccb9e 100644 --- a/haystack/generic_views.py +++ b/haystack/generic_views.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.conf import settings from django.core.paginator import Paginator from django.views.generic import FormView diff --git a/haystack/indexes.py b/haystack/indexes.py index dea404e80..1e3bdbd08 100644 --- a/haystack/indexes.py +++ b/haystack/indexes.py @@ -1,14 +1,10 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import copy import threading import warnings from django.core.exceptions import ImproperlyConfigured -from django.utils.encoding import force_text -from six import with_metaclass +from django.utils.encoding import force_str from haystack import connection_router, connections from haystack.constants import Indexable # NOQA — exposed as a public export @@ -95,7 +91,7 @@ def __new__(cls, name, bases, attrs): return super(DeclarativeMetaclass, cls).__new__(cls, name, bases, attrs) -class SearchIndex(with_metaclass(DeclarativeMetaclass, threading.local)): +class SearchIndex(threading.local, metaclass=DeclarativeMetaclass): """ Base class for building indexes. @@ -221,7 +217,7 @@ def prepare(self, obj): self.prepared_data = { ID: get_identifier(obj), DJANGO_CT: get_model_ct(self.get_model()), - DJANGO_ID: force_text(obj.pk), + DJANGO_ID: force_str(obj.pk), } for field_name, field in self.fields.items(): diff --git a/haystack/inputs.py b/haystack/inputs.py index d990cbddf..712bb8c60 100644 --- a/haystack/inputs.py +++ b/haystack/inputs.py @@ -1,15 +1,10 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import re import warnings -from django.utils.encoding import force_text -from six import python_2_unicode_compatible +from django.utils.encoding import force_str -@python_2_unicode_compatible class BaseInput(object): """ The base input type. Doesn't do much. You want ``Raw`` instead. @@ -26,7 +21,7 @@ def __repr__(self): return "<%s '%s'>" % (self.__class__.__name__, self) def __str__(self): - return force_text(self.query_string) + return force_str(self.query_string) def prepare(self, query_obj): return self.query_string diff --git a/haystack/management/commands/build_solr_schema.py b/haystack/management/commands/build_solr_schema.py index dc6e48a8a..ab92166b8 100644 --- a/haystack/management/commands/build_solr_schema.py +++ b/haystack/management/commands/build_solr_schema.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import os import requests diff --git a/haystack/management/commands/clear_index.py b/haystack/management/commands/clear_index.py index 25011faa4..cb8a18ff5 100644 --- a/haystack/management/commands/clear_index.py +++ b/haystack/management/commands/clear_index.py @@ -1,8 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - -import six from django.core.management.base import BaseCommand from haystack import connections @@ -53,7 +49,7 @@ def handle(self, **options): "Your choices after this are to restore from backups or rebuild via the `rebuild_index` command." ) - yes_or_no = six.moves.input("Are you sure you wish to continue? [y/N] ") + yes_or_no = input("Are you sure you wish to continue? [y/N] ") if not yes_or_no.lower().startswith("y"): self.stdout.write("No action taken.") diff --git a/haystack/management/commands/haystack_info.py b/haystack/management/commands/haystack_info.py index 7d827e48b..603a72b9f 100644 --- a/haystack/management/commands/haystack_info.py +++ b/haystack/management/commands/haystack_info.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.core.management.base import BaseCommand from haystack import connections diff --git a/haystack/management/commands/rebuild_index.py b/haystack/management/commands/rebuild_index.py index aa8af8a7d..5d18f6afd 100644 --- a/haystack/management/commands/rebuild_index.py +++ b/haystack/management/commands/rebuild_index.py @@ -1,6 +1,4 @@ # encoding: utf-8 -from __future__ import absolute_import, division, print_function, unicode_literals - from django.core.management import call_command from django.core.management.base import BaseCommand diff --git a/haystack/management/commands/update_index.py b/haystack/management/commands/update_index.py index 3cb2f6d73..fdfbfc0c7 100755 --- a/haystack/management/commands/update_index.py +++ b/haystack/management/commands/update_index.py @@ -1,6 +1,4 @@ # encoding: utf-8 -from __future__ import absolute_import, division, print_function, unicode_literals - import logging import multiprocessing import os @@ -9,7 +7,7 @@ from django.core.management.base import BaseCommand from django.db import close_old_connections, reset_queries -from django.utils.encoding import force_text, smart_bytes +from django.utils.encoding import force_str, smart_bytes from django.utils.timezone import now from haystack import connections as haystack_connections @@ -305,7 +303,7 @@ def update_backend(self, label, using): if self.verbosity >= 1: self.stdout.write( "Indexing %d %s" - % (total, force_text(model._meta.verbose_name_plural)) + % (total, force_str(model._meta.verbose_name_plural)) ) batch_size = self.batchsize or backend.batch_size diff --git a/haystack/manager.py b/haystack/manager.py index fb262a464..711a2996c 100644 --- a/haystack/manager.py +++ b/haystack/manager.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from haystack.query import EmptySearchQuerySet, SearchQuerySet diff --git a/haystack/models.py b/haystack/models.py index dab9519ca..6a41665e9 100644 --- a/haystack/models.py +++ b/haystack/models.py @@ -1,12 +1,8 @@ # encoding: utf-8 # "Hey, Django! Look at me, I'm an app! For Serious!" - -from __future__ import absolute_import, division, print_function, unicode_literals - -import six from django.core.exceptions import ObjectDoesNotExist -from django.utils.encoding import force_text +from django.utils.encoding import force_str from django.utils.text import capfirst from haystack.exceptions import NotHandled, SpatialError @@ -59,8 +55,8 @@ def __repr__(self): self.pk, ) - def __unicode__(self): - return force_text(self.__repr__()) + def __str__(self): + return force_str(self.__repr__()) def __getattr__(self, attr): if attr == "__getnewargs__": @@ -169,7 +165,7 @@ def _get_verbose_name(self): self.log.error("Model could not be found for SearchResult '%s'.", self) return "" - return force_text(capfirst(self.model._meta.verbose_name)) + return force_str(capfirst(self.model._meta.verbose_name)) verbose_name = property(_get_verbose_name) @@ -178,7 +174,7 @@ def _get_verbose_name_plural(self): self.log.error("Model could not be found for SearchResult '%s'.", self) return "" - return force_text(capfirst(self.model._meta.verbose_name_plural)) + return force_str(capfirst(self.model._meta.verbose_name_plural)) verbose_name_plural = property(_get_verbose_name_plural) @@ -188,7 +184,7 @@ def content_type(self): self.log.error("Model could not be found for SearchResult '%s'.", self) return "" - return six.text_type(self.model._meta) + return str(self.model._meta) def get_additional_fields(self): """ diff --git a/haystack/panels.py b/haystack/panels.py index bdb9a7e4b..b1d3a48f5 100644 --- a/haystack/panels.py +++ b/haystack/panels.py @@ -1,10 +1,6 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import datetime -import six from debug_toolbar.panels import DebugPanel from django.template.loader import render_to_string from django.utils.translation import ugettext_lazy as _ @@ -70,7 +66,7 @@ def content(self): if query.get("additional_kwargs"): if query["additional_kwargs"].get("result_class"): - query["additional_kwargs"]["result_class"] = six.text_type( + query["additional_kwargs"]["result_class"] = str( query["additional_kwargs"]["result_class"] ) diff --git a/haystack/query.py b/haystack/query.py index 93f6ee1fd..606691bb2 100644 --- a/haystack/query.py +++ b/haystack/query.py @@ -1,12 +1,8 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - +from functools import reduce import operator import warnings -import six - from haystack import connection_router, connections from haystack.backends import SQ from haystack.constants import DEFAULT_OPERATOR, ITERATOR_LOAD_PER_QUERY @@ -283,7 +279,7 @@ def __getitem__(self, k): """ Retrieves an item or slice from the set of results. """ - if not isinstance(k, (slice, six.integer_types)): + if not isinstance(k, (slice, int)): raise TypeError assert (not isinstance(k, slice) and (k >= 0)) or ( isinstance(k, slice) @@ -513,7 +509,7 @@ def autocomplete(self, **kwargs): kwargs = {field_name: bit} query_bits.append(SQ(**kwargs)) - return clone.filter(six.moves.reduce(operator.__and__, query_bits)) + return clone.filter(reduce(operator.__and__, query_bits)) def using(self, connection_name): """ diff --git a/haystack/routers.py b/haystack/routers.py index 0a77e17f2..cdc180878 100644 --- a/haystack/routers.py +++ b/haystack/routers.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from haystack.constants import DEFAULT_ALIAS diff --git a/haystack/signals.py b/haystack/signals.py index 97d383056..a0f6a61c4 100644 --- a/haystack/signals.py +++ b/haystack/signals.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.db import models from haystack.exceptions import NotHandled diff --git a/haystack/templatetags/highlight.py b/haystack/templatetags/highlight.py index 3013b7368..ae901a9d6 100644 --- a/haystack/templatetags/highlight.py +++ b/haystack/templatetags/highlight.py @@ -1,8 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - -import six from django import template from django.conf import settings from django.core.exceptions import ImproperlyConfigured @@ -125,12 +121,12 @@ def highlight(parser, token): for bit in arg_bits: if bit == "css_class": - kwargs["css_class"] = six.next(arg_bits) + kwargs["css_class"] = next(arg_bits) if bit == "html_tag": - kwargs["html_tag"] = six.next(arg_bits) + kwargs["html_tag"] = next(arg_bits) if bit == "max_length": - kwargs["max_length"] = six.next(arg_bits) + kwargs["max_length"] = next(arg_bits) return HighlightNode(text_block, query, **kwargs) diff --git a/haystack/templatetags/more_like_this.py b/haystack/templatetags/more_like_this.py index 8f69cd3cb..2c4f37b77 100644 --- a/haystack/templatetags/more_like_this.py +++ b/haystack/templatetags/more_like_this.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import logging from django import template diff --git a/haystack/urls.py b/haystack/urls.py index f982545f1..5841f186e 100644 --- a/haystack/urls.py +++ b/haystack/urls.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.conf.urls import url from haystack.views import SearchView diff --git a/haystack/utils/__init__.py b/haystack/utils/__init__.py index 09737a79b..db47b7f0a 100644 --- a/haystack/utils/__init__.py +++ b/haystack/utils/__init__.py @@ -1,12 +1,7 @@ # encoding: utf-8 - -from __future__ import unicode_literals - import importlib -import six import re -import six from django.conf import settings from haystack.constants import ID, DJANGO_CT, DJANGO_ID @@ -23,7 +18,7 @@ def default_get_identifier(obj_or_string): If not overridden, uses ... """ - if isinstance(obj_or_string, six.string_types): + if isinstance(obj_or_string, str): if not IDENTIFIER_REGEX.match(obj_or_string): raise AttributeError( "Provided string '%s' is not a valid identifier." % obj_or_string diff --git a/haystack/utils/app_loading.py b/haystack/utils/app_loading.py index b553fd581..8e485cbbd 100755 --- a/haystack/utils/app_loading.py +++ b/haystack/utils/app_loading.py @@ -1,6 +1,4 @@ # encoding: utf-8 -from __future__ import absolute_import, division, print_function, unicode_literals - from django.apps import apps from django.core.exceptions import ImproperlyConfigured diff --git a/haystack/utils/geo.py b/haystack/utils/geo.py index a25c9dad9..6dcb22c06 100644 --- a/haystack/utils/geo.py +++ b/haystack/utils/geo.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from haystack.constants import WGS_84_SRID from haystack.exceptions import SpatialError diff --git a/haystack/utils/highlighting.py b/haystack/utils/highlighting.py index d57658267..a159233f0 100644 --- a/haystack/utils/highlighting.py +++ b/haystack/utils/highlighting.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.utils.html import strip_tags diff --git a/haystack/utils/loading.py b/haystack/utils/loading.py index 688a74de0..bd05e4503 100644 --- a/haystack/utils/loading.py +++ b/haystack/utils/loading.py @@ -1,14 +1,10 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import copy import inspect import threading import warnings from collections import OrderedDict -import six from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.utils.module_loading import module_has_submodule diff --git a/haystack/utils/log.py b/haystack/utils/log.py index ef9bec8f6..97c0ab49b 100644 --- a/haystack/utils/log.py +++ b/haystack/utils/log.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import logging from django.conf import settings diff --git a/haystack/views.py b/haystack/views.py index cdde85746..9083fde4d 100644 --- a/haystack/views.py +++ b/haystack/views.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.conf import settings from django.core.paginator import InvalidPage, Paginator from django.http import Http404 diff --git a/setup.py b/setup.py index 38c251ba2..faa5f7313 100755 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ use_setuptools() from setuptools import setup -install_requires = ["Django>=1.11", "six>=1.12.0"] +install_requires = ["Django>=2.2"] tests_require = [ "pysolr>=3.7.0", @@ -19,7 +19,6 @@ "python-dateutil", "geopy==0.95.1", "nose", - "mock", "coverage", "requests", ] @@ -47,15 +46,17 @@ "Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Framework :: Django", - "Framework :: Django :: 1.11", - "Framework :: Django :: 2.0", - "Framework :: Django :: 2.1", + "Framework :: Django :: 2.2", + "Framework :: Django :: 3.0", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", - "Programming Language :: Python :: 2", "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 :: Utilities", ], zip_safe=False, diff --git a/test_haystack/__init__.py b/test_haystack/__init__.py index 79256373d..9cd46a2ba 100644 --- a/test_haystack/__init__.py +++ b/test_haystack/__init__.py @@ -1,6 +1,4 @@ # encoding: utf-8 -from __future__ import absolute_import - import os test_runner = None diff --git a/test_haystack/core/admin.py b/test_haystack/core/admin.py index eaaacceea..681c246f1 100644 --- a/test_haystack/core/admin.py +++ b/test_haystack/core/admin.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.contrib import admin from haystack.admin import SearchModelAdmin diff --git a/test_haystack/core/custom_identifier.py b/test_haystack/core/custom_identifier.py index 8239d74d7..57e6a215b 100644 --- a/test_haystack/core/custom_identifier.py +++ b/test_haystack/core/custom_identifier.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import hashlib diff --git a/test_haystack/core/models.py b/test_haystack/core/models.py index 8334a357e..9ef9c2cb0 100644 --- a/test_haystack/core/models.py +++ b/test_haystack/core/models.py @@ -1,8 +1,6 @@ # encoding: utf-8 # A couple models for Haystack to test with. -from __future__ import absolute_import, division, print_function, unicode_literals - import datetime import uuid @@ -12,7 +10,7 @@ class MockTag(models.Model): name = models.CharField(max_length=32) - def __unicode__(self): + def __str__(self): return self.name @@ -22,7 +20,7 @@ class MockModel(models.Model): pub_date = models.DateTimeField(default=datetime.datetime.now) tag = models.ForeignKey(MockTag, models.CASCADE) - def __unicode__(self): + def __str__(self): return self.author def hello(self): @@ -33,7 +31,7 @@ class UUIDMockModel(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) characteristics = models.TextField() - def __unicode__(self): + def __str__(self): return str(self.id) @@ -41,7 +39,7 @@ class AnotherMockModel(models.Model): author = models.CharField(max_length=255) pub_date = models.DateTimeField(default=datetime.datetime.now) - def __unicode__(self): + def __str__(self): return self.author @@ -59,7 +57,7 @@ class AFourthMockModel(models.Model): editor = models.CharField(max_length=255) pub_date = models.DateTimeField(default=datetime.datetime.now) - def __unicode__(self): + def __str__(self): return self.author @@ -77,7 +75,7 @@ class AFifthMockModel(models.Model): objects = SoftDeleteManager() - def __unicode__(self): + def __str__(self): return self.author @@ -86,14 +84,14 @@ class ASixthMockModel(models.Model): lat = models.FloatField() lon = models.FloatField() - def __unicode__(self): + def __str__(self): return self.name class ScoreMockModel(models.Model): score = models.CharField(max_length=10) - def __unicode__(self): + def __str__(self): return self.score @@ -104,7 +102,7 @@ class ManyToManyLeftSideModel(models.Model): class ManyToManyRightSideModel(models.Model): name = models.CharField(max_length=32, default="Default name") - def __unicode__(self): + def __str__(self): return self.name diff --git a/test_haystack/core/urls.py b/test_haystack/core/urls.py index d9e36c78e..aab24c4db 100644 --- a/test_haystack/core/urls.py +++ b/test_haystack/core/urls.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.conf.urls import include, url from django.contrib import admin diff --git a/test_haystack/discovery/models.py b/test_haystack/discovery/models.py index ea7e2eef7..72220ae21 100644 --- a/test_haystack/discovery/models.py +++ b/test_haystack/discovery/models.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.db import models @@ -9,7 +6,7 @@ class Foo(models.Model): title = models.CharField(max_length=255) body = models.TextField() - def __unicode__(self): + def __str__(self): return self.title @@ -17,5 +14,5 @@ class Bar(models.Model): author = models.CharField(max_length=255) content = models.TextField() - def __unicode__(self): + def __str__(self): return self.author diff --git a/test_haystack/discovery/search_indexes.py b/test_haystack/discovery/search_indexes.py index 7b9793c5d..f40bc73ea 100644 --- a/test_haystack/discovery/search_indexes.py +++ b/test_haystack/discovery/search_indexes.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from test_haystack.discovery.models import Bar, Foo from haystack import indexes diff --git a/test_haystack/elasticsearch2_tests/test_backend.py b/test_haystack/elasticsearch2_tests/test_backend.py index 6c644fa79..ae421e657 100644 --- a/test_haystack/elasticsearch2_tests/test_backend.py +++ b/test_haystack/elasticsearch2_tests/test_backend.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import, division, print_function, unicode_literals - import datetime import logging as std_logging import operator diff --git a/test_haystack/elasticsearch2_tests/test_inputs.py b/test_haystack/elasticsearch2_tests/test_inputs.py index 09593e251..cd693f158 100644 --- a/test_haystack/elasticsearch2_tests/test_inputs.py +++ b/test_haystack/elasticsearch2_tests/test_inputs.py @@ -1,7 +1,4 @@ # -*- coding: utf-8 -*- - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.test import TestCase from haystack import connections, inputs diff --git a/test_haystack/elasticsearch2_tests/test_query.py b/test_haystack/elasticsearch2_tests/test_query.py index d10b7917e..e02a772a9 100644 --- a/test_haystack/elasticsearch2_tests/test_query.py +++ b/test_haystack/elasticsearch2_tests/test_query.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import, division, print_function, unicode_literals - import datetime import elasticsearch diff --git a/test_haystack/elasticsearch5_tests/test_backend.py b/test_haystack/elasticsearch5_tests/test_backend.py index cc94c0b03..f4dfb33db 100644 --- a/test_haystack/elasticsearch5_tests/test_backend.py +++ b/test_haystack/elasticsearch5_tests/test_backend.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import, division, print_function, unicode_literals - import datetime import logging as std_logging import operator diff --git a/test_haystack/elasticsearch5_tests/test_inputs.py b/test_haystack/elasticsearch5_tests/test_inputs.py index 423694972..b25ff09e2 100644 --- a/test_haystack/elasticsearch5_tests/test_inputs.py +++ b/test_haystack/elasticsearch5_tests/test_inputs.py @@ -1,7 +1,4 @@ # -*- coding: utf-8 -*- - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.test import TestCase from haystack import connections, inputs diff --git a/test_haystack/elasticsearch5_tests/test_query.py b/test_haystack/elasticsearch5_tests/test_query.py index 564a2fd15..c2038a472 100644 --- a/test_haystack/elasticsearch5_tests/test_query.py +++ b/test_haystack/elasticsearch5_tests/test_query.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import, division, print_function, unicode_literals - import datetime from django.contrib.gis.measure import D diff --git a/test_haystack/elasticsearch_tests/test_elasticsearch_backend.py b/test_haystack/elasticsearch_tests/test_elasticsearch_backend.py index 2f72d081e..a6664e059 100644 --- a/test_haystack/elasticsearch_tests/test_elasticsearch_backend.py +++ b/test_haystack/elasticsearch_tests/test_elasticsearch_backend.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import, division, print_function, unicode_literals - import datetime import logging as std_logging import operator diff --git a/test_haystack/elasticsearch_tests/test_elasticsearch_query.py b/test_haystack/elasticsearch_tests/test_elasticsearch_query.py index 56f32346d..cd994c310 100644 --- a/test_haystack/elasticsearch_tests/test_elasticsearch_query.py +++ b/test_haystack/elasticsearch_tests/test_elasticsearch_query.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import datetime import elasticsearch diff --git a/test_haystack/elasticsearch_tests/test_inputs.py b/test_haystack/elasticsearch_tests/test_inputs.py index 0b3c4a373..da904d799 100644 --- a/test_haystack/elasticsearch_tests/test_inputs.py +++ b/test_haystack/elasticsearch_tests/test_inputs.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.test import TestCase from haystack import connections, inputs diff --git a/test_haystack/mocks.py b/test_haystack/mocks.py index 70ebacc63..6e6b9c4e6 100644 --- a/test_haystack/mocks.py +++ b/test_haystack/mocks.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.apps import apps from haystack.backends import BaseEngine, BaseSearchBackend, BaseSearchQuery, log_query diff --git a/test_haystack/multipleindex/__init__.py b/test_haystack/multipleindex/__init__.py index 7b73b57e4..eddcb428a 100644 --- a/test_haystack/multipleindex/__init__.py +++ b/test_haystack/multipleindex/__init__.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import haystack from haystack.signals import RealtimeSignalProcessor diff --git a/test_haystack/multipleindex/models.py b/test_haystack/multipleindex/models.py index ea7e2eef7..72220ae21 100644 --- a/test_haystack/multipleindex/models.py +++ b/test_haystack/multipleindex/models.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.db import models @@ -9,7 +6,7 @@ class Foo(models.Model): title = models.CharField(max_length=255) body = models.TextField() - def __unicode__(self): + def __str__(self): return self.title @@ -17,5 +14,5 @@ class Bar(models.Model): author = models.CharField(max_length=255) content = models.TextField() - def __unicode__(self): + def __str__(self): return self.author diff --git a/test_haystack/multipleindex/routers.py b/test_haystack/multipleindex/routers.py index 32730f688..8f5a555da 100644 --- a/test_haystack/multipleindex/routers.py +++ b/test_haystack/multipleindex/routers.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from haystack.routers import BaseRouter diff --git a/test_haystack/multipleindex/search_indexes.py b/test_haystack/multipleindex/search_indexes.py index 4e68ba5ee..c20011585 100644 --- a/test_haystack/multipleindex/search_indexes.py +++ b/test_haystack/multipleindex/search_indexes.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from haystack import indexes from haystack.indexes import Indexable, SearchIndex diff --git a/test_haystack/multipleindex/tests.py b/test_haystack/multipleindex/tests.py index 9f5b3527d..c63c19e02 100644 --- a/test_haystack/multipleindex/tests.py +++ b/test_haystack/multipleindex/tests.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.db import models from haystack import connections diff --git a/test_haystack/results_per_page_urls.py b/test_haystack/results_per_page_urls.py index 60ec9f772..d44a84895 100644 --- a/test_haystack/results_per_page_urls.py +++ b/test_haystack/results_per_page_urls.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.conf.urls import url from haystack.views import SearchView diff --git a/test_haystack/run_tests.py b/test_haystack/run_tests.py index 0b76a71aa..136b0dc77 100755 --- a/test_haystack/run_tests.py +++ b/test_haystack/run_tests.py @@ -1,8 +1,5 @@ #!/usr/bin/env python # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import sys from os.path import abspath, dirname diff --git a/test_haystack/settings.py b/test_haystack/settings.py index dd426f1f2..095d948a8 100644 --- a/test_haystack/settings.py +++ b/test_haystack/settings.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import os from tempfile import mkdtemp @@ -17,6 +14,7 @@ "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", + "django.contrib.messages", "haystack", "test_haystack.discovery", "test_haystack.core", @@ -36,7 +34,10 @@ "BACKEND": "django.template.backends.django.DjangoTemplates", "APP_DIRS": True, "OPTIONS": { - "context_processors": ["django.contrib.auth.context_processors.auth"] + "context_processors": [ + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", + ] }, } ] diff --git a/test_haystack/simple_tests/search_indexes.py b/test_haystack/simple_tests/search_indexes.py index 1113e9b0b..9732d5067 100644 --- a/test_haystack/simple_tests/search_indexes.py +++ b/test_haystack/simple_tests/search_indexes.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from haystack import indexes from ..core.models import MockModel, ScoreMockModel diff --git a/test_haystack/simple_tests/test_simple_backend.py b/test_haystack/simple_tests/test_simple_backend.py index 20528dbea..1645ec31c 100644 --- a/test_haystack/simple_tests/test_simple_backend.py +++ b/test_haystack/simple_tests/test_simple_backend.py @@ -1,6 +1,4 @@ # coding: utf-8 -from __future__ import absolute_import, division, print_function, unicode_literals - from datetime import date from django.conf import settings diff --git a/test_haystack/simple_tests/test_simple_query.py b/test_haystack/simple_tests/test_simple_query.py index 708b50763..b093db1de 100644 --- a/test_haystack/simple_tests/test_simple_query.py +++ b/test_haystack/simple_tests/test_simple_query.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.test import TestCase from haystack import connections diff --git a/test_haystack/solr_tests/server/get-solr-download-url.py b/test_haystack/solr_tests/server/get-solr-download-url.py index 14569b708..1e0b66f12 100755 --- a/test_haystack/solr_tests/server/get-solr-download-url.py +++ b/test_haystack/solr_tests/server/get-solr-download-url.py @@ -1,8 +1,5 @@ #!/usr/bin/env python # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import sys from itertools import chain diff --git a/test_haystack/solr_tests/server/wait-for-solr b/test_haystack/solr_tests/server/wait-for-solr index 09958920c..179294c7b 100755 --- a/test_haystack/solr_tests/server/wait-for-solr +++ b/test_haystack/solr_tests/server/wait-for-solr @@ -1,8 +1,6 @@ #!/usr/bin/env python # encoding: utf-8 """Simple throttle to wait for Solr to start on busy test servers""" -from __future__ import absolute_import, print_function, unicode_literals - import sys import time diff --git a/test_haystack/solr_tests/test_admin.py b/test_haystack/solr_tests/test_admin.py index d1075630b..2a7d99398 100644 --- a/test_haystack/solr_tests/test_admin.py +++ b/test_haystack/solr_tests/test_admin.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.conf import settings from django.contrib.auth.models import User from django.test import TestCase diff --git a/test_haystack/solr_tests/test_inputs.py b/test_haystack/solr_tests/test_inputs.py index cea553a8e..b6a3a988b 100644 --- a/test_haystack/solr_tests/test_inputs.py +++ b/test_haystack/solr_tests/test_inputs.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.test import TestCase from haystack import connections, inputs diff --git a/test_haystack/solr_tests/test_solr_backend.py b/test_haystack/solr_tests/test_solr_backend.py index 6f2e1de02..4ac74f756 100644 --- a/test_haystack/solr_tests/test_solr_backend.py +++ b/test_haystack/solr_tests/test_solr_backend.py @@ -1,17 +1,15 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import, division, print_function, unicode_literals - import datetime import logging as std_logging import os import unittest from decimal import Decimal +from unittest.mock import patch import pysolr from django.conf import settings from django.test import TestCase from django.test.utils import override_settings -from mock import patch from pkg_resources import parse_version from haystack import connections, indexes, reset_search_queries diff --git a/test_haystack/solr_tests/test_solr_management_commands.py b/test_haystack/solr_tests/test_solr_management_commands.py index b9119c423..f0a7b66f1 100644 --- a/test_haystack/solr_tests/test_solr_management_commands.py +++ b/test_haystack/solr_tests/test_solr_management_commands.py @@ -1,10 +1,8 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import datetime import os from tempfile import mkdtemp +from unittest.mock import patch import pysolr from django.conf import settings @@ -12,7 +10,6 @@ from django.core.management import call_command from django.core.management.base import CommandError from django.test import TestCase -from mock import patch from haystack import connections, constants, indexes from haystack.utils.loading import UnifiedIndex diff --git a/test_haystack/solr_tests/test_solr_query.py b/test_haystack/solr_tests/test_solr_query.py index a3c3728ab..1a39e85d3 100644 --- a/test_haystack/solr_tests/test_solr_query.py +++ b/test_haystack/solr_tests/test_solr_query.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import datetime from django.test import TestCase diff --git a/test_haystack/solr_tests/test_templatetags.py b/test_haystack/solr_tests/test_templatetags.py index f2eee0151..08ab0dde1 100644 --- a/test_haystack/solr_tests/test_templatetags.py +++ b/test_haystack/solr_tests/test_templatetags.py @@ -1,11 +1,9 @@ # encoding: utf-8 -from __future__ import absolute_import, division, print_function, unicode_literals - import unittest +from unittest.mock import call, patch from django.template import Context, Template from django.test import TestCase -from mock import call, patch from ..core.models import MockModel diff --git a/test_haystack/spatial/__init__.py b/test_haystack/spatial/__init__.py index 272fab3c3..9e15777a6 100644 --- a/test_haystack/spatial/__init__.py +++ b/test_haystack/spatial/__init__.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from ..utils import check_solr diff --git a/test_haystack/spatial/models.py b/test_haystack/spatial/models.py index 756536e2e..0220cf218 100644 --- a/test_haystack/spatial/models.py +++ b/test_haystack/spatial/models.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import datetime from django.db import models diff --git a/test_haystack/spatial/search_indexes.py b/test_haystack/spatial/search_indexes.py index c850272b5..e412b0e7e 100644 --- a/test_haystack/spatial/search_indexes.py +++ b/test_haystack/spatial/search_indexes.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from haystack import indexes from .models import Checkin diff --git a/test_haystack/spatial/test_spatial.py b/test_haystack/spatial/test_spatial.py index 750e7e1c5..7bcfd1318 100644 --- a/test_haystack/spatial/test_spatial.py +++ b/test_haystack/spatial/test_spatial.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.contrib.gis.measure import D from django.test import TestCase diff --git a/test_haystack/test_altered_internal_names.py b/test_haystack/test_altered_internal_names.py index 1cedfdb45..ed3b6ec66 100644 --- a/test_haystack/test_altered_internal_names.py +++ b/test_haystack/test_altered_internal_names.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.conf import settings from django.test import TestCase from test_haystack.core.models import AnotherMockModel, MockModel diff --git a/test_haystack/test_app_loading.py b/test_haystack/test_app_loading.py index ff200c5cb..df3942366 100644 --- a/test_haystack/test_app_loading.py +++ b/test_haystack/test_app_loading.py @@ -1,6 +1,4 @@ # encoding: utf-8 -from __future__ import absolute_import, division, print_function, unicode_literals - from types import GeneratorType, ModuleType from django.test import TestCase diff --git a/test_haystack/test_app_using_appconfig/__init__.py b/test_haystack/test_app_using_appconfig/__init__.py index dcc8a4f04..fc48781a6 100644 --- a/test_haystack/test_app_using_appconfig/__init__.py +++ b/test_haystack/test_app_using_appconfig/__init__.py @@ -1,5 +1,2 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - default_app_config = "test_app_using_appconfig.apps.SimpleTestAppConfig" diff --git a/test_haystack/test_app_using_appconfig/apps.py b/test_haystack/test_app_using_appconfig/apps.py index c1e07cabe..12e444de6 100644 --- a/test_haystack/test_app_using_appconfig/apps.py +++ b/test_haystack/test_app_using_appconfig/apps.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, division, print_function, unicode_literals - from django.apps import AppConfig diff --git a/test_haystack/test_app_using_appconfig/migrations/0001_initial.py b/test_haystack/test_app_using_appconfig/migrations/0001_initial.py index b7630a500..57206f386 100644 --- a/test_haystack/test_app_using_appconfig/migrations/0001_initial.py +++ b/test_haystack/test_app_using_appconfig/migrations/0001_initial.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import, division, print_function, unicode_literals - from django.db import migrations, models diff --git a/test_haystack/test_app_using_appconfig/models.py b/test_haystack/test_app_using_appconfig/models.py index 6e37c8f56..5ca8079c7 100644 --- a/test_haystack/test_app_using_appconfig/models.py +++ b/test_haystack/test_app_using_appconfig/models.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.db.models import CharField, Model diff --git a/test_haystack/test_app_using_appconfig/search_indexes.py b/test_haystack/test_app_using_appconfig/search_indexes.py index ad0366bf8..3611784d1 100644 --- a/test_haystack/test_app_using_appconfig/search_indexes.py +++ b/test_haystack/test_app_using_appconfig/search_indexes.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from haystack import indexes from .models import MicroBlogPost diff --git a/test_haystack/test_app_using_appconfig/tests.py b/test_haystack/test_app_using_appconfig/tests.py index 0863ef664..5da9e0c9b 100644 --- a/test_haystack/test_app_using_appconfig/tests.py +++ b/test_haystack/test_app_using_appconfig/tests.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.test import TestCase from .models import MicroBlogPost diff --git a/test_haystack/test_app_with_hierarchy/contrib/django/hierarchal_app_django/models.py b/test_haystack/test_app_with_hierarchy/contrib/django/hierarchal_app_django/models.py index 59fac439f..0fd6d2ef3 100644 --- a/test_haystack/test_app_with_hierarchy/contrib/django/hierarchal_app_django/models.py +++ b/test_haystack/test_app_with_hierarchy/contrib/django/hierarchal_app_django/models.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.db.models import BooleanField, CharField, Model diff --git a/test_haystack/test_app_without_models/urls.py b/test_haystack/test_app_without_models/urls.py index 7bd1cbc75..4ce6ed04f 100644 --- a/test_haystack/test_app_without_models/urls.py +++ b/test_haystack/test_app_without_models/urls.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.conf.urls import url from .views import simple_view diff --git a/test_haystack/test_app_without_models/views.py b/test_haystack/test_app_without_models/views.py index 07dd1e962..fe612179f 100644 --- a/test_haystack/test_app_without_models/views.py +++ b/test_haystack/test_app_without_models/views.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.http import HttpResponse diff --git a/test_haystack/test_backends.py b/test_haystack/test_backends.py index 8edbea24a..3bd894d81 100644 --- a/test_haystack/test_backends.py +++ b/test_haystack/test_backends.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import warnings from django.core.exceptions import ImproperlyConfigured diff --git a/test_haystack/test_discovery.py b/test_haystack/test_discovery.py index 60c47ea66..b75ad77ec 100644 --- a/test_haystack/test_discovery.py +++ b/test_haystack/test_discovery.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.test import TestCase from test_haystack.discovery.search_indexes import FooIndex diff --git a/test_haystack/test_fields.py b/test_haystack/test_fields.py index c0291a4ef..50e709492 100644 --- a/test_haystack/test_fields.py +++ b/test_haystack/test_fields.py @@ -1,13 +1,10 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import datetime from decimal import Decimal +from unittest.mock import Mock from django.template import TemplateDoesNotExist from django.test import TestCase -from mock import Mock from test_haystack.core.models import ( ManyToManyLeftSideModel, ManyToManyRightSideModel, diff --git a/test_haystack/test_forms.py b/test_haystack/test_forms.py index 814ddb7a9..1e5620066 100644 --- a/test_haystack/test_forms.py +++ b/test_haystack/test_forms.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import, division, print_function, unicode_literals - from django.test import TestCase from test_haystack.core.models import AnotherMockModel, MockModel from test_haystack.test_views import ( diff --git a/test_haystack/test_generic_views.py b/test_haystack/test_generic_views.py index 82a9bc307..439615410 100644 --- a/test_haystack/test_generic_views.py +++ b/test_haystack/test_generic_views.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.test.client import RequestFactory from django.test.testcases import TestCase diff --git a/test_haystack/test_indexes.py b/test_haystack/test_indexes.py index 376a88355..94542f94a 100644 --- a/test_haystack/test_indexes.py +++ b/test_haystack/test_indexes.py @@ -1,13 +1,10 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import datetime +import queue import time from threading import Thread from django.test import TestCase -from six.moves import queue from test_haystack.core.models import ( AFifthMockModel, AnotherMockModel, diff --git a/test_haystack/test_inputs.py b/test_haystack/test_inputs.py index 5fe9f4191..110b7d1ed 100644 --- a/test_haystack/test_inputs.py +++ b/test_haystack/test_inputs.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.test import TestCase from haystack import connections, inputs diff --git a/test_haystack/test_loading.py b/test_haystack/test_loading.py index bfa46234d..928e769d7 100644 --- a/test_haystack/test_loading.py +++ b/test_haystack/test_loading.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import unittest from django.conf import settings diff --git a/test_haystack/test_management_commands.py b/test_haystack/test_management_commands.py index fa7f6dc17..33bf15041 100644 --- a/test_haystack/test_management_commands.py +++ b/test_haystack/test_management_commands.py @@ -1,11 +1,9 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals +from unittest.mock import call, patch from django.conf import settings from django.core.management import call_command from django.test import TestCase -from mock import call, patch __all__ = ["CoreManagementCommandsTestCase"] diff --git a/test_haystack/test_managers.py b/test_haystack/test_managers.py index 257de66d3..5c8b260c7 100644 --- a/test_haystack/test_managers.py +++ b/test_haystack/test_managers.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import datetime from django.contrib.gis.measure import D diff --git a/test_haystack/test_models.py b/test_haystack/test_models.py index c081086c8..06577c43a 100644 --- a/test_haystack/test_models.py +++ b/test_haystack/test_models.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import logging as std_logging import pickle @@ -95,14 +92,14 @@ def test_get_additional_fields(self): def test_unicode(self): self.assertEqual( - self.no_data_sr.__unicode__(), "" + self.no_data_sr.__str__(), "" ) self.assertEqual( - self.extra_data_sr.__unicode__(), + self.extra_data_sr.__str__(), "", ) self.assertEqual( - self.no_overwrite_data_sr.__unicode__(), + self.no_overwrite_data_sr.__str__(), "", ) diff --git a/test_haystack/test_query.py b/test_haystack/test_query.py index b4078d7c7..435ae2273 100644 --- a/test_haystack/test_query.py +++ b/test_haystack/test_query.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import, division, print_function, unicode_literals - import datetime import unittest diff --git a/test_haystack/test_templatetags.py b/test_haystack/test_templatetags.py index d392d5f50..2bf345787 100644 --- a/test_haystack/test_templatetags.py +++ b/test_haystack/test_templatetags.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import, division, print_function, unicode_literals - from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.template import Context, Template diff --git a/test_haystack/test_utils.py b/test_haystack/test_utils.py index 9a0fe8e8b..e0f22a56c 100644 --- a/test_haystack/test_utils.py +++ b/test_haystack/test_utils.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.test import TestCase from django.test.utils import override_settings from test_haystack.core.models import MockModel diff --git a/test_haystack/test_views.py b/test_haystack/test_views.py index a5acaee21..6dbb7a5c4 100644 --- a/test_haystack/test_views.py +++ b/test_haystack/test_views.py @@ -1,7 +1,5 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - +import queue import time from threading import Thread @@ -9,7 +7,6 @@ from django.http import HttpRequest, QueryDict from django.test import TestCase, override_settings from django.urls import reverse -from six.moves import queue from test_haystack.core.models import AnotherMockModel, MockModel from haystack import connections, indexes diff --git a/test_haystack/utils.py b/test_haystack/utils.py index 89101e0b4..d6b2799dc 100644 --- a/test_haystack/utils.py +++ b/test_haystack/utils.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import unittest from django.conf import settings diff --git a/test_haystack/whoosh_tests/test_forms.py b/test_haystack/whoosh_tests/test_forms.py index 564ab92d5..d69271486 100644 --- a/test_haystack/whoosh_tests/test_forms.py +++ b/test_haystack/whoosh_tests/test_forms.py @@ -1,7 +1,5 @@ # encoding: utf-8 """Tests for Whoosh spelling suggestions""" -from __future__ import absolute_import, division, print_function, unicode_literals - from django.conf import settings from django.http import HttpRequest diff --git a/test_haystack/whoosh_tests/test_inputs.py b/test_haystack/whoosh_tests/test_inputs.py index 00a4b4e0e..8cd505e9e 100644 --- a/test_haystack/whoosh_tests/test_inputs.py +++ b/test_haystack/whoosh_tests/test_inputs.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - from django.test import TestCase from haystack import connections, inputs diff --git a/test_haystack/whoosh_tests/test_whoosh_backend.py b/test_haystack/whoosh_tests/test_whoosh_backend.py index 6af5da043..0511e7f0e 100644 --- a/test_haystack/whoosh_tests/test_whoosh_backend.py +++ b/test_haystack/whoosh_tests/test_whoosh_backend.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import os import unittest from datetime import timedelta diff --git a/test_haystack/whoosh_tests/test_whoosh_query.py b/test_haystack/whoosh_tests/test_whoosh_query.py index 9813ac458..0fb54e3d2 100644 --- a/test_haystack/whoosh_tests/test_whoosh_query.py +++ b/test_haystack/whoosh_tests/test_whoosh_query.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import datetime from haystack import connections diff --git a/test_haystack/whoosh_tests/testcases.py b/test_haystack/whoosh_tests/testcases.py index 28acf72e8..a2d1e6fe3 100644 --- a/test_haystack/whoosh_tests/testcases.py +++ b/test_haystack/whoosh_tests/testcases.py @@ -1,7 +1,4 @@ # encoding: utf-8 - -from __future__ import absolute_import, division, print_function, unicode_literals - import os import shutil diff --git a/tox.ini b/tox.ini index c2786ea69..6548f1023 100644 --- a/tox.ini +++ b/tox.ini @@ -1,222 +1,26 @@ [tox] -envlist = docs, - py35-django1.11-es1.x, - py35-django2.0-es1.x, - py35-django2.1-es1.x, - pypy-django1.11-es1.x, - py35-django1.11-es2.x, - py35-django2.0-es2.x, - py35-django2.1-es2.x, - py36-django1.11-es2.x, - py36-django2.0-es2.x, - py36-django2.1-es2.x, - py37-django1.11-es2.x, - py37-django2.0-es2.x, - py37-django2.1-es2.x, - pypy-django1.11-es2.x, - py36-django1.11-es5.x, - py36-django2.0-es5.x, - py36-django2.1-es5.x, - py37-django1.11-es5.x, - py37-django2.0-es5.x, - py37-django2.1-es5.x, - pypy-django1.11-es5.x, +envlist = + docs + py35-django2.2-es{1.x,2.x,5.x} + py{36,37,38,py}-django{2.2,3.0}-es{1.x,2.x,5.x} -[base] -deps = requests - -[django2.1] -deps = Django>=2.1,<2.2 - -[django2.0] -deps = - Django>=2.0,<2.1 - -[django1.11] -deps = - Django>=1.11,<2.0 - -[es5.x] -deps = - elasticsearch>=5.0.0,<6.0.0 - -[es2.x] -deps = - elasticsearch>=2.0.0,<3.0.0 - -[es1.x] -deps = - elasticsearch>=1.0.0,<2.0.0 [testenv] commands = python test_haystack/solr_tests/server/wait-for-solr python {toxinidir}/setup.py test - -[testenv:pypy-django1.11-es1.x] -setenv = VERSION_ES=>=1.0.0,<2.0.0 -deps = - {[es1.x]deps} - {[django1.11]deps} - {[base]deps} - -[testenv:py35-django1.11-es1.x] -basepython = python3.5 -setenv = VERSION_ES=>=1.0.0,<2.0.0 -deps = - {[es1.x]deps} - {[django1.11]deps} - {[base]deps} - -[testenv:py35-django2.0-es1.x] -basepython = python3.5 -setenv = VERSION_ES=>=1.0.0,<2.0.0 -deps = - {[es1.x]deps} - {[django2.0]deps} - {[base]deps} - -[testenv:py35-django2.1-es1.x] -basepython = python3.5 -setenv = VERSION_ES=>=1.0.0,<2.0.0 -deps = - {[es1.x]deps} - {[django2.1]deps} - {[base]deps} - -[testenv:pypy-django1.11-es2.x] -setenv = VERSION_ES=>=2.0.0,<3.0.0 -deps = - {[es2.x]deps} - {[django1.11]deps} - {[base]deps} - -[testenv:py35-django1.11-es2.x] -basepython = python3.5 -setenv = VERSION_ES=>=2.0.0,<3.0.0 -deps = - {[es2.x]deps} - {[django1.11]deps} - {[base]deps} - -[testenv:py35-django2.0-es2.x] -basepython = python3.5 -setenv = VERSION_ES=>=2.0.0,<3.0.0 -deps = - {[es2.x]deps} - {[django2.0]deps} - {[base]deps} - -[testenv:py35-django2.1-es2.x] -basepython = python3.5 -setenv = VERSION_ES=>=2.0.0,<3.0.0 deps = - {[es2.x]deps} - {[django2.1]deps} - {[base]deps} + requests + django2.2: Django>=2.2,<3.0 + django3.0: Django>=3.0,<3.1 + es1.x: elasticsearch>=1,<2 + es2.x: elasticsearch>=2,<3 + es5.x: elasticsearch>=5,<6 +setenv = + es1.x: VERSION_ES=>=1,<2 + es2.x: VERSION_ES=>=2,<3 + es5.x: VERSION_ES=>=5,<6 -[testenv:py36-django1.11-es2.x] -basepython = python3.6 -setenv = VERSION_ES=>=2.0.0,<3.0.0 -deps = - {[es2.x]deps} - {[django1.11]deps} - {[base]deps} - -[testenv:py36-django2.0-es2.x] -basepython = python3.6 -setenv = VERSION_ES=>=2.0.0,<3.0.0 -deps = - {[es2.x]deps} - {[django2.0]deps} - {[base]deps} - -[testenv:py36-django2.1-es2.x] -basepython = python3.6 -setenv = VERSION_ES=>=2.0.0,<3.0.0 -deps = - {[es2.x]deps} - {[django2.1]deps} - {[base]deps} - -[testenv:py37-django1.11-es2.x] -basepython = python3.7 -setenv = VERSION_ES=>=2.0.0,<3.0.0 -deps = - {[es2.x]deps} - {[django1.11]deps} - {[base]deps} - -[testenv:py37-django2.0-es2.x] -basepython = python3.7 -setenv = VERSION_ES=>=2.0.0,<3.0.0 -deps = - {[es2.x]deps} - {[django2.0]deps} - {[base]deps} - -[testenv:py37-django2.1-es2.x] -basepython = python3.7 -setenv = VERSION_ES=>=2.0.0,<3.0.0 -deps = - {[es2.x]deps} - {[django2.1]deps} - {[base]deps} - -[testenv:pypy-django1.11-es5.x] -setenv = VERSION_ES=>=5.0.0,<6.0.0 -deps = - {[es5.x]deps} - {[django1.11]deps} - {[base]deps} - -[testenv:py36-django1.11-es5.x] -basepython = python3.6 -setenv = VERSION_ES=>=5.0.0,<6.0.0 -deps = - {[es5.x]deps} - {[django1.11]deps} - {[base]deps} - -[testenv:py36-django2.0-es5.x] -basepython = python3.6 -setenv = VERSION_ES=>=5.0.0,<6.0.0 -deps = - {[es5.x]deps} - {[django2.0]deps} - {[base]deps} - -[testenv:py36-django2.1-es5.x] -basepython = python3.6 -setenv = VERSION_ES=>=5.0.0,<6.0.0 -deps = - {[es5.x]deps} - {[django2.1]deps} - {[base]deps} - -[testenv:py37-django1.11-es5.x] -basepython = python3.7 -setenv = VERSION_ES=>=5.0.0,<6.0.0 -deps = - {[es5.x]deps} - {[django1.11]deps} - {[base]deps} - -[testenv:py37-django2.0-es5.x] -basepython = python3.7 -setenv = VERSION_ES=>=5.0.0,<6.0.0 -deps = - {[es5.x]deps} - {[django2.0]deps} - {[base]deps} - -[testenv:py37-django2.1-es5.x] -basepython = python3.7 -setenv = VERSION_ES=>=5.0.0,<6.0.0 -deps = - {[es5.x]deps} - {[django2.1]deps} - {[base]deps} [testenv:docs] changedir = docs From a948e371236458fbb421195f235b06887cbaba3b Mon Sep 17 00:00:00 2001 From: Fakhar Date: Thu, 13 Feb 2020 03:56:58 +0500 Subject: [PATCH 34/37] Fixed hardcoded default connection alias --- haystack/admin.py | 5 +++-- haystack/management/commands/haystack_info.py | 3 ++- haystack/models.py | 5 +++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/haystack/admin.py b/haystack/admin.py index 390672393..7ccbdaa60 100644 --- a/haystack/admin.py +++ b/haystack/admin.py @@ -8,13 +8,14 @@ from django.utils.translation import ungettext from haystack import connections +from haystack.constants import DEFAULT_ALIAS from haystack.query import SearchQuerySet from haystack.utils import get_model_ct_tuple class SearchChangeList(ChangeList): def __init__(self, **kwargs): - self.haystack_connection = kwargs.pop("haystack_connection", "default") + self.haystack_connection = kwargs.pop("haystack_connection", DEFAULT_ALIAS) super(SearchChangeList, self).__init__(**kwargs) def get_results(self, request): @@ -58,7 +59,7 @@ def get_results(self, request): class SearchModelAdminMixin(object): # haystack connection to use for searching - haystack_connection = "default" + haystack_connection = DEFAULT_ALIAS @csrf_protect_m def changelist_view(self, request, extra_context=None): diff --git a/haystack/management/commands/haystack_info.py b/haystack/management/commands/haystack_info.py index 603a72b9f..6b321d9f9 100644 --- a/haystack/management/commands/haystack_info.py +++ b/haystack/management/commands/haystack_info.py @@ -2,6 +2,7 @@ from django.core.management.base import BaseCommand from haystack import connections +from haystack.constants import DEFAULT_ALIAS class Command(BaseCommand): @@ -10,7 +11,7 @@ class Command(BaseCommand): def handle(self, **options): """Provides feedback about the current Haystack setup.""" - unified_index = connections["default"].get_unified_index() + unified_index = connections[DEFAULT_ALIAS].get_unified_index() indexed = unified_index.get_indexed_models() index_count = len(indexed) self.stdout.write("Number of handled %s index(es)." % index_count) diff --git a/haystack/models.py b/haystack/models.py index 6a41665e9..c774e81c8 100644 --- a/haystack/models.py +++ b/haystack/models.py @@ -5,6 +5,7 @@ from django.utils.encoding import force_str from django.utils.text import capfirst +from haystack.constants import DEFAULT_ALIAS from haystack.exceptions import NotHandled, SpatialError from haystack.utils import log as logging from haystack.utils.app_loading import haystack_get_model @@ -67,7 +68,7 @@ def __getattr__(self, attr): def _get_searchindex(self): from haystack import connections - return connections["default"].get_unified_index().get_index(self.model) + return connections[DEFAULT_ALIAS].get_unified_index().get_index(self.model) searchindex = property(_get_searchindex) @@ -212,7 +213,7 @@ def get_stored_fields(self): from haystack import connections try: - index = connections["default"].get_unified_index().get_index(self.model) + index = connections[DEFAULT_ALIAS].get_unified_index().get_index(self.model) except NotHandled: # Not found? Return nothing. return {} From d03e0ac99d75fd9e651bd18476e87975ad795981 Mon Sep 17 00:00:00 2001 From: Tim Gates Date: Mon, 17 Feb 2020 22:23:51 +1100 Subject: [PATCH 35/37] Fix simple typo: specifially -> specifically Closes #1723 --- docs/spatial.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/spatial.rst b/docs/spatial.rst index 4e2906d58..34227fa85 100644 --- a/docs/spatial.rst +++ b/docs/spatial.rst @@ -33,7 +33,7 @@ Support ======= You need the latest & greatest of either Solr or Elasticsearch. None of the -other backends (specifially the engines) support this kind of search. +other backends (specifically the engines) support this kind of search. For Solr_, you'll need at least **v3.5+**. In addition, if you have an existing install of Haystack & Solr, you'll need to upgrade the schema & reindex your From 2cb04b9442493be16414d07fcbefdfe3f8af9387 Mon Sep 17 00:00:00 2001 From: Alvin Mites Date: Tue, 3 Mar 2020 23:24:59 -0700 Subject: [PATCH 36/37] doc update -- fixes broken link --- docs/multiple_index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/multiple_index.rst b/docs/multiple_index.rst index 48b28a828..529bbf2b1 100644 --- a/docs/multiple_index.rst +++ b/docs/multiple_index.rst @@ -9,7 +9,7 @@ support. This allows you to talk to several different engines at the same time. It enables things like master-slave setups, multiple language indexing, separate indexes for general search & autocomplete as well as other options. -.. _`multiple database support`: http://docs.djangoproject.com/en/1.3/topics/db/multi-db/ +.. _`multiple database support`: http://docs.djangoproject.com/en/dev/topics/db/multi-db/ Specifying Available Connections From 6a25a4ebc5bdd4e731d0b043b1835ff5afa5b091 Mon Sep 17 00:00:00 2001 From: Kelvin Chan Date: Wed, 29 Jan 2020 12:12:15 -0500 Subject: [PATCH 37/37] Add support for retry param for Whoosh file writer * Can be used to prevent writer from hanging indefinitly * Added HAYSTACK_WHOOSH_WRITER_ACQUIRE_MAX_RETRIES setting * Added HAYSTACK_WHOOSH_WRITER_ACQUIRE_DELAY setting --- haystack/backends/whoosh_backend.py | 4 +++- setup.py | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/haystack/backends/whoosh_backend.py b/haystack/backends/whoosh_backend.py index d4bc9053e..cc4d288cf 100644 --- a/haystack/backends/whoosh_backend.py +++ b/haystack/backends/whoosh_backend.py @@ -262,7 +262,9 @@ def update(self, index, iterable, commit=True): self.setup() self.index = self.index.refresh() - writer = AsyncWriter(self.index) + max_retries = getattr(settings, 'HAYSTACK_WHOOSH_WRITER_ACQUIRE_MAX_RETRIES', 0) + delay = getattr(settings, 'HAYSTACK_WHOOSH_WRITER_ACQUIRE_DELAY', 0.25) + writer = AsyncWriter(self.index, delay=delay, max_retries=max_retries) for obj in iterable: try: diff --git a/setup.py b/setup.py index faa5f7313..c53884676 100755 --- a/setup.py +++ b/setup.py @@ -25,7 +25,8 @@ setup( name="django-haystack", - use_scm_version=True, + #use_scm_version=True, + version="3.0.dev1", description="Pluggable search for Django.", author="Daniel Lindsley", author_email="daniel@toastdriven.com",