Skip to content

Commit 88be80e

Browse files
committed
WL#16318: Deprecate Cursors Prepared Raw and Named Tuple
Change-Id: Ia365baf6d5f258a2c689d2e68e35122fc70cbb25
1 parent 4bfbe2d commit 88be80e

File tree

8 files changed

+432
-175
lines changed

8 files changed

+432
-175
lines changed

CHANGES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ v9.0.0
1212
======
1313

1414
- WL#16350: Update dnspython version
15+
- WL#16318: Deprecate Cursors Prepared Raw and Named Tuple
1516
- WL#16283: Remove OpenTelemetry Bundled Installation
1617
- BUG#36476195: Incorrect escaping in pure Python mode if sql_mode includes NO_BACKSLASH_ESCAPES
1718
- BUG#36289767: MySQLCursorBufferedRaw does not skip conversion

mysql-connector-python/lib/mysql/connector/aio/connection.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
ServerCmd,
6767
ServerFlag,
6868
flag_is_set,
69+
raise_warning_against_deprecated_cursor_class,
6970
)
7071
from ..errors import (
7172
DatabaseError,
@@ -758,6 +759,9 @@ async def cursor(
758759
24: MySQLCursorPreparedNamedTuple,
759760
}
760761
try:
762+
raise_warning_against_deprecated_cursor_class(
763+
cursor_name=types[cursor_type].__name__
764+
)
761765
return (types[cursor_type])(self)
762766
except KeyError:
763767
args = ("buffered", "raw", "dictionary", "named_tuple", "prepared")

mysql-connector-python/lib/mysql/connector/connection.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
ServerCmd,
6767
ServerFlag,
6868
flag_is_set,
69+
raise_warning_against_deprecated_cursor_class,
6970
)
7071
from .conversion import MySQLConverter
7172
from .cursor import (
@@ -1274,6 +1275,9 @@ def cursor(
12741275
24: MySQLCursorPreparedNamedTuple,
12751276
}
12761277
try:
1278+
raise_warning_against_deprecated_cursor_class(
1279+
cursor_name=types[cursor_type].__name__
1280+
)
12771281
return (types[cursor_type])(self)
12781282
except KeyError:
12791283
args = ("buffered", "raw", "dictionary", "named_tuple", "prepared")

mysql-connector-python/lib/mysql/connector/connection_cext.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,14 @@
5050

5151
from . import version
5252
from .abstracts import CMySQLPrepStmt, MySQLConnectionAbstract
53-
from .constants import ClientFlag, FieldFlag, FieldType, ServerFlag, ShutdownType
53+
from .constants import (
54+
ClientFlag,
55+
FieldFlag,
56+
FieldType,
57+
ServerFlag,
58+
ShutdownType,
59+
raise_warning_against_deprecated_cursor_class,
60+
)
5461
from .conversion import MySQLConverter
5562
from .errors import (
5663
InterfaceError,
@@ -799,6 +806,9 @@ def cursor(
799806
24: CMySQLCursorPreparedNamedTuple,
800807
}
801808
try:
809+
raise_warning_against_deprecated_cursor_class(
810+
cursor_name=types[cursor_type].__name__
811+
)
802812
return (types[cursor_type])(self)
803813
except KeyError:
804814
args = ("buffered", "raw", "dictionary", "named_tuple", "prepared")

mysql-connector-python/lib/mysql/connector/constants.py

Lines changed: 203 additions & 172 deletions
Large diffs are not rendered by default.

mysql-connector-python/tests/cext/test_cext_cursor.py

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import unittest
4040

4141
from collections import namedtuple
42+
import warnings
4243

4344
import tests
4445

@@ -76,7 +77,9 @@ def _get_cursor(self, cnx=None):
7677
def test___init__(self):
7778
self.assertRaises(errors.InterfaceError, CMySQLCursor, connection="ham")
7879
cur = self._get_cursor(self.cnx)
79-
self.assertTrue(hex(id(self.cnx)).upper()[2:-1] in repr(cur._connection).upper())
80+
self.assertTrue(
81+
hex(id(self.cnx)).upper()[2:-1] in repr(cur._connection).upper()
82+
)
8083

8184
def test_lastrowid(self):
8285
cur = self._get_cursor(self.cnx)
@@ -657,7 +660,9 @@ def test___init__(self):
657660
self.assertRaises(errors.InterfaceError, CMySQLCursorBuffered, connection="ham")
658661

659662
cur = self._get_cursor(self.cnx)
660-
self.assertTrue(hex(id(self.cnx)).upper()[2:-1] in repr(cur._connection).upper())
663+
self.assertTrue(
664+
hex(id(self.cnx)).upper()[2:-1] in repr(cur._connection).upper()
665+
)
661666

662667
def test_execute(self):
663668
self.cnx.get_warnings = True
@@ -1364,3 +1369,66 @@ def test_executemany(self):
13641369
self.assertEqual(len(rows), 4)
13651370
for row in rows:
13661371
self.assertEqual(row[1:], self.exp)
1372+
1373+
1374+
class CMySQLCursorDeprecatedTests(tests.CMySQLCursorTests):
1375+
1376+
def test_deprecation_cursor_prepared_raw(self):
1377+
with warnings.catch_warnings(record=True) as warnings_stack:
1378+
# Cause all warnings to always be triggered.
1379+
warnings.simplefilter("always", DeprecationWarning)
1380+
# The warning should be raised as the cursor is instantiated
1381+
with self.cnx.cursor(prepared=True, raw=True) as _:
1382+
pass
1383+
self.assertTrue(
1384+
len(warnings_stack) != 0,
1385+
msg="No warnings were caught as warnings_stack was empty",
1386+
)
1387+
self.assertTrue(issubclass(warnings_stack[-1].category, DeprecationWarning))
1388+
self.assertTrue("deprecated" in str(warnings_stack[-1].message))
1389+
warnings.resetwarnings()
1390+
1391+
def test_deprecation_cursor_named_tuple(self):
1392+
with warnings.catch_warnings(record=True) as warnings_stack:
1393+
# Cause all warnings to always be triggered.
1394+
warnings.simplefilter("always", DeprecationWarning)
1395+
# The warning should be raised as the cursor is instantiated
1396+
with self.cnx.cursor(named_tuple=True) as _:
1397+
pass
1398+
self.assertTrue(
1399+
len(warnings_stack) != 0,
1400+
msg="No warnings were caught as warnings_stack was empty",
1401+
)
1402+
self.assertTrue(issubclass(warnings_stack[-1].category, DeprecationWarning))
1403+
self.assertTrue("deprecated" in str(warnings_stack[-1].message))
1404+
warnings.resetwarnings()
1405+
1406+
def test_deprecation_cursor_buffered_named_tuple(self):
1407+
with warnings.catch_warnings(record=True) as warnings_stack:
1408+
# Cause all warnings to always be triggered.
1409+
warnings.simplefilter("always", DeprecationWarning)
1410+
# The warning should be raised as the cursor is instantiated
1411+
with self.cnx.cursor(buffered=True, named_tuple=True) as _:
1412+
pass
1413+
self.assertTrue(
1414+
len(warnings_stack) != 0,
1415+
msg="No warnings were caught as warnings_stack was empty",
1416+
)
1417+
self.assertTrue(issubclass(warnings_stack[-1].category, DeprecationWarning))
1418+
self.assertTrue("deprecated" in str(warnings_stack[-1].message))
1419+
warnings.resetwarnings()
1420+
1421+
def test_deprecation_cursor_prepared_named_tuple(self):
1422+
with warnings.catch_warnings(record=True) as warnings_stack:
1423+
# Cause all warnings to always be triggered.
1424+
warnings.simplefilter("always", DeprecationWarning)
1425+
# The warning should be raised as the cursor is instantiated
1426+
with self.cnx.cursor(prepared=True, named_tuple=True) as _:
1427+
pass
1428+
self.assertTrue(
1429+
len(warnings_stack) != 0,
1430+
msg="No warnings were caught as warnings_stack was empty",
1431+
)
1432+
self.assertTrue(issubclass(warnings_stack[-1].category, DeprecationWarning))
1433+
self.assertTrue("deprecated" in str(warnings_stack[-1].message))
1434+
warnings.resetwarnings()

mysql-connector-python/tests/test_aio_cursor.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
# along with this program; if not, write to the Free Software Foundation, Inc.,
2727
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2828

29+
import warnings
2930
import tests
3031

3132
from tests import cmp_result, cnx_aio_config, foreach_cnx_aio
@@ -1056,3 +1057,70 @@ async def test_fetchall(self):
10561057
@foreach_cnx_aio()
10571058
async def test_fetchmany(self):
10581059
await self._test_fetchmany(self.cnx, MySQLCursorPreparedNamedTuple)
1060+
1061+
1062+
class MySQLCursorDeprecatedTests(tests.MySQLConnectorAioTestCase):
1063+
1064+
@foreach_cnx_aio()
1065+
async def test_deprecation_cursor_prepared_raw(self):
1066+
with warnings.catch_warnings(record=True) as warnings_stack:
1067+
# Cause all warnings to always be triggered.
1068+
warnings.simplefilter("always", DeprecationWarning)
1069+
# The warning should be raised as the cursor is instantiated
1070+
async with await self.cnx.cursor(prepared=True, raw=True) as _:
1071+
pass
1072+
self.assertTrue(
1073+
len(warnings_stack) != 0,
1074+
msg="No warnings were caught as warnings_stack was empty",
1075+
)
1076+
self.assertTrue(issubclass(warnings_stack[-1].category, DeprecationWarning))
1077+
self.assertTrue("deprecated" in str(warnings_stack[-1].message))
1078+
warnings.resetwarnings()
1079+
1080+
@foreach_cnx_aio()
1081+
async def test_deprecation_cursor_named_tuple(self):
1082+
with warnings.catch_warnings(record=True) as warnings_stack:
1083+
# Cause all warnings to always be triggered.
1084+
warnings.simplefilter("always", DeprecationWarning)
1085+
# The warning should be raised as the cursor is instantiated
1086+
async with await self.cnx.cursor(named_tuple=True) as _:
1087+
pass
1088+
self.assertTrue(
1089+
len(warnings_stack) != 0,
1090+
msg="No warnings were caught as warnings_stack was empty",
1091+
)
1092+
self.assertTrue(issubclass(warnings_stack[-1].category, DeprecationWarning))
1093+
self.assertTrue("deprecated" in str(warnings_stack[-1].message))
1094+
warnings.resetwarnings()
1095+
1096+
@foreach_cnx_aio()
1097+
async def test_deprecation_cursor_buffered_named_tuple(self):
1098+
with warnings.catch_warnings(record=True) as warnings_stack:
1099+
# Cause all warnings to always be triggered.
1100+
warnings.simplefilter("always", DeprecationWarning)
1101+
# The warning should be raised as the cursor is instantiated
1102+
async with await self.cnx.cursor(buffered=True, named_tuple=True) as _:
1103+
pass
1104+
self.assertTrue(
1105+
len(warnings_stack) != 0,
1106+
msg="No warnings were caught as warnings_stack was empty",
1107+
)
1108+
self.assertTrue(issubclass(warnings_stack[-1].category, DeprecationWarning))
1109+
self.assertTrue("deprecated" in str(warnings_stack[-1].message))
1110+
warnings.resetwarnings()
1111+
1112+
@foreach_cnx_aio()
1113+
async def test_deprecation_cursor_prepared_named_tuple(self):
1114+
with warnings.catch_warnings(record=True) as warnings_stack:
1115+
# Cause all warnings to always be triggered.
1116+
warnings.simplefilter("always", DeprecationWarning)
1117+
# The warning should be raised as the cursor is instantiated
1118+
async with await self.cnx.cursor(prepared=True, named_tuple=True) as _:
1119+
pass
1120+
self.assertTrue(
1121+
len(warnings_stack) != 0,
1122+
msg="No warnings were caught as warnings_stack was empty",
1123+
)
1124+
self.assertTrue(issubclass(warnings_stack[-1].category, DeprecationWarning))
1125+
self.assertTrue("deprecated" in str(warnings_stack[-1].message))
1126+
warnings.resetwarnings()

mysql-connector-python/tests/test_cursor.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747

4848
from collections import namedtuple
4949
from decimal import Decimal
50+
import warnings
5051

5152
import tests
5253

@@ -1680,3 +1681,73 @@ def test_fetchall(self):
16801681
self.cur.execute(f"SELECT * FROM {self.table_name}")
16811682
exp = self.data[:]
16821683
self.assertEqual(exp, self.cur.fetchall())
1684+
1685+
1686+
class MySQLCursorDeprecatedTests(tests.TestsCursor):
1687+
1688+
def setUp(self):
1689+
config = tests.get_mysql_config()
1690+
self.cnx = connection.MySQLConnection(**config)
1691+
1692+
def tearDown(self):
1693+
self.cnx.close()
1694+
1695+
def test_deprecation_cursor_prepared_raw(self):
1696+
with warnings.catch_warnings(record=True) as warnings_stack:
1697+
# Cause all warnings to always be triggered.
1698+
warnings.simplefilter("always", DeprecationWarning)
1699+
# The warning should be raised as the cursor is instantiated
1700+
with self.cnx.cursor(prepared=True, raw=True) as _:
1701+
pass
1702+
self.assertTrue(
1703+
len(warnings_stack) != 0,
1704+
msg="No warnings were caught as warnings_stack was empty",
1705+
)
1706+
self.assertTrue(issubclass(warnings_stack[-1].category, DeprecationWarning))
1707+
self.assertTrue("deprecated" in str(warnings_stack[-1].message))
1708+
warnings.resetwarnings()
1709+
1710+
def test_deprecation_cursor_named_tuple(self):
1711+
with warnings.catch_warnings(record=True) as warnings_stack:
1712+
# Cause all warnings to always be triggered.
1713+
warnings.simplefilter("always", DeprecationWarning)
1714+
# The warning should be raised as the cursor is instantiated
1715+
with self.cnx.cursor(named_tuple=True) as _:
1716+
pass
1717+
self.assertTrue(
1718+
len(warnings_stack) != 0,
1719+
msg="No warnings were caught as warnings_stack was empty",
1720+
)
1721+
self.assertTrue(issubclass(warnings_stack[-1].category, DeprecationWarning))
1722+
self.assertTrue("deprecated" in str(warnings_stack[-1].message))
1723+
warnings.resetwarnings()
1724+
1725+
def test_deprecation_cursor_buffered_named_tuple(self):
1726+
with warnings.catch_warnings(record=True) as warnings_stack:
1727+
# Cause all warnings to always be triggered.
1728+
warnings.simplefilter("always", DeprecationWarning)
1729+
# The warning should be raised as the cursor is instantiated
1730+
with self.cnx.cursor(buffered=True, named_tuple=True) as _:
1731+
pass
1732+
self.assertTrue(
1733+
len(warnings_stack) != 0,
1734+
msg="No warnings were caught as warnings_stack was empty",
1735+
)
1736+
self.assertTrue(issubclass(warnings_stack[-1].category, DeprecationWarning))
1737+
self.assertTrue("deprecated" in str(warnings_stack[-1].message))
1738+
warnings.resetwarnings()
1739+
1740+
def test_deprecation_cursor_prepared_named_tuple(self):
1741+
with warnings.catch_warnings(record=True) as warnings_stack:
1742+
# Cause all warnings to always be triggered.
1743+
warnings.simplefilter("always", DeprecationWarning)
1744+
# The warning should be raised as the cursor is instantiated
1745+
with self.cnx.cursor(prepared=True, named_tuple=True) as _:
1746+
pass
1747+
self.assertTrue(
1748+
len(warnings_stack) != 0,
1749+
msg="No warnings were caught as warnings_stack was empty",
1750+
)
1751+
self.assertTrue(issubclass(warnings_stack[-1].category, DeprecationWarning))
1752+
self.assertTrue("deprecated" in str(warnings_stack[-1].message))
1753+
warnings.resetwarnings()

0 commit comments

Comments
 (0)