diff options
| author | Salvo 'LtWorf' Tomaselli <ltworf@debian.org> | 2024-10-15 01:01:58 +0200 |
|---|---|---|
| committer | git-ubuntu importer <ubuntu-devel-discuss@lists.ubuntu.com> | 2024-10-15 04:44:20 +0000 |
| commit | 926b939d3582f54b9730b4b33f5e14431970cf7c (patch) | |
| tree | acb2ba80db9cb979c8fc9fee40cd9ce6e03726d1 | |
| parent | 78ab29bd8d914f4c96246eaa0cc836644117d3be (diff) | |
0.29.1-1 (patches unapplied)HEADimport/0.29.1-1ubuntu/resolute-develubuntu/resoluteubuntu/questing-develubuntu/questingubuntu/plucky-proposedubuntu/plucky-develubuntu/pluckyubuntu/develdebian/sid
Imported using git-ubuntu import.
Notes
Notes:
* Team upload
* New upstream release
* Fix autopkgtest
* Require the new pymongo
35 files changed, 301 insertions, 281 deletions
@@ -264,3 +264,4 @@ that much better: * oleksandr-l5 (https://github.com/oleksandr-l5) * Ido Shraga (https://github.com/idoshr) * Terence Honles (https://github.com/terencehonles) + * Sean Bermejo (https://github.com/seanbermejo) @@ -1,12 +1,12 @@ Metadata-Version: 2.1 Name: mongoengine -Version: 0.28.2 +Version: 0.29.1 Summary: MongoEngine is a Python Object-Document Mapper for working with MongoDB. Home-page: http://mongoengine.org/ Author: Harry Marr Author-email: harry.marr@gmail.com -Maintainer: Stefan Wojcik -Maintainer-email: wojcikstefan@gmail.com +Maintainer: Bastien Gerard +Maintainer-email: bast.gerard@gmail.com License: MIT Download-URL: https://github.com/MongoEngine/mongoengine/tarball/master Platform: any @@ -24,6 +24,7 @@ Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Database Classifier: Topic :: Software Development :: Libraries :: Python Modules Requires-Python: >=3.7 +Provides-Extra: test License-File: LICENSE License-File: AUTHORS @@ -33,7 +34,7 @@ MongoEngine :Info: MongoEngine is an ORM-like layer on top of PyMongo. :Repository: https://github.com/MongoEngine/mongoengine :Author: Harry Marr (http://github.com/hmarr) -:Maintainer: Stefan Wójcik (http://github.com/wojcikstefan) +:Maintainer: Bastien Gerard (http://github.com/bagerard) .. image:: https://travis-ci.org/MongoEngine/mongoengine.svg?branch=master :target: https://travis-ci.org/MongoEngine/mongoengine @@ -50,6 +51,10 @@ MongoEngine .. image:: https://img.shields.io/pypi/v/mongoengine.svg :target: https://pypi.python.org/pypi/mongoengine + +.. image:: https://readthedocs.org/projects/mongoengine-odm/badge/?version=latest + :target: https://readthedocs.org/projects/mongoengine-odm/builds/ + About ===== MongoEngine is a Python Object-Document Mapper for working with MongoDB. @@ -73,7 +78,7 @@ You may also have `setuptools <http://peak.telecommunity.com/DevCenter/setuptool and thus you can use ``easy_install -U mongoengine``. Another option is `pipenv <https://docs.pipenv.org/>`_. You can then use ``pipenv install mongoengine`` to both create the virtual environment and install the package. Otherwise, you can -download the source from `GitHub <http://github.com/MongoEngine/mongoengine>`_ and +download the source from `GitHub <https://github.com/MongoEngine/mongoengine>`_ and run ``python setup.py install``. The support for Python2 was dropped with MongoEngine 0.20.0 @@ -91,7 +96,7 @@ If you utilize a ``DateTimeField``, you might also use a more flexible date pars If you need to use an ``ImageField`` or ``ImageGridFsProxy``: -- Pillow>=2.0.0 +- Pillow>=7.0.0 If you need to use signals: @@ -154,8 +159,7 @@ Some simple examples of what MongoEngine code looks like: Tests ===== To run the test suite, ensure you are running a local instance of MongoDB on -the standard port and have ``pytest`` installed. Then, run ``python setup.py test`` -or simply ``pytest``. +the standard port and have ``pytest`` installed. Then, run ``pytest tests/``. To run the test suite on every supported Python and PyMongo version, you can use ``tox``. You'll need to make sure you have each supported Python version @@ -168,15 +172,6 @@ installed in your environment and then: # Run the test suites $ tox -If you wish to run a subset of tests, use the pytest convention: - -.. code-block:: shell - - # Run all the tests in a particular test file - $ pytest tests/fields/test_fields.py - # Run only particular test class in that file - $ pytest tests/fields/test_fields.py::TestField - Community ========= - `MongoEngine Users mailing list @@ -4,7 +4,7 @@ MongoEngine :Info: MongoEngine is an ORM-like layer on top of PyMongo. :Repository: https://github.com/MongoEngine/mongoengine :Author: Harry Marr (http://github.com/hmarr) -:Maintainer: Stefan Wójcik (http://github.com/wojcikstefan) +:Maintainer: Bastien Gerard (http://github.com/bagerard) .. image:: https://travis-ci.org/MongoEngine/mongoengine.svg?branch=master :target: https://travis-ci.org/MongoEngine/mongoengine @@ -21,6 +21,10 @@ MongoEngine .. image:: https://img.shields.io/pypi/v/mongoengine.svg :target: https://pypi.python.org/pypi/mongoengine + +.. image:: https://readthedocs.org/projects/mongoengine-odm/badge/?version=latest + :target: https://readthedocs.org/projects/mongoengine-odm/builds/ + About ===== MongoEngine is a Python Object-Document Mapper for working with MongoDB. @@ -44,7 +48,7 @@ You may also have `setuptools <http://peak.telecommunity.com/DevCenter/setuptool and thus you can use ``easy_install -U mongoengine``. Another option is `pipenv <https://docs.pipenv.org/>`_. You can then use ``pipenv install mongoengine`` to both create the virtual environment and install the package. Otherwise, you can -download the source from `GitHub <http://github.com/MongoEngine/mongoengine>`_ and +download the source from `GitHub <https://github.com/MongoEngine/mongoengine>`_ and run ``python setup.py install``. The support for Python2 was dropped with MongoEngine 0.20.0 @@ -62,7 +66,7 @@ If you utilize a ``DateTimeField``, you might also use a more flexible date pars If you need to use an ``ImageField`` or ``ImageGridFsProxy``: -- Pillow>=2.0.0 +- Pillow>=7.0.0 If you need to use signals: @@ -125,8 +129,7 @@ Some simple examples of what MongoEngine code looks like: Tests ===== To run the test suite, ensure you are running a local instance of MongoDB on -the standard port and have ``pytest`` installed. Then, run ``python setup.py test`` -or simply ``pytest``. +the standard port and have ``pytest`` installed. Then, run ``pytest tests/``. To run the test suite on every supported Python and PyMongo version, you can use ``tox``. You'll need to make sure you have each supported Python version @@ -139,15 +142,6 @@ installed in your environment and then: # Run the test suites $ tox -If you wish to run a subset of tests, use the pytest convention: - -.. code-block:: shell - - # Run all the tests in a particular test file - $ pytest tests/fields/test_fields.py - # Run only particular test class in that file - $ pytest tests/fields/test_fields.py::TestField - Community ========= - `MongoEngine Users mailing list diff --git a/debian/changelog b/debian/changelog index b4536a7..3bf2f72 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +python-mongoengine (0.29.1-1) unstable; urgency=high + + * Team upload + * New upstream release + * Fix autopkgtest + * Require the new pymongo + + -- Salvo 'LtWorf' Tomaselli <ltworf@debian.org> Tue, 15 Oct 2024 01:01:58 +0200 + python-mongoengine (0.28.2-1) unstable; urgency=medium * Team upload diff --git a/debian/control b/debian/control index b1f149a..9762b31 100644 --- a/debian/control +++ b/debian/control @@ -11,7 +11,7 @@ Build-Depends: python3-coverage, python3-gridfs, python3-pillow, - python3-pymongo, + python3-pymongo (>= 4.10.1-2), python3-setuptools, python3-sphinx, python3-sphinx-rtd-theme, @@ -26,7 +26,7 @@ Package: python3-mongoengine Architecture: all Depends: python3-gridfs, - python3-pymongo, + python3-pymongo (>= 4.10.1-2), ${misc:Depends}, ${python3:Depends}, Suggests: diff --git a/debian/tests/test-mongoengine b/debian/tests/test-mongoengine index 7d8f0b7..7d425fa 100644 --- a/debian/tests/test-mongoengine +++ b/debian/tests/test-mongoengine @@ -7,11 +7,12 @@ cd "${AUTOPKGTEST_TMP}" cat <<EOF > test_mongo.py from mongoengine import * import pymongo +import pymongo.database connect('mongo_test') conn = get_connection() -assert isinstance(conn, pymongo.mongo_client.MongoClient) +assert isinstance(conn, pymongo.MongoClient) db = get_db() assert isinstance(db, pymongo.database.Database) diff --git a/docs/Makefile b/docs/Makefile index 301b44f..68149fe 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -16,13 +16,10 @@ ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . help: @echo "Please use \`make <target>' where <target> is one of" + @echo " html-readthedocs to simulate an html-build for readthedocs" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" - @echo " pickle to make pickle files" - @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" @@ -40,47 +37,20 @@ html: html-readthedocs: $(SPHINXBUILD) -T -E -b readthedocs $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - + @echo "Open in browser: file://`realpath $(BUILDDIR)/html/index.html`" dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/MongoEngine.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/MongoEngine.qhc" - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ - "run these through (pdf)latex." - changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo diff --git a/docs/apireference.rst b/docs/apireference.rst index dbcb3b8..5cc8a29 100644 --- a/docs/apireference.rst +++ b/docs/apireference.rst @@ -80,6 +80,7 @@ Fields .. autoclass:: mongoengine.fields.LongField .. autoclass:: mongoengine.fields.FloatField .. autoclass:: mongoengine.fields.DecimalField +.. autoclass:: mongoengine.fields.Decimal128Field .. autoclass:: mongoengine.fields.BooleanField .. autoclass:: mongoengine.fields.DateTimeField .. autoclass:: mongoengine.fields.ComplexDateTimeField diff --git a/docs/changelog.rst b/docs/changelog.rst index 81a0ce6..0f5ce06 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -8,6 +8,26 @@ Development =========== - (Fill this out as you fix issues and develop your features). + +Changes in 0.29.1 +================= +- Add support for freshly released pymongo 4.9 #2849 + +Changes in 0.29.0 +================= +- Fix weakref in EmbeddedDocumentListField (causing brief mem leak in certain circumstances) #2827 +- Fix pillow deprecation warning related with LANCZOS filter #2824 +- Allow gt/gte/lt/lte/ne operators to be used with a list as value on ListField #2813 +- Switch tox to use pytest instead of legacy `python setup.py test` #2804 +- Add support for timeseries collection #2661 +- Add support in tests for MongoDB 7.0, pymongo 4.7 and pymongo 4.8 in the CI #2826 +- Add support for `array_filters` in Queryset.modify #2811 +- Integrate a docker-compose setup for local testing #2555 +- improve ReferenceField wrong usage detection +- Fix no_dereference thread-safetyness #2830 +- BREAKING CHANGE: max_length in ListField is now keyword only on ListField signature +- BREAKING CHANGE: Force `field` argument of ListField/DictField to be a field instance (e.g ListField(StringField()) instead of ListField(StringField) + Changes in 0.28.2 ================= - Fix typing import incompatible with Pymongo 3.7 #2802 diff --git a/docs/django.rst b/docs/django.rst index d43a205..b9986f8 100644 --- a/docs/django.rst +++ b/docs/django.rst @@ -3,17 +3,4 @@ Django Support ============== .. note:: Django support has been split from the main MongoEngine - repository. The *legacy* Django extension may be found bundled with the - 0.9 release of MongoEngine. - - - -Help Wanted! ------------- - -The MongoEngine team is looking for help contributing and maintaining a new -Django extension for MongoEngine! If you have Django experience and would like -to help contribute to the project, please get in touch on the -`mailing list <http://groups.google.com/group/mongoengine-users>`_ or by -simply contributing on -`GitHub <https://github.com/MongoEngine/django-mongoengine>`_. + repository. diff --git a/docs/faq.rst b/docs/faq.rst index 49c7302..1c05df7 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -8,5 +8,5 @@ Does MongoEngine support asynchronous drivers (Motor, TxMongo)? No, MongoEngine is exclusively based on PyMongo and isn't designed to support other driver. If this is a requirement for your project, check the alternative: `uMongo`_ and `MotorEngine`_. -.. _uMongo: https://umongo.readthedocs.io/ -.. _MotorEngine: https://motorengine.readthedocs.io/ +.. _uMongo: https://umongo.readthedocs.io/en/latest/ +.. _MotorEngine: https://motorengine.readthedocs.io/en/latest/ diff --git a/docs/guide/connecting.rst b/docs/guide/connecting.rst index 2cbdb44..78d59f8 100644 --- a/docs/guide/connecting.rst +++ b/docs/guide/connecting.rst @@ -47,7 +47,7 @@ of the MongoDB connection string is for:: connect(host="mongodb://my_user:my_password@127.0.0.1:27017/my_db?authSource=my_db") The URI string can also be used to configure advanced parameters like ssl, replicaSet, etc. For more -information or example about URI string, you can refer to the `official doc <https://docs.mongodb.com/manual/reference/connection-string/>`_:: +information or example about URI string, you can refer to the `official doc <https://www.mongodb.com/docs/manual/reference/connection-string/>`_:: connect(host="mongodb://my_user:my_password@127.0.0.1:27017/my_db?authSource=admin&ssl=true&replicaSet=globaldb") diff --git a/docs/guide/defining-documents.rst b/docs/guide/defining-documents.rst index df749ee..cc59a8c 100644 --- a/docs/guide/defining-documents.rst +++ b/docs/guide/defining-documents.rst @@ -29,7 +29,7 @@ documents are serialized based on their field order. .. _dynamic-document-schemas: -Dynamic document schemas +Dynamic Document Schemas ======================== One of the benefits of MongoDB is dynamic schemas for a collection, whilst data should be planned and organised (after all explicit is better than implicit!) @@ -260,7 +260,7 @@ document class as the first argument:: comment2 = Comment(content='Nice article!') page = Page(comments=[comment1, comment2]) -Embedded documents can also leverage the flexibility of :ref:`dynamic-document-schemas:` +Embedded documents can also leverage the flexibility of :ref:`dynamic-document-schemas` by inheriting :class:`~mongoengine.DynamicEmbeddedDocument`. Dictionary Fields @@ -325,7 +325,7 @@ as the constructor's argument:: .. _many-to-many-with-listfields: Many to Many with ListFields -''''''''''''''''''''''''''' +'''''''''''''''''''''''''''' If you are implementing a many to many relationship via a list of references, then the references are stored as DBRefs and to query you need to pass an @@ -491,6 +491,26 @@ The following example shows a :class:`Log` document that will be limited to ip_address = StringField() meta = {'max_documents': 1000, 'max_size': 2000000} +Timeseries collections +---------------------- +A :class:`~mongoengine.Document` may use a **Timeseries Collection** by specifying +:attr:`timeseries` in the :attr:`meta` dictionary. Timeseries collection were added +in MongoDB 5.0 (`doc <https://www.mongodb.com/docs/v5.3/core/timeseries-collections/>`_). +The following example shows a Document class with a basic setup:: + + class SensorData(Document): + timestamp = DateTimeField(required=True) + temperature = FloatField() + + meta = { + "timeseries": { + "timeField": "timestamp", + "metaField": "temperature", + "granularity": "seconds", + "expireAfterSeconds": 5, + }, + } + .. defining-indexes_ Indexes @@ -579,7 +599,7 @@ There are a few top level defaults for all indexes that can be set:: :attr:`index_opts` (Optional) - Set any default index options - see the `full options list <https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/#db.collection.createIndex>`_ + Set any default index options - see the `full options list <https://www.mongodb.com/docs/manual/reference/method/db.collection.createIndex/>`_ :attr:`index_background` (Optional) Set the default value for if an index should be indexed in the background diff --git a/docs/guide/gridfs.rst b/docs/guide/gridfs.rst index e6c097f..4d1b483 100644 --- a/docs/guide/gridfs.rst +++ b/docs/guide/gridfs.rst @@ -9,7 +9,7 @@ GridFS support comes in the form of the :class:`~mongoengine.fields.FileField` f object. This field acts as a file-like object and provides a couple of different ways of inserting and retrieving data. Arbitrary metadata such as content type can also be stored alongside the files. The object returned when accessing a -FileField is a proxy to `Pymongo's GridFS <https://api.mongodb.com/python/current/examples/gridfs.html#gridfs-example>`_ +FileField is a proxy to `Pymongo's GridFS <https://pymongo.readthedocs.io/en/stable/examples/gridfs.html#gridfs-example>`_ In the following example, a document is created to store details about animals, including a photo:: class Animal(Document): diff --git a/docs/guide/installing.rst b/docs/guide/installing.rst index 2c962ad..efdb46f 100644 --- a/docs/guide/installing.rst +++ b/docs/guide/installing.rst @@ -2,7 +2,7 @@ Installing MongoEngine ====================== -To use MongoEngine, you will need to download `MongoDB <http://mongodb.com/>`_ +To use MongoEngine, you will need to download `MongoDB <https://www.mongodb.com/>`_ and ensure it is running in an accessible location. You will also need `PyMongo <http://api.mongodb.org/python>`_ to use MongoEngine, but if you install MongoEngine using setuptools, then the dependencies will be handled for @@ -22,7 +22,7 @@ Alternatively, if you don't have setuptools installed, `download it from PyPi $ python setup.py install To use the bleeding-edge version of MongoEngine, you can get the source from -`GitHub <http://github.com/mongoengine/mongoengine/>`_ and install it as above: +`GitHub <https://github.com/MongoEngine/mongoengine/>`_ and install it as above: .. code-block:: console diff --git a/docs/guide/migration.rst b/docs/guide/migration.rst index ed982ef..116910e 100644 --- a/docs/guide/migration.rst +++ b/docs/guide/migration.rst @@ -262,7 +262,7 @@ If you would remove the 'name' field or its index, you would have to call: User._get_collection().drop_index('name_1') .. note:: When adding new fields or new indexes, MongoEngine will take care of creating them - (unless `auto_create_index` is disabled) :: + (unless `auto_create_index` is disabled) Recommendations =============== diff --git a/docs/guide/mongomock.rst b/docs/guide/mongomock.rst index d923205..024fda1 100644 --- a/docs/guide/mongomock.rst +++ b/docs/guide/mongomock.rst @@ -5,7 +5,7 @@ Use mongomock for testing Although we recommend running your tests against a regular MongoDB server, it is sometimes useful to plug MongoEngine to alternative implementations (mongomock, montydb, mongita, etc). -`mongomock <https://github.com/vmalloc/mongomock/>`_ is historically the one suggested for MongoEngine and is +`mongomock <https://github.com/mongomock/mongomock>`_ is historically the one suggested for MongoEngine and is a package to do just what the name implies, mocking a mongo database. To use with mongoengine, simply specify mongomock when connecting with diff --git a/docs/guide/querying.rst b/docs/guide/querying.rst index d5ac70b..d347806 100644 --- a/docs/guide/querying.rst +++ b/docs/guide/querying.rst @@ -241,7 +241,7 @@ Update with Aggregation Pipeline It is possible to provide a raw :mod:`PyMongo` aggregation update parameter, which will be integrated directly into the update. This is done by using ``__raw__`` keyword argument to the update method and provide the pipeline as a list -`Update with Aggregation Pipeline <https://docs.mongodb.com/manual/reference/method/db.collection.updateMany/#update-with-aggregation->`_ +`Update with Aggregation Pipeline <https://www.mongodb.com/docs/manual/reference/method/db.collection.updateMany/#update-with-aggregation->`_ :: # 'tags' field is set to 'coding is fun' @@ -257,7 +257,7 @@ Update with Array Operator It is possible to update specific value in array by use array_filters (arrayFilters) operator. This is done by using ``__raw__`` keyword argument to the update method and provide the arrayFilters as a list. -`Update with Array Operator <https://www.mongodb.com/docs/manual/reference/operator/update/positional-filtered->`_ +`Update with Array Operator <https://www.mongodb.com/docs/manual/reference/operator/update/positional-filtered/>`_ :: # assuming an initial 'tags' field == ['test1', 'test2', 'test3'] @@ -447,7 +447,7 @@ would be generating "tag-clouds":: MongoDB aggregation API ----------------------- -If you need to run aggregation pipelines, MongoEngine provides an entry point to `Pymongo's aggregation framework <https://api.mongodb.com/python/current/examples/aggregation.html#aggregation-framework>`_ +If you need to run aggregation pipelines, MongoEngine provides an entry point to `Pymongo's aggregation framework <https://pymongo.readthedocs.io/en/stable/examples/aggregation.html#aggregation-framework>`_ through :meth:`~mongoengine.queryset.QuerySet.aggregate`. Check out Pymongo's documentation for the syntax and pipeline. An example of its use would be:: @@ -661,7 +661,7 @@ to push values with index:: .. note:: Currently only top level lists are handled, future versions of mongodb / pymongo plan to support nested positional operators. See `The $ positional - operator <https://docs.mongodb.com/manual/tutorial/update-documents/#Updating-The%24positionaloperator>`_. + operator <https://www.mongodb.com/docs/manual/tutorial/update-documents/#Updating-The%24positionaloperator>`_. Server-side javascript execution ================================ diff --git a/docs/index.rst b/docs/index.rst index a42ff85..e550760 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -20,9 +20,6 @@ MongoDB. To install it, simply run :doc:`apireference` The complete API documentation --- the innards of documents, querysets and fields. -:doc:`upgrade` - How to upgrade MongoEngine. - :doc:`faq` Frequently Asked Questions @@ -33,7 +30,7 @@ MongoDB and driver support -------------------------- MongoEngine is based on the PyMongo driver and tested against multiple versions of MongoDB. -For further details, please refer to the `readme <https://github.com/MongoEngine/mongoengine#mongoengine>`_. +For further details, please refer to the `readme <https://github.com/MongoEngine/mongoengine>`_. Community --------- @@ -47,22 +44,18 @@ Contributing **Yes please!** We are always looking for contributions, additions and improvements. -The source is available on `GitHub <http://github.com/MongoEngine/mongoengine>`_ +The source is available on `GitHub <https://github.com/MongoEngine/mongoengine>`_ and contributions are always encouraged. Contributions can be as simple as minor tweaks to this documentation, the website or the core. To contribute, fork the project on -`GitHub <http://github.com/MongoEngine/mongoengine>`_ and send a +`GitHub <https://github.com/MongoEngine/mongoengine>`_ and send a pull request. Changes ------- -See the :doc:`changelog` for a full list of changes to MongoEngine and -:doc:`upgrade` for upgrade information. - -.. note:: Always read and test the `upgrade <upgrade>`_ documentation before - putting updates live in production **;)** +See the :doc:`changelog` for a full list of changes to MongoEngine. Offline Reading --------------- @@ -81,7 +74,6 @@ formats for offline reading. guide/index apireference changelog - upgrade faq django diff --git a/docs/requirements.txt b/docs/requirements.txt index 4ecb012..4d4be82 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,5 +1,5 @@ -Sphinx==3.3.0 -sphinx-rtd-theme==0.5.0 -readthedocs-sphinx-ext==2.1.1 -docutils==0.17.1 -Jinja2<3.1 +Sphinx==7.4.7 +sphinx-rtd-theme==2.1.0rc2 +readthedocs-sphinx-ext==2.2.5 +docutils==0.20.1 +Jinja2==3.1.4 diff --git a/mongoengine.egg-info/PKG-INFO b/mongoengine.egg-info/PKG-INFO index b83bf81..3daf721 100644 --- a/mongoengine.egg-info/PKG-INFO +++ b/mongoengine.egg-info/PKG-INFO @@ -1,12 +1,12 @@ Metadata-Version: 2.1 Name: mongoengine -Version: 0.28.2 +Version: 0.29.1 Summary: MongoEngine is a Python Object-Document Mapper for working with MongoDB. Home-page: http://mongoengine.org/ Author: Harry Marr Author-email: harry.marr@gmail.com -Maintainer: Stefan Wojcik -Maintainer-email: wojcikstefan@gmail.com +Maintainer: Bastien Gerard +Maintainer-email: bast.gerard@gmail.com License: MIT Download-URL: https://github.com/MongoEngine/mongoengine/tarball/master Platform: any @@ -24,6 +24,7 @@ Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Database Classifier: Topic :: Software Development :: Libraries :: Python Modules Requires-Python: >=3.7 +Provides-Extra: test License-File: LICENSE License-File: AUTHORS @@ -33,7 +34,7 @@ MongoEngine :Info: MongoEngine is an ORM-like layer on top of PyMongo. :Repository: https://github.com/MongoEngine/mongoengine :Author: Harry Marr (http://github.com/hmarr) -:Maintainer: Stefan Wójcik (http://github.com/wojcikstefan) +:Maintainer: Bastien Gerard (http://github.com/bagerard) .. image:: https://travis-ci.org/MongoEngine/mongoengine.svg?branch=master :target: https://travis-ci.org/MongoEngine/mongoengine @@ -50,6 +51,10 @@ MongoEngine .. image:: https://img.shields.io/pypi/v/mongoengine.svg :target: https://pypi.python.org/pypi/mongoengine + +.. image:: https://readthedocs.org/projects/mongoengine-odm/badge/?version=latest + :target: https://readthedocs.org/projects/mongoengine-odm/builds/ + About ===== MongoEngine is a Python Object-Document Mapper for working with MongoDB. @@ -73,7 +78,7 @@ You may also have `setuptools <http://peak.telecommunity.com/DevCenter/setuptool and thus you can use ``easy_install -U mongoengine``. Another option is `pipenv <https://docs.pipenv.org/>`_. You can then use ``pipenv install mongoengine`` to both create the virtual environment and install the package. Otherwise, you can -download the source from `GitHub <http://github.com/MongoEngine/mongoengine>`_ and +download the source from `GitHub <https://github.com/MongoEngine/mongoengine>`_ and run ``python setup.py install``. The support for Python2 was dropped with MongoEngine 0.20.0 @@ -91,7 +96,7 @@ If you utilize a ``DateTimeField``, you might also use a more flexible date pars If you need to use an ``ImageField`` or ``ImageGridFsProxy``: -- Pillow>=2.0.0 +- Pillow>=7.0.0 If you need to use signals: @@ -154,8 +159,7 @@ Some simple examples of what MongoEngine code looks like: Tests ===== To run the test suite, ensure you are running a local instance of MongoDB on -the standard port and have ``pytest`` installed. Then, run ``python setup.py test`` -or simply ``pytest``. +the standard port and have ``pytest`` installed. Then, run ``pytest tests/``. To run the test suite on every supported Python and PyMongo version, you can use ``tox``. You'll need to make sure you have each supported Python version @@ -168,15 +172,6 @@ installed in your environment and then: # Run the test suites $ tox -If you wish to run a subset of tests, use the pytest convention: - -.. code-block:: shell - - # Run all the tests in a particular test file - $ pytest tests/fields/test_fields.py - # Run only particular test class in that file - $ pytest tests/fields/test_fields.py::TestField - Community ========= - `MongoEngine Users mailing list diff --git a/mongoengine.egg-info/requires.txt b/mongoengine.egg-info/requires.txt index dd5d096..49dbae9 100644 --- a/mongoengine.egg-info/requires.txt +++ b/mongoengine.egg-info/requires.txt @@ -1 +1,8 @@ pymongo<5.0,>=3.4 + +[test] +pytest +pytest-cov +coverage +blinker +Pillow>=7.0.0 diff --git a/mongoengine/__init__.py b/mongoengine/__init__.py index 799dad6..f74e30a 100644 --- a/mongoengine/__init__.py +++ b/mongoengine/__init__.py @@ -29,7 +29,7 @@ __all__ = ( ) -VERSION = (0, 28, 2) +VERSION = (0, 29, 1) def get_version(): diff --git a/mongoengine/base/datastructures.py b/mongoengine/base/datastructures.py index a3561b8..a175cd1 100644 --- a/mongoengine/base/datastructures.py +++ b/mongoengine/base/datastructures.py @@ -113,7 +113,11 @@ class BaseList(list): BaseDocument = _import_class("BaseDocument") if isinstance(instance, BaseDocument): - self._instance = weakref.proxy(instance) + if isinstance(instance, weakref.ProxyTypes): + self._instance = instance + else: + self._instance = weakref.proxy(instance) + self._name = name super().__init__(list_items) @@ -186,10 +190,6 @@ class BaseList(list): class EmbeddedDocumentList(BaseList): - def __init__(self, list_items, instance, name): - super().__init__(list_items, instance, name) - self._instance = instance - @classmethod def __match_all(cls, embedded_doc, kwargs): """Return True if a given embedded doc matches all the filter diff --git a/mongoengine/base/document.py b/mongoengine/base/document.py index 194b24e..379f5e8 100644 --- a/mongoengine/base/document.py +++ b/mongoengine/base/document.py @@ -202,6 +202,8 @@ class BaseDocument: and self__created and name == self._meta.get("id_field") ): + # When setting the ID field of an instance already instantiated and that was user-created (i.e not saved in db yet) + # Typically this is when calling .save() super().__setattr__("_created", False) super().__setattr__(name, value) @@ -459,13 +461,13 @@ class BaseDocument: @classmethod def from_json(cls, json_data, created=False, **kwargs): - """Converts json data to a Document instance + """Converts json data to a Document instance. - :param str json_data: The json data to load into the Document + :param str json_data: The json data to load into the Document. :param bool created: Boolean defining whether to consider the newly instantiated document as brand new or as persisted already: * If True, consider the document as brand new, no matter what data - it's loaded with (i.e. even if an ID is loaded). + it's loaded with (i.e., even if an ID is loaded). * If False and an ID is NOT provided, consider the document as brand new. * If False and an ID is provided, assume that the object has @@ -804,10 +806,15 @@ class BaseDocument: fields = cls._fields if not _auto_dereference: + # if auto_deref is turned off, we copy the fields so + # we can mutate the auto_dereference of the fields fields = copy.deepcopy(fields) + # Apply field-name / db-field conversion for field_name, field in fields.items(): - field._auto_dereference = _auto_dereference + field.set_auto_dereferencing( + _auto_dereference + ) # align the field's auto-dereferencing with the document's if field.db_field in data: value = data[field.db_field] try: diff --git a/mongoengine/base/fields.py b/mongoengine/base/fields.py index 037e916..cead144 100644 --- a/mongoengine/base/fields.py +++ b/mongoengine/base/fields.py @@ -1,4 +1,6 @@ +import contextlib import operator +import threading import weakref import pymongo @@ -16,6 +18,19 @@ from mongoengine.errors import DeprecatedError, ValidationError __all__ = ("BaseField", "ComplexBaseField", "ObjectIdField", "GeoJsonBaseField") +@contextlib.contextmanager +def _no_dereference_for_fields(*fields): + """Context manager for temporarily disabling a Field's auto-dereferencing + (meant to be used from no_dereference context manager)""" + try: + for field in fields: + field._incr_no_dereference_context() + yield None + finally: + for field in fields: + field._decr_no_dereference_context() + + class BaseField: """A base class for fields in a MongoDB document. Instances of this class may be added to subclasses of `Document` to define a document's schema. @@ -24,7 +39,7 @@ class BaseField: name = None # set in TopLevelDocumentMetaclass _geo_index = False _auto_gen = False # Call `generate` to generate a value - _auto_dereference = True + _thread_local_storage = threading.local() # These track each time a Field instance is created. Used to retain order. # The auto_creation_counter is used for fields that MongoEngine implicitly @@ -85,6 +100,8 @@ class BaseField: self.sparse = sparse self._owner_document = None + self.__auto_dereference = True + # Make sure db_field is a string (if it's explicitly defined). if self.db_field is not None and not isinstance(self.db_field, str): raise TypeError("db_field should be a string.") @@ -120,6 +137,33 @@ class BaseField: self.creation_counter = BaseField.creation_counter BaseField.creation_counter += 1 + def set_auto_dereferencing(self, value): + self.__auto_dereference = value + + @property + def _no_dereference_context_local(self): + if not hasattr(self._thread_local_storage, "no_dereference_context"): + self._thread_local_storage.no_dereference_context = 0 + return self._thread_local_storage.no_dereference_context + + @property + def _no_dereference_context_is_set(self): + return self._no_dereference_context_local > 0 + + def _incr_no_dereference_context(self): + self._thread_local_storage.no_dereference_context = ( + self._no_dereference_context_local + 1 + ) + + def _decr_no_dereference_context(self): + self._thread_local_storage.no_dereference_context = ( + self._no_dereference_context_local - 1 + ) + + @property + def _auto_dereference(self): + return self.__auto_dereference and not self._no_dereference_context_is_set + def __get__(self, instance, owner): """Descriptor for retrieving a value from a field in a document.""" if instance is None: @@ -268,6 +312,10 @@ class ComplexBaseField(BaseField): """ def __init__(self, field=None, **kwargs): + if field is not None and not isinstance(field, BaseField): + raise TypeError( + f"field argument must be a Field instance (e.g {self.__class__.__name__}(StringField()))" + ) self.field = field super().__init__(**kwargs) @@ -375,7 +423,7 @@ class ComplexBaseField(BaseField): return value if self.field: - self.field._auto_dereference = self._auto_dereference + self.field.set_auto_dereferencing(self._auto_dereference) value_dict = { key: self.field.to_python(item) for key, item in value.items() } diff --git a/mongoengine/connection.py b/mongoengine/connection.py index 42a7943..2f07b83 100644 --- a/mongoengine/connection.py +++ b/mongoengine/connection.py @@ -2,7 +2,11 @@ import warnings from pymongo import MongoClient, ReadPreference, uri_parser from pymongo.common import _UUID_REPRESENTATIONS -from pymongo.database import _check_name + +try: + from pymongo.database_shared import _check_name +except ImportError: + from pymongo.database import _check_name # DriverInfo was added in PyMongo 3.7. try: diff --git a/mongoengine/context_managers.py b/mongoengine/context_managers.py index f16753e..6b987dd 100644 --- a/mongoengine/context_managers.py +++ b/mongoengine/context_managers.py @@ -1,9 +1,11 @@ +import contextlib import threading from contextlib import contextmanager from pymongo.read_concern import ReadConcern from pymongo.write_concern import WriteConcern +from mongoengine.base.fields import _no_dereference_for_fields from mongoengine.common import _import_class from mongoengine.connection import DEFAULT_CONNECTION_NAME, get_db from mongoengine.pymongo_support import count_documents @@ -22,6 +24,7 @@ __all__ = ( class MyThreadLocals(threading.local): def __init__(self): + # {DocCls: count} keeping track of classes with an active no_dereference context self.no_dereferencing_class = {} @@ -126,46 +129,37 @@ class switch_collection: self.cls._get_collection_name = self.ori_get_collection_name -class no_dereference: +@contextlib.contextmanager +def no_dereference(cls): """no_dereference context manager. Turns off all dereferencing in Documents for the duration of the context manager:: with no_dereference(Group): - Group.objects.find() + Group.objects() """ - - def __init__(self, cls): - """Construct the no_dereference context manager. - - :param cls: the class to turn dereferencing off on - """ - self.cls = cls + try: + cls = cls ReferenceField = _import_class("ReferenceField") GenericReferenceField = _import_class("GenericReferenceField") ComplexBaseField = _import_class("ComplexBaseField") - self.deref_fields = [ - k - for k, v in self.cls._fields.items() - if isinstance(v, (ReferenceField, GenericReferenceField, ComplexBaseField)) + deref_fields = [ + field + for name, field in cls._fields.items() + if isinstance( + field, (ReferenceField, GenericReferenceField, ComplexBaseField) + ) ] - def __enter__(self): - """Change the objects default and _auto_dereference values.""" - _register_no_dereferencing_for_class(self.cls) - - for field in self.deref_fields: - self.cls._fields[field]._auto_dereference = False - - def __exit__(self, t, value, traceback): - """Reset the default and _auto_dereference values.""" - _unregister_no_dereferencing_for_class(self.cls) + _register_no_dereferencing_for_class(cls) - for field in self.deref_fields: - self.cls._fields[field]._auto_dereference = True + with _no_dereference_for_fields(*deref_fields): + yield None + finally: + _unregister_no_dereferencing_for_class(cls) class no_sub_classes: @@ -180,7 +174,7 @@ class no_sub_classes: def __init__(self, cls): """Construct the no_sub_classes context manager. - :param cls: the class to turn querying sub classes on + :param cls: the class to turn querying subclasses on """ self.cls = cls self.cls_initial_subclasses = None @@ -221,7 +215,7 @@ class query_counter: Be aware that: - - Iterating over large amount of documents (>101) makes pymongo issue `getmore` queries to fetch the next batch of documents (https://docs.mongodb.com/manual/tutorial/iterate-a-cursor/#cursor-batches) + - Iterating over large amount of documents (>101) makes pymongo issue `getmore` queries to fetch the next batch of documents (https://www.mongodb.com/docs/manual/tutorial/iterate-a-cursor/#cursor-batches) - Some queries are ignored by default by the counter (killcursors, db.system.indexes) """ diff --git a/mongoengine/document.py b/mongoengine/document.py index 3fddec3..ad166c9 100644 --- a/mongoengine/document.py +++ b/mongoengine/document.py @@ -220,6 +220,8 @@ class Document(BaseDocument, metaclass=TopLevelDocumentMetaclass): # Get the collection, either capped or regular. if cls._meta.get("max_size") or cls._meta.get("max_documents"): cls._collection = cls._get_capped_collection() + elif cls._meta.get("timeseries"): + cls._collection = cls._get_timeseries_collection() else: db = cls._get_db() collection_name = cls._get_collection_name() @@ -271,6 +273,27 @@ class Document(BaseDocument, metaclass=TopLevelDocumentMetaclass): return db.create_collection(collection_name, **opts) + @classmethod + def _get_timeseries_collection(cls): + """Create a new or get an existing timeseries PyMongo collection.""" + db = cls._get_db() + collection_name = cls._get_collection_name() + timeseries_opts = cls._meta.get("timeseries") + + if collection_name in list_collection_names( + db, include_system_collections=True + ): + collection = db[collection_name] + collection.options() + return collection + + opts = {"expireAfterSeconds": timeseries_opts.pop("expireAfterSeconds", None)} + return db.create_collection( + name=collection_name, + timeseries=timeseries_opts, + **opts, + ) + def to_mongo(self, *args, **kwargs): data = super().to_mongo(*args, **kwargs) diff --git a/mongoengine/fields.py b/mongoengine/fields.py index 40469bf..a5ebba2 100644 --- a/mongoengine/fields.py +++ b/mongoengine/fields.py @@ -6,6 +6,7 @@ import re import socket import time import uuid +from inspect import isclass from io import BytesIO from operator import itemgetter @@ -48,8 +49,12 @@ from mongoengine.queryset.transform import STRING_OPERATORS try: from PIL import Image, ImageOps - LANCZOS = Image.LANCZOS if hasattr(Image, "LANCZOS") else Image.ANTIALIAS + if hasattr(Image, "Resampling"): + LANCZOS = Image.Resampling.LANCZOS + else: + LANCZOS = Image.LANCZOS except ImportError: + # pillow is optional so may not be installed Image = None ImageOps = None @@ -707,7 +712,6 @@ class EmbeddedDocumentField(BaseField): """ def __init__(self, document_type, **kwargs): - # XXX ValidationError raised outside of the "validate" method. if not ( isinstance(document_type, str) or issubclass(document_type, EmbeddedDocument) @@ -910,9 +914,9 @@ class ListField(ComplexBaseField): Required means it cannot be empty - as the default for ListFields is [] """ - def __init__(self, field=None, max_length=None, **kwargs): + def __init__(self, field=None, *, max_length=None, **kwargs): self.max_length = max_length - kwargs.setdefault("default", lambda: []) + kwargs.setdefault("default", list) super().__init__(field=field, **kwargs) def __get__(self, instance, owner): @@ -951,11 +955,11 @@ class ListField(ComplexBaseField): if self.field: # If the value is iterable and it's not a string nor a # BaseDocument, call prepare_query_value for each of its items. + is_iter = hasattr(value, "__iter__") + eligible_iter = is_iter and not isinstance(value, (str, BaseDocument)) if ( - op in ("set", "unset", None) - and hasattr(value, "__iter__") - and not isinstance(value, str) - and not isinstance(value, BaseDocument) + op in ("set", "unset", "gt", "gte", "lt", "lte", "ne", None) + and eligible_iter ): return [self.field.prepare_query_value(op, v) for v in value] @@ -1035,10 +1039,9 @@ class DictField(ComplexBaseField): """ def __init__(self, field=None, *args, **kwargs): - self._auto_dereference = False - - kwargs.setdefault("default", lambda: {}) + kwargs.setdefault("default", dict) super().__init__(*args, field=field, **kwargs) + self.set_auto_dereferencing(False) def validate(self, value): """Make sure that a list of valid fields is being used.""" @@ -1151,8 +1154,9 @@ class ReferenceField(BaseField): :class:`~pymongo.dbref.DBRef`, regardless of the value of `dbref`. """ # XXX ValidationError raised outside of the "validate" method. - if not isinstance(document_type, str) and not issubclass( - document_type, Document + if not ( + isinstance(document_type, str) + or (isclass(document_type) and issubclass(document_type, Document)) ): self.error( "Argument to ReferenceField constructor must be a " @@ -2065,7 +2069,7 @@ class ImageField(FileField): class SequenceField(BaseField): """Provides a sequential counter see: - https://docs.mongodb.com/manual/reference/method/ObjectId/#ObjectIDs-SequenceNumbers + https://www.mongodb.com/docs/manual/reference/method/ObjectId/#ObjectIDs-SequenceNumbers .. note:: diff --git a/mongoengine/mongodb_support.py b/mongoengine/mongodb_support.py index 23c538d..f15a72c 100644 --- a/mongoengine/mongodb_support.py +++ b/mongoengine/mongodb_support.py @@ -1,6 +1,7 @@ """ Helper functions, constants, and types to aid with MongoDB version support """ + from mongoengine.connection import get_connection # Constant that can be used to compare the version retrieved with diff --git a/mongoengine/pymongo_support.py b/mongoengine/pymongo_support.py index 7aa5567..674a9b6 100644 --- a/mongoengine/pymongo_support.py +++ b/mongoengine/pymongo_support.py @@ -1,6 +1,7 @@ """ Helper functions, constants, and types to aid with PyMongo support. """ + import pymongo from bson import binary, json_util from pymongo.errors import OperationFailure diff --git a/mongoengine/queryset/base.py b/mongoengine/queryset/base.py index 3ce3cb3..068374f 100644 --- a/mongoengine/queryset/base.py +++ b/mongoengine/queryset/base.py @@ -405,7 +405,7 @@ class BaseQuerySet: getting the count """ # mimic the fact that setting .limit(0) in pymongo sets no limit - # https://docs.mongodb.com/manual/reference/method/cursor.limit/#zero-value + # https://www.mongodb.com/docs/manual/reference/method/cursor.limit/#zero-value if ( self._limit == 0 and with_limit_and_skip is False @@ -634,7 +634,14 @@ class BaseQuerySet: document = self._document.objects.with_id(atomic_update.upserted_id) return document - def update_one(self, upsert=False, write_concern=None, full_result=False, **update): + def update_one( + self, + upsert=False, + write_concern=None, + full_result=False, + array_filters=None, + **update, + ): """Perform an atomic update on the fields of the first document matched by the query. @@ -647,6 +654,7 @@ class BaseQuerySet: will force an fsync on the primary server. :param full_result: Return the associated ``pymongo.UpdateResult`` rather than just the number updated items + :param array_filters: A list of filters specifying which array elements an update should apply. :param update: Django-style update keyword arguments full_result :returns the number of updated documents (unless ``full_result`` is True) @@ -656,11 +664,18 @@ class BaseQuerySet: multi=False, write_concern=write_concern, full_result=full_result, + array_filters=array_filters, **update, ) def modify( - self, upsert=False, full_response=False, remove=False, new=False, **update + self, + upsert=False, + full_response=False, + remove=False, + new=False, + array_filters=None, + **update, ): """Update and return the updated document. @@ -680,6 +695,7 @@ class BaseQuerySet: :param remove: remove rather than updating (default ``False``) :param new: return updated rather than original document (default ``False``) + :param array_filters: A list of filters specifying which array elements an update should apply. :param update: Django-style update keyword arguments """ @@ -717,6 +733,7 @@ class BaseQuerySet: upsert=upsert, sort=sort, return_document=return_doc, + array_filters=array_filters, **self._cursor_args, ) except pymongo.errors.DuplicateKeyError as err: @@ -946,7 +963,7 @@ class BaseQuerySet: """Limit the number of documents returned in a single batch (each batch requires a round trip to the server). - See http://api.mongodb.com/python/current/api/pymongo/cursor.html#pymongo.cursor.Cursor.batch_size + See https://pymongo.readthedocs.io/en/stable/api/pymongo/cursor.html#pymongo.cursor.Cursor for details. :param size: desired size of each batch. @@ -1180,7 +1197,7 @@ class BaseQuerySet: def comment(self, text): """Add a comment to the query. - See https://docs.mongodb.com/manual/reference/method/cursor.comment/#cursor.comment + See https://www.mongodb.com/docs/manual/reference/method/cursor.comment/ for details. """ return self._chainable_method("comment", text) @@ -1324,7 +1341,7 @@ class BaseQuerySet: :param suppl_pipeline: unpacked list of pipeline (added to support deprecation of the old interface) parameter will be removed shortly :param kwargs: (optional) kwargs dictionary to be passed to pymongo's aggregate call - See https://api.mongodb.com/python/current/api/pymongo/collection.html#pymongo.collection.Collection.aggregate + See https://pymongo.readthedocs.io/en/stable/api/pymongo/collection.html#pymongo.collection.Collection.aggregate """ using_deprecated_interface = isinstance(pipeline, dict) or bool(suppl_pipeline) user_pipeline = [pipeline] if isinstance(pipeline, dict) else list(pipeline) @@ -1347,7 +1364,7 @@ class BaseQuerySet: initial_pipeline.append({"$sort": dict(self._ordering)}) if self._limit is not None: - # As per MongoDB Documentation (https://docs.mongodb.com/manual/reference/operator/aggregation/limit/), + # As per MongoDB Documentation (https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit/), # keeping limit stage right after sort stage is more efficient. But this leads to wrong set of documents # for a skip stage that might succeed these. So we need to maintain more documents in memory in such a # case (https://stackoverflow.com/a/24161461). @@ -1384,7 +1401,7 @@ class BaseQuerySet: :class:`~bson.code.Code` or string :param output: output collection name, if set to 'inline' will return the results inline. This can also be a dictionary containing output options - see: http://docs.mongodb.org/manual/reference/command/mapReduce/#dbcmd.mapReduce + see: https://www.mongodb.com/docs/manual/reference/command/mapReduce/#mongodb-dbcommand-dbcmd.mapReduce :param finalize_f: finalize function, an optional function that performs any post-reduction processing. :param scope: values to insert into map/reduce global scope. Optional. diff --git a/mongoengine/signals.py b/mongoengine/signals.py index 582b533..940209a 100644 --- a/mongoengine/signals.py +++ b/mongoengine/signals.py @@ -38,9 +38,9 @@ except ImportError: ) send = lambda *a, **kw: None # noqa - connect = ( - disconnect - ) = has_receivers_for = receivers_for = temporarily_connected_to = _fail + connect = disconnect = has_receivers_for = receivers_for = ( + temporarily_connected_to + ) = _fail del _fail @@ -1,15 +1,6 @@ import os -import sys -from pkg_resources import normalize_path from setuptools import find_packages, setup -from setuptools.command.test import test as TestCommand - -# Hack to silence atexit traceback in newer python versions -try: - import multiprocessing # noqa: F401 -except ImportError: - pass DESCRIPTION = "MongoEngine is a Python Object-Document Mapper for working with MongoDB." @@ -27,62 +18,6 @@ def get_version(version_tuple): return ".".join(map(str, version_tuple)) -class PyTest(TestCommand): - """Will force pytest to search for tests inside the build directory - for 2to3 converted code (used by tox), instead of the current directory. - Required as long as we need 2to3 - - Known Limitation: https://tox.readthedocs.io/en/latest/example/pytest.html#known-issues-and-limitations - Source: https://www.hackzine.org/python-testing-with-pytest-and-2to3-plus-tox-and-travis-ci.html - """ - - # https://pytest.readthedocs.io/en/2.7.3/goodpractises.html#integration-with-setuptools-test-commands - # Allows to provide pytest command argument through the test runner command `python setup.py test` - # e.g: `python setup.py test -a "-k=test"` - # This only works for 1 argument though - user_options = [("pytest-args=", "a", "Arguments to pass to py.test")] - - def initialize_options(self): - TestCommand.initialize_options(self) - self.pytest_args = "" - - def finalize_options(self): - TestCommand.finalize_options(self) - self.test_args = ["tests"] - self.test_suite = True - - def run_tests(self): - # import here, cause outside the eggs aren't loaded - import pytest - from pkg_resources import _namespace_packages - - # Purge modules under test from sys.modules. The test loader will - # re-import them from the build location. Required when 2to3 is used - # with namespace packages. - if sys.version_info >= (3,) and getattr(self.distribution, "use_2to3", False): - module = self.test_args[-1].split(".")[0] - if module in _namespace_packages: - del_modules = [] - if module in sys.modules: - del_modules.append(module) - module += "." - for name in sys.modules: - if name.startswith(module): - del_modules.append(name) - map(sys.modules.__delitem__, del_modules) - - # Run on the build directory for 2to3-built code - # This will prevent the old 2.x code from being found - # by py.test discovery mechanism, that apparently - # ignores sys.path.. - ei_cmd = self.get_finalized_command("egg_info") - self.test_args = [normalize_path(ei_cmd.egg_base)] - - cmd_args = self.test_args + ([self.pytest_args] if self.pytest_args else []) - errno = pytest.main(cmd_args) - sys.exit(errno) - - # Dirty hack to get version number from monogengine/__init__.py - we can't # import it as it depends on PyMongo and PyMongo isn't installed until this # file is read @@ -107,30 +42,22 @@ CLASSIFIERS = [ "Topic :: Software Development :: Libraries :: Python Modules", ] -extra_opts = { - "packages": find_packages(exclude=["tests", "tests.*"]), - "tests_require": [ - "pytest", - "pytest-cov", - "coverage", - "blinker", - "Pillow>=7.0.0", - ], -} - -if "test" in sys.argv: - extra_opts["packages"] = find_packages() - extra_opts["package_data"] = { - "tests": ["fields/mongoengine.png", "fields/mongodb_leaf.png"] - } +install_require = ["pymongo>=3.4,<5.0"] +tests_require = [ + "pytest", + "pytest-cov", + "coverage", + "blinker", + "Pillow>=7.0.0", +] setup( name="mongoengine", version=VERSION, author="Harry Marr", author_email="harry.marr@gmail.com", - maintainer="Stefan Wojcik", - maintainer_email="wojcikstefan@gmail.com", + maintainer="Bastien Gerard", + maintainer_email="bast.gerard@gmail.com", url="http://mongoengine.org/", download_url="https://github.com/MongoEngine/mongoengine/tarball/master", license="MIT", @@ -140,7 +67,9 @@ setup( platforms=["any"], classifiers=CLASSIFIERS, python_requires=">=3.7", - install_requires=["pymongo>=3.4,<5.0"], - cmdclass={"test": PyTest}, - **extra_opts + install_requires=install_require, + extras_require={ + "test": tests_require, + }, + packages=find_packages(exclude=["tests", "tests.*"]), ) |
