From cc831394e611f120d4536d657eeea992ce80d8fd Mon Sep 17 00:00:00 2001 From: Jeff Horemans Date: Thu, 8 Aug 2024 17:14:43 +0200 Subject: [PATCH] Fixed tox lint errors. --- lib/sqlalchemy/dialects/sqlite/base.py | 25 ++++++++++++++++--------- test/dialect/test_sqlite.py | 23 ++++++++++++++++++----- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/lib/sqlalchemy/dialects/sqlite/base.py b/lib/sqlalchemy/dialects/sqlite/base.py index 1efa65032f..b088ff9352 100644 --- a/lib/sqlalchemy/dialects/sqlite/base.py +++ b/lib/sqlalchemy/dialects/sqlite/base.py @@ -2625,17 +2625,24 @@ class SQLiteDialect(default.DefaultDialect): ) # Notes: - # * The pattern currently matches any character for the name of the constraint, - # including newline and tab characters, as long as none of the SQLite's table constraints - # keywords are encountered seperated by spaces. - # This prevents the pattern from matching subsequent constraints as part of the name. - # * Because check constraints can contain special characters and newline and tab characters, - # the pattern matches any character untill either the beginning of the next constraint - # statement using a non-capturing non-consuming group (allowing the next one to match), - # or the end of the table definition e.g. newline and closing ')'. + # * The pattern currently matches any character for the name of the + # constraint, including newline characters (re.S flag) as long as + # none of the SQLite's table constraints keywords are encountered + # by a negative lookahead. + # This prevents the pattern from matching subsequent constraints + # as part of the name. + # This is only done for those keywords if seperated by spaces, to + # support constraint names that contains them e.g. "check_value". + # + # * Because check constraint definitions can also contain newline + # or tab characters, the pattern matches any character untill either + # the beginning of the next constraint statement using a + # non-capturing and non-consuming group, allowing the next one + # to match, or the end of the table definition + # e.g. newline and closing ')'. CHECK_PATTERN = r"(?:CONSTRAINT ((?:(?! PRIMARY | FOREIGN KEY| UNIQUE | CHECK ).)+) )?CHECK \((.+?)\)(?:, *\n\t?(?=CONSTRAINT|CHECK)|\n\))" cks = [] - for match in re.finditer(CHECK_PATTERN, table_data or "", re.I|re.S): + for match in re.finditer(CHECK_PATTERN, table_data or "", re.I | re.S): name = match.group(1) if name: diff --git a/test/dialect/test_sqlite.py b/test/dialect/test_sqlite.py index 255d8857bd..ccfbb31a06 100644 --- a/test/dialect/test_sqlite.py +++ b/test/dialect/test_sqlite.py @@ -1817,15 +1817,22 @@ class ConstraintReflectionTest(fixtures.TestBase): Table("q", meta, Column("id", Integer), PrimaryKeyConstraint("id")) # intentional new line - Table("r", meta, Column("id", Integer), Column("value", Integer), Column("prefix", String), PrimaryKeyConstraint("id"), + Table("r", meta, + Column("id", Integer), + Column("value", Integer), + Column("prefix", String), + PrimaryKeyConstraint("id"), CheckConstraint("id > 0"), # Constraint definition with newline and tab characters - CheckConstraint("((value > 0) AND \n\t(value < 100) AND \n\t(value != 50))", name='ck_r_value_multiline'), - # Constraint name with special characters and 'check' in the name + CheckConstraint( + """((value > 0) AND \n\t(value < 100) AND \n\t + (value != 50))""", + name='ck_r_value_multiline'), + # Constraint name with special chars and 'check' in the name CheckConstraint("value IS NOT NULL", name="^check-r* #\n\t"), # Constraint definition with special characters. CheckConstraint("prefix NOT GLOB '*[^-. /#,]*'") - ) + ) meta.create_all(conn) @@ -2468,11 +2475,16 @@ class ConstraintReflectionTest(fixtures.TestBase): {"sqltext": "q > 1 AND q < 6", "name": None}, ], ) + print(inspector.get_check_constraints("r")) eq_( inspector.get_check_constraints("r"), [ {"sqltext": "value IS NOT NULL", "name": "^check-r* #\n\t"}, - {"sqltext": "((value > 0) AND \n\t(value < 100) AND \n\t(value != 50))", "name": "ck_r_value_multiline"}, + # Triple-quote multi-line definition should have added a + # newline and whitespace: + {"sqltext": "((value > 0) AND \n\t(value < 100) AND \n\t\n" + " (value != 50))", + "name": "ck_r_value_multiline"}, {"sqltext": "id > 0", "name": None}, {"sqltext": "prefix NOT GLOB '*[^-. /#,]*'", "name": None}, ], @@ -2527,6 +2539,7 @@ class ConstraintReflectionTest(fixtures.TestBase): else: assert False + class SavepointTest(fixtures.TablesTest): """test that savepoints work when we use the correct event setup""" -- 2.47.3