Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-tinydb for openSUSE:Factory 
checked in at 2021-08-28 22:29:18
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-tinydb (Old)
 and      /work/SRC/openSUSE:Factory/.python-tinydb.new.1899 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-tinydb"

Sat Aug 28 22:29:18 2021 rev:10 rq:914744 version:4.5.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-tinydb/python-tinydb.changes      
2021-04-10 15:28:06.322429842 +0200
+++ /work/SRC/openSUSE:Factory/.python-tinydb.new.1899/python-tinydb.changes    
2021-08-28 22:29:34.690003340 +0200
@@ -1,0 +2,16 @@
+Fri Aug 27 11:09:53 UTC 2021 - pgaj...@suse.com
+
+- version update to 4.5.1
+  v4.5.1 (2021-07-17)
+  ^^^^^^^^^^^^^^^^^^^
+  - Fix: Correctly install ``typing-extensions`` on Python 3.7
+    (see `issue 413 <https://github.com/msiemens/tinydb/issues/413>`__)
+  v4.5.0 (2021-06-25)
+  ^^^^^^^^^^^^^^^^^^^
+  - Feature: Better type hinting/IntelliSense for PyCharm, VS Code and MyPy
+    (see `issue 372 <https://github.com/msiemens/tinydb/issues/372>`__).
+    PyCharm and VS Code should work out of the box, for MyPy see
+    :ref:`MyPy Type Checking <mypy_type_checking>`
+- actually test the package
+
+-------------------------------------------------------------------

Old:
----
  tinydb-4.4.0.tar.gz

New:
----
  tinydb-4.5.1.tar.gz
  v4.5.1.tar.gz

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

Other differences:
------------------
++++++ python-tinydb.spec ++++++
--- /var/tmp/diff_new_pack.yoeLCK/_old  2021-08-28 22:29:36.038004738 +0200
+++ /var/tmp/diff_new_pack.yoeLCK/_new  2021-08-28 22:29:36.042004743 +0200
@@ -19,15 +19,18 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define skip_python2 1
 Name:           python-tinydb
-Version:        4.4.0
+Version:        4.5.1
 Release:        0
 Summary:        A document-oriented database
 License:        MIT
 Group:          Productivity/Databases/Servers
 URL:            https://github.com/msiemens/tinydb
 Source:         
https://files.pythonhosted.org/packages/source/t/tinydb/tinydb-%{version}.tar.gz
+# https://github.com/msiemens/tinydb/issues/324
+Source1:        
https://github.com/msiemens/tinydb/archive/refs/tags/v%{version}.tar.gz
 BuildRequires:  %{python_module PyYAML}
-BuildRequires:  %{python_module pytest-runner}
+BuildRequires:  %{python_module pytest-mypy}
+BuildRequires:  %{python_module pytest}
 BuildRequires:  %{python_module setuptools}
 BuildRequires:  dos2unix
 BuildRequires:  fdupes
@@ -42,7 +45,7 @@
 external database server.
 
 %prep
-%setup -q -n tinydb-%{version}
+%setup -q -n tinydb-%{version} -b1
 sed -i '/pytest-cov/d' setup.py
 chmod a-x LICENSE
 dos2unix LICENSE
@@ -59,7 +62,8 @@
 %python_expand %fdupes %{buildroot}%{$python_sitelib}
 
 %check
-%python_exec setup.py test
+mv pytest.ini{,.notused}
+%pytest
 
 %files %{python_files}
 %license LICENSE

++++++ tinydb-4.4.0.tar.gz -> tinydb-4.5.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tinydb-4.4.0/PKG-INFO new/tinydb-4.5.1/PKG-INFO
--- old/tinydb-4.4.0/PKG-INFO   2021-02-11 20:31:23.965108600 +0100
+++ new/tinydb-4.5.1/PKG-INFO   2021-07-17 10:35:20.332101300 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: tinydb
-Version: 4.4.0
+Version: 4.5.1
 Summary: TinyDB is a tiny, document oriented database optimized for your 
happiness :)
 Home-page: https://github.com/msiemens/tinydb
 License: MIT
@@ -25,6 +25,7 @@
 Classifier: Topic :: Database :: Database Engines/Servers
 Classifier: Topic :: Utilities
 Classifier: Typing :: Typed
+Requires-Dist: typing-extensions (>=3.10.0,<4.0.0); python_version <= "3.7"
 Project-URL: Changelog, 
https://github.com/msiemens/tinydb/en/latest/changelog.html
 Project-URL: Documentation, https://tinydb.readthedocs.org/
 Project-URL: Issues, https://github.com/msiemens/tinydb/issues
@@ -68,7 +69,7 @@
   e.g. `PyMongo <https://api.mongodb.org/python/current/>`_) nor any 
dependencies
   from PyPI.
 
-- **works on Python 3.5+ and PyPy:** TinyDB works on all modern versions of 
Python
+- **works on Python 3.6+ and PyPy3:** TinyDB works on all modern versions of 
Python
   and PyPy.
 
 - **powerfully extensible:** You can easily extend TinyDB by writing new
@@ -84,7 +85,7 @@
 Supported Python Versions
 *************************
 
-TinyDB has been tested with Python 3.5 - 3.8 and PyPy.
+TinyDB has been tested with Python 3.6 - 3.9 and PyPy3.
 
 Example Code
 ************
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tinydb-4.4.0/README.rst new/tinydb-4.5.1/README.rst
--- old/tinydb-4.4.0/README.rst 2021-02-11 20:30:49.629945300 +0100
+++ new/tinydb-4.5.1/README.rst 2021-07-17 10:34:48.420737300 +0200
@@ -36,7 +36,7 @@
   e.g. `PyMongo <https://api.mongodb.org/python/current/>`_) nor any 
dependencies
   from PyPI.
 
-- **works on Python 3.5+ and PyPy:** TinyDB works on all modern versions of 
Python
+- **works on Python 3.6+ and PyPy3:** TinyDB works on all modern versions of 
Python
   and PyPy.
 
 - **powerfully extensible:** You can easily extend TinyDB by writing new
@@ -52,7 +52,7 @@
 Supported Python Versions
 *************************
 
-TinyDB has been tested with Python 3.5 - 3.8 and PyPy.
+TinyDB has been tested with Python 3.6 - 3.9 and PyPy3.
 
 Example Code
 ************
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tinydb-4.4.0/pyproject.toml 
new/tinydb-4.5.1/pyproject.toml
--- old/tinydb-4.4.0/pyproject.toml     2021-02-11 20:30:49.629945300 +0100
+++ new/tinydb-4.5.1/pyproject.toml     2021-07-17 10:34:48.424737200 +0200
@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "tinydb"
-version = "4.4.0"
+version = "4.5.1"
 description = "TinyDB is a tiny, document oriented database optimized for your 
happiness :)"
 authors = ["Markus Siemens <mar...@m-siemens.de>"]
 license = "MIT"
@@ -21,7 +21,6 @@
     "Topic :: Database :: Database Engines/Servers",
     "Topic :: Utilities",
     "Programming Language :: Python :: 3",
-    "Programming Language :: Python :: 3.5",
     "Programming Language :: Python :: 3.6",
     "Programming Language :: Python :: 3.7",
     "Programming Language :: Python :: 3.8",
@@ -42,6 +41,7 @@
 
 [tool.poetry.dependencies]
 python = "^3.5"
+typing-extensions = { version = "^3.10.0", python = "<=3.7" }
 
 [tool.poetry.dev-dependencies]
 pytest = "^5.2.2"
@@ -52,7 +52,9 @@
 coveralls = "^1.8.2"
 pyyaml = "^5.1.2"
 pytest-mypy = { version = "^0.4.1", markers = "platform_python_implementation 
!= 'PyPy'" }
+types-PyYAML = "^5.4.3"
+typing-extensions = { version = "^3.10.0" }
 
 [build-system]
-requires = ["poetry>=0.12"]
-build-backend = "poetry.masonry.api"
+requires = ["poetry-core"]
+build-backend = "poetry.core.masonry.api"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tinydb-4.4.0/setup.py new/tinydb-4.5.1/setup.py
--- old/tinydb-4.4.0/setup.py   2021-02-11 20:31:23.964544000 +0100
+++ new/tinydb-4.5.1/setup.py   2021-07-17 10:35:20.331332700 +0200
@@ -7,11 +7,14 @@
 package_data = \
 {'': ['*']}
 
+extras_require = \
+{':python_version <= "3.7"': ['typing-extensions>=3.10.0,<4.0.0']}
+
 setup_kwargs = {
     'name': 'tinydb',
-    'version': '4.4.0',
+    'version': '4.5.1',
     'description': 'TinyDB is a tiny, document oriented database optimized for 
your happiness :)',
-    'long_description': ".. image:: 
https://raw.githubusercontent.com/msiemens/tinydb/master/artwork/logo.png\n    
:scale: 100%\n    :height: 150px\n\n|Build Status| |Coverage| 
|Version|\n\nQuick Links\n***********\n\n- `Example Code`_\n- `Supported Python 
Versions`_\n- `Documentation <http://tinydb.readthedocs.org/>`_\n- `Changelog 
<https://tinydb.readthedocs.io/en/latest/changelog.html>`_\n- `Extensions 
<https://tinydb.readthedocs.io/en/latest/extensions.html>`_\n- 
`Contributing`_\n\nIntroduction\n************\n\nTinyDB is a lightweight 
document oriented database optimized for your happiness :)\nIt's written in 
pure Python and has no external dependencies. The target are\nsmall apps that 
would be blown away by a SQL-DB or an external database server.\n\nTinyDB 
is:\n\n- **tiny:** The current source code has 1800 lines of code (with about 
40%\n  documentation) and 1600 lines tests.\n\n- **document oriented:** Like 
MongoDB_, you can store any document\n  (represented as ``dict``) in 
 TinyDB.\n\n- **optimized for your happiness:** TinyDB is designed to be simple 
and\n  fun to use by providing a simple and clean API.\n\n- **written in pure 
Python:** TinyDB neither needs an external server (as\n  e.g. `PyMongo 
<https://api.mongodb.org/python/current/>`_) nor any dependencies\n  from 
PyPI.\n\n- **works on Python 3.5+ and PyPy:** TinyDB works on all modern 
versions of Python\n  and PyPy.\n\n- **powerfully extensible:** You can easily 
extend TinyDB by writing new\n  storages or modify the behaviour of storages 
with Middlewares.\n\n- **100% test coverage:** No explanation needed.\n\nTo 
dive straight into all the details, head over to the `TinyDB 
docs\n<https://tinydb.readthedocs.io/>`_. You can also discuss everything 
related\nto TinyDB like general development, extensions or showcase your 
TinyDB-based\nprojects on the `discussion forum 
<http://forum.m-siemens.de/.>`_.\n\nSupported Python 
Versions\n*************************\n\nTinyDB has been tested with Python 3.5 - 
3
 .8 and PyPy.\n\nExample Code\n************\n\n.. code-block:: python\n\n    
>>> from tinydb import TinyDB, Query\n    >>> db = TinyDB('/path/to/db.json')\n 
   >>> db.insert({'int': 1, 'char': 'a'})\n    >>> db.insert({'int': 1, 'char': 
'b'})\n\nQuery Language\n==============\n\n.. code-block:: python\n\n    >>> 
User = Query()\n    >>> # Search for a field value\n    >>> db.search(User.name 
== 'John')\n    [{'name': 'John', 'age': 22}, {'name': 'John', 'age': 37}]\n\n  
  >>> # Combine two queries with logical and\n    >>> db.search((User.name == 
'John') & (User.age <= 30))\n    [{'name': 'John', 'age': 22}]\n\n    >>> # 
Combine two queries with logical or\n    >>> db.search((User.name == 'John') | 
(User.name == 'Bob'))\n    [{'name': 'John', 'age': 22}, {'name': 'John', 
'age': 37}, {'name': 'Bob', 'age': 42}]\n\n    >>> # More possible comparisons: 
 !=  <  >  <=  >=\n    >>> # More possible checks: where(...).matches(regex), 
where(...).test(your_test_func)\n\nTables\n======\n\n.. cod
 e-block:: python\n\n    >>> table = db.table('name')\n    >>> 
table.insert({'value': True})\n    >>> table.all()\n    [{'value': 
True}]\n\nUsing Middlewares\n=================\n\n.. code-block:: python\n\n    
>>> from tinydb.storages import JSONStorage\n    >>> from tinydb.middlewares 
import CachingMiddleware\n    >>> db = TinyDB('/path/to/db.json', 
storage=CachingMiddleware(JSONStorage))\n\n\nContributing\n************\n\nWhether
 reporting bugs, discussing improvements and new ideas or writing\nextensions: 
Contributions to TinyDB are welcome! Here's how to get started:\n\n1. Check for 
open issues or open a fresh issue to start a discussion around\n   a feature 
idea or a bug\n2. Fork `the repository <https://github.com/msiemens/tinydb/>`_ 
on Github,\n   create a new branch off the `master` branch and start making 
your changes\n   (known as `GitHub Flow 
<https://guides.github.com/introduction/flow/index.html>`_)\n3. Write a test 
which shows that the bug was fixed or that the feature 
 works\n   as expected\n4. Send a pull request and bug the maintainer until it 
gets merged and\n   published ???\n\n.. |Build Status| image:: 
https://img.shields.io/azure-devops/build/msiemens/3e5baa75-12ec-43ac-9728-89823ee8c7e2/2.svg?style=flat-square\n
   :target: https://dev.azure.com/msiemens/github/_build?definitionId=2\n.. 
|Coverage| image:: 
http://img.shields.io/coveralls/msiemens/tinydb.svg?style=flat-square\n   
:target: https://coveralls.io/r/msiemens/tinydb\n.. |Version| image:: 
http://img.shields.io/pypi/v/tinydb.svg?style=flat-square\n   :target: 
https://pypi.python.org/pypi/tinydb/\n.. _Buzhug: 
http://buzhug.sourceforge.net/\n.. _CodernityDB: 
https://github.com/perchouli/codernitydb\n.. _MongoDB: http://mongodb.org/\n";,
+    'long_description': ".. image:: 
https://raw.githubusercontent.com/msiemens/tinydb/master/artwork/logo.png\n    
:scale: 100%\n    :height: 150px\n\n|Build Status| |Coverage| 
|Version|\n\nQuick Links\n***********\n\n- `Example Code`_\n- `Supported Python 
Versions`_\n- `Documentation <http://tinydb.readthedocs.org/>`_\n- `Changelog 
<https://tinydb.readthedocs.io/en/latest/changelog.html>`_\n- `Extensions 
<https://tinydb.readthedocs.io/en/latest/extensions.html>`_\n- 
`Contributing`_\n\nIntroduction\n************\n\nTinyDB is a lightweight 
document oriented database optimized for your happiness :)\nIt's written in 
pure Python and has no external dependencies. The target are\nsmall apps that 
would be blown away by a SQL-DB or an external database server.\n\nTinyDB 
is:\n\n- **tiny:** The current source code has 1800 lines of code (with about 
40%\n  documentation) and 1600 lines tests.\n\n- **document oriented:** Like 
MongoDB_, you can store any document\n  (represented as ``dict``) in 
 TinyDB.\n\n- **optimized for your happiness:** TinyDB is designed to be simple 
and\n  fun to use by providing a simple and clean API.\n\n- **written in pure 
Python:** TinyDB neither needs an external server (as\n  e.g. `PyMongo 
<https://api.mongodb.org/python/current/>`_) nor any dependencies\n  from 
PyPI.\n\n- **works on Python 3.6+ and PyPy3:** TinyDB works on all modern 
versions of Python\n  and PyPy.\n\n- **powerfully extensible:** You can easily 
extend TinyDB by writing new\n  storages or modify the behaviour of storages 
with Middlewares.\n\n- **100% test coverage:** No explanation needed.\n\nTo 
dive straight into all the details, head over to the `TinyDB 
docs\n<https://tinydb.readthedocs.io/>`_. You can also discuss everything 
related\nto TinyDB like general development, extensions or showcase your 
TinyDB-based\nprojects on the `discussion forum 
<http://forum.m-siemens.de/.>`_.\n\nSupported Python 
Versions\n*************************\n\nTinyDB has been tested with Python 3.6 - 
 3.9 and PyPy3.\n\nExample Code\n************\n\n.. code-block:: python\n\n    
>>> from tinydb import TinyDB, Query\n    >>> db = TinyDB('/path/to/db.json')\n 
   >>> db.insert({'int': 1, 'char': 'a'})\n    >>> db.insert({'int': 1, 'char': 
'b'})\n\nQuery Language\n==============\n\n.. code-block:: python\n\n    >>> 
User = Query()\n    >>> # Search for a field value\n    >>> db.search(User.name 
== 'John')\n    [{'name': 'John', 'age': 22}, {'name': 'John', 'age': 37}]\n\n  
  >>> # Combine two queries with logical and\n    >>> db.search((User.name == 
'John') & (User.age <= 30))\n    [{'name': 'John', 'age': 22}]\n\n    >>> # 
Combine two queries with logical or\n    >>> db.search((User.name == 'John') | 
(User.name == 'Bob'))\n    [{'name': 'John', 'age': 22}, {'name': 'John', 
'age': 37}, {'name': 'Bob', 'age': 42}]\n\n    >>> # More possible comparisons: 
 !=  <  >  <=  >=\n    >>> # More possible checks: where(...).matches(regex), 
where(...).test(your_test_func)\n\nTables\n======\n\n.. c
 ode-block:: python\n\n    >>> table = db.table('name')\n    >>> 
table.insert({'value': True})\n    >>> table.all()\n    [{'value': 
True}]\n\nUsing Middlewares\n=================\n\n.. code-block:: python\n\n    
>>> from tinydb.storages import JSONStorage\n    >>> from tinydb.middlewares 
import CachingMiddleware\n    >>> db = TinyDB('/path/to/db.json', 
storage=CachingMiddleware(JSONStorage))\n\n\nContributing\n************\n\nWhether
 reporting bugs, discussing improvements and new ideas or writing\nextensions: 
Contributions to TinyDB are welcome! Here's how to get started:\n\n1. Check for 
open issues or open a fresh issue to start a discussion around\n   a feature 
idea or a bug\n2. Fork `the repository <https://github.com/msiemens/tinydb/>`_ 
on Github,\n   create a new branch off the `master` branch and start making 
your changes\n   (known as `GitHub Flow 
<https://guides.github.com/introduction/flow/index.html>`_)\n3. Write a test 
which shows that the bug was fixed or that the featur
 e works\n   as expected\n4. Send a pull request and bug the maintainer until 
it gets merged and\n   published ???\n\n.. |Build Status| image:: 
https://img.shields.io/azure-devops/build/msiemens/3e5baa75-12ec-43ac-9728-89823ee8c7e2/2.svg?style=flat-square\n
   :target: https://dev.azure.com/msiemens/github/_build?definitionId=2\n.. 
|Coverage| image:: 
http://img.shields.io/coveralls/msiemens/tinydb.svg?style=flat-square\n   
:target: https://coveralls.io/r/msiemens/tinydb\n.. |Version| image:: 
http://img.shields.io/pypi/v/tinydb.svg?style=flat-square\n   :target: 
https://pypi.python.org/pypi/tinydb/\n.. _Buzhug: 
http://buzhug.sourceforge.net/\n.. _CodernityDB: 
https://github.com/perchouli/codernitydb\n.. _MongoDB: http://mongodb.org/\n";,
     'author': 'Markus Siemens',
     'author_email': 'mar...@m-siemens.de',
     'maintainer': None,
@@ -19,6 +22,7 @@
     'url': 'https://github.com/msiemens/tinydb',
     'packages': packages,
     'package_data': package_data,
+    'extras_require': extras_require,
     'python_requires': '>=3.5,<4.0',
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tinydb-4.4.0/tinydb/database.py 
new/tinydb-4.5.1/tinydb/database.py
--- old/tinydb-4.4.0/tinydb/database.py 2021-02-11 20:30:49.633945200 +0100
+++ new/tinydb-4.5.1/tinydb/database.py 2021-07-17 10:34:48.424737200 +0200
@@ -1,14 +1,19 @@
 """
 This module contains the main component of TinyDB: the database.
 """
-from typing import Dict, Iterator, Set
+from typing import Dict, Iterator, Set, Type
 
 from . import JSONStorage
 from .storages import Storage
 from .table import Table, Document
+from .utils import with_typehint
 
+# The table's base class. This is used to add type hinting from the Table
+# class to TinyDB. Currently this supports PyCharm, Pyright/VS Code and MyPy.
+TableBase: Type[Table] = with_typehint(Table)
 
-class TinyDB:
+
+class TinyDB(TableBase):
     """
     The main class of TinyDB.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tinydb-4.4.0/tinydb/mypy_plugin.py 
new/tinydb-4.5.1/tinydb/mypy_plugin.py
--- old/tinydb-4.4.0/tinydb/mypy_plugin.py      1970-01-01 01:00:00.000000000 
+0100
+++ new/tinydb-4.5.1/tinydb/mypy_plugin.py      2021-07-17 10:34:48.424737200 
+0200
@@ -0,0 +1,38 @@
+from typing import TypeVar, Optional, Callable, Dict
+
+from mypy.nodes import NameExpr
+from mypy.options import Options
+from mypy.plugin import Plugin, DynamicClassDefContext
+
+T = TypeVar('T')
+CB = Optional[Callable[[T], None]]
+DynamicClassDef = DynamicClassDefContext
+
+
+class TinyDBPlugin(Plugin):
+    def __init__(self, options: Options):
+        super().__init__(options)
+
+        self.named_placeholders: Dict[str, str] = {}
+
+    def get_dynamic_class_hook(self, fullname: str) -> CB[DynamicClassDef]:
+        if fullname == 'tinydb.utils.with_typehint':
+            def hook(ctx: DynamicClassDefContext):
+                klass = ctx.call.args[0]
+                assert isinstance(klass, NameExpr)
+
+                type_name = klass.fullname
+                assert type_name is not None
+
+                qualified = self.lookup_fully_qualified(type_name)
+                assert qualified is not None
+
+                ctx.api.add_symbol_table_node(ctx.name, qualified)
+
+            return hook
+
+        return None
+
+
+def plugin(_version: str):
+    return TinyDBPlugin
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tinydb-4.4.0/tinydb/queries.py 
new/tinydb-4.5.1/tinydb/queries.py
--- old/tinydb-4.4.0/tinydb/queries.py  2021-02-11 20:30:49.633945200 +0100
+++ new/tinydb-4.5.1/tinydb/queries.py  2021-07-17 10:34:48.424737200 +0200
@@ -17,17 +17,43 @@
 """
 
 import re
+import sys
 from typing import Mapping, Tuple, Callable, Any, Union, List
 
 from .utils import freeze
 
-__all__ = ('Query', 'where')
+if sys.version_info >= (3, 8):
+    from typing import Protocol
+else:
+    from typing_extensions import Protocol
+
+__all__ = ('Query', 'QueryLike', 'where')
 
 
 def is_sequence(obj):
     return hasattr(obj, '__iter__')
 
 
+class QueryLike(Protocol):
+    """
+    A typing protocol that acts like a query.
+
+    Something that we use as a query must have two properties:
+
+    1. It must be callable, accepting a `Mapping` object and returning a
+       boolean that indicates whether the value matches the query, and
+    2. it must have a stable hash that will be used for query caching.
+
+    This query protocol is used to make MyPy correctly support the query
+    pattern that TinyDB uses.
+
+    See also 
https://mypy.readthedocs.io/en/stable/protocols.html#simple-user-defined-protocols
+    """
+    def __call__(self, value: Mapping) -> bool: ...
+
+    def __hash__(self): ...
+
+
 class QueryInstance:
     """
     A query instance.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tinydb-4.4.0/tinydb/table.py 
new/tinydb-4.5.1/tinydb/table.py
--- old/tinydb-4.4.0/tinydb/table.py    2021-02-11 20:30:49.633945200 +0100
+++ new/tinydb-4.5.1/tinydb/table.py    2021-07-17 10:34:48.424737200 +0200
@@ -16,8 +16,8 @@
     Tuple
 )
 
+from .queries import QueryLike
 from .storages import Storage
-from .queries import Query
 from .utils import LRUCache
 
 __all__ = ('Document', 'Table')
@@ -106,8 +106,8 @@
 
         self._storage = storage
         self._name = name
-        self._query_cache = self.query_cache_class(capacity=cache_size) \
-            # type: LRUCache[Query, List[Document]]
+        self._query_cache: LRUCache[QueryLike, List[Document]] \
+            = self.query_cache_class(capacity=cache_size)
 
         self._next_id = None
 
@@ -215,7 +215,7 @@
 
         return list(iter(self))
 
-    def search(self, cond: Query) -> List[Document]:
+    def search(self, cond: QueryLike) -> List[Document]:
         """
         Search for all documents matching a 'where' cond.
 
@@ -239,7 +239,7 @@
 
     def get(
         self,
-        cond: Optional[Query] = None,
+        cond: Optional[QueryLike] = None,
         doc_id: Optional[int] = None,
     ) -> Optional[Document]:
         """
@@ -276,7 +276,7 @@
 
     def contains(
         self,
-        cond: Optional[Query] = None,
+        cond: Optional[QueryLike] = None,
         doc_id: Optional[int] = None
     ) -> bool:
         """
@@ -301,7 +301,7 @@
     def update(
         self,
         fields: Union[Mapping, Callable[[Mapping], None]],
-        cond: Optional[Query] = None,
+        cond: Optional[QueryLike] = None,
         doc_ids: Optional[Iterable[int]] = None,
     ) -> List[int]:
         """
@@ -348,7 +348,7 @@
             updated_ids = []
 
             def updater(table: dict):
-                _cond = cast('Query', cond)
+                _cond = cast(QueryLike, cond)
 
                 # We need to convert the keys iterator to a list because
                 # we may remove entries from the ``table`` dict during
@@ -392,7 +392,7 @@
     def update_multiple(
         self,
         updates: Iterable[
-            Tuple[Union[Mapping, Callable[[Mapping], None]], Query]
+            Tuple[Union[Mapping, Callable[[Mapping], None]], QueryLike]
         ],
     ) -> List[int]:
         """
@@ -425,7 +425,7 @@
             # during iteration)
             for doc_id in list(table.keys()):
                 for fields, cond in updates:
-                    _cond = cast('Query', cond)
+                    _cond = cast(QueryLike, cond)
 
                     # Pass through all documents to find documents matching the
                     # query. Call the processing callback with the document ID
@@ -441,19 +441,38 @@
 
         return updated_ids
 
-    def upsert(self, document: Mapping, cond: Query) -> List[int]:
+    def upsert(self, document: Mapping, cond: Optional[QueryLike] = None) -> 
List[int]:
         """
-        Update a document, if it exist, insert it otherwise.
+        Update documents, if they exist, insert them otherwise.
 
-        Note: this will update *all* documents matching the query.
+        Note: This will update *all* documents matching the query. Document
+        argument can be a tinydb.table.Document object if you want to specify a
+        doc_id.
 
         :param document: the document to insert or the fields to update
-        :param cond: which document to look for
-        :returns: a list containing the updated document's ID
+        :param cond: which document to look for, optional if you've passed a
+        Document with a doc_id
+        :returns: a list containing the updated documents' IDs
         """
 
+        # Extract doc_id
+        if isinstance(document, Document) and hasattr(document, 'doc_id'):
+            doc_ids: Optional[List[int]] = [document.doc_id]
+        else:
+            doc_ids = None
+
+        # Make sure we can actually find a matching document
+        if doc_ids is None and cond is None:
+            raise ValueError("If you don't specify a search query, you must "
+                             "specify a doc_id. Hint: use a table.Document "
+                             "object.")
+
         # Perform the update operation
-        updated_docs = self.update(document, cond)
+        try:
+            updated_docs: Optional[List[int]] = self.update(document, cond, 
doc_ids)
+        except KeyError:
+            # This happens when a doc_id is specified, but it's missing
+            updated_docs = None
 
         # If documents have been updated: return their IDs
         if updated_docs:
@@ -465,7 +484,7 @@
 
     def remove(
         self,
-        cond: Optional[Query] = None,
+        cond: Optional[QueryLike] = None,
         doc_ids: Optional[Iterable[int]] = None,
     ) -> List[int]:
         """
@@ -485,7 +504,7 @@
                 # We need to convince MyPy (the static type checker) that
                 # the ``cond is not None`` invariant still holds true when
                 # the updater function is called
-                _cond = cast('Query', cond)
+                _cond = cast(QueryLike, cond)
 
                 # We need to convert the keys iterator to a list because
                 # we may remove entries from the ``table`` dict during
@@ -537,7 +556,7 @@
         # Reset document ID counter
         self._next_id = None
 
-    def count(self, cond: Query) -> int:
+    def count(self, cond: QueryLike) -> int:
         """
         Count the documents matching a query.
 
@@ -691,7 +710,7 @@
 
         # Convert the document IDs back to strings.
         # This is required as some storages (most notably the JSON file format)
-        # don't require IDs other than strings.
+        # don't support IDs other than strings.
         tables[self.name] = {
             str(doc_id): doc
             for doc_id, doc in table.items()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tinydb-4.4.0/tinydb/utils.py 
new/tinydb-4.5.1/tinydb/utils.py
--- old/tinydb-4.4.0/tinydb/utils.py    2021-02-11 20:30:49.633945200 +0100
+++ new/tinydb-4.5.1/tinydb/utils.py    2021-07-17 10:34:48.424737200 +0200
@@ -3,13 +3,37 @@
 """
 
 from collections import OrderedDict, abc
-from typing import List, Iterator, TypeVar, Generic, Union, Optional
+from typing import List, Iterator, TypeVar, Generic, Union, Optional, Type, \
+    TYPE_CHECKING
 
 K = TypeVar('K')
 V = TypeVar('V')
 D = TypeVar('D')
+T = TypeVar('T')
 
-__all__ = ('LRUCache', 'freeze')
+__all__ = ('LRUCache', 'freeze', 'with_typehint')
+
+
+def with_typehint(baseclass: Type[T]):
+    """
+    Add type hints from a specified class to a base class:
+
+    >>> class Foo(with_typehint(Bar)):
+    ...     pass
+
+    This would add type hints from class ``Bar`` to class ``Foo``.
+
+    Note that while PyCharm and Pyright (for VS Code) understand this pattern,
+    MyPy does not. For that reason TinyDB has a MyPy plugin in
+    ``mypy_plugin.py`` that adds support for this pattern.
+    """
+    if TYPE_CHECKING:
+        # In the case of type checking: pretend that the target class inherits
+        # from the specified base class
+        return baseclass
+
+    # Otherwise: just inherit from `object` like a regular Python class
+    return object
 
 
 class LRUCache(abc.MutableMapping, Generic[K, V]):
@@ -89,7 +113,7 @@
 
 class FrozenDict(dict):
     """
-    An immutable dictoinary.
+    An immutable dictionary.
 
     This is used to generate stable hashes for queries that contain dicts.
     Usually, Python dicts are not hashable because they are mutable. This
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tinydb-4.4.0/tinydb/version.py 
new/tinydb-4.5.1/tinydb/version.py
--- old/tinydb-4.4.0/tinydb/version.py  2021-02-11 20:30:49.633945200 +0100
+++ new/tinydb-4.5.1/tinydb/version.py  2021-07-17 10:34:48.424737200 +0200
@@ -1 +1 @@
-__version__ = '4.4.0'
+__version__ = '4.5.1'

Reply via email to