Skip to content

Commit c3b8f16

Browse files
committed
cqltypes: fix SyntaxWarning for invalid escape sequence in UDT names
In cqltype_to_python(), double-quoted UDT names containing backslashes (e.g. '"!@#$%^&*()[]\ frozen >>>") were passed to ast.literal_eval without escaping, producing SyntaxWarning on Python 3.12+: SyntaxWarning: "\ " is an invalid escape sequence Escape backslashes before wrapping the token for ast.literal_eval. The reverse operation already exists in python_to_cqltype() at line 159.
1 parent 9c53d78 commit c3b8f16

2 files changed

Lines changed: 24 additions & 2 deletions

File tree

cassandra/cqltypes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ def cqltype_to_python(cql_string):
130130
(r'<', lambda s, t: ', ['),
131131
(r'>', lambda s, t: ']'),
132132
(r'[, ]', lambda s, t: t),
133-
(r'".*?"', lambda s, t: "'{}'".format(t)),
133+
(r'".*?"', lambda s, t: "'{}'".format(t.replace('\\', '\\\\'))),
134134
))
135135

136136
scanned_tokens = scanner.scan(cql_string)[0]

tests/unit/test_metadata.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
import unittest
15+
import warnings
1516

1617
from binascii import unhexlify
1718
import logging
@@ -21,7 +22,7 @@
2122
import uuid
2223

2324
import cassandra
24-
from cassandra.cqltypes import strip_frozen
25+
from cassandra.cqltypes import cqltype_to_python, python_to_cqltype, strip_frozen
2526
from cassandra.marshal import uint16_unpack, uint16_pack
2627
from cassandra.metadata import (Murmur3Token, MD5Token,
2728
BytesToken, ReplicationStrategy,
@@ -846,3 +847,24 @@ def test_strip_frozen(self):
846847
for argument, expected_result in argument_to_expected_results:
847848
result = strip_frozen(argument)
848849
assert result == expected_result, "strip_frozen() arg: {}".format(argument)
850+
851+
def test_cqltype_backslash_escape(self):
852+
"""Verify that UDT names containing backslashes don't trigger SyntaxWarning (python-driver#XXX)."""
853+
udt_input = r'map<"!@#$%^&*()[]\ frozen >>>", int>'
854+
855+
# Parsing must not emit SyntaxWarning
856+
with warnings.catch_warnings(record=True) as caught:
857+
warnings.simplefilter('always')
858+
result = cqltype_to_python(udt_input)
859+
syntax_warnings = [w for w in caught if issubclass(w.category, SyntaxWarning)]
860+
self.assertEqual(syntax_warnings, [], 'cqltype_to_python emitted SyntaxWarning')
861+
862+
# Parsed result should preserve the quoted UDT name with backslash
863+
self.assertEqual(result[0], 'map')
864+
self.assertIsInstance(result[1], list)
865+
self.assertEqual(result[1][0], r'"!@#$%^&*()[]\ frozen >>>"')
866+
self.assertEqual(result[1][1], 'int')
867+
868+
# Round-trip: python_to_cqltype(cqltype_to_python(x)) == x
869+
round_tripped = python_to_cqltype(result)
870+
self.assertEqual(round_tripped, udt_input)

0 commit comments

Comments
 (0)