Hello community, here is the log from the commit of package python-Ming for openSUSE:Factory checked in at 2020-08-19 18:56:02 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-Ming (Old) and /work/SRC/openSUSE:Factory/.python-Ming.new.3399 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-Ming" Wed Aug 19 18:56:02 2020 rev:12 rq:827704 version:0.10.2 Changes: -------- --- /work/SRC/openSUSE:Factory/python-Ming/python-Ming.changes 2020-03-26 23:37:51.750874447 +0100 +++ /work/SRC/openSUSE:Factory/.python-Ming.new.3399/python-Ming.changes 2020-08-19 18:57:12.419859399 +0200 @@ -1,0 +2,23 @@ +Sat Aug 15 09:37:39 UTC 2020 - John Vandenberg <jay...@gmail.com> + +- Improve Summary +- Add %license from upstream repository +- Replace nose with pytest +- Tidy spec +- Remove Recommends python-python-spidermonkey which is not buildable +- Remove pymongo-reqs.patch merged upstream +- Replace 0001-disable_test_gridfs.patch with inline "rm" command +- Update to v0.10.2 + * Fix error using save() and no _id + * MIM: Avoid errors from _ensure_orig_key when positional $ is used +- from v0.10.1 + * fix situation with gridfs indexes and MIM + * fix validate=False and update some MIM params to match pymongo closer +- from v0.10.0 + * Support for PyMongo 3.10 + * Support for Python 3.8 + * Removed start_request/end_request from MIM + * Added Cursor.close to MIM + * Moved testing from nose to unittest + +------------------------------------------------------------------- Old: ---- 0001-disable_test_gridfs.patch Ming-0.9.2.tar.gz pymongo-reqs.patch New: ---- LICENSE.txt Ming-0.10.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-Ming.spec ++++++ --- /var/tmp/diff_new_pack.jZgE0i/_old 2020-08-19 18:57:13.799860132 +0200 +++ /var/tmp/diff_new_pack.jZgE0i/_new 2020-08-19 18:57:13.799860132 +0200 @@ -18,40 +18,40 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-Ming -Version: 0.9.2 +Version: 0.10.2 Release: 0 -Summary: Bringing order to Mongo since 2009 +Summary: Database mapping layer for MongoDB on Python License: MIT Group: Development/Languages/Python -URL: http://merciless.sourceforge.net +URL: https://github.com/TurboGears/Ming Source: https://files.pythonhosted.org/packages/source/M/Ming/Ming-%{version}.tar.gz -Patch0: 0001-disable_test_gridfs.patch -Patch1: pymongo-reqs.patch +Source1: https://raw.githubusercontent.com/TurboGears/Ming/master/LICENSE.txt BuildRequires: %{python_module FormEncode >= 1.2.1} BuildRequires: %{python_module WebOb} BuildRequires: %{python_module WebTest} BuildRequires: %{python_module mock >= 0.8.0} -BuildRequires: %{python_module nose} -BuildRequires: %{python_module pymongo >= 2.4} +BuildRequires: %{python_module pymongo >= 3.0} +BuildRequires: %{python_module pytest} BuildRequires: %{python_module pytz} BuildRequires: %{python_module setuptools} BuildRequires: fdupes BuildRequires: python-rpm-macros -Requires: python-pymongo >= 3.0 Requires: python-pytz Requires: python-six >= 1.6.1 Recommends: python-FormEncode >= 1.2.1 -Recommends: python-python-spidermonkey >= 0.0.10 BuildArch: noarch %python_subpackages %description -Database mapping layer for MongoDB on Python. Includes schema enforcement and some facilities for schema migration. +Database mapping layer for MongoDB on Python. +Includes schema enforcement and some facilities for schema migration. %prep %setup -q -n Ming-%{version} -%patch0 -p1 -%patch1 -p1 +cp %{SOURCE1} . + +# gridfs fails +rm ming/tests/test_gridfs.py %build %python_build @@ -61,11 +61,12 @@ %python_expand %fdupes %{buildroot}%{$python_sitelib} %check -%python_exec setup.py -q test +# Real tests require running mongo instance +%pytest -rs -k 'not (TestMappingReal or TestRealBasicMapping or TestRealMongoRelation)' %files %{python_files} %doc README.rst -# no license available, neither in the tarball nor upstream +%license LICENSE.txt %{python_sitelib}/* %changelog ++++++ LICENSE.txt ++++++ This is the MIT license: http://www.opensource.org/licenses/mit-license.php Copyright (c) 2019 Rick Copeland, Alessandro Molina and contributors. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++++++ Ming-0.9.2.tar.gz -> Ming-0.10.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Ming-0.9.2/Ming.egg-info/PKG-INFO new/Ming-0.10.2/Ming.egg-info/PKG-INFO --- old/Ming-0.9.2/Ming.egg-info/PKG-INFO 2020-03-12 19:48:36.000000000 +0100 +++ new/Ming-0.10.2/Ming.egg-info/PKG-INFO 2020-06-19 21:48:45.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: Ming -Version: 0.9.2 +Version: 0.10.2 Summary: Bringing order to Mongo since 2009 Home-page: https://github.com/TurboGears/Ming Author: Rick Copeland diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Ming-0.9.2/Ming.egg-info/requires.txt new/Ming-0.10.2/Ming.egg-info/requires.txt --- old/Ming-0.9.2/Ming.egg-info/requires.txt 2020-03-12 19:48:36.000000000 +0100 +++ new/Ming-0.10.2/Ming.egg-info/requires.txt 2020-06-19 21:48:45.000000000 +0200 @@ -1,4 +1,4 @@ -pymongo<3.8,>=3.0 +pymongo<3.11,>=3.0 pytz six>=1.6.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Ming-0.9.2/PKG-INFO new/Ming-0.10.2/PKG-INFO --- old/Ming-0.9.2/PKG-INFO 2020-03-12 19:48:37.000000000 +0100 +++ new/Ming-0.10.2/PKG-INFO 2020-06-19 21:48:45.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: Ming -Version: 0.9.2 +Version: 0.10.2 Summary: Bringing order to Mongo since 2009 Home-page: https://github.com/TurboGears/Ming Author: Rick Copeland diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Ming-0.9.2/ming/datastore.py new/Ming-0.10.2/ming/datastore.py --- old/Ming-0.9.2/ming/datastore.py 2020-03-12 19:48:08.000000000 +0100 +++ new/Ming-0.10.2/ming/datastore.py 2020-06-17 23:36:55.000000000 +0200 @@ -176,7 +176,7 @@ @property def conn(self): - return self.connection + return self.bind.conn @property def db(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Ming-0.9.2/ming/mim.py new/Ming-0.10.2/ming/mim.py --- old/Ming-0.9.2/ming/mim.py 2020-03-12 19:48:08.000000000 +0100 +++ new/Ming-0.10.2/ming/mim.py 2020-06-19 21:43:32.000000000 +0200 @@ -85,12 +85,6 @@ for db in self._databases.values(): db.clear() - def start_request(self): - return _DummyRequest() - - def end_request(self): - pass - def _make_database(self): return Database(self) @@ -139,6 +133,13 @@ else: self._jsruntime = None + def __repr__(self): + return "mim.Database(%r, %r)" % (self.__client, self.__name) + + def with_options(self, codec_options=None, read_preference=None, write_concern=None, read_concern=None): + # options have no meaning for MIM + return self + @property def name(self): return self._name @@ -351,6 +352,9 @@ self._unique_indexes = {} self._indexes = {} + def __repr__(self): + return "mim.Collection(%r, %r)" % (self._database, self.__name) + def clear(self): self._data = {} for ui in self._unique_indexes.values(): @@ -382,11 +386,12 @@ if mspec is not None: yield doc, mspec return _gen() - def find(self, filter=None, projection=None, sort=None, limit=None, skip=None, as_class=dict, **kwargs): + def find(self, filter=None, projection=None, skip=0, limit=0, **kwargs): if filter is None: filter = {} - cur = Cursor(collection=self, fields=projection, limit=limit, skip=skip, as_class=as_class, + cur = Cursor(collection=self, projection=projection, limit=limit, skip=skip, _iterator_gen=lambda: self._find(filter, **kwargs)) + sort = kwargs.get('sort') if sort: cur = cur.sort(sort) return cur @@ -490,7 +495,7 @@ warnings.warn('save is now deprecated, please use insert_one or replace_one', DeprecationWarning) _id = doc.get('_id', ()) if _id == (): - return self._insert(doc) + return self.__insert(doc) else: self.__update({'_id':_id}, doc, upsert=True) return _id @@ -693,24 +698,24 @@ class Cursor(object): def __init__(self, collection, _iterator_gen, - sort=None, skip=None, limit=None, fields=None, as_class=dict): - if isinstance(fields, (tuple, list)): - fields = dict((f, 1) for f in fields) + sort=None, skip=None, limit=None, projection=None): + if isinstance(projection, (tuple, list)): + projection = dict((f, 1) for f in projection) self._collection = collection self._iterator_gen = _iterator_gen self._sort = sort self._skip = skip or None # cope with 0 being passed. self._limit = limit or None # cope with 0 being passed. - self._fields = fields - self._projection = Projection(fields) - self._as_class = as_class + self._projection = Projection(projection) self._safe_to_chain = True @LazyProperty def iterator(self): self._safe_to_chain = False - result = (doc for doc,match in self._iterator_gen()) + # normally a (doc, match) tuple but could be a single doc (e.g. when gridfs indexes involved) + result = (doc_match[0] if isinstance(doc_match, tuple) else doc_match + for doc_match in self._iterator_gen()) if self._sort is not None: result = sorted(result, key=cmp_to_key( cursor_comparator(self._sort))) @@ -727,8 +732,8 @@ sort=self._sort, skip=self._skip, limit=self._limit, - fields=self._fields, - as_class=self._as_class) + projection=self._projection._projection, + ) for k,v in overrides.items(): setattr(result, k, v) return result @@ -765,7 +770,10 @@ value = six.next(self.iterator) value = bcopy(value) value = self._projection.apply(value) - return wrap_as_class(value, self._as_class) + + # mim doesn't currently do anything with codec_options, so this doesn't do anything currently + # but leaving it here as a placeholder for the future - otherwise we should delete wrap_as_class() + return wrap_as_class(value, self._collection.codec_options.document_class) __next__ = next @@ -822,6 +830,9 @@ # Adding options to MIM does nothing. pass + def close(self): + self._iterator_gen = lambda: iter(()) + def cursor_comparator(keys): def comparator(a, b): @@ -1055,6 +1066,8 @@ doc = self for step in path[:-1]: if isinstance(doc, MatchList): + if step == '$': + return step = int(step) if step not in doc._orig: doc._orig[step] = doc._doc[step]._orig @@ -1474,14 +1487,3 @@ return collection return None - -class _DummyRequest(object): - - def __enter__(self): - pass - - def __exit__(self, ex_type, ex_value, ex_tb): - pass - - def end(self): - pass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Ming-0.9.2/ming/odm/declarative.py new/Ming-0.10.2/ming/odm/declarative.py --- old/Ming-0.9.2/ming/odm/declarative.py 2020-03-12 19:44:06.000000000 +0100 +++ new/Ming-0.10.2/ming/odm/declarative.py 2020-06-17 23:36:55.000000000 +0200 @@ -5,21 +5,19 @@ import six class _MappedClassMeta(type): - + def __init__(cls, name, bases, dct): cls._registry['%s.%s' % (cls.__module__, cls.__name__)] = mapper(cls) cls._compiled = False def __new__(meta, name, bases, dct): # Get the mapped base class(es) - mapped_bases = [ - b for b in bases if hasattr(b, 'query') ] - doc_bases = [ - mapper(b).collection for b in mapped_bases ] + mapped_bases = [b for b in bases if hasattr(b, 'query')] + doc_bases = [mapper(b).collection for b in mapped_bases] # Build up the mongometa class mm_bases = tuple( - (b.__mongometa__ for b in mapped_bases - if hasattr(b, '__mongometa__'))) + (b.__mongometa__ for b in mapped_bases if hasattr(b, '__mongometa__')) + ) if not mm_bases: mm_bases = (object,) mm_dict = {} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Ming-0.9.2/ming/odm/mapper.py new/Ming-0.10.2/ming/odm/mapper.py --- old/Ming-0.9.2/ming/odm/mapper.py 2015-10-16 23:36:22.000000000 +0200 +++ new/Ming-0.10.2/ming/odm/mapper.py 2020-06-17 23:36:55.000000000 +0200 @@ -148,7 +148,10 @@ for m in cls.all_mappers(): m._compiled = False cls._all_mappers = [] - + cls._mapper_by_classname.clear() + cls._mapper_by_class.clear() + cls._mapper_by_collection.clear() + @classmethod def ensure_all_indexes(cls): """Ensures indexes for each registered :class:`.MappedClass` subclass are created""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Ming-0.9.2/ming/odm/odmsession.py new/Ming-0.10.2/ming/odm/odmsession.py --- old/Ming-0.9.2/ming/odm/odmsession.py 2020-03-12 19:48:08.000000000 +0100 +++ new/Ming-0.10.2/ming/odm/odmsession.py 2020-06-17 23:36:57.000000000 +0200 @@ -127,14 +127,9 @@ self.imap.clear() def close(self): - """Clear the session and tell MongoDB the connection can be closed.""" + """Clear the session.""" self.clear() - # This should now be needed anymore, - # see http://emptysqua.re/blog/good-idea-at-the-time-pymongo-start-request/ - # if self.impl.bind: - # self.impl.bind.conn.end_request() - def get(self, cls, idvalue): """Retrieves ``cls`` by its ``_id`` value passed as ``idvalue``. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Ming-0.9.2/ming/session.py new/Ming-0.10.2/ming/session.py --- old/Ming-0.9.2/ming/session.py 2020-03-12 19:48:08.000000000 +0100 +++ new/Ming-0.10.2/ming/session.py 2020-06-17 23:36:57.000000000 +0200 @@ -75,13 +75,10 @@ strip_extra = kwargs.pop('strip_extra', True) validate = kwargs.pop('validate', True) - projection = kwargs.pop('fields', kwargs.pop('projection', None)) + projection = kwargs.pop('projection', None) if projection is not None: kwargs['projection'] = projection - if not validate: - kwargs['as_class'] = Object - collection = self._impl(cls) cursor = collection.find(*args, **kwargs) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Ming-0.9.2/ming/tests/odm/test_declarative.py new/Ming-0.10.2/ming/tests/odm/test_declarative.py --- old/Ming-0.9.2/ming/tests/odm/test_declarative.py 2020-03-12 19:44:06.000000000 +0100 +++ new/Ming-0.10.2/ming/tests/odm/test_declarative.py 2020-06-17 23:36:55.000000000 +0200 @@ -25,10 +25,78 @@ mgr = mapper(Test).collection.m assert len(mgr.indexes) == 1, mgr.indexes +class TestMapping(TestCase): + DATASTORE = 'mim:///test_db' + + def setUp(self): + Mapper._mapper_by_classname.clear() + self.datastore = create_datastore(self.DATASTORE) + self.session = ODMSession(bind=self.datastore) + + def tearDown(self): + self.session.clear() + try: + self.datastore.conn.drop_all() + except TypeError: + self.datastore.conn.drop_database(self.datastore.db) + Mapper._mapper_by_classname.clear() + + def test_with_mixins(self): + class Mixin1(object): + def __init__(self): + pass + + def dosomething(self): + pass + + class Mixin2(object): + def domore(self): + pass + + class User(MappedClass, Mixin1, Mixin2): + class __mongometa__: + name = "userswithmixin" + session = self.session + + _id = FieldProperty(S.ObjectId) + username = FieldProperty(str) + + u = User(_id=None, username="anonymous") + self.session.flush() + + u2 = User.query.find({"username": "anonymous"}).first() + assert u._id == u2._id + + def test_delete_super(self): + class User(MappedClass): + class __mongometa__: + name = "user_with_custom_delete" + session = self.session + + _id = FieldProperty(S.ObjectId) + username = FieldProperty(str) + + def delete(self): + super(User, self).delete() + + u = User(_id=None, username="anonymous") + self.session.flush() + u.delete() + self.session.flush() + + assert not User.query.find({"username": "anonymous"}).count() + + +class TestMappingReal(TestMapping): + DATASTORE = "ming_tests" + + class TestRelation(TestCase): + DATASTORE = 'mim:///test_db' def setUp(self): - self.datastore = create_datastore('mim:///test_db') + Mapper._mapper_by_classname.clear() + self.datastore = create_datastore(self.DATASTORE) self.session = ODMSession(bind=self.datastore) class Parent(MappedClass): class __mongometa__: @@ -49,7 +117,10 @@ def tearDown(self): self.session.clear() - self.datastore.conn.drop_all() + try: + self.datastore.conn.drop_all() + except TypeError: + self.datastore.conn.drop_database(self.datastore.db) def test_parent(self): parent = self.Parent(_id=1) @@ -136,9 +207,14 @@ self.assertEqual(len(parent.children), 4) +class TestRealMongoRelation(TestRelation): + DATASTORE = "ming_tests" + + class TestManyToManyListRelation(TestCase): def setUp(self): + Mapper._mapper_by_classname.clear() self.datastore = create_datastore('mim:///test_db') self.session = ODMSession(bind=self.datastore) class Parent(MappedClass): @@ -250,6 +326,7 @@ class TestManyToManyListReverseRelation(TestCase): def setUp(self): + Mapper._mapper_by_classname.clear() self.datastore = create_datastore('mim:///test_db') self.session = ODMSession(bind=self.datastore) class Parent(MappedClass): @@ -297,6 +374,7 @@ class TestManyToManyListCyclic(TestCase): def setUp(self): + Mapper._mapper_by_classname.clear() self.datastore = create_datastore('mim:///test_db') self.session = ODMSession(bind=self.datastore) @@ -340,6 +418,7 @@ class TestRelationWithNone(TestCase): def setUp(self): + Mapper._mapper_by_classname.clear() self.datastore = create_datastore('mim:///test_db') self.session = ODMSession(bind=self.datastore) class GrandParent(MappedClass): @@ -407,6 +486,8 @@ class ObjectIdRelationship(TestCase): def setUp(self): + Mapper._mapper_by_classname.clear() + self.datastore = create_datastore('mim:///test_db') self.session = ODMSession(bind=self.datastore) class Parent(MappedClass): @@ -430,6 +511,7 @@ Parent, if_missing=lambda:bson.ObjectId('deadbeefdeadbeefdeadbeef')) field_with_default = RelationProperty('Parent', 'field_with_default_id') + Mapper.compile_all() self.Parent = Parent self.Child = Child @@ -500,9 +582,10 @@ self.session.flush() class TestBasicMapping(TestCase): + DATASTORE = 'mim:///test_db' def setUp(self): - self.datastore = create_datastore('mim:///test_db') + self.datastore = create_datastore(self.DATASTORE) self.session = ODMSession(bind=self.datastore) class Basic(MappedClass): class __mongometa__: @@ -521,7 +604,10 @@ def tearDown(self): self.session.clear() - self.datastore.conn.drop_all() + try: + self.datastore.conn.drop_all() + except TypeError: + self.datastore.conn.drop_database(self.datastore.db) def test_repr(self): doc = self.Basic(a=1, b=[2,3], c=dict(d=4, e=5)) @@ -619,9 +705,14 @@ self.session.expunge(doc) +class TestRealBasicMapping(TestBasicMapping): + DATASTORE = "test_ming" + + class TestPolymorphic(TestCase): def setUp(self): + Mapper._mapper_by_classname.clear() self.datastore = create_datastore('mim:///test_db') self.doc_session = Session(self.datastore) self.odm_session = ODMSession(self.doc_session) @@ -671,6 +762,7 @@ class TestHooks(TestCase): def setUp(self): + Mapper._mapper_by_classname.clear() self.datastore = create_datastore('mim:///test_db') self.session = ODMSession(bind=self.datastore) self.hooks_called = defaultdict(list) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Ming-0.9.2/ming/tests/test_gridfs.py new/Ming-0.10.2/ming/tests/test_gridfs.py --- old/Ming-0.9.2/ming/tests/test_gridfs.py 2020-03-12 19:48:08.000000000 +0100 +++ new/Ming-0.10.2/ming/tests/test_gridfs.py 2020-06-17 23:36:57.000000000 +0200 @@ -27,8 +27,8 @@ def setUp(self): self.ds = create_datastore('mim:///test') self.Session = Session(bind=self.ds) - self.TestFS = fs.filesystem( - 'test_fs', self.Session) + self.fs_coll = 'test_fs' + self.TestFS = fs.filesystem(self.fs_coll, self.Session) def tearDown(self): self.ds.bind.drop_all() @@ -52,6 +52,12 @@ assert not self.TestFS.m.exists(filename='test.txt') fobj = self.TestFS.m.get() assert fobj is None + + def test_seek(self): + with self.TestFS.m.new_file('test.txt') as fp: + fp.write('The quick brown fox') + fobj = self.TestFS.m.fs.get(fp._id) + fobj.seek(0) def test_strange_mimetype(self): with self.TestFS.m.new_file('test.ming') as fp: @@ -91,4 +97,7 @@ self.TestFS.m.get_version('test.txt', -1).read().decode(), 'jumped over the lazy dog') - + def test_custom_index(self): + self.ds.db['{}.files'.format(self.fs_coll)].ensure_index('custom_fld') + with self.TestFS.m.new_file('test.txt') as fp: + fp.write('The quick brown fox') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Ming-0.9.2/ming/tests/test_middleware.py new/Ming-0.10.2/ming/tests/test_middleware.py --- old/Ming-0.9.2/ming/tests/test_middleware.py 2014-04-29 20:00:38.000000000 +0200 +++ new/Ming-0.10.2/ming/tests/test_middleware.py 2020-06-17 23:36:55.000000000 +0200 @@ -14,6 +14,7 @@ class TestRelation(TestCase): def setUp(self): + Mapper._mapper_by_classname.clear() self.datastore = create_datastore('mim:///test_db') self.session = ThreadLocalODMSession(Session(bind=self.datastore)) class Parent(MappedClass): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Ming-0.9.2/ming/tests/test_mim.py new/Ming-0.10.2/ming/tests/test_mim.py --- old/Ming-0.9.2/ming/tests/test_mim.py 2020-03-12 19:48:08.000000000 +0100 +++ new/Ming-0.10.2/ming/tests/test_mim.py 2020-06-19 21:43:32.000000000 +0200 @@ -6,7 +6,6 @@ from ming import create_datastore, mim from pymongo import UpdateOne from pymongo.errors import OperationFailure, DuplicateKeyError -from nose import SkipTest from mock import patch @@ -99,8 +98,7 @@ self.assertEqual(0, f(dict({'_id': 'bar', '$or': [{'a': 2}, {'c':{'$all':[1,2,3]}}]})).count()) self.assertEqual(1, f(dict({'_id': 'foo', '$or': [{'a': 2}, {'c':{'$all':[1,2,3]}}]})).count()) - def test_find_with_fields(self): - # I think this should be removed + def test_find_with_projection_list(self): o = self.bind.db.coll.find_one({'a': 2}, projection=['a']) assert o['a'] == 2 assert o['_id'] == 'foo' @@ -159,6 +157,13 @@ cursor.rewind() assert cursor.next() == doc + def test_close(self): + collection = self.bind.db.coll + collection.insert({'a': 'b'}) + cursor = collection.find() + cursor.close() + self.assertRaises(StopIteration, cursor.next) + def test_search(self): conn = mim.Connection().get() coll = conn.searchdatabase.coll @@ -186,6 +191,12 @@ obj = self.coll.find_one({}, { '_id': 0, 'b.e': 1 }) self.assertEqual(obj, { 'b': { 'e': [ 1,3,3 ] } }) + def test_inc_dotted_dollar_middle1(self): + # match on g=1 and $inc by 10 + self.coll.update({'b.f.g': 1}, { '$inc': { 'b.f.$.g': 10 } }) + obj = self.coll.find_one({}, { '_id': 0, 'b.f': 1 }) + self.assertEqual(obj, { 'b': { 'f': [ { 'g': 11 }, { 'g': 2 } ] }}) + def test_find_dotted(self): self.assertEqual(self.coll.find({'b.c': 1}).count(), 1) self.assertEqual(self.coll.find({'b.c': 2}).count(), 0) @@ -326,7 +337,7 @@ def setUp(self): super(TestMRCommands, self).setUp() if not self.bind.db._jsruntime: - raise SkipTest + self.skipTest("Javascript Runtime Unavailable") def test_mr_inline(self): result = self.bind.db.command( @@ -759,6 +770,15 @@ self.bind.db.coll.insert(doc, manipulate=True) self.assertEqual(doc, {'x': 1, '_id': sample_id}) + def test_save_id(self): + doc = {'_id': bson.ObjectId(), 'x': 1} + self.bind.db.coll.save(doc) + + def test_save_no_id(self): + doc = {'x': 1} + self.bind.db.coll.save(doc) + assert isinstance(doc['_id'], bson.ObjectId) + def test_unique_index_subdocument(self): coll = self.bind.db.coll diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Ming-0.9.2/ming/tests/test_schema.py new/Ming-0.10.2/ming/tests/test_schema.py --- old/Ming-0.9.2/ming/tests/test_schema.py 2020-03-12 19:48:08.000000000 +0100 +++ new/Ming-0.10.2/ming/tests/test_schema.py 2020-06-17 23:36:57.000000000 +0200 @@ -27,6 +27,7 @@ def test_extra_fields_stripped(self): r = self.Doc.m.find().all() assert r == [ dict(a=2, _id='foo') ], r + assert 'Doc' in str(type(r[0])) r = self.Doc.m.find({}, allow_extra=True).all() assert r == [ dict(a=2, _id='foo') ], r r = self.Doc.m.get(_id='foo') @@ -40,6 +41,12 @@ q = self.Doc.m.find({}, allow_extra=False) self.assertRaises(S.Invalid, q.all) + def test_no_validate(self): + r = list(self.Doc.m.find({}, validate=False)) + assert 'Doc' in str(type(r[0])) + assert r == [dict(_id='foo', a=2, b=3)], r + + class TestSchemaItem(TestCase): def test_make_array(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Ming-0.9.2/ming/version.py new/Ming-0.10.2/ming/version.py --- old/Ming-0.9.2/ming/version.py 2020-03-12 19:48:08.000000000 +0100 +++ new/Ming-0.10.2/ming/version.py 2020-06-19 21:47:49.000000000 +0200 @@ -1,2 +1,2 @@ -__version_info__ = ('0', '9', '2') +__version_info__ = ('0', '10', '2') __version__ = '.'.join(__version_info__) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Ming-0.9.2/setup.py new/Ming-0.10.2/setup.py --- old/Ming-0.9.2/setup.py 2020-03-12 19:48:08.000000000 +0100 +++ new/Ming-0.10.2/setup.py 2020-06-17 23:36:55.000000000 +0200 @@ -35,12 +35,11 @@ include_package_data=True, zip_safe=True, install_requires=[ - "pymongo>=3.0,<3.8", + "pymongo>=3.0,<3.11", "pytz", "six>=1.6.1" ], tests_require=[ - "nose", "mock >=0.8.0", "pytz", "WebOb", @@ -48,6 +47,7 @@ "FormEncode >= 1.2.1", # "python-spidermonkey >= 0.0.10", # required for full MIM functionality ], + test_suite="ming.tests", extras_require={ "configure": [ "FormEncode >= 1.2.1", # required to use ``ming.configure`` @@ -57,6 +57,5 @@ # -*- Entry points: -*- [paste.filter_factory] ming_autoflush=ming.odm.middleware:make_ming_autoflush_middleware - """, - test_suite='nose.collector' - ) + """ +)