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'