diff --git a/.travis.yml b/.travis.yml index f44f67a0..30eace11 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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 diff --git a/flask_mongoengine/__init__.py b/flask_mongoengine/__init__.py index 445b7a90..051df9f0 100644 --- a/flask_mongoengine/__init__.py +++ b/flask_mongoengine/__init__.py @@ -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): """ @@ -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']: diff --git a/flask_mongoengine/connection.py b/flask_mongoengine/connection.py index 31a0de90..9f4fbcdb 100644 --- a/flask_mongoengine/connection.py +++ b/flask_mongoengine/connection.py @@ -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 @@ -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() @@ -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): """ @@ -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): @@ -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 @@ -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 @@ -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) @@ -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) diff --git a/flask_mongoengine/operation_tracker.py b/flask_mongoengine/operation_tracker.py index b3acd9cf..3bd5f471 100644 --- a/flask_mongoengine/operation_tracker.py +++ b/flask_mongoengine/operation_tracker.py @@ -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, @@ -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, @@ -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, @@ -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, diff --git a/flask_mongoengine/panels.py b/flask_mongoengine/panels.py index e4dda31e..b915132b 100644 --- a/flask_mongoengine/panels.py +++ b/flask_mongoengine/panels.py @@ -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) diff --git a/flask_mongoengine/wtf/__init__.py b/flask_mongoengine/wtf/__init__.py index 8632d44b..c6801523 100644 --- a/flask_mongoengine/wtf/__init__.py +++ b/flask_mongoengine/wtf/__init__.py @@ -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 diff --git a/flask_mongoengine/wtf/models.py b/flask_mongoengine/wtf/models.py index abd473f5..082a78b6 100644 --- a/flask_mongoengine/wtf/models.py +++ b/flask_mongoengine/wtf/models.py @@ -18,4 +18,4 @@ def save(self, commit=True, **kwargs): if commit: self.instance.save(**kwargs) - return self.instance \ No newline at end of file + return self.instance diff --git a/requirements.txt b/requirements.txt index 7208dea8..62c07577 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,4 @@ Flask>=0.8 Flask-DebugToolbar>=0.8 Flask-WTF>=0.8.3 mongoengine>=0.8.0 +flake8 diff --git a/setup.cfg b/setup.cfg index 3a179556..fbd2ceee 100644 --- a/setup.cfg +++ b/setup.cfg @@ -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 diff --git a/setup.py b/setup.py index 7e9a21d6..64d93a9e 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,6 @@ -import os, imp +import imp +import os + from setuptools import setup def load_module(module_name, script_file): @@ -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', diff --git a/tests/__init__.py b/tests/__init__.py index ec1c9080..76d09dd0 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,6 +1,6 @@ import flask import unittest -from flask import current_app + from flask_mongoengine import current_mongoengine_instance class FlaskMongoEngineTestCase(unittest.TestCase): diff --git a/tests/test_connection.py b/tests/test_connection.py index aa0d7959..2c50ff96 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -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 @@ -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() diff --git a/tests/test_forms.py b/tests/test_forms.py index af3811ef..8690859d 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -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): @@ -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): @@ -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) @@ -485,6 +485,5 @@ class Post(db.Document): self.assertTrue("content-text" in "%s" % form.content.text) - if __name__ == '__main__': unittest.main() diff --git a/tests/test_json_app.py b/tests/test_json_app.py index 69ccd9e9..4f4cdbc8 100644 --- a/tests/test_json_app.py +++ b/tests/test_json_app.py @@ -63,9 +63,9 @@ def test_with_id(self): self.assertEqual(resp.status_code, 200) res = flask.json.loads(resp.data).get('result') self.assertDictContains(res, { - 'title': 'First Item', - 'text': 'The text' - }) + 'title': 'First Item', + 'text': 'The text' + }) def test_basic_insert(self): c = self.app.test_client() @@ -84,4 +84,4 @@ def test_basic_insert(self): self.assertTrue(any([ self.dictContains(obj, d1), self.dictContains(obj, d2) - ])) + ])) diff --git a/tests/test_metadata.py b/tests/test_metadata.py index 323f03f0..44719dba 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -1,4 +1,7 @@ -import unittest, os, imp +import imp +import os +import unittest + from tests import FlaskMongoEngineTestCase class MetaDataTestCase(FlaskMongoEngineTestCase): diff --git a/tox.ini b/tox.ini index de8d6957..8a0eeb2f 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = {py26,py27,py33,py34,py35,pypy,pypy3}-{me08,me09,medev,me0100} +envlist = {py26,py27,py33,py34,py35,pypy,pypy3}-{me08,me09,medev,me0100},flake8 [testenv] commands = @@ -11,3 +11,8 @@ deps = me0100: mongoengine>=0.10.0 medev: https://github.com/MongoEngine/mongoengine/tarball/master me0{7,8,9,100}: PyMongo<3.0 + +[testenv:flake8] +deps = flake8 +commands = + flake8