Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,13 @@ install:
- travis_retry pip install --upgrade pip
- travis_retry pip install --upgrade nose
- travis_retry pip install --upgrade setuptools
- travis_retry pip install flake8
- travis_retry pip install tox>=1.9
- travis_retry tox -e $(echo py$TRAVIS_PYTHON_VERSION-me$MONGOENGINE | tr -d . | sed -e 's/pypypy/pypy/') -- -e test

before_script:
- if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then tox -e flake8; fi

script:
- tox -e $(echo py$TRAVIS_PYTHON_VERSION-me$MONGOENGINE | tr -d . | sed -e 's/pypypy/pypy/') -- --with-coverage

Expand Down
9 changes: 4 additions & 5 deletions flask_mongoengine/__init__.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
import mongoengine, inspect
import inspect
import mongoengine

from flask import abort, current_app
from mongoengine.base.fields import BaseField
from mongoengine.queryset import (MultipleObjectsReturned,
DoesNotExist, QuerySet)
DoesNotExist, QuerySet)

from mongoengine.base import ValidationError
from pymongo import uri_parser
from .sessions import *
from .pagination import *
from .metadata import *
from .json import override_json_encoder
from .wtf import WtfBaseField
from .connection import *
import flask_mongoengine

def redirect_connection_calls(cls):
"""
Expand Down Expand Up @@ -120,7 +119,7 @@ def init_app(self, app, config=None):
# Make documents JSON serializable
override_json_encoder(app)

if not 'mongoengine' in app.extensions:
if 'mongoengine' not in app.extensions:
app.extensions['mongoengine'] = {}

if self in app.extensions['mongoengine']:
Expand Down
65 changes: 37 additions & 28 deletions flask_mongoengine/connection.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import atexit, os.path, time, mongoengine, sys
import shutil, subprocess, tempfile
import atexit
import os.path
import mongoengine
import shutil
import subprocess
import sys
import tempfile
import time

from flask import current_app
from pymongo import MongoClient, ReadPreference, errors, uri_parser
from pymongo import MongoClient, ReadPreference, errors
from subprocess import Popen, PIPE
from pymongo.errors import InvalidURI
from mongoengine import connection
Expand All @@ -24,11 +31,14 @@
class InvalidSettingsError(Exception):
pass

class ConnectionError(Exception):
pass

def disconnect(alias=DEFAULT_CONNECTION_NAME, preserved=False):
global _connections, _process, _tmpdir

if alias in _connections:
conn = get_connection(alias=alias);
conn = get_connection(alias=alias)
client = conn.client
if client:
client.close()
Expand All @@ -46,8 +56,7 @@ def disconnect(alias=DEFAULT_CONNECTION_NAME, preserved=False):
if os.path.exists(_tmpdir):
shutil.rmtree(_tmpdir, ignore_errors=True)
if os.path.exists(sock_file):
os.remove("{0}/{1}".\
format(tempfile.gettempdir(), sock_file))
os.remove("{0}/{1}".format(tempfile.gettempdir(), sock_file))

def _validate_settings(is_test, temp_db, preserved, conn_host):
"""
Expand All @@ -56,21 +65,20 @@ def _validate_settings(is_test, temp_db, preserved, conn_host):
connection.

"""
if (not isinstance(is_test, bool)
or not isinstance(temp_db, bool)
or not isinstance(preserved, bool)):
msg = '`TESTING`, `TEMP_DB`, and `PRESERVE_TEMP_DB`'\
' must be boolean values'
if (not isinstance(is_test, bool) or not isinstance(temp_db, bool) or
not isinstance(preserved, bool)):
msg = ('`TESTING`, `TEMP_DB`, and `PRESERVE_TEMP_DB`'
' must be boolean values')
raise InvalidSettingsError(msg)

elif not is_test and conn_host.startswith('mongomock://'):
msg = "`MongoMock` connection is only required for `unittest`."\
"To enable this set `TESTING` to true`."
msg = ("`MongoMock` connection is only required for `unittest`."
"To enable this set `TESTING` to true`.")
raise InvalidURI(msg)

elif not is_test and temp_db or preserved:
msg = '`TESTING` and/or `TEMP_DB` can be used '\
'only when `TESTING` is set to true.'
msg = ('`TESTING` and/or `TEMP_DB` can be used '
'only when `TESTING` is set to true.')
raise InvalidSettingsError(msg)

def __get_app_config(key):
Expand Down Expand Up @@ -117,7 +125,7 @@ def get_connection(alias=DEFAULT_CONNECTION_NAME, reconnect=False):
return _register_test_connection(port, db_alias, preserved)

elif (conn_host.startswith('mongomock://') and
mongoengine.VERSION < (0, 10, 6)):
mongoengine.VERSION < (0, 10, 6)):
# Use MongoClient from mongomock
try:
import mongomock
Expand Down Expand Up @@ -212,16 +220,16 @@ def _register_test_connection(port, db_alias, preserved):

if _conn is None:
_process = subprocess.Popen([
'mongod', '--bind_ip', 'localhost',
'--port', str(port),
'--dbpath', _tmpdir,
'--nojournal', '--nohttpinterface',
'--noauth', '--smallfiles',
'--syncdelay', '0',
'--maxConns', '10',
'--nssize', '1', ],
stdout=open(os.devnull, 'wb'),
stderr=subprocess.STDOUT)
'mongod', '--bind_ip', 'localhost',
'--port', str(port),
'--dbpath', _tmpdir,
'--nojournal', '--nohttpinterface',
'--noauth', '--smallfiles',
'--syncdelay', '0',
'--maxConns', '10',
'--nssize', '1', ],
stdout=open(os.devnull, 'wb'),
stderr=subprocess.STDOUT)
atexit.register(disconnect, preserved=preserved)

# wait for the instance db to be ready
Expand All @@ -232,7 +240,8 @@ def _register_test_connection(port, db_alias, preserved):
_conn = MongoClient('localhost', port)
except errors.ConnectionFailure:
continue
else: break
else:
break
else:
msg = 'Cannot connect to the mongodb test instance'
raise mongoengine.ConnectionError(msg)
Expand Down Expand Up @@ -358,7 +367,7 @@ def create_connection(config, app):
_app_instance = app if app else config

if config is None or not isinstance(config, dict):
raise Exception("Invalid application configuration");
raise InvalidSettingsError("Invalid application configuration")

conn_settings = fetch_connection_settings(config, False)

Expand Down
8 changes: 4 additions & 4 deletions flask_mongoengine/operation_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def _insert(collection_self, doc_or_docs, manipulate=True,
)
total_time = (time.time() - start_time) * 1000

__traceback_hide__ = True
__traceback_hide__ = True # noqa
stack_trace, internal = _tidy_stacktrace()
inserts.append({
'document': doc_or_docs,
Expand All @@ -86,7 +86,7 @@ def _update(collection_self, spec, document, upsert=False,
)
total_time = (time.time() - start_time) * 1000

__traceback_hide__ = True
__traceback_hide__ = True # noqa
stack_trace, internal = _tidy_stacktrace()
updates.append({
'document': document,
Expand All @@ -111,7 +111,7 @@ def _remove(collection_self, spec_or_id, safe=None, **kwargs):
)
total_time = (time.time() - start_time) * 1000

__traceback_hide__ = True
__traceback_hide__ = True # noqa
stack_trace, internal = _tidy_stacktrace()
removes.append({
'spec_or_id': spec_or_id,
Expand Down Expand Up @@ -167,7 +167,7 @@ def privar(name):
if maxScan:
query_son["$maxScan"] = maxScan

__traceback_hide__ = True
__traceback_hide__ = True # noqa
stack_trace, internal = _tidy_stacktrace()
query_data = {
'time': total_time,
Expand Down
4 changes: 2 additions & 2 deletions flask_mongoengine/panels.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ def nav_title(self):
def nav_subtitle(self):
attrs = ['queries', 'inserts', 'updates', 'removes']
ops = sum(sum((1 for o in getattr(operation_tracker, a)
if not o['internal']))
for a in attrs)
if not o['internal']))
for a in attrs)
total_time = sum(sum(o['time'] for o in getattr(operation_tracker, a))
for a in attrs)
return '{0} operations in {1:.2f}ms'.format(ops, total_time)
Expand Down
4 changes: 2 additions & 2 deletions flask_mongoengine/wtf/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
from flask_mongoengine.wtf.orm import model_fields, model_form
from flask_mongoengine.wtf.base import WtfBaseField
from flask_mongoengine.wtf.orm import model_fields, model_form # noqa
from flask_mongoengine.wtf.base import WtfBaseField # noqa
2 changes: 1 addition & 1 deletion flask_mongoengine/wtf/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ def save(self, commit=True, **kwargs):

if commit:
self.instance.save(**kwargs)
return self.instance
return self.instance
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ Flask>=0.8
Flask-DebugToolbar>=0.8
Flask-WTF>=0.8.3
mongoengine>=0.8.0
flake8
5 changes: 5 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,8 @@ cover-erase = 1
cover-branches = 1
cover-package = flask_mongoengine
tests = tests

[flake8]
ignore=E2,E129,E302,E5,W391,F403,F405,E501,E731,F999
exclude=build,dist,docs,examples,venv,.tox,.eggs
max-complexity=35
15 changes: 7 additions & 8 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import os, imp
import imp
import os

from setuptools import setup

def load_module(module_name, script_file):
Expand All @@ -22,22 +24,19 @@ def load_module(module_name, script_file):

# Load documentation
doc_path = os.path.join(os.path.dirname(__file__), "docs", "index.rst")

# Load guide
doc_path = os.path.join(os.path.dirname(__file__), "docs", "index.rst")
DESCRIPTION = 'Flask-MongoEngine is a Flask extension ' + \
'that provides integration with MongoEngine and WTF model forms.'
DESCRIPTION = ('Flask-MongoEngine is a Flask extension '
'that provides integration with MongoEngine and WTF model forms.')

LONG_DESCRIPTION = None
try:
LONG_DESCRIPTION = open(doc_path).read()

# Stops exit traceback on tests
import multiprocessing
import multiprocessing # noqa
except:
pass

test_requirements = ['nose', 'rednose', 'coverage', 'mongomock']
test_requirements = ['coverage', 'flake8', 'mongomock', 'nose', 'rednose']

setup(
name='flask-mongoengine',
Expand Down
2 changes: 1 addition & 1 deletion tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import flask
import unittest
from flask import current_app

from flask_mongoengine import current_mongoengine_instance

class FlaskMongoEngineTestCase(unittest.TestCase):
Expand Down
21 changes: 12 additions & 9 deletions tests/test_connection.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import mongomock
import mongoengine, pymongo
import mongoengine
import pymongo

from pymongo.errors import InvalidURI
from flask_mongoengine import MongoEngine, InvalidSettingsError
from tests import FlaskMongoEngineTestCase
Expand Down Expand Up @@ -66,18 +68,19 @@ def test_multiple_connections(self):
self.app.config['TESTING'] = True
self.app.config['MONGODB_SETTINGS'] = [
{
"ALIAS": "default",
"DB": 'my_db1',
"HOST": 'localhost',
"PORT": 27017
"ALIAS": "default",
"DB": 'my_db1',
"HOST": 'localhost',
"PORT": 27017
},
{
"ALIAS": "my_db2",
"DB": 'my_db2',
"HOST": 'localhost',
"PORT": 27017
"ALIAS": "my_db2",
"DB": 'my_db2',
"HOST": 'localhost',
"PORT": 27017
},
]

class Todo(db.Document):
title = db.StringField(max_length=60)
text = db.StringField()
Expand Down
21 changes: 10 additions & 11 deletions tests/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,13 +257,13 @@ class DogOwner(db.Document):
# Validate selecting one item
form = DogOwnerForm(MultiDict({
'dog': dog.id,
}))
}))
self.assertEqual(form.dog.data, dog)

# Validate selecting no item
form = DogOwnerForm(MultiDict({
'dog': u'__None',
}), dog=dog)
}), dog=dog)
self.assertEqual(form.dog.data, None)

def test_modelselectfield_multiple(self):
Expand Down Expand Up @@ -297,13 +297,13 @@ class DogOwner(db.Document):
# Validate selecting two items
form = DogOwnerForm(MultiDict({
'dogs': [dog.id for dog in dogs],
}))
}))
self.assertEqual(form.dogs.data, dogs)

# Validate selecting none actually empties the list
form = DogOwnerForm(MultiDict({
'dogs': [],
}), dogs=dogs)
}), dogs=dogs)
self.assertEqual(form.dogs.data, None)

def test_modelselectfield_multiple_initalvalue_None(self):
Expand Down Expand Up @@ -333,21 +333,21 @@ class DogOwner(db.Document):
self.assertEqual(len(choices), 2)
self.assertFalse(choices[0].checked)
self.assertFalse(choices[1].checked)

def test_modelradiofield(self):
with self.app.test_request_context('/'):
db = self.db

choices = (('male', 'Male'), ('female', 'Female'), ('other', 'Other'))

class Poll(db.Document):
answer = db.StringField(choices=choices)

PollForm = model_form(Poll, field_args={'answer': {'radio': True}})

form = PollForm(answer=None)
self.assertTrue(form.validate())

self.assertEqual(form.answer.type, 'RadioField')
self.assertEqual(form.answer.choices, choices)

Expand Down Expand Up @@ -485,6 +485,5 @@ class Post(db.Document):
self.assertTrue("content-text" in "%s" % form.content.text)



if __name__ == '__main__':
unittest.main()
Loading