Просмотр исходного кода

Run lints as separate tox tasks

Alec Nikolas Reiter 7 лет назад
Родитель
Сommit
03e17eeac7

+ 12 - 1
.travis.yml

@@ -1,15 +1,26 @@
 language: python
+env:
 matrix:
+  fast_finish: true
   include:
     - python: 2.7
     - python: 3.4
     - python: 3.5
     - python: 3.6
+    - python: 3.6
+      env: TOXENV=flake8
+    - python: 3.6
+      env: TOXENV=black
     # see the following issue on why 3.7 is weirdo
     # https://github.com/travis-ci/travis-ci/issues/9815
     - python: 3.7
       dist: xenial
       sudo: true
+  allow_failures:
+    # until the entire code base is properly formatted
+    # allow failures to occur here rather than doing a
+    # big all at once reformat that could hide errors
+    - env: TOXENV=black
 install:
 - pip install -r requirements-travis.txt
 script:
@@ -31,4 +42,4 @@ deploy:
     tags: true
     all_branches: true
     repo: flaskbb/flaskbb
-    python: '3.6'
+    python: '3.7'

+ 7 - 5
flaskbb/core/auth/authentication.py

@@ -150,7 +150,7 @@ class PostAuthenticationHandler(ABC):
     their account.
 
     Cancelling a successful authentication will cause registered
-    :class:`AuthenticationFailureHandler<flaskbb.core.auth.authentication.AuthenticationFailureHandler>`
+    :class:`~flaskbb.core.auth.authentication.AuthenticationFailureHandler`
     instances to be run.
 
     Success handlers should not return a value as it will not be considered.
@@ -179,6 +179,7 @@ class ReauthenticateManager(ABC):
     Unlike the AuthenticationManager, there is no need to return the user to
     the caller.
     """
+
     @abstractmethod
     def reauthenticate(self, user, secret):
         """
@@ -200,7 +201,7 @@ class ReauthenticateProvider(ABC):
     for example when suspicious activity is detected in their session.
 
     ReauthenticateProviders are similiar to
-    :class:`AuthenticationProvider<flaskbb.core.auth.authentication.AuthenticationProvider>`
+    :class:`~flaskbb.core.auth.authentication.AuthenticationProvider`
     except they receive a user instance rather than an identifer for a user.
 
     A successful reauthentication should return True while failures should
@@ -208,7 +209,7 @@ class ReauthenticateProvider(ABC):
 
     If a ReauthenticateProvider determines that reauthentication should
     immediately end, it may raise
-    :class:`StopAuthentication<flaskbb.core.auth.authentication.StopAuthentication>`
+    :class:~flaskbb.core.auth.authentication.StopAuthentication`
     to safely end the process.
 
 
@@ -250,9 +251,10 @@ class ReauthenticateFailureHandler(ABC):
     Used to manager reauthentication failures in FlaskBB.
 
     ReauthenticateFailureHandlers are similiar to
-    :class:`AuthenticationFailureHandler<flaskbb.core.auth.authentication.AuthenticationFailureHandler>`
+    :class:`~flaskbb.core.auth.authentication.AuthenticationFailureHandler`
     except they receive the user instance rather than an indentifier for a user
     """
+
     @abstractmethod
     def handle_reauth_failure(self, user):
         """
@@ -272,7 +274,7 @@ class PostReauthenticateHandler(ABC):
     Used to post process successful reauthentication attempts.
 
     PostAuthenticationHandlers are similar to
-    :class:`PostAuthenticationHandler<flaskbb.core.auth.authentication.PostAuthenticationHandler>`,
+    :class:`~flaskbb.core.auth.authentication.PostAuthenticationHandler`,
     including their ability to cancel a successful attempt by raising
     :class:`StopAuthentication<flaskbb.core.auth.authentication.StopAuthentication>`
     """

+ 1 - 1
flaskbb/forum/views.py

@@ -327,7 +327,7 @@ class ManageForum(MethodView):
         )
 
     # TODO(anr): Clean this up. @_@
-    def post(self, forum_id, slug=None):
+    def post(self, forum_id, slug=None):  # noqa: C901
         forum_instance, __ = Forum.get_forum(
             forum_id=forum_id, user=real(current_user)
         )

+ 4 - 1
flaskbb/tokens/serializer.py

@@ -15,6 +15,9 @@ from itsdangerous import (BadData, BadSignature, SignatureExpired,
 from ..core import tokens
 
 
+_DEFAULT_EXPIRY = timedelta(hours=1)
+
+
 class FlaskBBTokenSerializer(tokens.TokenSerializer):
     """
     Default token serializer for FlaskBB. Generates JWTs
@@ -33,7 +36,7 @@ class FlaskBBTokenSerializer(tokens.TokenSerializer):
     :timedelta expiry: Expiration of tokens
     """
 
-    def __init__(self, secret_key, expiry=timedelta(hours=1)):
+    def __init__(self, secret_key, expiry=_DEFAULT_EXPIRY):
         self._serializer = TimedJSONWebSignatureSerializer(
             secret_key, int(expiry.total_seconds())
         )

+ 2 - 2
flaskbb/utils/database.py

@@ -126,7 +126,7 @@ class HideableMixin(object):
     hidden_at = db.Column(UTCDateTime(timezone=True), nullable=True)
 
     @declared_attr
-    def hidden_by_id(cls):
+    def hidden_by_id(cls):  # noqa: B902
         return db.Column(
             db.Integer,
             db.ForeignKey(
@@ -136,7 +136,7 @@ class HideableMixin(object):
         )
 
     @declared_attr
-    def hidden_by(cls):
+    def hidden_by(cls):  # noqa: B902
         return db.relationship(
             "User", uselist=False, foreign_keys=[cls.hidden_by_id]
         )

+ 6 - 2
flaskbb/utils/fields.py

@@ -159,16 +159,20 @@ class SelectBirthdayWidget(object):
         '%Y': 'select_date_year'
     }
 
-    def __init__(self, years=range(1930, datetime.utcnow().year + 1)):
+    def __init__(self, years=None):
         """Initialzes the widget.
 
         :param years: The min year which should be chooseable.
                       Defatuls to ``1930``.
         """
+        if years is None:
+            years = range(1930, datetime.utcnow().year + 1)
+
         super(SelectBirthdayWidget, self).__init__()
         self.FORMAT_CHOICES['%Y'] = [(x, str(x)) for x in years]
 
-    def __call__(self, field, **kwargs):
+    # TODO(anr): clean up
+    def __call__(self, field, **kwargs):  # noqa: C901
         field_id = kwargs.pop('id', field.id)
         html = []
         allowed_format = ['%d', '%m', '%Y']

+ 2 - 1
flaskbb/utils/forms.py

@@ -58,7 +58,8 @@ def populate_settings_form(form, settings):
     return form
 
 
-def generate_settings_form(settings):
+# TODO(anr): clean this up
+def generate_settings_form(settings):  # noqa: C901
     """Generates a settings form which includes field validation
     based on our Setting Schema."""
     class SettingsForm(FlaskBBForm):

+ 2 - 1
flaskbb/utils/helpers.py

@@ -92,7 +92,8 @@ def render_template(template, **context):  # pragma: no cover
     return render_theme_template(theme, template, **context)
 
 
-def do_topic_action(topics, user, action, reverse):
+# TODO(anr): clean this up
+def do_topic_action(topics, user, action, reverse):  # noqa: C901
     """Executes a specific action for topics. Returns a list with the modified
     topic objects.
 

+ 3 - 8
flaskbb/utils/populate.py

@@ -279,11 +279,6 @@ def create_test_data(users=5, categories=2, forums=2, topics=1, posts=1):
     user1 = User.query.filter_by(id=1).first()
     user2 = User.query.filter_by(id=2).first()
 
-    # lets send them a few private messages
-    for i in range(1, 3):
-        # TODO
-        pass
-
     # create 2 categories
     for i in range(1, categories + 1):
         category_title = "Test Category %s" % i
@@ -303,7 +298,7 @@ def create_test_data(users=5, categories=2, forums=2, topics=1, posts=1):
             forum.save()
             data_created['forums'] += 1
 
-            for t in range(1, topics + 1):
+            for _ in range(1, topics + 1):
                 # create a topic
                 topic = Topic(title="Test Title %s" % j)
                 post = Post(content="Test Content")
@@ -311,7 +306,7 @@ def create_test_data(users=5, categories=2, forums=2, topics=1, posts=1):
                 topic.save(post=post, user=user1, forum=forum)
                 data_created['topics'] += 1
 
-                for p in range(1, posts + 1):
+                for _ in range(1, posts + 1):
                     # create a second post in the forum
                     post = Post(content="Test Post")
                     post.save(user=user2, topic=topic)
@@ -354,7 +349,7 @@ def insert_bulk_data(topic_count=10, post_count=100):
         created_topics += 1
 
         # create some posts in the topic
-        for j in range(1, post_count + 1):
+        for _ in range(1, post_count + 1):
             last_post_id += 1
             post = Post(content="Some other Post", user=user2, topic=topic.id)
             topic.last_updated = post.date_created

+ 1 - 1
requirements-cov.txt

@@ -1 +1 @@
-coverage==4.5.1
+coverage>=4.5.1

+ 2 - 2
requirements-dev.txt

@@ -7,5 +7,5 @@ pytest-cov
 Sphinx
 alabaster
 flake8
-tox==3.0.0
-bumpversion==0.5.3
+tox>=3.0.0
+bumpversion>=0.5.3

+ 2 - 0
requirements-lint.txt

@@ -0,0 +1,2 @@
+flake8>=3.5.0
+flake8-bugbear>=18.2.0

+ 3 - 5
requirements-test.txt

@@ -1,7 +1,5 @@
 -rrequirements.txt
 -rrequirements-cov.txt
-flake8==3.5.0
-pytest==3.6.2
-pytest-flake8==1.0.1
-pytest-mock==1.10.0
-freezegun==0.3.10
+pytest>=3.6.4
+pytest-mock>=1.10.0
+freezegun>=0.3.10

+ 3 - 3
requirements-travis.txt

@@ -1,4 +1,4 @@
 -r requirements-cov.txt
--r requirements.txt
-tox-travis==0.10
-coveralls==1.3.0
+-rrequirements.txt
+tox-travis>=0.10
+coveralls>=1.3.0

+ 57 - 57
requirements.txt

@@ -1,58 +1,58 @@
-alembic==0.9.9
-amqp==2.3.2
-attrs==18.1.0
-Babel==2.6.0
-billiard==3.5.0.3
-blinker==1.4
-celery==4.2.0
-certifi==2018.4.16
-chardet==3.0.4
-click==6.7
-click-log==0.3.2
-enum34==1.1.6
-Flask==1.0.2
-Flask-Alembic==2.0.1
-flask-allows==0.6.0
-Flask-BabelPlus==2.1.1
-Flask-Caching==1.4.0
-Flask-DebugToolbar==0.10.1
-flask-debugtoolbar-warnings==0.1.0
-Flask-Limiter==1.0.1
-Flask-Login==0.4.1
-Flask-Mail==0.9.1
-Flask-Redis==0.3.0
-Flask-SQLAlchemy==2.3.2
-Flask-Themes2==0.1.4
-flask-whooshee==0.6.0
-Flask-WTF==0.14.2
-flaskbb-plugin-conversations==1.0.3
-flaskbb-plugin-portal==1.1.1
-idna==2.7
-itsdangerous==0.24
-Jinja2==2.10
-kombu==4.2.1
-limits==1.3
-Mako==1.0.7
-MarkupSafe==1.0
-mistune==0.8.3
-olefile==0.45.1
-Pillow==5.1.0
-pluggy==0.6.0
-Pygments==2.2.0
-python-dateutil==2.7.3
-python-editor==1.0.3
-pytz==2018.4
-redis==2.10.6
-requests==2.19.1
-simplejson==3.15.0
-six==1.11.0
-speaklater==1.3
-SQLAlchemy==1.2.8
-SQLAlchemy-Utils==0.33.3
-Unidecode==1.0.22
-urllib3==1.23
-vine==1.1.4
-Werkzeug==0.14.1
-Whoosh==2.7.4
-WTForms==2.2.1
+alembic>=0.9.9
+amqp>=2.3.2
+attrs>=18.1.0
+Babel>=2.6.0
+billiard>=3.5.0.3
+blinker>=1.4
+celery>=4.2.0
+certifi>=2018.4.16
+chardet>=3.0.4
+click>=6.7
+click-log>=0.3.2
+enum34>=1.1.6
+Flask>=1.0.2
+Flask-Alembic>=2.0.1
+flask-allows>=0.6.0
+Flask-BabelPlus>=2.1.1
+Flask-Caching>=1.4.0
+Flask-DebugToolbar>=0.10.1
+flask-debugtoolbar-warnings>=0.1.0
+Flask-Limiter>=1.0.1
+Flask-Login>=0.4.1
+Flask-Mail>=0.9.1
+Flask-Redis>=0.3.0
+Flask-SQLAlchemy>=2.3.2
+Flask-Themes2>=0.1.4
+flask-whooshee>=0.6.0
+Flask-WTF>=0.14.2
+flaskbb-plugin-conversations>=1.0.3
+flaskbb-plugin-portal>=1.1.1
+idna>=2.7
+itsdangerous>=0.24
+Jinja2>=2.10
+kombu>=4.2.1
+limits>=1.3
+Mako>=1.0.7
+MarkupSafe>=1.0
+mistune>=0.8.3
+olefile>=0.45.1
+Pillow>=5.1.0
+pluggy>=0.6.0
+Pygments>=2.2.0
+python-dateutil>=2.7.3
+python-editor>=1.0.3
+pytz>=2018.4
+redis>=2.10.6
+requests>=2.19.1
+simplejson>=3.15.0
+six>=1.11.0
+speaklater>=1.3
+SQLAlchemy>=1.2.8
+SQLAlchemy-Utils>=0.33.3
+Unidecode>=1.0.22
+urllib3>=1.23
+vine>=1.1.4
+Werkzeug>=0.14.1
+Whoosh>=2.7.4
+WTForms>=2.2.1
 -e .

+ 35 - 5
tox.ini

@@ -1,10 +1,10 @@
 [tox]
-envlist = py27,py34,py35,py36,py37,cov-report,cov-store
+envlist = flake8,py27,py34,py35,py36,py37,cov-report,cov-store
 
 [testenv]
 use_develop = true
 deps =
-    py27: mock==2.0.0
+    py27: mock>=2.0.0
     -r{toxinidir}/requirements-test.txt
 setenv =
     COVERAGE_FILE = tests/.coverage.{envname}
@@ -12,6 +12,14 @@ setenv =
 commands =
     coverage run -m pytest {toxinidir}/tests {toxinidir}/flaskbb {posargs}
 
+[testenv:flake8]
+skip_install = true
+deps = -r{toxinidir}/requirements-lint.txt
+basepython=python3.6
+commands =
+    flake8 --version
+    flake8 --config={toxinidir}/tox.ini {toxinidir}/flaskbb {toxinidir}/tests
+
 [testenv:cov-report]
 skip_install = true
 setenv =
@@ -32,12 +40,34 @@ commands =
     coverage html
 
 
+[testenv:black]
+skip_install = true
+deps = black
+basepython=python3.6
+commands = black --check tests/ flaskbb/
+
 [flake8]
-ignore = E712, E711, C901, W503
+ignore = E203, E712, E711, W503
+select = C,E,F,W,B,B9
 max-complexity = 10
 max-line-length = 88
-exclude = flaskbb/configs/default.py,flaskbb/_compat.py
+exclude =
+    # allowed to break the rules
+    flaskbb/configs/default.py,
+    flaskbb/_compat.py,
+    # migrations are autogenerated
+    migrations,
+    # stuff to not inspect at all
+    node_modules,
+    .git,
+    .tox,
+    *.pyc,
+    __pycache__,
+    instance,
+    dist,
+    build,
+    docs
 
 [pytest]
-addopts =  -vvl --strict --flake8 --capture fd -W error::flaskbb.deprecation.FlaskBBDeprecation
+addopts =  -vvl --strict --capture fd -W error::flaskbb.deprecation.FlaskBBDeprecation
 norecursedirs = node_modules