From 7fb07c43b5ccea068ecd5986dda8689510708752 Mon Sep 17 00:00:00 2001 From: Israel Fruchter Date: Wed, 11 Oct 2023 19:23:01 +0300 Subject: [PATCH 1/5] Ignore AttributeError on eventlet import running on python 3.12, we get this error, we should ignore it until eventlet is fixed ``` ImportError while loading conftest '/home/runner/work/python-driver/python-driver/tests/integration/conftest.py'. tests/integration/__init__.py:16: in from cassandra.cluster import Cluster cassandra/cluster.py:103: in init cassandra.cluster from cassandra.io.eventletreactor import EventletConnection cassandra/io/eventletreactor.py:18: in import eventlet .test-venv/lib/python3.12/site-packages/eventlet/__init__.py:17: in from eventlet import convenience .test-venv/lib/python3.12/site-packages/eventlet/convenience.py:7: in from eventlet.green import socket .test-venv/lib/python3.12/site-packages/eventlet/green/socket.py:21: in from eventlet.support import greendns .test-venv/lib/python3.12/site-packages/eventlet/support/greendns.py:45: in from eventlet.green import ssl .test-venv/lib/python3.12/site-packages/eventlet/green/ssl.py:25: in _original_wrap_socket = __ssl.wrap_socket E AttributeError: module 'ssl' has no attribute 'wrap_socket' ``` Ref: https://github.com/eventlet/eventlet/issues/812 --- cassandra/cluster.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/cassandra/cluster.py b/cassandra/cluster.py index 6ec04521c7..9530333ba6 100644 --- a/cassandra/cluster.py +++ b/cassandra/cluster.py @@ -101,7 +101,9 @@ try: from cassandra.io.eventletreactor import EventletConnection -except ImportError: +except (ImportError, AttributeError): + # AttributeError was add for handling python 3.12 https://github.com/eventlet/eventlet/issues/812 + # TODO: remove it when eventlet issue would be fixed EventletConnection = None try: @@ -115,9 +117,13 @@ def _is_eventlet_monkey_patched(): if 'eventlet.patcher' not in sys.modules: return False - import eventlet.patcher - return eventlet.patcher.is_monkey_patched('socket') - + try: + import eventlet.patcher + return eventlet.patcher.is_monkey_patched('socket') + except (ImportError, AttributeError): + # AttributeError was add for handling python 3.12 https://github.com/eventlet/eventlet/issues/812 + # TODO: remove it when eventlet issue would be fixed + return False def _is_gevent_monkey_patched(): if 'gevent.monkey' not in sys.modules: From ed2b2442d6483f91c843207ba8e71f8d8ee2c25c Mon Sep 17 00:00:00 2001 From: Israel Fruchter Date: Thu, 12 Oct 2023 12:27:21 +0300 Subject: [PATCH 2/5] test_cluster: remove `import asyncore` this isn't being used anyhow, and breaking support for python 3.12 --- tests/integration/standard/test_cluster.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/integration/standard/test_cluster.py b/tests/integration/standard/test_cluster.py index 36a54aedae..43356dbd82 100644 --- a/tests/integration/standard/test_cluster.py +++ b/tests/integration/standard/test_cluster.py @@ -11,7 +11,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -import asyncore import subprocess import unittest From 34037ed8f82150e3f83b2b72b7f77d6efa428828 Mon Sep 17 00:00:00 2001 From: Israel Fruchter Date: Thu, 12 Oct 2023 16:03:43 +0300 Subject: [PATCH 3/5] handle the case asyncore isn't available since asyncore isn't available in python 3.12, we should be gracfully handle it, and enable any other event loop implementions to work --- tests/integration/standard/test_connection.py | 8 ++++++-- .../integration/standard/test_scylla_cloud.py | 19 +++++++++++++------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/tests/integration/standard/test_connection.py b/tests/integration/standard/test_connection.py index 9eb658316e..0220ffbb1a 100644 --- a/tests/integration/standard/test_connection.py +++ b/tests/integration/standard/test_connection.py @@ -26,8 +26,12 @@ from cassandra import ConsistencyLevel, OperationTimedOut from cassandra.cluster import NoHostAvailable, ConnectionShutdown, ExecutionProfile, EXEC_PROFILE_DEFAULT -import cassandra.io.asyncorereactor -from cassandra.io.asyncorereactor import AsyncoreConnection + +try: + from cassandra.io.asyncorereactor import AsyncoreConnection +except ImportError: + AsyncoreConnection = None + from cassandra.protocol import QueryMessage from cassandra.connection import Connection from cassandra.policies import HostFilterPolicy, RoundRobinPolicy, HostStateListener diff --git a/tests/integration/standard/test_scylla_cloud.py b/tests/integration/standard/test_scylla_cloud.py index 751bf656c3..4515358085 100644 --- a/tests/integration/standard/test_scylla_cloud.py +++ b/tests/integration/standard/test_scylla_cloud.py @@ -6,15 +6,22 @@ from tests.integration import use_cluster from cassandra.cluster import Cluster, TwistedConnection -from cassandra.io.asyncorereactor import AsyncoreConnection + + from cassandra.io.libevreactor import LibevConnection -from cassandra.io.geventreactor import GeventConnection -from cassandra.io.eventletreactor import EventletConnection -from cassandra.io.asyncioreactor import AsyncioConnection +supported_connection_classes = [LibevConnection, TwistedConnection] +try: + from cassandra.io.asyncorereactor import AsyncoreConnection + supported_connection_classes += [AsyncoreConnection] +except ImportError: + pass + +#from cassandra.io.geventreactor import GeventConnection +#from cassandra.io.eventletreactor import EventletConnection +#from cassandra.io.asyncioreactor import AsyncioConnection -supported_connection_classes = [AsyncoreConnection, LibevConnection, TwistedConnection] # need to run them with specific configuration like `gevent.monkey.patch_all()` or under async functions -unsupported_connection_classes = [GeventConnection, AsyncioConnection, EventletConnection] +# unsupported_connection_classes = [GeventConnection, AsyncioConnection, EventletConnection] class ScyllaCloudConfigTests(TestCase): From 7148b8746cf4313f41049b30d664d0e60e06e65b Mon Sep 17 00:00:00 2001 From: Israel Fruchter Date: Wed, 18 Oct 2023 00:14:45 +0300 Subject: [PATCH 4/5] cassandra/cluster.py: make asyncio default if asyncore not available since python 3.12 is deprecating asyncore, we should make asyncio the default fallback event loop when asyncore isn't available asyncio now that it's fixed and we verified it's working (passing the integration suite) in multiple python versions we support (from 3.8 - 3.12) --- cassandra/cluster.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cassandra/cluster.py b/cassandra/cluster.py index 9530333ba6..1de3a6f508 100644 --- a/cassandra/cluster.py +++ b/cassandra/cluster.py @@ -143,7 +143,10 @@ def _is_gevent_monkey_patched(): try: from cassandra.io.libevreactor import LibevConnection as DefaultConnection # NOQA except ImportError: - from cassandra.io.asyncorereactor import AsyncoreConnection as DefaultConnection # NOQA + try: + from cassandra.io.asyncorereactor import AsyncoreConnection as DefaultConnection # NOQA + except ImportError: + from cassandra.io.asyncioreactor import AsyncioConnection as DefaultConnection # NOQA # Forces load of utf8 encoding module to avoid deadlock that occurs # if code that is being imported tries to import the module in a seperate From 6730c6754c8ec8c9916ddf7dde4b686d86aeaec6 Mon Sep 17 00:00:00 2001 From: Israel Fruchter Date: Sun, 19 Nov 2023 18:35:31 +0200 Subject: [PATCH 5/5] CI: enable builds of python 3.12 wheels --- .github/workflows/build-experimental.yml | 2 +- .github/workflows/build-push.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-experimental.yml b/.github/workflows/build-experimental.yml index 182f57d239..bfc6bd0949 100644 --- a/.github/workflows/build-experimental.yml +++ b/.github/workflows/build-experimental.yml @@ -4,7 +4,7 @@ on: [push, pull_request] env: CIBW_BEFORE_BUILD_LINUX: "rm -rf ~/.pyxbld && yum install -y libev libev-devel openssl openssl-devel" CIBW_ENVIRONMENT: "CASS_DRIVER_BUILD_CONCURRENCY=2 CFLAGS='-g0 -O3'" - CIBW_BUILD: "cp38* cp39* cp310* cp311*" + CIBW_BUILD: "cp39* cp310* cp311* cp312*" CIBW_SKIP: "*musllinux*" jobs: build_wheels: diff --git a/.github/workflows/build-push.yml b/.github/workflows/build-push.yml index 2118478a9c..74f0415822 100644 --- a/.github/workflows/build-push.yml +++ b/.github/workflows/build-push.yml @@ -10,7 +10,7 @@ env: CIBW_BEFORE_TEST: "pip install -r {project}/test-requirements.txt" CIBW_BEFORE_BUILD_LINUX: "rm -rf ~/.pyxbld && yum install -y libffi-devel libev libev-devel openssl openssl-devel" CIBW_ENVIRONMENT: "CASS_DRIVER_BUILD_CONCURRENCY=2 CFLAGS='-g0 -O3'" - CIBW_SKIP: cp35* cp36* *musllinux* cp312* + CIBW_SKIP: cp35* cp36* *musllinux* jobs: build_wheels: