Code Monkey home page Code Monkey logo

minimongo's Introduction

minimongo

Info:Minimal database Model management for MongoDB.
Author:Steve Lacy ([email protected])

About

minimongo is a lightweight, schemaless, Pythonic Object-Oriented interface to MongoDB.

It provides a very thin, dynamicly typed (schema-less) object management layer for any data stored in any MongoDB collection. minimongo directly calls the existing pymongo query syntax.

minimongo can easily layer on top of existing MongoDB collections, and will work properly with almost any existing schema, even from third party applications.

Installation

If you have setuptools you can use easy_install -U minimongo. Otherwise, you can download the source from GitHub and run python setup.py install.

Dependencies

Example

Here's a very brief example of creating an object, querying for it, modifying a field, and then saving it back again:

from minimongo import Model, Index

class Foo(Model):
    class Meta:
        # Here, we specify the database and collection names.
        # A connection to your DB is automatically created.
        database = "minimongo"
        collection = "rocks"

        # Now, we programatically declare what indices we want.
        # The arguments to the Index constructor are identical to
        # the args to pymongo"s ensure_index function.
        indices = (
            Index("a"),
        )


if __name__ == "__main__":
    # Create & save an object, and return a local in-memory copy of it:
    foo = Foo({"x": 1, "y": 2}).save()

    # Find that object again, loading it into memory:
    foo = Foo.collection.find_one({"x": 1})

    # Change a field value, and save it back to the DB.
    foo.other = "some data"
    foo.save()

Feedback welcome!

Please email [email protected] with comments, suggestions, or comment via http://github.com/slacy/minimongo

minimongo's People

Contributors

knsd avatar larroy avatar phblj avatar ricksore avatar slacy avatar superbobry avatar uniphil avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

minimongo's Issues

Proposing a PR to fix a few small typos

Issue Type

[x] Bug (Typo)

Steps to Replicate and Expected Behaviour

  • Examine README.rst, docs/source/index.rst and observe dynamicly, however expect to see dynamically.
  • Examine minimongo/config.py and observe successfull, however expect to see successful.
  • Examine minimongo/config.py and observe modlue, however expect to see module.
  • Examine minimongo/options.py and observe explicictly, however expect to see explicitly.

Notes

Semi-automated issue generated by
https://github.com/timgates42/meticulous/blob/master/docs/NOTE.md

To avoid wasting CI processing resources a branch with the fix has been
prepared but a pull request has not yet been created. A pull request fixing
the issue can be prepared from the link below, feel free to create it or
request @timgates42 create the PR. Alternatively if the fix is undesired please
close the issue with a small comment about the reasoning.

https://github.com/timgates42/minimongo/pull/new/bugfix_typos

Thanks.

Feature request: mongomock compatibility

I've just encountered minimongo and it looks really great, but I don't think it will work with e.g. mongomock out of the box. mongomock is a drop-in substitute for pymongo which doesn't use a real mongodb backend but performs operations in-memory (not necessarily efficiently) so that you don't need the hassle of setting up a real mongodb instance for unit testing.

As an example:

>>> import mongomock
>>> client = mongomock.MongoClient()
>>> client.db.collection.insert({'foo': 'bar'})
ObjectId('586651608eda9b078e37499e')
>>> list(client.db.collection.find({}))
[{'foo': 'bar', '_id': ObjectId('586651608eda9b078e37499e')}]

It would seem better if minimongo wrapped around an existing MongoDB client (which could then be either a pymongo or a mongomock client) or an existing MongoDB database (ditto).

Upcoming API changes & simplification.

Hi, as I continue to use minimongo for my own development, I'm finding that it's a bit limiting when you're subclassing your own models. I can go into more details if you'd like, but the long & short of it is that I'm going to be changing the API and simplifying member access quite a bit.

In addition, I'm planning on using the as_class ability of pymongo itself, which should also simplify the code. What I'm expecting is that the current API of:

DerivedModel.find_one({'query': 'here'})
will change to:
DerivedModel.collection.find_one({'query': 'here'})
and similarly for database methods.

Let me know if you'll have any issues with this conversion or have any other ideas. I'm also going to be supporting dict-like access to returned values from find_one and friends.

Keep your eyes on the repo for more updates.

Handle AutoReconnects

Create a new Connection automatically, once pymongo.errors.AutoReconnect is raised.

Explicit configuration

Currently minimongo looks for configuration file in a number of special places: .config, .app_config etc.

This sure is a nice way of doing things, but why not add a shortcut for changing the defaults, so we don't force any specific locations. The idea is similar to what mongoengine offers:

from minimongo import configure

# a) manual configuration
configure(host="...", port="...")
# b) from a module
import app_config; configure(app_config)

What do you think?

Alternative to MongoCollection

I think the name MongoCollection is a little confusing for the metadata container -- especially when we have the original pymongo.collection.Collection hanging around. So, how about changing the way metadata is declared?

  1. Django style

    class MyModel(Model):
    class Meta:
    collection = "foo"
    database = "bar"

    or ...

    class MyModel(Model):
    class Mongo:
    collection = "foo"
    database = "bar"

  2. Similar to what we have, but with different names

    class MyModel(Model):
    meta = Meta(database="bar")

Support for atomic updates

Delta modification tracking so that when you call save(), it doesn't send the whole document back to the server to modify one field.

Model behaviors

Implement at least three following behaviors for a Model:

  • Read-only
  • Rigid (no schema change allowed after read)
  • Type-Rigid (allow changing values, but not changing types)

pip install failing

I don't think the package as fetched from pip includes the README.rst anymore? I'm having trouble installing it:

Downloading/unpacking minimongo
Running setup.py egg_info for package minimongo
Traceback (most recent call last):
File "", line 16, in
File "/var/folders/tz/gvwfckmx06vg9107bqd3mmynbxzgjs/T/pip-build/minimongo/setup.py", line 58, in
long_description=LONG_DESCRIPTION,
NameError: name 'LONG_DESCRIPTION' is not defined
Complete output from command python setup.py egg_info:
Traceback (most recent call last):

File "", line 16, in

File "/var/folders/tz/gvwfckmx06vg9107bqd3mmynbxzgjs/T/pip-build/minimongo/setup.py", line 58, in

long_description=LONG_DESCRIPTION,

NameError: name 'LONG_DESCRIPTION' is not defined

delayed and partial loading

I've started implementing MongoDB support in my Pyramid app with pure pymongo because I didn't like the rigid schema of MongoEngine and MongoKit, but it looks like minimongo is closer to what I need.

However, I do a lot of delayed loading and partial loading of my data, because I store information in the database that I don't usually need to manipulate on a regular basis. Would this be possible with minimongo?

What I'm thinking is something like:

item = MiniMongoObject()
item._id = get_id_from_somewhere()
item.load(fields=['name', 'description'] )

this would partially load the object, only fetching the name and description field
Ideally this would mark the object as partially loaded, so that save() would raise an
error, or use update() behind the scene instead.

I would also like to see MongoObject.mongo_update() take an optional data parameter, so I can use it to send my own field to update ( like '$inc' )

item.mongo_update(  {'$inc": {'counter': 1} }  )

And also expose all the optional update parameters as well ( I sometime need to use safe=True)

License

I wonder if it's possible to license minimongo under a BSD-style license, so it can be modified and improved by anyone?

Handle Embedded SubDocuments

It would be interesting to see what kind of support for SubDocument there could be in minimongo.

A subdocument being a dictionary that contains a top-level _id key. a DBRef is a special kind of subdocument, but you could have a fully embedded SubDocument. What would get interesting is specifically supporting embedded documents that are in arrays.

This is a often suggested MongoDB pattern (the blog + comment example) , and dealing with updating these is always a pain in the butt.

Maybe some sort of client-side pseudo-collection?

blog = Blog.collection.find_one()
comment = blog.comments.collection.find_one( ... )
...
comment.update()

food for thoughs...

Add minimongo to PyMongo/Tools section

PyMongo has a list of projects using it -- would be nice, to see minimongo among them.

By the way, pymongo-bongo looks very similar to what we already have -- but as far as I know -- it's not updated any more.

Usage problem: can't delay configuration until after model class declaration.

I'm having a problem figuring out where/when to call minimongo.configure() in my Pyramid app, to make sure that my minimongo class actually have a valid connection to the database.

The whole metaclass thing is causing the connection to be created when the module is imported and the class declaration is parsed, which is way before I've had a chance to read my setting files and get valid values for host and database.

It seems that I can't write an example like this in a single file:

import minimongo


class MyModel( minimongo.Model ):
    """Base MiniMongo model. all models should inherit from this one"""
    class Meta:
        """Collection definition should go here."""
        colection = "test"


def main():
    minimongo.configure(
        host = "mongo.ozoux.com",
        database = "test"
    )
    a = MyModel()
    a.name = "foo"
    a.save()


if __name__ == '__main__':
    main()

I get the following error:

 File "test_minimongo.py", line 21, in <module> 
 class MyModel( minimongo.Model ):
 File "minimongo/minimongo/model.py", line 49, in __new__ 
 (name, options.host, options.port, options.database)
 Exception: Model 'MyModel' improperly configured: localhost 27017 None

How exactly can I use minimongo with a deferred configuration call? I'd like to be able to define my models wherever I want, and as long as the call to configure happens before the class is instanciated, everything should be fine, no?

Sphinx support

I think it would be nice to have an autogenerated API documentation -- more.

License

Mentioned nowhere in the code -- what is it?

AttrDict doesn't handle list properly

Example:

        d = AttrDict({"a": 1, "b": 2, "c": {"d": 3, "e": [4, 5, {"f": 6, "g": 7}]}})
        self.assertEqual(d.c.e[2].f, 6) # AttributeError: 'dict' object has no attribute 'f'

I suggest to change AttrDict.setitem:

    def __convert_value__(self, value):
        if isinstance(value, dict):
            return AttrDict(value)
        elif isinstance(value, (list, tuple)):
            return [self.__convert_value__(v) for v in value]
        return value

    def __setitem__(self, key, value):
        # Coerce all nested dict-valued fields into AttrDicts
        return super(AttrDict, self).__setitem__(key, self.__convert_value__(value))



My tests:
    def test_attrdict(self):
        d = AttrDict({"a": 1, "b": 2, "c": {"d": 3, "e": [4, 5, {"f": 6, "g": 7}]}})
        self.assertEqual(d.a, 1)
        self.assertEqual(d.b, 2)
        self.assertEqual(d.c.d, 3)
        self.assertEqual(d.c.e[2].f, 6)
        self.assertEqual(d.c.e[2].g, 7)

        with self.assertRaises(AttributeError):
            a = d.qq


        d = AttrDict({"c": [{"f": 6, "g": 7}, [{"a": 1}]]})
        self.assertEqual(d.c[1][0], 1)

Support for custom collection classes

What do you think about extending Model to support custom collection classes. For instance, I want to preprocess each find() call on MyCollection:

class MyCollection(Collection):
    def find(self, **query):
        query.update({"foo": "bar"})
        return super(MyCollection, self).find(**query)

class MyModel(Model):
    mongo = ...
    collection = MyCollection()

In fact, I'd love to implement that myself, if it's allright with you :)

Update pypi package obsolete

Currently, Pypi version of minimongo is 0.2.8

Please, update to the latest (so far 0.2.9).

As a suggestion, maybe can be interesting to integrate Travis and provide automatic deployment when merging to master or creating a new tag/release

Fixtures support

Would be nice to have helpers for dumping and loading a collection of minimongo models.

Empty model instances shouldn't evaluate to False

The behavior of empty model instances is unexpected IMO. When you create a new model instance without any properties set, it evaluates to False in boolean expression. For example the following code snippet raises an assertion error either if some_id is None or some_id = 'DOES_NOT_EXIST':

if some_id is None:
obj = MyModel() # create a new instance
else:
obj = MyModel.collection.find_one({'_id': ObjectId(some_id)}) # retrieve from datastore
assert obj

I would have expected that only the second path raises an assertion error.

Inherit Model from dict?

One thing that's really nice with pymongo is that it converts BSON to plain dicts instead of "magical" objects. So for instance Collection.find_one() result can be easily passed to json.dumps() and serialized, which unfortunately is not true, when using minimongo.

minimongo tests fail out of the box

Clean virtualenv, latest minimongo:

============================= test session starts ==============================
platform darwin -- Python 2.7.2 -- pytest-2.0.1
collecting ... collected 105 items

minimongo/tests/test_model.py ............................
minimongo/tests/test_utils.py .........
venv/lib/python2.7/site-packages/distribute-0.6.31-py2.7.egg/setuptools/tests/test_bdist_egg.py ..
venv/lib/python2.7/site-packages/distribute-0.6.31-py2.7.egg/setuptools/tests/test_build_ext.py .
venv/lib/python2.7/site-packages/distribute-0.6.31-py2.7.egg/setuptools/tests/test_develop.py .
venv/lib/python2.7/site-packages/distribute-0.6.31-py2.7.egg/setuptools/tests/test_dist_info.py ..
venv/lib/python2.7/site-packages/distribute-0.6.31-py2.7.egg/setuptools/tests/test_easy_install.py .............
venv/lib/python2.7/site-packages/distribute-0.6.31-py2.7.egg/setuptools/tests/test_markerlib.py .
venv/lib/python2.7/site-packages/distribute-0.6.31-py2.7.egg/setuptools/tests/test_packageindex.py .....F..
venv/lib/python2.7/site-packages/distribute-0.6.31-py2.7.egg/setuptools/tests/test_resources.py ..............................F
venv/lib/python2.7/site-packages/distribute-0.6.31-py2.7.egg/setuptools/tests/test_sandbox.py .
venv/lib/python2.7/site-packages/distribute-0.6.31-py2.7.egg/setuptools/tests/test_sdist.py ...F..
venv/lib/python2.7/site-packages/distribute-0.6.31-py2.7.egg/setuptools/tests/test_test.py .
venv/lib/python2.7/site-packages/distribute-0.6.31-py2.7.egg/setuptools/tests/test_upload_docs.py .

=================================== FAILURES ===================================
_____________________ TestPackageIndex.test_links_priority _____________________

self = <setuptools.tests.test_packageindex.TestPackageIndex testMethod=test_links_priority>

def test_links_priority(self):
    """
        Download links from the pypi simple index should be used before
        external download links.
        http://bitbucket.org/tarek/distribute/issue/163/md5-validation-error

        Usecase :
        - someone uploads a package on pypi, a md5 is generated
        - someone manually copies this link (with the md5 in the url) onto an
          external page accessible from the package page.
        - someone reuploads the package (with a different md5)
        - while easy_installing, an MD5 error occurs because the external link
          is used
        -> Distribute should use the link from pypi, not the external one.
        """
    if sys.platform.startswith('java'):
        # Skip this test on jython because binding to :0 fails
        return

    # start an index server
    server = IndexServer()
    server.start()
    index_url = server.base_url() + 'test_links_priority/simple/'

    # scan a test index
    pi = setuptools.package_index.PackageIndex(index_url)
    requirement = pkg_resources.Requirement.parse('foobar')
    pi.find_packages(requirement)
    server.stop()

    # the distribution has been found
  self.assertTrue('foobar' in pi)

venv/lib/python2.7/site-packages/distribute-0.6.31-py2.7.egg/setuptools/tests/test_packageindex.py:131:


self = <setuptools.tests.test_packageindex.TestPackageIndex testMethod=test_links_priority>
expr = False, msg = 'False is not true'

def assertTrue(self, expr, msg=None):
    """Check that the expression is true."""
    if not expr:
        msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
      raise self.failureException(msg)

E AssertionError: False is not true

/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py:420: AssertionError
------------------------------- Captured stdout --------------------------------
Reading http://127.0.0.1:55186/setuptools/tests/indexes/test_links_priority/simple/foobar/
Scanning index of all packages (this may take a while)
Reading http://127.0.0.1:55186/setuptools/tests/indexes/test_links_priority/simple/
------------------------------- Captured stderr --------------------------------
1.0.0.127.in-addr.arpa - - [08/Jan/2013 10:36:33] code 404, message File not found
1.0.0.127.in-addr.arpa - - [08/Jan/2013 10:36:33] "GET /setuptools/tests/indexes/test_links_priority/simple/foobar/ HTTP/1.1" 404 -
Couldn't find index page for 'foobar' (maybe misspelled?)
1.0.0.127.in-addr.arpa - - [08/Jan/2013 10:36:33] code 404, message File not found
1.0.0.127.in-addr.arpa - - [08/Jan/2013 10:36:33] "GET /setuptools/tests/indexes/test_links_priority/simple/ HTTP/1.1" 404 -
1.0.0.127.in-addr.arpa - - [08/Jan/2013 10:36:33] "GET / HTTP/1.1" 200 -
_____________________ NamespaceTests.test_two_levels_deep ______________________

self = <setuptools.tests.test_resources.NamespaceTests testMethod=test_two_levels_deep>

def test_two_levels_deep(self):
    """
        Test nested namespace packages
        Create namespace packages in the following tree :
            site-packages-1/pkg1/pkg2
            site-packages-2/pkg1/pkg2
        Check both are in the _namespace_packages dict and that their __path__
        is correct
        """
    sys.path.append(os.path.join(self._tmpdir, "site-pkgs2"))
    os.makedirs(os.path.join(self._tmpdir, "site-pkgs", "pkg1", "pkg2"))
    os.makedirs(os.path.join(self._tmpdir, "site-pkgs2", "pkg1", "pkg2"))
    ns_str = "__import__('pkg_resources').declare_namespace(__name__)\n"
    for site in ["site-pkgs", "site-pkgs2"]:
        pkg1_init = open(os.path.join(self._tmpdir, site,
                         "pkg1", "__init__.py"), "w")
        pkg1_init.write(ns_str)
        pkg1_init.close()
        pkg2_init = open(os.path.join(self._tmpdir, site,
                         "pkg1", "pkg2", "__init__.py"), "w")
        pkg2_init.write(ns_str)
        pkg2_init.close()
    import pkg1
    self._assertIn("pkg1", pkg_resources._namespace_packages.keys())
    try:
        import pkg1.pkg2
    except ImportError, e:
        self.fail("Distribute tried to import the parent namespace package")
    # check the _namespace_packages dict
    self._assertIn("pkg1.pkg2", pkg_resources._namespace_packages.keys())
    self.assertEqual(pkg_resources._namespace_packages["pkg1"], ["pkg1.pkg2"])
    # check the __path__ attribute contains both paths
    self.assertEqual(pkg1.pkg2.__path__, [
            os.path.join(self._tmpdir, "site-pkgs", "pkg1", "pkg2"),
          os.path.join(self._tmpdir, "site-pkgs2", "pkg1", "pkg2") ])

venv/lib/python2.7/site-packages/distribute-0.6.31-py2.7.egg/setuptools/tests/test_resources.py:648:


self = <setuptools.tests.test_resources.NamespaceTests testMethod=test_two_levels_deep>
first = ['/private/var/folders/kg/nqgwfps95hbbfbdmwbyjgtzw0000gn/T/tests-distribute-oLvfWI/site-pkgs/pkg1/pkg2', '/private/var.../site-pkgs2/pkg1/pkg2', '/var/folders/kg/nqgwfps95hbbfbdmwbyjgtzw0000gn/T/tests-distribute-oLvfWI/site-pkgs/pkg1/pkg2']
second = ['/var/folders/kg/nqgwfps95hbbfbdmwbyjgtzw0000gn/T/tests-distribute-oLvfWI/site-pkgs/pkg1/pkg2', '/var/folders/kg/nqgwfps95hbbfbdmwbyjgtzw0000gn/T/tests-distribute-oLvfWI/site-pkgs2/pkg1/pkg2']
msg = None

def assertEqual(self, first, second, msg=None):
    """Fail if the two objects are unequal as determined by the '=='
           operator.
        """
    assertion_func = self._getAssertEqualityFunc(first, second)
  assertion_func(first, second, msg=msg)

/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py:509:


self = <setuptools.tests.test_resources.NamespaceTests testMethod=test_two_levels_deep>
list1 = ['/private/var/folders/kg/nqgwfps95hbbfbdmwbyjgtzw0000gn/T/tests-distribute-oLvfWI/site-pkgs/pkg1/pkg2', '/private/var.../site-pkgs2/pkg1/pkg2', '/var/folders/kg/nqgwfps95hbbfbdmwbyjgtzw0000gn/T/tests-distribute-oLvfWI/site-pkgs/pkg1/pkg2']
list2 = ['/var/folders/kg/nqgwfps95hbbfbdmwbyjgtzw0000gn/T/tests-distribute-oLvfWI/site-pkgs/pkg1/pkg2', '/var/folders/kg/nqgwfps95hbbfbdmwbyjgtzw0000gn/T/tests-distribute-oLvfWI/site-pkgs2/pkg1/pkg2']
msg = None

def assertListEqual(self, list1, list2, msg=None):
    """A list-specific equality assertion.

        Args:
            list1: The first list to compare.
            list2: The second list to compare.
            msg: Optional message to use on failure instead of a list of
                    differences.

        """
  self.assertSequenceEqual(list1, list2, msg, seq_type=list)

/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py:738:


self = <setuptools.tests.test_resources.NamespaceTests testMethod=test_two_levels_deep>
seq1 = ['/private/var/folders/kg/nqgwfps95hbbfbdmwbyjgtzw0000gn/T/tests-distribute-oLvfWI/site-pkgs/pkg1/pkg2', '/private/var.../site-pkgs2/pkg1/pkg2', '/var/folders/kg/nqgwfps95hbbfbdmwbyjgtzw0000gn/T/tests-distribute-oLvfWI/site-pkgs/pkg1/pkg2']
seq2 = ['/var/folders/kg/nqgwfps95hbbfbdmwbyjgtzw0000gn/T/tests-distribute-oLvfWI/site-pkgs/pkg1/pkg2', '/var/folders/kg/nqgwfps95hbbfbdmwbyjgtzw0000gn/T/tests-distribute-oLvfWI/site-pkgs2/pkg1/pkg2']
msg = "Lists differ: ['/private/var/folders/kg/nqgw... != ['/var/folders/kg/nqgwfps95hbb...\n\nFirst differing element 0:\n/...vfWI/site-pkgs2/pkg1/pkg2']\n? +\n"
seq_type = <type 'list'>

def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
    """An equality assertion for ordered sequences (like lists and tuples).

        For the purposes of this function, a valid ordered sequence type is one
        which can be indexed, has a length, and has an equality operator.

        Args:
            seq1: The first sequence to compare.
            seq2: The second sequence to compare.
            seq_type: The expected datatype of the sequences, or None if no
                    datatype should be enforced.
            msg: Optional message to use on failure instead of a list of
                    differences.
        """
    if seq_type is not None:
        seq_type_name = seq_type.__name__
        if not isinstance(seq1, seq_type):
            raise self.failureException('First sequence is not a %s: %s'
                                    % (seq_type_name, safe_repr(seq1)))
        if not isinstance(seq2, seq_type):
            raise self.failureException('Second sequence is not a %s: %s'
                                    % (seq_type_name, safe_repr(seq2)))
    else:
        seq_type_name = "sequence"

    differing = None
    try:
        len1 = len(seq1)
    except (TypeError, NotImplementedError):
        differing = 'First %s has no length.    Non-sequence?' % (
                seq_type_name)

    if differing is None:
        try:
            len2 = len(seq2)
        except (TypeError, NotImplementedError):
            differing = 'Second %s has no length.    Non-sequence?' % (
                    seq_type_name)

    if differing is None:
        if seq1 == seq2:
            return

        seq1_repr = safe_repr(seq1)
        seq2_repr = safe_repr(seq2)
        if len(seq1_repr) > 30:
            seq1_repr = seq1_repr[:30] + '...'
        if len(seq2_repr) > 30:
            seq2_repr = seq2_repr[:30] + '...'
        elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
        differing = '%ss differ: %s != %s\n' % elements

        for i in xrange(min(len1, len2)):
            try:
                item1 = seq1[i]
            except (TypeError, IndexError, NotImplementedError):
                differing += ('\nUnable to index element %d of first %s\n' %
                             (i, seq_type_name))
                break

            try:
                item2 = seq2[i]
            except (TypeError, IndexError, NotImplementedError):
                differing += ('\nUnable to index element %d of second %s\n' %
                             (i, seq_type_name))
                break

            if item1 != item2:
                differing += ('\nFirst differing element %d:\n%s\n%s\n' %
                             (i, item1, item2))
                break
        else:
            if (len1 == len2 and seq_type is None and
                type(seq1) != type(seq2)):
                # The sequences are the same, but have differing types.
                return

        if len1 > len2:
            differing += ('\nFirst %s contains %d additional '
                         'elements.\n' % (seq_type_name, len1 - len2))
            try:
                differing += ('First extra element %d:\n%s\n' %
                              (len2, seq1[len2]))
            except (TypeError, IndexError, NotImplementedError):
                differing += ('Unable to index element %d '
                              'of first %s\n' % (len2, seq_type_name))
        elif len1 < len2:
            differing += ('\nSecond %s contains %d additional '
                         'elements.\n' % (seq_type_name, len2 - len1))
            try:
                differing += ('First extra element %d:\n%s\n' %
                              (len1, seq2[len1]))
            except (TypeError, IndexError, NotImplementedError):
                differing += ('Unable to index element %d '
                              'of second %s\n' % (len1, seq_type_name))
    standardMsg = differing
    diffMsg = '\n' + '\n'.join(
        difflib.ndiff(pprint.pformat(seq1).splitlines(),
                      pprint.pformat(seq2).splitlines()))
    standardMsg = self._truncateMessage(standardMsg, diffMsg)
    msg = self._formatMessage(msg, standardMsg)
  self.fail(msg)

/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py:720:


self = <setuptools.tests.test_resources.NamespaceTests testMethod=test_two_levels_deep>
msg = "Lists differ: ['/private/var/folders/kg/nqgw... != ['/var/folders/kg/nqgwfps95hbb...\n\nFirst differing element 0:\n/...vfWI/site-pkgs2/pkg1/pkg2']\n? +\n"

def fail(self, msg=None):
    """Fail immediately, with the given message."""
  raise self.failureException(msg)

E AssertionError: Lists differ: ['/private/var/folders/kg/nqgw... != ['/var/folders/kg/nqgwfps95hbb...
E
E First differing element 0:
E /private/var/folders/kg/nqgwfps95hbbfbdmwbyjgtzw0000gn/T/tests-distribute-oLvfWI/site-pkgs/pkg1/pkg2
E /var/folders/kg/nqgwfps95hbbfbdmwbyjgtzw0000gn/T/tests-distribute-oLvfWI/site-pkgs/pkg1/pkg2
E
E First list contains 1 additional elements.
E First extra element 2:
E /var/folders/kg/nqgwfps95hbbfbdmwbyjgtzw0000gn/T/tests-distribute-oLvfWI/site-pkgs/pkg1/pkg2
E
E - ['/private/var/folders/kg/nqgwfps95hbbfbdmwbyjgtzw0000gn/T/tests-distribute-oLvfWI/site-pkgs/pkg1/pkg2',
E ? --------
E
E + ['/var/folders/kg/nqgwfps95hbbfbdmwbyjgtzw0000gn/T/tests-distribute-oLvfWI/site-pkgs/pkg1/pkg2',
E - '/private/var/folders/kg/nqgwfps95hbbfbdmwbyjgtzw0000gn/T/tests-distribute-oLvfWI/site-pkgs2/pkg1/pkg2',
E - '/var/folders/kg/nqgwfps95hbbfbdmwbyjgtzw0000gn/T/tests-distribute-oLvfWI/site-pkgs/pkg1/pkg2']
E + '/var/folders/kg/nqgwfps95hbbfbdmwbyjgtzw0000gn/T/tests-distribute-oLvfWI/site-pkgs2/pkg1/pkg2']
E ? +

/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py:408: AssertionError
____________ TestSdistTest.test_sdist_with_latin1_encoded_filename _____________

self = <setuptools.tests.test_sdist.TestSdistTest testMethod=test_sdist_with_latin1_encoded_filename>

def test_sdist_with_latin1_encoded_filename(self):
    # Test for #303.
    dist = Distribution(SETUP_ATTRS)
    dist.script_name = 'setup.py'
    cmd = sdist(dist)
    cmd.ensure_finalized()

    # Latin-1 filename
    filename = os.path.join(b('sdist_test'), LATIN1_FILENAME)
    open(filename, 'w').close()

    quiet()
    try:
        cmd.run()
    finally:
        unquiet()

    if sys.version_info >= (3,):
        filename = filename.decode('latin-1')
        if sys.platform == 'win32':
            # Latin-1 is similar to Windows-1252
            self.assertTrue(filename in cmd.filelist.files)
        else:
            # The Latin-1 filename should have been skipped
            self.assertFalse(filename in cmd.filelist.files)
    else:
        # No conversion takes place under Python 2 and the file
        # is included. We shall keep it that way for BBB.
      self.assertTrue(filename in cmd.filelist.files)

venv/lib/python2.7/site-packages/distribute-0.6.31-py2.7.egg/setuptools/tests/test_sdist.py:378:


self = <setuptools.tests.test_sdist.TestSdistTest testMethod=test_sdist_with_latin1_encoded_filename>
expr = False, msg = 'False is not true'

def assertTrue(self, expr, msg=None):
    """Check that the expression is true."""
    if not expr:
        msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
      raise self.failureException(msg)

E AssertionError: False is not true

/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py:420: AssertionError
==================== 3 failed, 102 passed in 78.16 seconds =====================

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.