From d65bfc0b156364154548869eb007c78892afdabc Mon Sep 17 00:00:00 2001 From: rlskoeser Date: Fri, 24 Feb 2023 10:29:28 -0500 Subject: [PATCH 1/9] Set develop version to 0.10 --- parasolr/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parasolr/__init__.py b/parasolr/__init__.py index ff89738..ef5bb9c 100644 --- a/parasolr/__init__.py +++ b/parasolr/__init__.py @@ -1,6 +1,6 @@ default_app_config = "parasolr.apps.ParasolConfig" -__version_info__ = (0, 9, 0, None) +__version_info__ = (0, 10, 0, "dev") # Dot-connect all but the last. Last is dash-connected if not None. __version__ = ".".join([str(i) for i in __version_info__[:-1]]) From 37c5555a3294c4e4d55f35995ca029210b904812 Mon Sep 17 00:00:00 2001 From: rlskoeser Date: Thu, 22 Jun 2023 16:56:25 -0400 Subject: [PATCH 2/9] Remove default_app_config, not needed in newer versions of django --- parasolr/__init__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/parasolr/__init__.py b/parasolr/__init__.py index ef5bb9c..15ac6f8 100644 --- a/parasolr/__init__.py +++ b/parasolr/__init__.py @@ -1,5 +1,3 @@ -default_app_config = "parasolr.apps.ParasolConfig" - __version_info__ = (0, 10, 0, "dev") # Dot-connect all but the last. Last is dash-connected if not None. From bf4c87cc2bd44ab2790a014bf8205a82d676cdd9 Mon Sep 17 00:00:00 2001 From: rlskoeser Date: Thu, 22 Jun 2023 17:01:12 -0400 Subject: [PATCH 3/9] Update django/solr/python versions for testing --- .github/workflows/unit_tests.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 2a3fb83..3a7e240 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -12,9 +12,9 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python: [3.8, 3.9] - solr: [8.6] - django: [0, 3.0, 3.1, 3.2] + python: [3.9, 3.10, 3.11] + solr: [8.6, 9.2] + django: [0, 3.2, "4.0"] # We use service containers to avoid needing to set up a local copy of # mysql or postgres on the test runner instance. This syntax is similar to # the spec of a docker-compose file. For more, see: From 0f26cc1b5220601f1bacc2ccffcda5d585498e3c Mon Sep 17 00:00:00 2001 From: rlskoeser Date: Thu, 22 Jun 2023 17:10:22 -0400 Subject: [PATCH 4/9] Replace attrdict with addict --- parasolr/solr/admin.py | 2 +- parasolr/solr/base.py | 2 +- parasolr/solr/client.py | 6 +++--- parasolr/solr/schema.py | 2 +- parasolr/solr/tests/test_base.py | 2 +- parasolr/solr/tests/test_client.py | 4 +--- parasolr/tests/test_schema.py | 3 +-- setup.py | 2 +- 8 files changed, 10 insertions(+), 13 deletions(-) diff --git a/parasolr/solr/admin.py b/parasolr/solr/admin.py index 509ead8..ac62c9c 100644 --- a/parasolr/solr/admin.py +++ b/parasolr/solr/admin.py @@ -2,7 +2,7 @@ from urllib.parse import urljoin import requests -from attrdict import AttrDict +from addict import Dict as AttrDict from parasolr.solr.base import ClientBase, SolrConnectionNotFound diff --git a/parasolr/solr/base.py b/parasolr/solr/base.py index f07a326..a23efcb 100644 --- a/parasolr/solr/base.py +++ b/parasolr/solr/base.py @@ -5,7 +5,7 @@ from urllib.parse import urljoin import requests -from attrdict import AttrDict +from addict import Dict as AttrDict logger = logging.getLogger(__name__) diff --git a/parasolr/solr/client.py b/parasolr/solr/client.py index 2c3f0d3..c3d43d9 100644 --- a/parasolr/solr/client.py +++ b/parasolr/solr/client.py @@ -3,7 +3,7 @@ from typing import Any, Dict, List, Optional import requests -from attrdict import AttrDict +from addict import Dict as AttrDict from parasolr import __version__ as parasol_version from parasolr.solr.admin import CoreAdmin @@ -20,7 +20,7 @@ class ParasolrDict(AttrDict): - """A subclass of :class:`attrdict.AttrDict` that can convert itself to a + """A subclass of :class:`addict.Dict` that can convert itself to a regular dictionary.""" def as_dict(self): @@ -35,7 +35,7 @@ def as_dict(self): return copy def __repr__(self): - """Print a dict-like :meth:`repr`, without including 'AttrDict'.""" + """Print a dict-like :meth:`repr`, without including 'addict.Dict'.""" return "ParasolrDict(%s)" % super(AttrDict, self).__repr__() diff --git a/parasolr/solr/schema.py b/parasolr/solr/schema.py index cd4e5a8..5510945 100644 --- a/parasolr/solr/schema.py +++ b/parasolr/solr/schema.py @@ -5,7 +5,7 @@ from urllib.parse import urljoin import requests -from attrdict import AttrDict +from addict import Dict as AttrDict from parasolr.solr.client import ClientBase diff --git a/parasolr/solr/tests/test_base.py b/parasolr/solr/tests/test_base.py index 69def3e..dee2ee5 100644 --- a/parasolr/solr/tests/test_base.py +++ b/parasolr/solr/tests/test_base.py @@ -1,7 +1,7 @@ from unittest.mock import Mock, patch import requests -from attrdict import AttrDict +from addict import Dict as AttrDict from parasolr.solr.base import ClientBase diff --git a/parasolr/solr/tests/test_client.py b/parasolr/solr/tests/test_client.py index 9e8fa13..b581b12 100644 --- a/parasolr/solr/tests/test_client.py +++ b/parasolr/solr/tests/test_client.py @@ -2,7 +2,7 @@ from collections import OrderedDict import requests -from attrdict import AttrDict +from addict import Dict as AttrDict from parasolr import __version__ as parasolr_ver from parasolr.solr.admin import CoreAdmin @@ -49,7 +49,6 @@ def test_repr(self): class TestQueryResponse: def test_init(self): - response = AttrDict( { "responseHeader": {"params": {"foo": "bar"}}, @@ -182,7 +181,6 @@ def test_query(self, test_client): class TestGroupedResponse: def test_init(self): - response = AttrDict( { "responseHeader": {"params": {"group": "true", "group.field": "A"}}, diff --git a/parasolr/tests/test_schema.py b/parasolr/tests/test_schema.py index e173e79..3f83b78 100644 --- a/parasolr/tests/test_schema.py +++ b/parasolr/tests/test_schema.py @@ -1,7 +1,7 @@ from unittest.mock import Mock, patch import pytest -from attrdict import AttrDict +from addict import Dict as AttrDict from parasolr import schema from parasolr.solr import SolrClient @@ -164,7 +164,6 @@ class LocalTestSchema(schema.SolrSchema): with patch.object( LocalTestSchema, "configure_copy_fields" ) as mock_config_cp_fields: - # simulate only standard fields defined mocksolr.schema.list_fields.return_value = [ AttrDict({"name": "id"}), diff --git a/setup.py b/setup.py index ee69c7a..42beb1a 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ # allow setup.py to be run from any path os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir))) -REQUIREMENTS = ["requests", "attrdict", "progressbar2"] +REQUIREMENTS = ["requests", "addict", "progressbar2"] # NOTE: progressbar only needed for django index script; make optional? TEST_REQUIREMENTS = ["pytest>5.2", "pytest-cov"] DEV_REQUIREMENTS = [ From a5cb1a8e1919cecb0d821041ae0c967521a4c9b3 Mon Sep 17 00:00:00 2001 From: rlskoeser Date: Thu, 22 Jun 2023 17:14:21 -0400 Subject: [PATCH 5/9] Use strings instead of numbers for versions to avoid py3.10 => 3.1 --- .github/workflows/unit_tests.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 3a7e240..85968ce 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -12,9 +12,9 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python: [3.9, 3.10, 3.11] - solr: [8.6, 9.2] - django: [0, 3.2, "4.0"] + python: ["3.9", "3.10", "3.11"] + solr: ["8.6", "9.2"] + django: [0, "3.2", "4.0"] # We use service containers to avoid needing to set up a local copy of # mysql or postgres on the test runner instance. This syntax is similar to # the spec of a docker-compose file. For more, see: From 04010e45ff3606e4922f3c181c60059db4ab0751 Mon Sep 17 00:00:00 2001 From: rlskoeser Date: Thu, 22 Jun 2023 18:36:45 -0400 Subject: [PATCH 6/9] Update attrdict AttrDefault code to use equivalent addict logic --- parasolr/schema.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/parasolr/schema.py b/parasolr/schema.py index adbf778..db5015e 100644 --- a/parasolr/schema.py +++ b/parasolr/schema.py @@ -76,9 +76,10 @@ class MySolrSchema(schema.SolrSchema): """ import logging +from collections import defaultdict from typing import Any, Optional -from attrdict import AttrDefault +from addict import Dict as AttrDict from parasolr.solr.client import SolrClient @@ -247,7 +248,7 @@ def get_field_types(cls) -> list: ] @classmethod - def configure_fields(cls, solr: SolrClient) -> AttrDefault: + def configure_fields(cls, solr: SolrClient) -> AttrDict: """Update the configured Solr instance schema to match the configured fields. @@ -266,8 +267,7 @@ def configure_fields(cls, solr: SolrClient) -> AttrDefault: current_fields = [field.name for field in solr.schema.list_fields()] configured_field_names = cls.get_field_names() - # use attrdict instead of defaultdict since we have attrmap - stats = AttrDefault(int, {}) + stats = AttrDict(added=0, replaced=0, deleted=0) for field_name in configured_field_names: field_opts = getattr(cls, field_name) @@ -310,7 +310,7 @@ def configure_copy_fields(cls, solr: SolrClient) -> None: solr_copy_fields = solr.schema.list_copy_fields() # create a dictionary lookup of existing copy fields from Solr # source field -> list of destination fields - cp_fields = AttrDefault(list, {}) + cp_fields = defaultdict(list) for copyfield in solr_copy_fields: cp_fields[copyfield.source].append(copyfield.dest) @@ -341,7 +341,7 @@ def configure_copy_fields(cls, solr: SolrClient) -> None: solr.schema.delete_copy_field(cp_field.source, cp_field.dest) @classmethod - def configure_fieldtypes(cls, solr: SolrClient) -> AttrDefault: + def configure_fieldtypes(cls, solr: SolrClient) -> AttrDict: """Update the configured Solr instance so the schema includes the configured field types, if any. @@ -349,17 +349,17 @@ def configure_fieldtypes(cls, solr: SolrClient) -> AttrDefault: solr: A configured Solr instance. Returns: - :class:`attrdict.AttrDefault` with counts for updated + :class:`addict.Dict` with counts for updated and added field types. """ configured_field_types = cls.get_field_types() - stats = AttrDefault(int, {}) + stats = AttrDict(updated=0, added=0) # if none are configured, nothing to do if not configured_field_types: - return stats + return AttrDict({}) # convert list return into dictionary keyed on field type name current_field_types = { From 5dc4e184fff0b45281809383dfd95c5f9e86e528 Mon Sep 17 00:00:00 2001 From: rlskoeser Date: Thu, 22 Jun 2023 18:56:34 -0400 Subject: [PATCH 7/9] Run configset copy command for solr 9.x as well as 8.x --- .github/workflows/unit_tests.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 85968ce..045aecd 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -25,9 +25,8 @@ jobs: ports: - 8983:8983 steps: - - name: Copy solr configsets to solr home directory (Solr 8 only) + - name: Copy solr configsets to solr home directory (Solr 8+) run: "docker exec -d ${{ job.services.solr.id }} cp -r /opt/solr/server/solr/configsets /var/solr/data" - if: ${{ matrix.solr == 8.6 }} - name: Checkout repository uses: actions/checkout@v2 From 2e37960b26611e46ed40423f158f5eed636a849d Mon Sep 17 00:00:00 2001 From: rlskoeser Date: Fri, 23 Jun 2023 08:29:56 -0400 Subject: [PATCH 8/9] Update action versions; only run one test on solr 9.2 --- .github/workflows/unit_tests.yml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 045aecd..22543d3 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -13,8 +13,12 @@ jobs: strategy: matrix: python: ["3.9", "3.10", "3.11"] - solr: ["8.6", "9.2"] + solr: ["8.6"] django: [0, "3.2", "4.0"] + include: # run one build on solr 9.2; no need to run all combinations + - python: 3.9 + solr: 9.2 + django: 3.2 # We use service containers to avoid needing to set up a local copy of # mysql or postgres on the test runner instance. This syntax is similar to # the spec of a docker-compose file. For more, see: @@ -25,21 +29,21 @@ jobs: ports: - 8983:8983 steps: - - name: Copy solr configsets to solr home directory (Solr 8+) + - name: Copy solr configsets to solr home directory run: "docker exec -d ${{ job.services.solr.id }} cp -r /opt/solr/server/solr/configsets /var/solr/data" - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python }} # We base the python cache on the hash of all requirements files, so that # if any change, the cache is invalidated. - name: Cache pip - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ~/.cache/pip key: pip-${{ hashFiles('setup.py') }} @@ -65,4 +69,4 @@ jobs: run: py.test --cov=parasolr --cov-report=xml - name: Upload test coverage to Codecov - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v3 From 1f5def38df1d2ab00d8fedcf838e57605bf10d61 Mon Sep 17 00:00:00 2001 From: rlskoeser Date: Thu, 5 Oct 2023 16:43:48 -0400 Subject: [PATCH 9/9] Document changes and update versions in readme --- CHANGELOG.rst | 7 +++++++ README.rst | 2 +- parasolr/__init__.py | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index bce86c6..ecac667 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -3,6 +3,13 @@ CHANGELOG ========= +0.9.1 +---- + +* Solr 9 compatible; now tested against Solr 9.2 and 8.6 +* Dropped support for python 3.7; now tested against python 3.9-3.11 +* Now tested against Django 4.0 and 3.2 + 0.9 --- diff --git a/README.rst b/README.rst index 20ef802..82b5531 100644 --- a/README.rst +++ b/README.rst @@ -57,7 +57,7 @@ configuration and indexing content. .. image:: https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336 :target: https://pycqa.github.io/isort/ -Currently tested against Python 3.8 and 3.9, Solr 8.6.2, and Django 3.0-3.2 and without Django. +Tested against Python 3.9-3.11, Solr 8.6 and 9.2, and Django 3.2-4.0 and without Django. Installation diff --git a/parasolr/__init__.py b/parasolr/__init__.py index 15ac6f8..976272e 100644 --- a/parasolr/__init__.py +++ b/parasolr/__init__.py @@ -1,4 +1,4 @@ -__version_info__ = (0, 10, 0, "dev") +__version_info__ = (0, 9, 1, None) # Dot-connect all but the last. Last is dash-connected if not None. __version__ = ".".join([str(i) for i in __version_info__[:-1]])