Skip to content

Commit 030d252

Browse files
authored
Merge pull request #518 from DhavalGojiya/python3.9-deprecation
EOL: Drop support for Python 3.9 and below
2 parents 2a8ec8d + a1fe28c commit 030d252

File tree

14 files changed

+278
-366
lines changed

14 files changed

+278
-366
lines changed

.github/workflows/tox.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@ jobs:
88
tox:
99
strategy:
1010
fail-fast: false
11-
max-parallel: 5
1211
matrix:
13-
python: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14", "3.14t"]
12+
python: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.14t"]
1413
runs-on: ubuntu-latest
1514
steps:
1615
- uses: actions/checkout@v5

Pipfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ requests = "*"
1111
kazoo = "*"
1212

1313
[requires]
14-
python_version = "3.9"
14+
python_version = "3.10"

Pipfile.lock

Lines changed: 225 additions & 154 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.rst

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ Features
2525
Requirements
2626
============
2727

28-
* A supported version of Python 3
29-
* Requests 2.9.1+
28+
* Python 3.10+
29+
* Requests 2.32.5+
3030
* **Optional** - ``simplejson``
3131
* **Optional** - ``kazoo`` for SolrCloud mode
3232

@@ -52,9 +52,6 @@ Basic usage looks like:
5252

5353
.. code-block:: python
5454
55-
# If on Python 2.X
56-
from __future__ import print_function
57-
5855
import pysolr
5956
6057
# Create a client instance. The timeout and authentication options are not required.

get-solr-download-url.py

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,11 @@
11
#!/usr/bin/env python
2-
# encoding: utf-8
3-
4-
from __future__ import absolute_import, division, print_function, unicode_literals
52

63
import sys
74
from itertools import chain
5+
from urllib.parse import urljoin
86

97
import requests
108

11-
# Try to import urllib from the Python 3 reorganized stdlib first:
12-
try:
13-
from urllib.parse import urljoin
14-
except ImportError:
15-
try:
16-
from urlparse.parse import urljoin
17-
except ImportError:
18-
from urlparse import urljoin
19-
20-
219
if len(sys.argv) != 2:
2210
print("Usage: %s SOLR_VERSION" % sys.argv[0], file=sys.stderr)
2311
sys.exit(1)

pysolr.py

Lines changed: 32 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,16 @@
1-
# -*- coding: utf-8 -*-
2-
from __future__ import absolute_import, print_function, unicode_literals
3-
41
import ast
52
import datetime
63
import logging
74
import os
85
import random
96
import re
107
import time
8+
from importlib.metadata import PackageNotFoundError
9+
from importlib.metadata import version as _get_version
1110
from xml.etree import ElementTree # noqa: ICN001
1211

1312
import requests
1413

15-
try:
16-
from importlib.metadata import PackageNotFoundError
17-
from importlib.metadata import version as _get_version
18-
except ImportError:
19-
# python < 3.8
20-
from importlib_metadata import PackageNotFoundError
21-
from importlib_metadata import version as _get_version
22-
2314
try:
2415
from kazoo.client import KazooClient, KazooState
2516
except ImportError:
@@ -31,42 +22,10 @@
3122
except ImportError:
3223
import json
3324

34-
try:
35-
# Python 3.X
36-
from urllib.parse import urlencode
37-
except ImportError:
38-
# Python 2.X
39-
from urllib import urlencode
40-
41-
try:
42-
# Python 3.X
43-
from urllib.parse import quote
44-
except ImportError:
45-
# Python 2.X
46-
from urllib import quote
47-
48-
try:
49-
# Python 3.X
50-
import html.entities as htmlentities
51-
except ImportError:
52-
# Python 2.X
53-
import htmlentitydefs as htmlentities
54-
55-
try:
56-
# Python 3.X
57-
from http.client import HTTPException
58-
except ImportError:
59-
from httplib import HTTPException
60-
61-
try:
62-
# Python 2.X
63-
unicode_char = unichr
64-
except NameError:
65-
# Python 3.X
66-
unicode_char = chr
67-
# Ugh.
68-
long = int # NOQA: A001
6925

26+
import html.entities as htmlentities
27+
from http.client import HTTPException
28+
from urllib.parse import quote, urlencode
7029

7130
__author__ = "Daniel Lindsley, Joseph Kocherhans, Jacob Kaplan-Moss, Thomas Rieder"
7231
__all__ = ["Solr"]
@@ -110,33 +69,14 @@ def emit(self, record):
11069
LOG.addHandler(stream)
11170

11271

113-
def is_py3():
114-
try:
115-
basestring
116-
return False
117-
except NameError:
118-
return True
119-
120-
121-
IS_PY3 = is_py3()
122-
123-
12472
def force_unicode(value):
12573
"""
12674
Forces a bytestring to become a Unicode string.
12775
"""
128-
if IS_PY3:
129-
# Python 3.X
130-
if isinstance(value, bytes):
131-
value = value.decode("utf-8", errors="replace")
132-
elif not isinstance(value, str):
133-
value = str(value)
134-
else:
135-
# Python 2.X
136-
if isinstance(value, str):
137-
value = value.decode("utf-8", "replace")
138-
elif not isinstance(value, basestring): # NOQA: F821
139-
value = unicode(value) # NOQA: F821
76+
if isinstance(value, bytes):
77+
value = value.decode("utf-8", errors="replace")
78+
elif not isinstance(value, str):
79+
value = str(value)
14080

14181
return value
14282

@@ -145,12 +85,8 @@ def force_bytes(value):
14585
"""
14686
Forces a Unicode string to become a bytestring.
14787
"""
148-
if IS_PY3:
149-
if isinstance(value, str):
150-
value = value.encode("utf-8", "backslashreplace")
151-
else:
152-
if isinstance(value, unicode): # NOQA: F821
153-
value = value.encode("utf-8")
88+
if isinstance(value, str):
89+
value = value.encode("utf-8", "backslashreplace")
15490

15591
return value
15692

@@ -171,46 +107,30 @@ def fixup(m):
171107
# character reference
172108
try:
173109
if text[:3] == "&#x":
174-
return unicode_char(int(text[3:-1], 16))
110+
return chr(int(text[3:-1], 16))
175111
else:
176-
return unicode_char(int(text[2:-1]))
112+
return chr(int(text[2:-1]))
177113
except ValueError:
178114
pass
179115
else:
180116
# named entity
181117
try:
182-
text = unicode_char(htmlentities.name2codepoint[text[1:-1]])
118+
text = chr(htmlentities.name2codepoint[text[1:-1]])
183119
except KeyError:
184120
pass
185121
return text # leave as is
186122

187123
return re.sub(r"&#?\w+;", fixup, text)
188124

189125

190-
def safe_urlencode(params, doseq=0):
126+
def safe_urlencode(params, doseq=False):
191127
"""
192-
UTF-8-safe version of safe_urlencode
128+
URL-encode parameters using UTF-8 encoding.
193129
194-
The stdlib safe_urlencode prior to Python 3.x chokes on UTF-8 values
195-
which can't fail down to ascii.
130+
This is a wrapper around `urllib.parse.urlencode` that ensures
131+
consistent UTF-8 handling for all parameter values.
196132
"""
197-
if IS_PY3:
198-
return urlencode(params, doseq)
199-
200-
if hasattr(params, "items"):
201-
params = params.items()
202-
203-
new_params = []
204-
205-
for k, v in params:
206-
k = k.encode("utf-8")
207-
208-
if isinstance(v, (list, tuple)):
209-
new_params.append((k, [force_bytes(i) for i in v]))
210-
else:
211-
new_params.append((k, force_bytes(v)))
212-
213-
return urlencode(new_params, doseq)
133+
return urlencode(params, doseq)
214134

215135

216136
def clean_xml_string(s):
@@ -622,9 +542,9 @@ def _scrape_response(self, headers, response):
622542
full_html = ""
623543
dom_tree = None
624544

625-
# In Python3, response can be made of bytes
626-
if IS_PY3 and hasattr(response, "decode"):
545+
if hasattr(response, "decode"):
627546
response = response.decode()
547+
628548
if response.startswith("<?xml"):
629549
# Try a strict XML parse
630550
try:
@@ -707,14 +627,8 @@ def _from_python(self, value):
707627
else:
708628
value = "false"
709629
else:
710-
if IS_PY3:
711-
# Python 3.X
712-
if isinstance(value, bytes):
713-
value = str(value, errors="replace") # NOQA: F821
714-
else:
715-
# Python 2.X
716-
if isinstance(value, str):
717-
value = unicode(value, errors="replace") # NOQA: F821
630+
if isinstance(value, bytes):
631+
value = str(value, errors="replace") # NOQA: F821
718632

719633
value = "{0}".format(value)
720634

@@ -724,7 +638,7 @@ def _to_python(self, value):
724638
"""
725639
Converts values from Solr to native Python values.
726640
"""
727-
if isinstance(value, (int, float, long, complex)):
641+
if isinstance(value, (int, float, complex)):
728642
return value
729643

730644
if isinstance(value, (list, tuple)):
@@ -740,18 +654,11 @@ def _to_python(self, value):
740654

741655
is_string = False
742656

743-
if IS_PY3:
744-
if isinstance(value, bytes):
745-
value = force_unicode(value)
746-
747-
if isinstance(value, str):
748-
is_string = True
749-
else:
750-
if isinstance(value, str):
751-
value = force_unicode(value)
657+
if isinstance(value, bytes):
658+
value = force_unicode(value)
752659

753-
if isinstance(value, basestring): # NOQA: F821
754-
is_string = True
660+
if isinstance(value, str):
661+
is_string = True
755662

756663
if is_string:
757664
possible_datetime = DATETIME_REGEX.search(value)
@@ -791,14 +698,8 @@ def _is_null_value(self, value):
791698
if value is None:
792699
return True
793700

794-
if IS_PY3:
795-
# Python 3.X
796-
if isinstance(value, str) and len(value) == 0:
797-
return True
798-
else:
799-
# Python 2.X
800-
if isinstance(value, basestring) and len(value) == 0: # NOQA: F821
801-
return True
701+
if isinstance(value, str) and len(value) == 0:
702+
return True
802703

803704
# TODO: This should probably be removed when solved in core Solr level?
804705
return False
@@ -1484,7 +1385,7 @@ def __init__(
14841385
auth=None,
14851386
verify=True,
14861387
*args,
1487-
**kwargs
1388+
**kwargs,
14881389
):
14891390
url = zookeeper.getRandomURL(collection)
14901391
self.auth = auth
@@ -1502,7 +1403,7 @@ def __init__(
15021403
auth=self.auth,
15031404
verify=self.verify,
15041405
*args,
1505-
**kwargs
1406+
**kwargs,
15061407
)
15071408

15081409
def _send_request(self, method, path="", body=None, headers=None, files=None):

run-tests.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
#!/usr/bin/env python
2-
# encoding: utf-8
3-
4-
from __future__ import absolute_import, print_function, unicode_literals
52

63
import faulthandler
74
import signal

setup.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,8 @@
2323
],
2424
url="https://github.com/django-haystack/pysolr/",
2525
license="BSD",
26-
install_requires=[
27-
"requests>=2.9.1",
28-
"setuptools",
29-
"importlib_metadata; python_version<'3.8'",
30-
],
26+
install_requires=["requests>=2.32.5", "setuptools"],
27+
python_requires=">=3.10",
3128
extras_require={"solrcloud": ["kazoo>=2.5.0"]},
3229
setup_requires=["setuptools_scm"],
3330
)

tests/__init__.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
# encoding: utf-8
2-
3-
from __future__ import absolute_import, print_function, unicode_literals
4-
51
from .test_admin import * # NOQA
62
from .test_client import * # NOQA
73
from .test_cloud import * # NOQA

tests/test_admin.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
# -*- coding: utf-8 -*-
2-
3-
from __future__ import absolute_import, unicode_literals
4-
51
import unittest
62

73
from pysolr import SolrCoreAdmin

0 commit comments

Comments
 (0)