Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-sqlite-utils for 
openSUSE:Factory checked in at 2024-01-12 23:45:48
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-sqlite-utils (Old)
 and      /work/SRC/openSUSE:Factory/.python-sqlite-utils.new.21961 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-sqlite-utils"

Fri Jan 12 23:45:48 2024 rev:6 rq:1138236 version:3.36

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-sqlite-utils/python-sqlite-utils.changes  
2023-12-08 22:34:31.401452681 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-sqlite-utils.new.21961/python-sqlite-utils.changes
       2024-01-12 23:46:09.992222430 +0100
@@ -1,0 +2,23 @@
+Fri Jan 12 08:20:52 UTC 2024 - Dirk Müller <dmuel...@suse.com>
+
+- update to 3.36:
+  *  Support for creating tables in SQLite STRICT mode. Thanks,
+    Taj Khattra. (:issue:`344`)  CLI commands create-table,
+    insert and upsert all now accept a --strict option. Python
+    methods that can create a table - table.create() and
+    insert/upsert/insert_all/upsert_all all now accept an
+    optional strict=True parameter. The transform command and
+    table.transform() method preserve strict mode when
+    transforming a table.
+  * CLI commands create-table, insert and upsert all now accept a
+    --strict option.
+  * Python methods that can create a table - table.create() and
+    insert/upsert/insert_all/upsert_all all now accept an
+    optional strict=True parameter.
+  * The transform command and table.transform() method preserve
+    strict mode when transforming a table.
+  * The sqlite-utils create-table command now accepts str, int
+    and bytes as aliases for text, integer and blob respectively.
+    (:issue:`606`)
+
+-------------------------------------------------------------------

Old:
----
  sqlite-utils-3.35.2.tar.gz

New:
----
  sqlite-utils-3.36.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-sqlite-utils.spec ++++++
--- /var/tmp/diff_new_pack.1u4Hvy/_old  2024-01-12 23:46:11.608281579 +0100
+++ /var/tmp/diff_new_pack.1u4Hvy/_new  2024-01-12 23:46:11.624282164 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-sqlite-utils
 #
-# Copyright (c) 2023 SUSE LLC
+# Copyright (c) 2024 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -16,11 +16,8 @@
 #
 
 
-%{?!python_module:%define python_module() python-%{**} python3-%{**}}
-%define skip_python2 1
-%define skip_python36 1
 Name:           python-sqlite-utils
-Version:        3.35.2
+Version:        3.36
 Release:        0
 Summary:        Python CLI tool and library for manipulating SQLite databases
 License:        Apache-2.0

++++++ sqlite-utils-3.35.2.tar.gz -> sqlite-utils-3.36.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sqlite-utils-3.35.2/PKG-INFO 
new/sqlite-utils-3.36/PKG-INFO
--- old/sqlite-utils-3.35.2/PKG-INFO    2023-11-04 02:17:11.781244500 +0100
+++ new/sqlite-utils-3.36/PKG-INFO      2023-12-08 06:36:17.164974500 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: sqlite-utils
-Version: 3.35.2
+Version: 3.36
 Summary: CLI tool and Python library for manipulating SQLite databases
 Home-page: https://github.com/simonw/sqlite-utils
 Author: Simon Willison
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sqlite-utils-3.35.2/docs/changelog.rst 
new/sqlite-utils-3.36/docs/changelog.rst
--- old/sqlite-utils-3.35.2/docs/changelog.rst  2023-11-04 02:17:02.000000000 
+0100
+++ new/sqlite-utils-3.36/docs/changelog.rst    2023-12-08 06:36:09.000000000 
+0100
@@ -4,6 +4,17 @@
  Changelog
 ===========
 
+.. _v3_36:
+
+3.36 (2023-12-07)
+-----------------
+
+- Support for creating tables in `SQLite STRICT mode 
<https://www.sqlite.org/stricttables.html>`__. Thanks, `Taj Khattra 
<https://github.com/tkhattra>`__. (:issue:`344`)
+    - CLI commands ``create-table``, ``insert`` and ``upsert`` all now accept 
a ``--strict`` option.
+    - Python methods that can create a table - ``table.create()`` and 
``insert/upsert/insert_all/upsert_all`` all now accept an optional 
``strict=True`` parameter.
+    - The ``transform`` command and ``table.transform()`` method preserve 
strict mode when transforming a table.
+- The ``sqlite-utils create-table`` command now accepts ``str``, ``int`` and 
``bytes`` as aliases for ``text``, ``integer`` and ``blob`` respectively. 
(:issue:`606`)
+
 .. _v3_35_2:
 
 3.35.2 (2023-11-03)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sqlite-utils-3.35.2/docs/cli-reference.rst 
new/sqlite-utils-3.36/docs/cli-reference.rst
--- old/sqlite-utils-3.35.2/docs/cli-reference.rst      2023-11-04 
02:17:02.000000000 +0100
+++ new/sqlite-utils-3.36/docs/cli-reference.rst        2023-12-08 
06:36:09.000000000 +0100
@@ -289,6 +289,7 @@
       --analyze                 Run ANALYZE at the end of this operation
       --load-extension TEXT     Path to SQLite extension, with optional 
:entrypoint
       --silent                  Do not show progress bar
+      --strict                  Apply STRICT mode to created table
       --ignore                  Ignore records if pk already exists
       --replace                 Replace records if pk already exists
       --truncate                Truncate table before inserting records, if 
table
@@ -345,6 +346,7 @@
       --analyze                 Run ANALYZE at the end of this operation
       --load-extension TEXT     Path to SQLite extension, with optional 
:entrypoint
       --silent                  Do not show progress bar
+      --strict                  Apply STRICT mode to created table
       -h, --help                Show this message and exit.
 
 
@@ -920,6 +922,7 @@
       --replace                 If table already exists, replace it
       --transform               If table already exists, try to transform the 
schema
       --load-extension TEXT     Path to SQLite extension, with optional 
:entrypoint
+      --strict                  Apply STRICT mode to created table
       -h, --help                Show this message and exit.
 
 
@@ -1157,7 +1160,7 @@
 ::
 
     Usage: sqlite-utils add-column [OPTIONS] PATH TABLE COL_NAME
-                          [[integer|float|blob|text|INTEGER|FLOAT|BLOB|TEXT]]
+                          [[integer|int|float|text|str|blob|bytes]]
 
       Add a column to the specified table
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sqlite-utils-3.35.2/docs/cli.rst 
new/sqlite-utils-3.36/docs/cli.rst
--- old/sqlite-utils-3.35.2/docs/cli.rst        2023-11-04 02:17:02.000000000 
+0100
+++ new/sqlite-utils-3.36/docs/cli.rst  2023-12-08 06:36:09.000000000 +0100
@@ -1972,6 +1972,25 @@
                 [author_id] INTEGER REFERENCES [authors]([id])
              )
 
+You can create a table in `SQLite STRICT mode 
<https://www.sqlite.org/stricttables.html>`__ using ``--strict``:
+
+.. code-block:: bash
+
+   sqlite-utils create-table mydb.db mytable id integer name text --strict
+
+.. code-block:: bash
+
+   sqlite-utils tables mydb.db --schema -t
+
+.. code-block:: output
+
+   table    schema
+   -------  ------------------------
+   mytable  CREATE TABLE [mytable] (
+               [id] INTEGER,
+               [name] TEXT
+            ) STRICT
+
 If a table with the same name already exists, you will get an error. You can 
choose to silently ignore this error with ``--ignore``, or you can replace the 
existing table with a new, empty table using ``--replace``.
 
 You can also pass ``--transform`` to transform the existing table to match the 
new schema. See :ref:`python_api_explicit_create` in the Python library 
documentation for details of how this option works.
@@ -2018,7 +2037,7 @@
 Transforming tables
 ===================
 
-The ``transform`` command allows you to apply complex transformations to a 
table that cannot be implemented using a regular SQLite ``ALTER TABLE`` 
command. See :ref:`python_api_transform` for details of how this works.
+The ``transform`` command allows you to apply complex transformations to a 
table that cannot be implemented using a regular SQLite ``ALTER TABLE`` 
command. See :ref:`python_api_transform` for details of how this works. The 
``transform`` command preserves a table's ``STRICT`` mode.
 
 .. code-block:: bash
 
@@ -2310,7 +2329,14 @@
 
     sqlite-utils add-column mydb.db mytable nameofcolumn text
 
-The last argument here is the type of the column to be created. You can use 
one of ``text``, ``integer``, ``float`` or ``blob``. If you leave it off, 
``text`` will be used.
+The last argument here is the type of the column to be created. This can be 
one of:
+
+- ``text`` or ``str``
+- ``integer`` or ``int``
+- ``float``
+- ``blob`` or ``bytes``
+
+This argument is optional and defaults to ``text``.
 
 You can add a column that is a foreign key reference to another table using 
the ``--fk`` option:
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sqlite-utils-3.35.2/docs/plugins.rst 
new/sqlite-utils-3.36/docs/plugins.rst
--- old/sqlite-utils-3.35.2/docs/plugins.rst    2023-11-04 02:17:02.000000000 
+0100
+++ new/sqlite-utils-3.36/docs/plugins.rst      2023-12-08 06:36:09.000000000 
+0100
@@ -49,7 +49,7 @@
     [project.entry-points.sqlite_utils]
     hello_world = "sqlite_utils_hello_world"
 
-The ```[project.entry-points.sqlite_utils]`` section tells ``sqlite-tils`` 
which module to load when executing the plugin.
+The ``[project.entry-points.sqlite_utils]`` section tells ``sqlite-utils`` 
which module to load when executing the plugin.
 
 Then create ``sqlite_utils_hello_world.py`` with the following content:
 
@@ -75,7 +75,7 @@
 
 .. code-block:: bash
 
-    sqlite-utils install -e `/dev/sqlite-utils-hello-world
+    sqlite-utils install -e /dev/sqlite-utils-hello-world
 
 Now, running this should execute your new command:
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sqlite-utils-3.35.2/docs/python-api.rst 
new/sqlite-utils-3.36/docs/python-api.rst
--- old/sqlite-utils-3.35.2/docs/python-api.rst 2023-11-04 02:17:02.000000000 
+0100
+++ new/sqlite-utils-3.36/docs/python-api.rst   2023-12-08 06:36:09.000000000 
+0100
@@ -117,6 +117,12 @@
 
     db = Database(memory=True, execute_plugins=False)
 
+You can pass ``strict=True`` to enable `SQLite STRICT mode 
<https://www.sqlite.org/stricttables.html>`__ for all tables created using this 
database object:
+
+.. code-block:: python
+
+    db = Database("my_database.db", strict=True)
+
 .. _python_api_attach:
 
 Attaching additional databases
@@ -581,6 +587,15 @@
 
 Changes to ``foreign_keys=`` are not currently detected and applied by 
``transform=True``.
 
+You can pass ``strict=True`` to create a table in ``STRICT`` mode:
+
+.. code-block:: python
+
+    db["cats"].create({
+        "id": int,
+        "name": str,
+    }, strict=True)
+
 .. _python_api_compound_primary_keys:
 
 Compound primary keys
@@ -661,7 +676,7 @@
     # Now you can call .insert() like so:
     table.insert({"id": 1, "name": "Tracy", "score": 5})
 
-The configuration options that can be specified in this way are ``pk``, 
``foreign_keys``, ``column_order``, ``not_null``, ``defaults``, ``batch_size``, 
``hash_id``, ``hash_id_columns``, ``alter``, ``ignore``, ``replace``, 
``extracts``, ``conversions``, ``columns``. These are all documented below.
+The configuration options that can be specified in this way are ``pk``, 
``foreign_keys``, ``column_order``, ``not_null``, ``defaults``, ``batch_size``, 
``hash_id``, ``hash_id_columns``, ``alter``, ``ignore``, ``replace``, 
``extracts``, ``conversions``, ``columns``, ``strict``. These are all 
documented below.
 
 .. _python_api_defaults_not_null:
 
@@ -1011,6 +1026,7 @@
 - ``extracts``
 - ``conversions``
 - ``columns``
+- ``strict``
 
 .. _python_api_extracts:
 
@@ -2161,6 +2177,18 @@
     >>> db["authors"].has_counts_triggers
     True
 
+.. _python_api_introspection_supports_strict
+
+db.supports_strict
+------------------
+
+This property on the database object returns ``True`` if the available SQLite 
version supports `STRICT mode <https://www.sqlite.org/stricttables.html>`__, 
which was added in SQLite 3.37.0 (on 2021-11-27).
+
+::
+
+    >>> db.supports_strict
+    True
+
 .. _python_api_fts:
 
 Full-text search
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sqlite-utils-3.35.2/setup.py 
new/sqlite-utils-3.36/setup.py
--- old/sqlite-utils-3.35.2/setup.py    2023-11-04 02:17:02.000000000 +0100
+++ new/sqlite-utils-3.36/setup.py      2023-12-08 06:36:09.000000000 +0100
@@ -2,7 +2,7 @@
 import io
 import os
 
-VERSION = "3.35.2"
+VERSION = "3.36"
 
 
 def get_long_description():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sqlite-utils-3.35.2/sqlite_utils/cli.py 
new/sqlite-utils-3.36/sqlite_utils/cli.py
--- old/sqlite-utils-3.35.2/sqlite_utils/cli.py 2023-11-04 02:17:02.000000000 
+0100
+++ new/sqlite-utils-3.36/sqlite_utils/cli.py   2023-12-08 06:36:09.000000000 
+0100
@@ -60,6 +60,14 @@
 maximize_csv_field_size_limit()
 
 
+class CaseInsensitiveChoice(click.Choice):
+    def __init__(self, choices):
+        super().__init__([choice.lower() for choice in choices])
+
+    def convert(self, value, param, ctx):
+        return super().convert(value.lower(), param, ctx)
+
+
 def output_options(fn):
     for decorator in reversed(
         (
@@ -412,7 +420,8 @@
 @click.argument(
     "col_type",
     type=click.Choice(
-        ["integer", "float", "blob", "text", "INTEGER", "FLOAT", "BLOB", 
"TEXT"]
+        ["integer", "int", "float", "text", "str", "blob", "bytes"],
+        case_sensitive=False,
     ),
     required=False,
 )
@@ -900,6 +909,12 @@
                 ),
                 load_extension_option,
                 click.option("--silent", is_flag=True, help="Do not show 
progress bar"),
+                click.option(
+                    "--strict",
+                    is_flag=True,
+                    default=False,
+                    help="Apply STRICT mode to created table",
+                ),
             )
         ):
             fn = decorator(fn)
@@ -942,6 +957,7 @@
     silent=False,
     bulk_sql=None,
     functions=None,
+    strict=False,
 ):
     db = sqlite_utils.Database(path)
     _load_extensions(db, load_extension)
@@ -1057,6 +1073,7 @@
             "replace": replace,
             "truncate": truncate,
             "analyze": analyze,
+            "strict": strict,
         }
         if not_null:
             extra_kwargs["not_null"] = set(not_null)
@@ -1177,6 +1194,7 @@
     truncate,
     not_null,
     default,
+    strict,
 ):
     """
     Insert records from FILE into a table, creating the table if it
@@ -1255,6 +1273,7 @@
             silent=silent,
             not_null=not_null,
             default=default,
+            strict=strict,
         )
     except UnicodeDecodeError as ex:
         raise click.ClickException(UNICODE_ERROR.format(ex))
@@ -1290,6 +1309,7 @@
     analyze,
     load_extension,
     silent,
+    strict,
 ):
     """
     Upsert records based on their primary key. Works like 'insert' but if
@@ -1334,6 +1354,7 @@
             analyze=analyze,
             load_extension=load_extension,
             silent=silent,
+            strict=strict,
         )
     except UnicodeDecodeError as ex:
         raise click.ClickException(UNICODE_ERROR.format(ex))
@@ -1502,6 +1523,11 @@
     help="If table already exists, try to transform the schema",
 )
 @load_extension_option
+@click.option(
+    "--strict",
+    is_flag=True,
+    help="Apply STRICT mode to created table",
+)
 def create_table(
     path,
     table,
@@ -1514,6 +1540,7 @@
     replace,
     transform,
     load_extension,
+    strict,
 ):
     """
     Add a table with the specified columns. Columns should be specified using
@@ -1561,6 +1588,7 @@
         ignore=ignore,
         replace=replace,
         transform=transform,
+        strict=strict,
     )
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sqlite-utils-3.35.2/sqlite_utils/db.py 
new/sqlite-utils-3.36/sqlite_utils/db.py
--- old/sqlite-utils-3.35.2/sqlite_utils/db.py  2023-11-04 02:17:02.000000000 
+0100
+++ new/sqlite-utils-3.36/sqlite_utils/db.py    2023-12-08 06:36:09.000000000 
+0100
@@ -197,9 +197,12 @@
     "FLOAT": "FLOAT",
     "BLOB": "BLOB",
     "text": "TEXT",
+    "str": "TEXT",
     "integer": "INTEGER",
+    "int": "INTEGER",
     "float": "FLOAT",
     "blob": "BLOB",
+    "bytes": "BLOB",
 }
 # If numpy is available, add more types
 if np:
@@ -300,6 +303,7 @@
       ``sql, parameters`` every time a SQL query is executed
     :param use_counts_table: set to ``True`` to use a cached counts table, if 
available. See
       :ref:`python_api_cached_table_counts`
+    :param strict: Apply STRICT mode to all created tables (unless overridden)
     """
 
     _counts_table_name = "_counts"
@@ -315,6 +319,7 @@
         tracer: Optional[Callable] = None,
         use_counts_table: bool = False,
         execute_plugins: bool = True,
+        strict: bool = False,
     ):
         assert (filename_or_conn is not None and (not memory and not 
memory_name)) or (
             filename_or_conn is None and (memory or memory_name)
@@ -348,6 +353,7 @@
         self.use_counts_table = use_counts_table
         if execute_plugins:
             pm.hook.prepare_connection(conn=self.conn)
+        self.strict = strict
 
     def close(self):
         "Close the SQLite connection, and the underlying database file"
@@ -534,8 +540,11 @@
 
         :param table_name: Name of the table
         """
-        klass = View if table_name in self.view_names() else Table
-        return klass(self, table_name, **kwargs)
+        if table_name in self.view_names():
+            return View(self, table_name, **kwargs)
+        else:
+            kwargs.setdefault("strict", self.strict)
+            return Table(self, table_name, **kwargs)
 
     def quote(self, value: str) -> str:
         """
@@ -821,6 +830,7 @@
         hash_id_columns: Optional[Iterable[str]] = None,
         extracts: Optional[Union[Dict[str, str], List[str]]] = None,
         if_not_exists: bool = False,
+        strict: bool = False,
     ) -> str:
         """
         Returns the SQL ``CREATE TABLE`` statement for creating the specified 
table.
@@ -836,6 +846,7 @@
         :param hash_id_columns: List of columns to be used when calculating 
the hash ID for a row
         :param extracts: List or dictionary of columns to be extracted during 
inserts, see :ref:`python_api_extracts`
         :param if_not_exists: Use ``CREATE TABLE IF NOT EXISTS``
+        :param strict: Apply STRICT mode to table
         """
         if hash_id_columns and (hash_id is None):
             hash_id = "id"
@@ -932,12 +943,13 @@
         columns_sql = ",\n".join(column_defs)
         sql = """CREATE TABLE {if_not_exists}[{table}] (
 {columns_sql}{extra_pk}
-);
+){strict};
         """.format(
             if_not_exists="IF NOT EXISTS " if if_not_exists else "",
             table=name,
             columns_sql=columns_sql,
             extra_pk=extra_pk,
+            strict=" STRICT" if strict and self.supports_strict else "",
         )
         return sql
 
@@ -957,6 +969,7 @@
         replace: bool = False,
         ignore: bool = False,
         transform: bool = False,
+        strict: bool = False,
     ) -> "Table":
         """
         Create a table with the specified name and the specified 
``{column_name: type}`` columns.
@@ -977,6 +990,7 @@
         :param replace: Drop and replace table if it already exists
         :param ignore: Silently do nothing if table already exists
         :param transform: If table already exists transform it to fit the 
specified schema
+        :param strict: Apply STRICT mode to table
         """
         # Transform table to match the new definition if table already exists:
         if self[name].exists():
@@ -1048,6 +1062,7 @@
             hash_id_columns=hash_id_columns,
             extracts=extracts,
             if_not_exists=if_not_exists,
+            strict=strict,
         )
         self.execute(sql)
         created_table = self.table(
@@ -1416,6 +1431,7 @@
     :param extracts: Dictionary or list of column names to extract into a 
separate table on inserts
     :param conversions: Dictionary of column names and conversion functions
     :param columns: Dictionary of column names to column types
+    :param strict: If True, apply STRICT mode to table
     """
 
     #: The ``rowid`` of the last inserted, updated or selected row.
@@ -1441,6 +1457,7 @@
         extracts: Optional[Union[Dict[str, str], List[str]]] = None,
         conversions: Optional[dict] = None,
         columns: Optional[Dict[str, Any]] = None,
+        strict: bool = False,
     ):
         super().__init__(db, name)
         self._defaults = dict(
@@ -1458,6 +1475,7 @@
             extracts=extracts,
             conversions=conversions or {},
             columns=columns,
+            strict=strict,
         )
 
     def __repr__(self) -> str:
@@ -1639,6 +1657,7 @@
         replace: bool = False,
         ignore: bool = False,
         transform: bool = False,
+        strict: bool = False,
     ) -> "Table":
         """
         Create a table with the specified columns.
@@ -1658,6 +1677,7 @@
         :param replace: Drop and replace table if it already exists
         :param ignore: Silently do nothing if table already exists
         :param transform: If table already exists transform it to fit the 
specified schema
+        :param strict: Apply STRICT mode to table
         """
         columns = {name: value for (name, value) in columns.items()}
         with self.db.conn:
@@ -1676,6 +1696,7 @@
                 replace=replace,
                 ignore=ignore,
                 transform=transform,
+                strict=strict,
             )
         return self
 
@@ -1909,6 +1930,7 @@
                 defaults=create_table_defaults,
                 foreign_keys=create_table_foreign_keys,
                 column_order=column_order,
+                strict=self.strict,
             ).strip()
         )
 
@@ -3111,6 +3133,7 @@
         extracts: Optional[Union[Dict[str, str], List[str], Default]] = 
DEFAULT,
         conversions: Optional[Union[Dict[str, str], Default]] = DEFAULT,
         columns: Optional[Union[Dict[str, Any], Default]] = DEFAULT,
+        strict: Optional[Union[bool, Default]] = DEFAULT,
     ) -> "Table":
         """
         Insert a single record into the table. The table will be created with 
a schema that matches
@@ -3143,6 +3166,7 @@
           is being inserted, for example ``{"name": "upper(?)"}``. See 
:ref:`python_api_conversions`.
         :param columns: Dictionary over-riding the detected types used for the 
columns, for example
           ``{"age": int, "weight": float}``.
+        :param strict: Boolean, apply STRICT mode if creating the table.
         """
         return self.insert_all(
             [record],
@@ -3159,6 +3183,7 @@
             extracts=extracts,
             conversions=conversions,
             columns=columns,
+            strict=strict,
         )
 
     def insert_all(
@@ -3181,6 +3206,7 @@
         columns=DEFAULT,
         upsert=False,
         analyze=False,
+        strict=DEFAULT,
     ) -> "Table":
         """
         Like ``.insert()`` but takes a list of records and ensures that the 
table
@@ -3202,6 +3228,7 @@
         extracts = self.value_or_default("extracts", extracts)
         conversions = self.value_or_default("conversions", conversions) or {}
         columns = self.value_or_default("columns", columns)
+        strict = self.value_or_default("strict", strict)
 
         if hash_id_columns and hash_id is None:
             hash_id = "id"
@@ -3257,6 +3284,7 @@
                         hash_id=hash_id,
                         hash_id_columns=hash_id_columns,
                         extracts=extracts,
+                        strict=strict,
                     )
                 all_columns_set = set()
                 for record in chunk:
@@ -3307,6 +3335,7 @@
         extracts=DEFAULT,
         conversions=DEFAULT,
         columns=DEFAULT,
+        strict=DEFAULT,
     ) -> "Table":
         """
         Like ``.insert()`` but performs an ``UPSERT``, where records are 
inserted if they do
@@ -3327,6 +3356,7 @@
             extracts=extracts,
             conversions=conversions,
             columns=columns,
+            strict=strict,
         )
 
     def upsert_all(
@@ -3345,6 +3375,7 @@
         conversions=DEFAULT,
         columns=DEFAULT,
         analyze=False,
+        strict=DEFAULT,
     ) -> "Table":
         """
         Like ``.upsert()`` but can be applied to a list of records.
@@ -3365,6 +3396,7 @@
             columns=columns,
             upsert=True,
             analyze=analyze,
+            strict=strict,
         )
 
     def add_missing_columns(self, records: Iterable[Dict[str, Any]]) -> 
"Table":
@@ -3387,6 +3419,7 @@
         extracts: Optional[Union[Dict[str, str], List[str]]] = None,
         conversions: Optional[Dict[str, str]] = None,
         columns: Optional[Dict[str, Any]] = None,
+        strict: Optional[bool] = False,
     ):
         """
         Create or populate a lookup table with the specified values.
@@ -3409,6 +3442,7 @@
 
         :param lookup_values: Dictionary specifying column names and values to 
use for the lookup
         :param extra_values: Additional column values to be used only if 
creating a new record
+        :param strict: Boolean, apply STRICT mode if creating the table.
         """
         assert isinstance(lookup_values, dict)
         if extra_values is not None:
@@ -3440,6 +3474,7 @@
                     extracts=extracts,
                     conversions=conversions,
                     columns=columns,
+                    strict=strict,
                 ).last_pk
         else:
             pk = self.insert(
@@ -3452,6 +3487,7 @@
                 extracts=extracts,
                 conversions=conversions,
                 columns=columns,
+                strict=strict,
             ).last_pk
             self.create_index(lookup_values.keys(), unique=True)
             return pk
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sqlite-utils-3.35.2/sqlite_utils.egg-info/PKG-INFO 
new/sqlite-utils-3.36/sqlite_utils.egg-info/PKG-INFO
--- old/sqlite-utils-3.35.2/sqlite_utils.egg-info/PKG-INFO      2023-11-04 
02:17:11.000000000 +0100
+++ new/sqlite-utils-3.36/sqlite_utils.egg-info/PKG-INFO        2023-12-08 
06:36:17.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: sqlite-utils
-Version: 3.35.2
+Version: 3.36
 Summary: CLI tool and Python library for manipulating SQLite databases
 Home-page: https://github.com/simonw/sqlite-utils
 Author: Simon Willison
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sqlite-utils-3.35.2/tests/test_cli.py 
new/sqlite-utils-3.36/tests/test_cli.py
--- old/sqlite-utils-3.35.2/tests/test_cli.py   2023-11-04 02:17:02.000000000 
+0100
+++ new/sqlite-utils-3.36/tests/test_cli.py     2023-12-08 06:36:09.000000000 
+0100
@@ -272,13 +272,23 @@
     "col_name,col_type,expected_schema",
     (
         ("text", "TEXT", "CREATE TABLE [dogs] (\n   [name] TEXT\n, [text] 
TEXT)"),
+        ("text", "str", "CREATE TABLE [dogs] (\n   [name] TEXT\n, [text] 
TEXT)"),
+        ("text", "STR", "CREATE TABLE [dogs] (\n   [name] TEXT\n, [text] 
TEXT)"),
         (
             "integer",
             "INTEGER",
             "CREATE TABLE [dogs] (\n   [name] TEXT\n, [integer] INTEGER)",
         ),
+        (
+            "integer",
+            "int",
+            "CREATE TABLE [dogs] (\n   [name] TEXT\n, [integer] INTEGER)",
+        ),
         ("float", "FLOAT", "CREATE TABLE [dogs] (\n   [name] TEXT\n, [float] 
FLOAT)"),
         ("blob", "blob", "CREATE TABLE [dogs] (\n   [name] TEXT\n, [blob] 
BLOB)"),
+        ("blob", "BLOB", "CREATE TABLE [dogs] (\n   [name] TEXT\n, [blob] 
BLOB)"),
+        ("blob", "bytes", "CREATE TABLE [dogs] (\n   [name] TEXT\n, [blob] 
BLOB)"),
+        ("blob", "BYTES", "CREATE TABLE [dogs] (\n   [name] TEXT\n, [blob] 
BLOB)"),
         ("default", None, "CREATE TABLE [dogs] (\n   [name] TEXT\n, [default] 
TEXT)"),
     ),
 )
@@ -2391,3 +2401,32 @@
             catch_exceptions=False,
         )
         assert result.exit_code == 1
+
+
+@pytest.mark.parametrize("strict", (False, True))
+def test_create_table_strict(strict):
+    runner = CliRunner()
+    with runner.isolated_filesystem():
+        db = Database("test.db")
+        result = runner.invoke(
+            cli.cli,
+            ["create-table", "test.db", "items", "id", "integer"]
+            + (["--strict"] if strict else []),
+        )
+        assert result.exit_code == 0
+        assert db["items"].strict == strict or not db.supports_strict
+
+
+@pytest.mark.parametrize("method", ("insert", "upsert"))
+@pytest.mark.parametrize("strict", (False, True))
+def test_insert_upsert_strict(tmpdir, method, strict):
+    db_path = str(tmpdir / "test.db")
+    result = CliRunner().invoke(
+        cli.cli,
+        [method, db_path, "items", "-", "--csv", "--pk", "id"]
+        + (["--strict"] if strict else []),
+        input="id\n1",
+    )
+    assert result.exit_code == 0
+    db = Database(db_path)
+    assert db["items"].strict == strict or not db.supports_strict
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sqlite-utils-3.35.2/tests/test_create.py 
new/sqlite-utils-3.36/tests/test_create.py
--- old/sqlite-utils-3.35.2/tests/test_create.py        2023-11-04 
02:17:02.000000000 +0100
+++ new/sqlite-utils-3.36/tests/test_create.py  2023-12-08 06:36:09.000000000 
+0100
@@ -1316,3 +1316,46 @@
     # Should error if table does not exist:
     with pytest.raises(sqlite3.OperationalError):
         fresh_db.rename_table("does_not_exist", "renamed")
+
+
+@pytest.mark.parametrize("strict", (False, True))
+def test_database_strict(strict):
+    db = Database(memory=True, strict=strict)
+    table = db.table("t", columns={"id": int})
+    table.insert({"id": 1})
+    assert table.strict == strict or not db.supports_strict
+
+
+@pytest.mark.parametrize("strict", (False, True))
+def test_database_strict_override(strict):
+    db = Database(memory=True, strict=strict)
+    table = db.table("t", columns={"id": int}, strict=not strict)
+    table.insert({"id": 1})
+    assert table.strict != strict or not db.supports_strict
+
+
+@pytest.mark.parametrize(
+    "method_name", ("insert", "upsert", "insert_all", "upsert_all")
+)
+@pytest.mark.parametrize("strict", (False, True))
+def test_insert_upsert_strict(fresh_db, method_name, strict):
+    table = fresh_db["t"]
+    method = getattr(table, method_name)
+    record = {"id": 1}
+    if method_name.endswith("_all"):
+        record = [record]
+    method(record, pk="id", strict=strict)
+    assert table.strict == strict or not fresh_db.supports_strict
+
+
+@pytest.mark.parametrize("strict", (False, True))
+def test_create_table_strict(fresh_db, strict):
+    table = fresh_db.create_table("t", {"id": int}, strict=strict)
+    assert table.strict == strict or not fresh_db.supports_strict
+
+
+@pytest.mark.parametrize("strict", (False, True))
+def test_create_strict(fresh_db, strict):
+    table = fresh_db["t"]
+    table.create({"id": int}, strict=strict)
+    assert table.strict == strict or not fresh_db.supports_strict
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sqlite-utils-3.35.2/tests/test_lookup.py 
new/sqlite-utils-3.36/tests/test_lookup.py
--- old/sqlite-utils-3.35.2/tests/test_lookup.py        2023-11-04 
02:17:02.000000000 +0100
+++ new/sqlite-utils-3.36/tests/test_lookup.py  2023-12-08 06:36:09.000000000 
+0100
@@ -151,3 +151,9 @@
             columns=["name", "type"],
         )
     ]
+
+
+@pytest.mark.parametrize("strict", (False, True))
+def test_lookup_new_table_strict(fresh_db, strict):
+    fresh_db["species"].lookup({"name": "Palm"}, strict=strict)
+    assert fresh_db["species"].strict == strict or not fresh_db.supports_strict
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sqlite-utils-3.35.2/tests/test_transform.py 
new/sqlite-utils-3.36/tests/test_transform.py
--- old/sqlite-utils-3.35.2/tests/test_transform.py     2023-11-04 
02:17:02.000000000 +0100
+++ new/sqlite-utils-3.36/tests/test_transform.py       2023-12-08 
06:36:09.000000000 +0100
@@ -530,3 +530,12 @@
         tuple(row) for row in fresh_db.execute("select rowid, id, name from 
places")
     )
     assert previous_rows == next_rows
+
+
+@pytest.mark.parametrize("strict", (False, True))
+def test_transform_strict(fresh_db, strict):
+    dogs = fresh_db.table("dogs", strict=strict)
+    dogs.insert({"id": 1, "name": "Cleo"})
+    assert dogs.strict == strict or not fresh_db.supports_strict
+    dogs.transform(not_null={"name"})
+    assert dogs.strict == strict or not fresh_db.supports_strict

Reply via email to