添加注册登录功能

This commit is contained in:
2025-08-29 00:34:40 +08:00
parent 09065f2ce7
commit 2fe3474d9e
3060 changed files with 29217 additions and 87137 deletions

View File

@@ -274,8 +274,8 @@ def int_within_variance(expected, received, variance):
)
def eq_regex(a, b, msg=None):
assert re.match(b, a), msg or "%r !~ %r" % (a, b)
def eq_regex(a, b, msg=None, flags=0):
assert re.match(b, a, flags), msg or "%r !~ %r" % (a, b)
def eq_(a, b, msg=None):
@@ -513,6 +513,7 @@ class AssertsCompiledSQL:
use_default_dialect=False,
allow_dialect_select=False,
supports_default_values=True,
supports_native_boolean=False,
supports_default_metavalue=True,
literal_binds=False,
render_postcompile=False,
@@ -527,6 +528,7 @@ class AssertsCompiledSQL:
dialect = default.DefaultDialect()
dialect.supports_default_values = supports_default_values
dialect.supports_default_metavalue = supports_default_metavalue
dialect.supports_native_boolean = supports_native_boolean
elif allow_dialect_select:
dialect = None
else:

View File

@@ -392,8 +392,8 @@ def open(): # noqa
return skip_if(BooleanPredicate(False, "mark as execute"))
def closed():
return skip_if(BooleanPredicate(True, "marked as skip"))
def closed(reason="marked as skip"):
return skip_if(BooleanPredicate(True, reason))
def fails(reason=None):

View File

@@ -14,6 +14,7 @@ from .. import assertions
from .. import config
from ..assertions import eq_
from ..util import drop_all_tables_from_metadata
from ..util import picklers
from ... import Column
from ... import func
from ... import Integer
@@ -194,6 +195,10 @@ class TestBase:
return go
@config.fixture(params=picklers())
def picklers(self, request):
yield request.param
@config.fixture()
def metadata(self, request):
"""Provide bound MetaData for a single test, dropping afterwards."""

View File

@@ -143,7 +143,9 @@ class MypyTest(TestBase):
from sqlalchemy.ext.mypy.util import mypy_14
expected_messages = []
expected_re = re.compile(r"\s*# EXPECTED(_MYPY)?(_RE)?(_TYPE)?: (.+)")
expected_re = re.compile(
r"\s*# EXPECTED(_MYPY)?(_RE)?(_ROW)?(_TYPE)?: (.+)"
)
py_ver_re = re.compile(r"^#\s*PYTHON_VERSION\s?>=\s?(\d+\.\d+)")
with open(path) as file_:
current_assert_messages = []
@@ -161,9 +163,24 @@ class MypyTest(TestBase):
if m:
is_mypy = bool(m.group(1))
is_re = bool(m.group(2))
is_type = bool(m.group(3))
is_row = bool(m.group(3))
is_type = bool(m.group(4))
expected_msg = re.sub(r"# noqa[:]? ?.*", "", m.group(5))
if is_row:
expected_msg = re.sub(
r"Row\[([^\]]+)\]",
lambda m: f"tuple[{m.group(1)}, fallback=s"
f"qlalchemy.engine.row.{m.group(0)}]",
expected_msg,
)
# For some reason it does not use or syntax (|)
expected_msg = re.sub(
r"Optional\[(.*)\]",
lambda m: f"Union[{m.group(1)}, None]",
expected_msg,
)
expected_msg = re.sub(r"# noqa[:]? ?.*", "", m.group(4))
if is_type:
if not is_re:
# the goal here is that we can cut-and-paste
@@ -243,7 +260,9 @@ class MypyTest(TestBase):
return expected_messages
def _check_output(self, path, expected_messages, stdout, stderr, exitcode):
def _check_output(
self, path, expected_messages, stdout: str, stderr, exitcode
):
not_located = []
filename = os.path.basename(path)
if expected_messages:
@@ -263,7 +282,8 @@ class MypyTest(TestBase):
):
while raw_lines:
ol = raw_lines.pop(0)
if not re.match(r".+\.py:\d+: note: +def \[.*", ol):
if not re.match(r".+\.py:\d+: note: +def .*", ol):
raw_lines.insert(0, ol)
break
elif re.match(
r".+\.py:\d+: note: .*(?:perhaps|suggestion)", e, re.I

View File

@@ -270,7 +270,6 @@ def pytest_collection_modifyitems(session, config, items):
for test_class in test_classes:
# transfer legacy __backend__ and __sparse_backend__ symbols
# to be markers
add_markers = set()
if getattr(test_class.cls, "__backend__", False) or getattr(
test_class.cls, "__only_on__", False
):

View File

@@ -19,6 +19,7 @@ to provide specific inclusion/exclusions.
from __future__ import annotations
import os
import platform
from . import asyncio as _test_asyncio
@@ -314,6 +315,13 @@ class SuiteRequirements(Requirements):
return exclusions.closed()
@property
def ctes_with_values(self):
"""target database supports CTES that ride on top of a VALUES
clause."""
return exclusions.closed()
@property
def ctes_on_dml(self):
"""target database supports CTES which consist of INSERT, UPDATE
@@ -657,6 +665,12 @@ class SuiteRequirements(Requirements):
return exclusions.closed()
@property
def temp_table_comment_reflection(self):
"""indicates if database supports comments on temp tables and
the dialect can reflect them"""
return exclusions.closed()
@property
def comment_reflection(self):
"""Indicates if the database support table comment reflection"""
@@ -822,6 +836,11 @@ class SuiteRequirements(Requirements):
return exclusions.open()
@property
def nvarchar_types(self):
"""target database supports NVARCHAR and NCHAR as an actual datatype"""
return exclusions.closed()
@property
def unicode_data_no_special_types(self):
"""Target database/dialect can receive / deliver / compare data with
@@ -1014,6 +1033,13 @@ class SuiteRequirements(Requirements):
"""target dialect supports 'AUTOCOMMIT' as an isolation_level"""
return exclusions.closed()
@property
def skip_autocommit_rollback(self):
"""target dialect supports the detect_autocommit_setting() method and
uses the default implementation of do_rollback()"""
return exclusions.closed()
@property
def isolation_level(self):
"""target dialect supports general isolation level settings.
@@ -1168,6 +1194,19 @@ class SuiteRequirements(Requirements):
"""
return self.precision_numerics_many_significant_digits
@property
def server_defaults(self):
"""Target backend supports server side defaults for columns"""
return exclusions.closed()
@property
def expression_server_defaults(self):
"""Target backend supports server side defaults with SQL expressions
for columns"""
return exclusions.closed()
@property
def implicit_decimal_binds(self):
"""target backend will return a selected Decimal as a Decimal, not
@@ -1485,6 +1524,10 @@ class SuiteRequirements(Requirements):
return config.add_to_marker.timing_intensive
@property
def posix(self):
return exclusions.skip_if(lambda: os.name != "posix")
@property
def memory_intensive(self):
from . import config
@@ -1526,6 +1569,27 @@ class SuiteRequirements(Requirements):
return exclusions.skip_if(check)
@property
def up_to_date_typealias_type(self):
# this checks a particular quirk found in typing_extensions <=4.12.0
# using older python versions like 3.10 or 3.9, we use TypeAliasType
# from typing_extensions which does not provide for sufficient
# introspection prior to 4.13.0
def check(config):
import typing
import typing_extensions
TypeAliasType = getattr(
typing, "TypeAliasType", typing_extensions.TypeAliasType
)
TV = typing.TypeVar("TV")
TA_generic = TypeAliasType( # type: ignore
"TA_generic", typing.List[TV], type_params=(TV,)
)
return hasattr(TA_generic[int], "__value__")
return exclusions.only_if(check)
@property
def python38(self):
return exclusions.only_if(
@@ -1556,6 +1620,26 @@ class SuiteRequirements(Requirements):
lambda: util.py312, "Python 3.12 or above required"
)
@property
def fail_python314b1(self):
return exclusions.fails_if(
lambda: util.compat.py314b1, "Fails as of python 3.14.0b1"
)
@property
def not_python314(self):
"""This requirement is interim to assist with backporting of
issue #12405.
SQLAlchemy 2.0 still includes the ``await_fallback()`` method that
makes use of ``asyncio.get_event_loop_policy()``. This is removed
in SQLAlchemy 2.1.
"""
return exclusions.skip_if(
lambda: util.py314, "Python 3.14 or above not supported"
)
@property
def cpython(self):
return exclusions.only_if(
@@ -1826,3 +1910,9 @@ class SuiteRequirements(Requirements):
def supports_bitwise_shift(self):
"""Target database supports bitwise left or right shift"""
return exclusions.closed()
@property
def like_escapes(self):
"""Target backend supports custom ESCAPE characters
with LIKE comparisons"""
return exclusions.open()

View File

@@ -10,11 +10,13 @@ from .. import fixtures
from ..assertions import eq_
from ..schema import Column
from ..schema import Table
from ... import column
from ... import ForeignKey
from ... import Integer
from ... import select
from ... import String
from ... import testing
from ... import values
class CTETest(fixtures.TablesTest):
@@ -209,3 +211,27 @@ class CTETest(fixtures.TablesTest):
).fetchall(),
[(1, "d1", None), (5, "d5", 3)],
)
@testing.variation("values_named", [True, False])
@testing.variation("cte_named", [True, False])
@testing.variation("literal_binds", [True, False])
@testing.requires.ctes_with_values
def test_values_named_via_cte(
self, connection, values_named, cte_named, literal_binds
):
cte1 = (
values(
column("col1", String),
column("col2", Integer),
literal_binds=bool(literal_binds),
name="some name" if values_named else None,
)
.data([("a", 2), ("b", 3)])
.cte("cte1" if cte_named else None)
)
stmt = select(cte1)
rows = connection.execute(stmt).all()
eq_(rows, [("a", 2), ("b", 3)])

View File

@@ -17,6 +17,7 @@ from .. import eq_
from .. import fixtures
from .. import is_not_none
from .. import is_true
from .. import mock
from .. import ne_
from .. import provide_metadata
from ..assertions import expect_raises
@@ -293,7 +294,11 @@ class AutocommitIsolationTest(fixtures.TablesTest):
test_needs_acid=True,
)
def _test_conn_autocommits(self, conn, autocommit):
def _test_conn_autocommits(self, conn, autocommit, ensure_table=False):
if ensure_table:
self.tables.some_table.create(conn, checkfirst=True)
conn.commit()
trans = conn.begin()
conn.execute(
self.tables.some_table.insert(), {"id": 1, "data": "some data"}
@@ -336,6 +341,37 @@ class AutocommitIsolationTest(fixtures.TablesTest):
)
self._test_conn_autocommits(conn, False)
@testing.requires.skip_autocommit_rollback
@testing.variation("autocommit_setting", ["false", "engine", "option"])
@testing.variation("block_rollback", [True, False])
def test_autocommit_block(
self, testing_engine, autocommit_setting, block_rollback
):
kw = {}
if bool(block_rollback):
kw["skip_autocommit_rollback"] = True
if autocommit_setting.engine:
kw["isolation_level"] = "AUTOCOMMIT"
engine = testing_engine(options=kw)
conn = engine.connect()
if autocommit_setting.option:
conn.execution_options(isolation_level="AUTOCOMMIT")
self._test_conn_autocommits(
conn,
autocommit_setting.engine or autocommit_setting.option,
ensure_table=True,
)
with mock.patch.object(
conn.connection, "rollback", wraps=conn.connection.rollback
) as check_rollback:
conn.close()
if autocommit_setting.false or not block_rollback:
eq_(check_rollback.mock_calls, [mock.call()])
else:
eq_(check_rollback.mock_calls, [])
@testing.requires.independent_readonly_connections
@testing.variation("use_dialect_setting", [True, False])
def test_dialect_autocommit_is_restored(
@@ -537,7 +573,7 @@ class DifficultParametersTest(fixtures.TestBase):
t.c[name].in_(["some name", "some other_name"])
)
row = connection.execute(stmt).first()
connection.execute(stmt).first()
@testing.fixture
def multirow_fixture(self, metadata, connection):
@@ -621,7 +657,7 @@ class ReturningGuardsTest(fixtures.TablesTest):
f"current server capabilities does not support "
f".*RETURNING when executemany is used",
):
result = connection.execute(
connection.execute(
stmt,
[
{id_param_name: 1, "data": "d1"},

View File

@@ -14,6 +14,7 @@ import sqlalchemy as sa
from .. import config
from .. import engines
from .. import eq_
from .. import eq_regex
from .. import expect_raises
from .. import expect_raises_message
from .. import expect_warnings
@@ -23,6 +24,8 @@ from ..provision import get_temp_table_name
from ..provision import temp_table_keyword_args
from ..schema import Column
from ..schema import Table
from ... import Boolean
from ... import DateTime
from ... import event
from ... import ForeignKey
from ... import func
@@ -220,6 +223,7 @@ class HasTableTest(OneConnectionTablesTest):
class HasIndexTest(fixtures.TablesTest):
__backend__ = True
__requires__ = ("index_reflection",)
@classmethod
def define_tables(cls, metadata):
@@ -294,25 +298,36 @@ class HasIndexTest(fixtures.TablesTest):
)
class BizarroCharacterFKResolutionTest(fixtures.TestBase):
"""tests for #10275"""
class BizarroCharacterTest(fixtures.TestBase):
__backend__ = True
@testing.combinations(
("id",), ("(3)",), ("col%p",), ("[brack]",), argnames="columnname"
)
def column_names():
return testing.combinations(
("plainname",),
("(3)",),
("col%p",),
("[brack]",),
argnames="columnname",
)
def table_names():
return testing.combinations(
("plain",),
("(2)",),
("per % cent",),
("[brackets]",),
argnames="tablename",
)
@testing.variation("use_composite", [True, False])
@testing.combinations(
("plain",),
("(2)",),
("per % cent",),
("[brackets]",),
argnames="tablename",
)
@column_names()
@table_names()
@testing.requires.foreign_key_constraint_reflection
def test_fk_ref(
self, connection, metadata, use_composite, tablename, columnname
):
"""tests for #10275"""
tt = Table(
tablename,
metadata,
@@ -352,6 +367,77 @@ class BizarroCharacterFKResolutionTest(fixtures.TestBase):
if use_composite:
assert o2.c.ref2.references(t1.c[1])
@column_names()
@table_names()
@testing.requires.identity_columns
def test_reflect_identity(
self, tablename, columnname, connection, metadata
):
Table(
tablename,
metadata,
Column(columnname, Integer, Identity(), primary_key=True),
)
metadata.create_all(connection)
insp = inspect(connection)
eq_(insp.get_columns(tablename)[0]["identity"]["start"], 1)
@column_names()
@table_names()
@testing.requires.comment_reflection
def test_reflect_comments(
self, tablename, columnname, connection, metadata
):
Table(
tablename,
metadata,
Column("id", Integer, primary_key=True),
Column(columnname, Integer, comment="some comment"),
)
metadata.create_all(connection)
insp = inspect(connection)
eq_(insp.get_columns(tablename)[1]["comment"], "some comment")
class TempTableElementsTest(fixtures.TestBase):
__backend__ = True
__requires__ = ("temp_table_reflection",)
@testing.fixture
def tablename(self):
return get_temp_table_name(
config, config.db, f"ident_tmp_{config.ident}"
)
@testing.requires.identity_columns
def test_reflect_identity(self, tablename, connection, metadata):
Table(
tablename,
metadata,
Column("id", Integer, Identity(), primary_key=True),
)
metadata.create_all(connection)
insp = inspect(connection)
eq_(insp.get_columns(tablename)[0]["identity"]["start"], 1)
@testing.requires.temp_table_comment_reflection
def test_reflect_comments(self, tablename, connection, metadata):
Table(
tablename,
metadata,
Column("id", Integer, primary_key=True),
Column("foobar", Integer, comment="some comment"),
)
metadata.create_all(connection)
insp = inspect(connection)
eq_(insp.get_columns(tablename)[1]["comment"], "some comment")
class QuotedNameArgumentTest(fixtures.TablesTest):
run_create_tables = "once"
@@ -455,7 +541,7 @@ class QuotedNameArgumentTest(fixtures.TablesTest):
is_true(isinstance(res, dict))
else:
with expect_raises(NotImplementedError):
res = insp.get_table_options(name)
insp.get_table_options(name)
@quote_fixtures
@testing.requires.view_column_reflection
@@ -474,11 +560,13 @@ class QuotedNameArgumentTest(fixtures.TablesTest):
assert insp.get_pk_constraint(name)
@quote_fixtures
@testing.requires.foreign_key_constraint_reflection
def test_get_foreign_keys(self, name):
insp = inspect(config.db)
assert insp.get_foreign_keys(name)
@quote_fixtures
@testing.requires.index_reflection
def test_get_indexes(self, name):
insp = inspect(config.db)
assert insp.get_indexes(name)
@@ -1947,6 +2035,8 @@ class ComponentReflectionTest(ComparesTables, OneConnectionTablesTest):
if dupe:
names_that_duplicate_index.add(dupe)
eq_(refl.pop("comment", None), None)
# ignore dialect_options
refl.pop("dialect_options", None)
eq_(orig, refl)
reflected_metadata = MetaData()
@@ -2038,7 +2128,7 @@ class ComponentReflectionTest(ComparesTables, OneConnectionTablesTest):
is_true(isinstance(res, dict))
else:
with expect_raises(NotImplementedError):
res = insp.get_table_options("users", schema=schema)
insp.get_table_options("users", schema=schema)
@testing.combinations((True, testing.requires.schemas), False)
def test_multi_get_table_options(self, use_schema):
@@ -2054,7 +2144,7 @@ class ComponentReflectionTest(ComparesTables, OneConnectionTablesTest):
eq_(res, exp)
else:
with expect_raises(NotImplementedError):
res = insp.get_multi_table_options()
insp.get_multi_table_options()
@testing.fixture
def get_multi_exp(self, connection):
@@ -2762,12 +2852,25 @@ class ComponentReflectionTestExtra(ComparesIndexes, fixtures.TestBase):
eq_(typ.scale, 5)
@testing.requires.table_reflection
def test_varchar_reflection(self, connection, metadata):
typ = self._type_round_trip(
connection, metadata, sql_types.String(52)
)[0]
assert isinstance(typ, sql_types.String)
@testing.combinations(
sql_types.String,
sql_types.VARCHAR,
sql_types.CHAR,
(sql_types.NVARCHAR, testing.requires.nvarchar_types),
(sql_types.NCHAR, testing.requires.nvarchar_types),
argnames="type_",
)
def test_string_length_reflection(self, connection, metadata, type_):
typ = self._type_round_trip(connection, metadata, type_(52))[0]
if issubclass(type_, sql_types.VARCHAR):
assert isinstance(typ, sql_types.VARCHAR)
elif issubclass(type_, sql_types.CHAR):
assert isinstance(typ, sql_types.CHAR)
else:
assert isinstance(typ, sql_types.String)
eq_(typ.length, 52)
assert isinstance(typ.length, int)
@testing.requires.table_reflection
def test_nullable_reflection(self, connection, metadata):
@@ -2879,6 +2982,47 @@ class ComponentReflectionTestExtra(ComparesIndexes, fixtures.TestBase):
eq_(opts, expected)
# eq_(dict((k, opts[k]) for k in opts if opts[k]), expected)
@testing.combinations(
(Integer, sa.text("10"), r"'?10'?"),
(Integer, "10", r"'?10'?"),
(Boolean, sa.true(), r"1|true"),
(
Integer,
sa.text("3 + 5"),
r"3\+5",
testing.requires.expression_server_defaults,
),
(
Integer,
sa.text("(3 * 5)"),
r"3\*5",
testing.requires.expression_server_defaults,
),
(DateTime, func.now(), r"current_timestamp|now|getdate"),
(
Integer,
sa.literal_column("3") + sa.literal_column("5"),
r"3\+5",
testing.requires.expression_server_defaults,
),
argnames="datatype, default, expected_reg",
)
@testing.requires.server_defaults
def test_server_defaults(
self, metadata, connection, datatype, default, expected_reg
):
t = Table(
"t",
metadata,
Column("id", Integer, primary_key=True),
Column("thecol", datatype, server_default=default),
)
t.create(connection)
reflected = inspect(connection).get_columns("t")[1]["default"]
reflected_sanitized = re.sub(r"[\(\) \']", "", reflected)
eq_regex(reflected_sanitized, expected_reg, flags=re.IGNORECASE)
class NormalizedNameTest(fixtures.TablesTest):
__requires__ = ("denormalized_names",)
@@ -3215,11 +3359,12 @@ __all__ = (
"ComponentReflectionTestExtra",
"TableNoColumnsTest",
"QuotedNameArgumentTest",
"BizarroCharacterFKResolutionTest",
"BizarroCharacterTest",
"HasTableTest",
"HasIndexTest",
"NormalizedNameTest",
"ComputedReflectionTest",
"IdentityReflectionTest",
"CompositeKeyReflectionTest",
"TempTableElementsTest",
)

View File

@@ -268,6 +268,8 @@ class ServerSideCursorsTest(
return isinstance(cursor, sscursor)
elif self.engine.dialect.driver == "mariadbconnector":
return not cursor.buffered
elif self.engine.dialect.driver == "mysqlconnector":
return "buffered" not in type(cursor).__name__.lower()
elif self.engine.dialect.driver in ("asyncpg", "aiosqlite"):
return cursor.server_side
elif self.engine.dialect.driver == "pg8000":

View File

@@ -1541,6 +1541,7 @@ class LikeFunctionsTest(fixtures.TablesTest):
col = self.tables.some_table.c.data
self._test(col.startswith("ab%c"), {1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
@testing.requires.like_escapes
def test_startswith_autoescape(self):
col = self.tables.some_table.c.data
self._test(col.startswith("ab%c", autoescape=True), {3})
@@ -1552,10 +1553,12 @@ class LikeFunctionsTest(fixtures.TablesTest):
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
)
@testing.requires.like_escapes
def test_startswith_escape(self):
col = self.tables.some_table.c.data
self._test(col.startswith("ab##c", escape="#"), {7})
@testing.requires.like_escapes
def test_startswith_autoescape_escape(self):
col = self.tables.some_table.c.data
self._test(col.startswith("ab%c", autoescape=True, escape="#"), {3})
@@ -1571,14 +1574,17 @@ class LikeFunctionsTest(fixtures.TablesTest):
col.endswith(literal_column("'e%fg'")), {1, 2, 3, 4, 5, 6, 7, 8, 9}
)
@testing.requires.like_escapes
def test_endswith_autoescape(self):
col = self.tables.some_table.c.data
self._test(col.endswith("e%fg", autoescape=True), {6})
@testing.requires.like_escapes
def test_endswith_escape(self):
col = self.tables.some_table.c.data
self._test(col.endswith("e##fg", escape="#"), {9})
@testing.requires.like_escapes
def test_endswith_autoescape_escape(self):
col = self.tables.some_table.c.data
self._test(col.endswith("e%fg", autoescape=True, escape="#"), {6})
@@ -1588,14 +1594,17 @@ class LikeFunctionsTest(fixtures.TablesTest):
col = self.tables.some_table.c.data
self._test(col.contains("b%cde"), {1, 2, 3, 4, 5, 6, 7, 8, 9})
@testing.requires.like_escapes
def test_contains_autoescape(self):
col = self.tables.some_table.c.data
self._test(col.contains("b%cde", autoescape=True), {3})
@testing.requires.like_escapes
def test_contains_escape(self):
col = self.tables.some_table.c.data
self._test(col.contains("b##cde", escape="#"), {7})
@testing.requires.like_escapes
def test_contains_autoescape_escape(self):
col = self.tables.some_table.c.data
self._test(col.contains("b%cd", autoescape=True, escape="#"), {3})
@@ -1771,7 +1780,7 @@ class IdentityAutoincrementTest(fixtures.TablesTest):
)
def test_autoincrement_with_identity(self, connection):
res = connection.execute(self.tables.tbl.insert(), {"desc": "row"})
connection.execute(self.tables.tbl.insert(), {"desc": "row"})
res = connection.execute(self.tables.tbl.select()).first()
eq_(res, (1, "row"))

View File

@@ -299,6 +299,7 @@ class ArrayTest(_LiteralRoundTripFixture, fixtures.TablesTest):
class BinaryTest(_LiteralRoundTripFixture, fixtures.TablesTest):
__backend__ = True
__requires__ = ("binary_literals",)
@classmethod
def define_tables(cls, metadata):
@@ -1483,6 +1484,7 @@ class JSONTest(_LiteralRoundTripFixture, fixtures.TablesTest):
return datatype, compare_value, p_s
@testing.requires.legacy_unconditional_json_extract
@_index_fixtures(False)
def test_index_typed_access(self, datatype, value):
data_table = self.tables.data_table
@@ -1504,6 +1506,7 @@ class JSONTest(_LiteralRoundTripFixture, fixtures.TablesTest):
eq_(roundtrip, compare_value)
is_(type(roundtrip), type(compare_value))
@testing.requires.legacy_unconditional_json_extract
@_index_fixtures(True)
def test_index_typed_comparison(self, datatype, value):
data_table = self.tables.data_table
@@ -1528,6 +1531,7 @@ class JSONTest(_LiteralRoundTripFixture, fixtures.TablesTest):
# make sure we get a row even if value is None
eq_(row, (compare_value,))
@testing.requires.legacy_unconditional_json_extract
@_index_fixtures(True)
def test_path_typed_comparison(self, datatype, value):
data_table = self.tables.data_table

View File

@@ -10,10 +10,12 @@
from __future__ import annotations
from collections import deque
from collections import namedtuple
import contextlib
import decimal
import gc
from itertools import chain
import pickle
import random
import sys
from sys import getsizeof
@@ -55,15 +57,10 @@ else:
def picklers():
picklers = set()
import pickle
nt = namedtuple("picklers", ["loads", "dumps"])
picklers.add(pickle)
# yes, this thing needs this much testing
for pickle_ in picklers:
for protocol in range(-2, pickle.HIGHEST_PROTOCOL + 1):
yield pickle_.loads, lambda d: pickle_.dumps(d, protocol)
for protocol in range(-2, pickle.HIGHEST_PROTOCOL + 1):
yield nt(pickle.loads, lambda d: pickle.dumps(d, protocol))
def random_choices(population, k=1):