diff --git a/cassandra/cluster.py b/cassandra/cluster.py index 6b2ab4b288..f1019410c9 100644 --- a/cassandra/cluster.py +++ b/cassandra/cluster.py @@ -1424,26 +1424,26 @@ def _create_thread_pool_executor(self, **kwargs): :return: A ThreadPoolExecutor instance. """ tpe_class = ThreadPoolExecutor - if sys.version_info[0] >= 3 and sys.version_info[1] >= 7: - try: - from cassandra.io.eventletreactor import EventletConnection - is_eventlet = issubclass(self.connection_class, EventletConnection) - except: - # Eventlet is not available or can't be detected - return tpe_class(**kwargs) - if is_eventlet: - try: - from futurist import GreenThreadPoolExecutor - tpe_class = GreenThreadPoolExecutor - except ImportError: - # futurist is not available - raise ImportError( - ("Python 3.7+ and Eventlet cause the `concurrent.futures.ThreadPoolExecutor` " - "to hang indefinitely. If you want to use the Eventlet reactor, you " - "need to install the `futurist` package to allow the driver to use " - "the GreenThreadPoolExecutor. See https://github.com/eventlet/eventlet/issues/508 " - "for more details.")) + try: + from cassandra.io.eventletreactor import EventletConnection + is_eventlet = issubclass(self.connection_class, EventletConnection) + except ImportError: + # Eventlet is not available or can't be detected + return tpe_class(**kwargs) + + if is_eventlet: + try: + from futurist import GreenThreadPoolExecutor + tpe_class = GreenThreadPoolExecutor + except ImportError: + # futurist is not available + raise ImportError( + ("Python 3.7+ and Eventlet cause the `concurrent.futures.ThreadPoolExecutor` " + "to hang indefinitely. If you want to use the Eventlet reactor, you " + "need to install the `futurist` package to allow the driver to use " + "the GreenThreadPoolExecutor. See https://github.com/eventlet/eventlet/issues/508 " + "for more details.")) return tpe_class(**kwargs) diff --git a/tests/integration/advanced/graph/fluent/__init__.py b/tests/integration/advanced/graph/fluent/__init__.py index 1c07cd46c0..d28fa9d315 100644 --- a/tests/integration/advanced/graph/fluent/__init__.py +++ b/tests/integration/advanced/graph/fluent/__init__.py @@ -585,10 +585,7 @@ def _validate_prop(key, value, unittest): typ = int elif any(key.startswith(t) for t in ('long',)): - if sys.version_info >= (3, 0): - typ = int - else: - typ = long + typ = int elif any(key.startswith(t) for t in ('float', 'double')): typ = float elif any(key.startswith(t) for t in ('polygon',)): diff --git a/tests/integration/cqlengine/base.py b/tests/integration/cqlengine/base.py index 1b99005fc4..321d7b5bdb 100644 --- a/tests/integration/cqlengine/base.py +++ b/tests/integration/cqlengine/base.py @@ -15,14 +15,13 @@ # limitations under the License. import unittest -import sys - from cassandra.cqlengine.connection import get_session from cassandra.cqlengine.models import Model from cassandra.cqlengine import columns from uuid import uuid4 + class TestQueryUpdateModel(Model): partition = columns.UUID(primary_key=True, default=uuid4) @@ -33,6 +32,7 @@ class TestQueryUpdateModel(Model): text_list = columns.List(columns.Text, required=False) text_map = columns.Map(columns.Text, columns.Text, required=False) + class BaseCassEngTestCase(unittest.TestCase): session = None @@ -48,6 +48,5 @@ def assertNotHasAttr(self, obj, attr): self.assertFalse(hasattr(obj, attr), "{0} shouldn't have the attribute: {1}".format(obj, attr)) - if sys.version_info > (3, 0): - def assertItemsEqual(self, first, second, msg=None): - return self.assertCountEqual(first, second, msg) + def assertItemsEqual(self, first, second, msg=None): + return self.assertCountEqual(first, second, msg) diff --git a/tests/integration/cqlengine/columns/test_validation.py b/tests/integration/cqlengine/columns/test_validation.py index 48ae74b5ab..5c3a20eb67 100644 --- a/tests/integration/cqlengine/columns/test_validation.py +++ b/tests/integration/cqlengine/columns/test_validation.py @@ -61,6 +61,7 @@ def test_datetime_tzinfo_io(self): class TZ(tzinfo): def utcoffset(self, date_time): return timedelta(hours=-1) + def dst(self, date_time): return None @@ -91,7 +92,7 @@ def test_datetime_none(self): self.assertIsNone(dts[0][0]) def test_datetime_invalid(self): - dt_value= 'INVALID' + dt_value = 'INVALID' with self.assertRaises(TypeError): self.DatetimeTest.objects.create(test_id=4, created_at=dt_value) @@ -125,7 +126,7 @@ def test_datetime_truncate_microseconds(self): dt_truncated = datetime(2024, 12, 31, 10, 10, 10, 923000) self.DatetimeTest.objects.create(test_id=6, created_at=dt_value) dt2 = self.DatetimeTest.objects(test_id=6).first() - self.assertEqual(dt2.created_at,dt_truncated) + self.assertEqual(dt2.created_at, dt_truncated) finally: # We need to always return behavior to default DateTime.truncate_microseconds = False @@ -191,7 +192,7 @@ def test_varint_io(self): self.VarIntTest.objects.create(test_id=0, bignum="not_a_number") -class DataType(): +class DataType: @classmethod def setUpClass(cls): if PROTOCOL_VERSION < 4 or CASSANDRA_VERSION < Version("3.0"): @@ -344,6 +345,7 @@ def setUpClass(cls): ) super(TestBoolean, cls).setUpClass() + @greaterthanorequalcass3_11 class TestDuration(DataType, BaseCassEngTestCase): @classmethod @@ -507,7 +509,7 @@ def test_timeuuid_io(self): class TestInteger(BaseCassEngTestCase): class IntegerTest(Model): - test_id = UUID(primary_key=True, default=lambda:uuid4()) + test_id = UUID(primary_key=True, default=lambda: uuid4()) value = Integer(default=0, required=True) def test_default_zero_fields_validate(self): @@ -519,8 +521,8 @@ def test_default_zero_fields_validate(self): class TestBigInt(BaseCassEngTestCase): class BigIntTest(Model): - test_id = UUID(primary_key=True, default=lambda:uuid4()) - value = BigInt(default=0, required=True) + test_id = UUID(primary_key=True, default=lambda: uuid4()) + value = BigInt(default=0, required=True) def test_default_zero_fields_validate(self): """ Tests that bigint columns with a default value of 0 validate """ @@ -612,10 +614,6 @@ def test_type_checking(self): with self.assertRaises(ValidationError): Ascii().validate('Beyonc' + chr(233)) - if sys.version_info < (3, 1): - with self.assertRaises(ValidationError): - Ascii().validate(u'Beyonc' + unichr(233)) - def test_unaltering_validation(self): """ Test the validation step doesn't re-interpret values. """ self.assertEqual(Ascii().validate(''), '') @@ -736,8 +734,6 @@ def test_type_checking(self): Text().validate("!#$%&\'()*+,-./") Text().validate('Beyonc' + chr(233)) - if sys.version_info < (3, 1): - Text().validate(u'Beyonc' + unichr(233)) def test_unaltering_validation(self): """ Test the validation step doesn't re-interpret values. """ @@ -810,7 +806,7 @@ def test_conversion_specific_date(self): from uuid import UUID assert isinstance(uuid, UUID) - ts = (uuid.time - 0x01b21dd213814000) / 1e7 # back to a timestamp + ts = (uuid.time - 0x01b21dd213814000) / 1e7 # back to a timestamp new_dt = datetime.fromtimestamp(ts, tz=timezone.utc).replace(tzinfo=None) # checks that we created a UUID1 with the proper timestamp diff --git a/tests/integration/standard/test_metadata.py b/tests/integration/standard/test_metadata.py index 8f7ba04883..9d256b3aff 100644 --- a/tests/integration/standard/test_metadata.py +++ b/tests/integration/standard/test_metadata.py @@ -1087,14 +1087,6 @@ def test_export_keyspace_schema_udts(self): Test udt exports """ - if PROTOCOL_VERSION < 3: - raise unittest.SkipTest( - "Protocol 3.0+ is required for UDT change events, currently testing against %r" - % (PROTOCOL_VERSION,)) - - if sys.version_info[0:2] != (2, 7): - raise unittest.SkipTest('This test compares static strings generated from dict items, which may change orders. Test with 2.7.') - cluster = TestCluster() session = cluster.connect() @@ -1591,7 +1583,7 @@ def test_function_no_parameters(self): with self.VerifiedFunction(self, **kwargs) as vf: fn_meta = self.keyspace_function_meta[vf.signature] - self.assertRegex(fn_meta.as_cql_query(), "CREATE FUNCTION.*%s\(\) .*" % kwargs['name']) + self.assertRegex(fn_meta.as_cql_query(), "CREATE FUNCTION.*%s() .*" % kwargs['name']) def test_functions_follow_keyspace_alter(self): """ @@ -1639,12 +1631,12 @@ def test_function_cql_called_on_null(self): kwargs['called_on_null_input'] = True with self.VerifiedFunction(self, **kwargs) as vf: fn_meta = self.keyspace_function_meta[vf.signature] - self.assertRegex(fn_meta.as_cql_query(), "CREATE FUNCTION.*\) CALLED ON NULL INPUT RETURNS .*") + self.assertRegex(fn_meta.as_cql_query(), "CREATE FUNCTION.*) CALLED ON NULL INPUT RETURNS .*") kwargs['called_on_null_input'] = False with self.VerifiedFunction(self, **kwargs) as vf: fn_meta = self.keyspace_function_meta[vf.signature] - self.assertRegex(fn_meta.as_cql_query(), "CREATE FUNCTION.*\) RETURNS NULL ON NULL INPUT RETURNS .*") + self.assertRegex(fn_meta.as_cql_query(), "CREATE FUNCTION.*) RETURNS NULL ON NULL INPUT RETURNS .*") class AggregateMetadata(FunctionTest): diff --git a/tests/unit/advanced/test_insights.py b/tests/unit/advanced/test_insights.py index e6be6fc3d1..aae1787997 100644 --- a/tests/unit/advanced/test_insights.py +++ b/tests/unit/advanced/test_insights.py @@ -18,7 +18,6 @@ import unittest import logging -import sys from unittest.mock import sentinel from cassandra import ConsistencyLevel @@ -32,7 +31,6 @@ from cassandra.datastax.graph.query import GraphOptions from cassandra.datastax.insights.registry import insights_registry from cassandra.datastax.insights.serializers import initialize_registry -from cassandra.datastax.insights.util import namespace from cassandra.policies import ( RoundRobinPolicy, LoadBalancingPolicy, @@ -63,8 +61,7 @@ class NoConfAsDict(object): obj = NoConfAsDict() ns = 'tests.unit.advanced.test_insights' - if sys.version_info > (3,): - ns += '.TestGetConfig.test_invalid_object.' + ns += '.TestGetConfig.test_invalid_object.' # no default # ... as a policy @@ -102,6 +99,7 @@ def superclass_sentinel_serializer(obj): self.assertIs(insights_registry.serialize(SubclassSentinel(), default=object()), sentinel.serialized_superclass) + class TestConfigAsDict(unittest.TestCase): # graph/query.py @@ -253,8 +251,8 @@ def test_constant_reconnection_policy(self): self.assertEqual( insights_registry.serialize(ConstantReconnectionPolicy(3, 200)), {'type': 'ConstantReconnectionPolicy', - 'namespace': 'cassandra.policies', - 'options': {'delay': 3, 'max_attempts': 200} + 'namespace': 'cassandra.policies', + 'options': {'delay': 3, 'max_attempts': 200} } ) @@ -262,8 +260,8 @@ def test_exponential_reconnection_policy(self): self.assertEqual( insights_registry.serialize(ExponentialReconnectionPolicy(4, 100, 10)), {'type': 'ExponentialReconnectionPolicy', - 'namespace': 'cassandra.policies', - 'options': {'base_delay': 4, 'max_delay': 100, 'max_attempts': 10} + 'namespace': 'cassandra.policies', + 'options': {'base_delay': 4, 'max_delay': 100, 'max_attempts': 10} } ) @@ -271,8 +269,8 @@ def test_retry_policy(self): self.assertEqual( insights_registry.serialize(RetryPolicy()), {'type': 'RetryPolicy', - 'namespace': 'cassandra.policies', - 'options': {} + 'namespace': 'cassandra.policies', + 'options': {} } ) @@ -280,8 +278,8 @@ def test_spec_exec_policy(self): self.assertEqual( insights_registry.serialize(SpeculativeExecutionPolicy()), {'type': 'SpeculativeExecutionPolicy', - 'namespace': 'cassandra.policies', - 'options': {} + 'namespace': 'cassandra.policies', + 'options': {} } ) diff --git a/tests/unit/test_policies.py b/tests/unit/test_policies.py index 792268cd7f..90c9a4b324 100644 --- a/tests/unit/test_policies.py +++ b/tests/unit/test_policies.py @@ -909,7 +909,7 @@ def test_schedule_with_max(self): if i == 0: self._assert_between(delay, base_delay*0.85, base_delay*1.15) elif i < 6: - value = base_delay * (2 ** i) + value = base_delay * (2 ** i) self._assert_between(delay, value*85/100, value*1.15) else: self._assert_between(delay, max_delay*85/100, max_delay*1.15) @@ -956,7 +956,7 @@ def test_schedule_with_jitter(self): """ for i in range(100): base_delay = float(randint(2, 5)) - max_delay = (base_delay - 1) * 100.0 + max_delay = (base_delay - 1) * 100.0 ep = ExponentialReconnectionPolicy(base_delay, max_delay, max_attempts=64) schedule = ep.new_schedule() for i in range(64): @@ -1467,13 +1467,12 @@ def get_replicas(keyspace, packed_key): # We don't allow randomness for ordering the replicas in RoundRobin hfp._child_policy._child_policy._position = 0 - mocked_query = Mock() query_plan = hfp.make_query_plan("keyspace", mocked_query) # First the not filtered replica, and then the rest of the allowed hosts ordered query_plan = list(query_plan) self.assertEqual(query_plan[0], Host(DefaultEndPoint("127.0.0.2"), SimpleConvictionPolicy)) - self.assertEqual(set(query_plan[1:]),{Host(DefaultEndPoint("127.0.0.3"), SimpleConvictionPolicy), + self.assertEqual(set(query_plan[1:]), {Host(DefaultEndPoint("127.0.0.3"), SimpleConvictionPolicy), Host(DefaultEndPoint("127.0.0.5"), SimpleConvictionPolicy)}) def test_create_whitelist(self): diff --git a/tests/unit/test_row_factories.py b/tests/unit/test_row_factories.py index 0055497a54..899fa9a030 100644 --- a/tests/unit/test_row_factories.py +++ b/tests/unit/test_row_factories.py @@ -24,12 +24,8 @@ from unittest import TestCase - log = logging.getLogger(__name__) - -NAMEDTUPLE_CREATION_BUG = sys.version_info >= (3,) and sys.version_info < (3, 7) - class TestNamedTupleFactory(TestCase): long_colnames, long_rows = ( @@ -49,37 +45,16 @@ class TestNamedTupleFactory(TestCase): def test_creation_warning_on_long_column_list(self): """ - Reproduces the failure described in PYTHON-893 - - @since 3.15 - @jira_ticket PYTHON-893 - @expected_result creation fails on Python > 3 and < 3.7 - - @test_category row_factory + Test for a regression in PYTHON-893. Shouldn't be an issue with currently + supported versions since the underlying issue was fixed in Python 3.7 """ - if not NAMEDTUPLE_CREATION_BUG: - named_tuple_factory(self.long_colnames, self.long_rows) - return - - with warnings.catch_warnings(record=True) as w: - rows = named_tuple_factory(self.long_colnames, self.long_rows) - self.assertEqual(len(w), 1) - warning = w[0] - self.assertIn('pseudo_namedtuple_factory', str(warning)) - self.assertIn('3.7', str(warning)) - - for r in rows: - self.assertEqual(r.col0, self.long_rows[0][0]) + named_tuple_factory(self.long_colnames, self.long_rows) def test_creation_no_warning_on_short_column_list(self): """ - Tests that normal namedtuple row creation still works after PYTHON-893 fix - - @since 3.15 - @jira_ticket PYTHON-893 - @expected_result creates namedtuple-based Rows - - @test_category row_factory + Tests that normal namedtuple row creation still works after PYTHON-893 fix. + Shouldn't be an issue with currently supported versions since the underlying + issue was fixed in Python 3.7 """ with warnings.catch_warnings(record=True) as w: rows = named_tuple_factory(self.short_colnames, self.short_rows)