diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 091475d0..5c227387 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -58,7 +58,7 @@ repos: additional_dependencies: - toml - repo: https://github.com/psf/black - rev: 23.12.1 + rev: 24.1.1 hooks: - id: black - repo: https://github.com/pre-commit/mirrors-mypy @@ -94,7 +94,7 @@ repos: additional_dependencies: - tomli - repo: https://github.com/PyCQA/bandit - rev: 1.7.6 + rev: 1.7.7 hooks: - id: bandit language_version: python3 diff --git a/docs/baseframe/conf.py b/docs/baseframe/conf.py index 56ecac66..3b46ce81 100644 --- a/docs/baseframe/conf.py +++ b/docs/baseframe/conf.py @@ -1,4 +1,5 @@ """Sphinx configuration.""" + # flake8: noqa # # baseframe documentation build configuration file, created by diff --git a/pyproject.toml b/pyproject.toml index 1e34e955..4b965f66 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,7 +71,7 @@ where = ['src'] [tool.black] line-length = 88 -target_version = ['py39'] +target-version = ['py39'] skip-string-normalization = true include = '\.pyi?$' exclude = ''' @@ -147,6 +147,7 @@ disable = [ 'cyclic-import', # We have tail imports all over 'fixme', # Our workflow is to tag for future fixes 'invalid-name', # Flake8 covers our naming convention requirements + 'line-too-long', # Let Black/Ruff handle this 'missing-class-docstring', # Backlog 'missing-function-docstring', # Backlog 'no-member', # Pylint doesn't understand mixins referring to main class members diff --git a/setup.cfg b/setup.cfg index b929a7b7..e93d7b4b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,7 +1,7 @@ # Config for tools that don't yet support pyproject.toml [flake8] -ignore = I100, I201, E501, E124, E128, E402, W503, D100, D101, D102, D103, D104, D107, S101 +ignore = I100, I201, E501, E124, E128, E402, E704, W503, D100, D101, D102, D103, D104, D107, S101 max-line-length = 88 exclude = src/baseframe/static enable-extensions = G diff --git a/src/baseframe/blueprint.py b/src/baseframe/blueprint.py index 9ebe6870..1688dda7 100644 --- a/src/baseframe/blueprint.py +++ b/src/baseframe/blueprint.py @@ -314,9 +314,9 @@ def init_app( app.config['theme'] = theme if 'NETWORKBAR_DATA' not in app.config: - app.config[ - 'NETWORKBAR_DATA' - ] = 'https://api.hasgeek.com/1/networkbar/networkbar.json' + app.config['NETWORKBAR_DATA'] = ( + 'https://api.hasgeek.com/1/networkbar/networkbar.json' + ) if isinstance(app.config.get('NETWORKBAR_DATA'), (list, tuple)): app.config['NETWORKBAR_LINKS'] = app.config['NETWORKBAR_DATA'] diff --git a/src/baseframe/extensions.py b/src/baseframe/extensions.py index 51298cc5..9618272d 100644 --- a/src/baseframe/extensions.py +++ b/src/baseframe/extensions.py @@ -1,4 +1,5 @@ """Standard extensions to add to the Flask app.""" + # pyright: reportMissingImports = false import os.path @@ -46,8 +47,7 @@ class GetTextProtocol(te.Protocol): and that the return type is a string (though actually a LazyString). """ - def __call__(self, string: te.LiteralString, **variables) -> str: - ... + def __call__(self, string: te.LiteralString, **variables) -> str: ... DEFAULT_LOCALE = 'en' diff --git a/src/baseframe/forms/fields.py b/src/baseframe/forms/fields.py index fde65ae9..77048713 100644 --- a/src/baseframe/forms/fields.py +++ b/src/baseframe/forms/fields.py @@ -1,4 +1,5 @@ """Form fields.""" + # pylint: disable=attribute-defined-outside-init from __future__ import annotations diff --git a/src/baseframe/forms/typing.py b/src/baseframe/forms/typing.py index ba423df2..4b5231f1 100644 --- a/src/baseframe/forms/typing.py +++ b/src/baseframe/forms/typing.py @@ -19,8 +19,7 @@ class WidgetProtocol(te.Protocol): """Protocol for a WTForms widget.""" - def __call__(self, field: WTField, **kwargs: t.Any) -> Markup: - ... + def __call__(self, field: WTField, **kwargs: t.Any) -> Markup: ... WidgetConstructor: te.TypeAlias = t.Callable[..., WidgetProtocol] @@ -31,5 +30,4 @@ class ValidatorProtocol(te.Protocol): field_flags: t.Dict[str, bool] - def __call__(self, form: WTForm, field: WTField) -> None: - ... + def __call__(self, form: WTForm, field: WTField) -> None: ... diff --git a/src/baseframe/views.py b/src/baseframe/views.py index 0be10a12..0665dfc3 100644 --- a/src/baseframe/views.py +++ b/src/baseframe/views.py @@ -161,13 +161,15 @@ def favicon(subdomain: t.Optional[str] = None) -> Response: def humans(subdomain: t.Optional[str] = None) -> Response: """Render humans.txt from app's static folder, falling back to default file.""" return send_from_directory( - current_app.static_folder - if os.path.exists( - os.path.join( - current_app.static_folder, 'humans.txt' # type: ignore[arg-type] + ( + current_app.static_folder + if os.path.exists( + os.path.join( + current_app.static_folder, 'humans.txt' # type: ignore[arg-type] + ) ) - ) - else baseframe.static_folder, + else baseframe.static_folder + ), 'humans.txt', mimetype='text/plain', ) @@ -178,13 +180,15 @@ def humans(subdomain: t.Optional[str] = None) -> Response: def robots(subdomain: t.Optional[str] = None) -> Response: """Render robots.txt from app's static folder, falling back to default file.""" return send_from_directory( - current_app.static_folder - if os.path.exists( - os.path.join( - current_app.static_folder, 'robots.txt' # type: ignore[arg-type] + ( + current_app.static_folder + if os.path.exists( + os.path.join( + current_app.static_folder, 'robots.txt' # type: ignore[arg-type] + ) ) - ) - else baseframe.static_folder, + else baseframe.static_folder + ), 'robots.txt', mimetype='text/plain', ) diff --git a/tests/baseframe_tests/conftest.py b/tests/baseframe_tests/conftest.py index fff2b35b..8ec589e6 100644 --- a/tests/baseframe_tests/conftest.py +++ b/tests/baseframe_tests/conftest.py @@ -1,4 +1,5 @@ """Test configuration.""" + # pylint: disable=redefined-outer-name import pytest diff --git a/tests/baseframe_tests/filters_test.py b/tests/baseframe_tests/filters_test.py index 36fe9969..e77fd055 100644 --- a/tests/baseframe_tests/filters_test.py +++ b/tests/baseframe_tests/filters_test.py @@ -1,4 +1,5 @@ """Test form filters.""" + # pylint: disable=redefined-outer-name import typing as t @@ -276,8 +277,7 @@ def test_dt_filters_timestamp_filter_hi(app, times) -> None: == "1 सेकंड में" ) assert ( - filters.timedelta_filter(timedelta(days=1), add_direction=True) - == "1 दिन में" + filters.timedelta_filter(timedelta(days=1), add_direction=True) == "1 दिन में" ) # Narrow format doesn't work for add_direction assert ( diff --git a/tests/baseframe_tests/forms/fields_test.py b/tests/baseframe_tests/forms/fields_test.py index b7c713f0..c08a380a 100644 --- a/tests/baseframe_tests/forms/fields_test.py +++ b/tests/baseframe_tests/forms/fields_test.py @@ -1,4 +1,5 @@ """Test form fields.""" + # pylint: disable=redefined-outer-name,protected-access from datetime import datetime diff --git a/tests/baseframe_tests/forms/form_test.py b/tests/baseframe_tests/forms/form_test.py index 3d72984d..b51e8665 100644 --- a/tests/baseframe_tests/forms/form_test.py +++ b/tests/baseframe_tests/forms/form_test.py @@ -1,4 +1,5 @@ """Test forms.""" + # pylint: disable=redefined-outer-name import pytest diff --git a/tests/baseframe_tests/forms/sqlalchemy_test.py b/tests/baseframe_tests/forms/sqlalchemy_test.py index a243f4cc..97cd9754 100644 --- a/tests/baseframe_tests/forms/sqlalchemy_test.py +++ b/tests/baseframe_tests/forms/sqlalchemy_test.py @@ -1,4 +1,5 @@ """Test SQLAlchemy fields.""" + # pylint: disable=redefined-outer-name import pytest diff --git a/tests/baseframe_tests/forms/validators_test.py b/tests/baseframe_tests/forms/validators_test.py index da9720ef..4ca5b4a2 100644 --- a/tests/baseframe_tests/forms/validators_test.py +++ b/tests/baseframe_tests/forms/validators_test.py @@ -1,4 +1,5 @@ """Test form validators.""" + # pylint: disable=redefined-outer-name import re diff --git a/tests/baseframe_tests/statsd_test.py b/tests/baseframe_tests/statsd_test.py index a579b69e..9e227456 100644 --- a/tests/baseframe_tests/statsd_test.py +++ b/tests/baseframe_tests/statsd_test.py @@ -1,4 +1,5 @@ """Test statsd logging.""" + # pylint: disable=redefined-outer-name # Tests adapted from https://github.com/bbelyeu/flask-statsdclient @@ -239,9 +240,11 @@ def test_tags(app, ctx, statsd) -> None: def test_request_handler_notags(app, statsd, view) -> None: """Test request_handlers logging with tags disabled.""" - with patch('statsd.StatsClient.incr') as mock_incr, patch( - 'statsd.StatsClient.timing' - ) as mock_timing, app.test_client() as client: + with ( + patch('statsd.StatsClient.incr') as mock_incr, + patch('statsd.StatsClient.timing') as mock_timing, + app.test_client() as client, + ): client.get('/') # First call mock_incr.assert_any_call( @@ -263,9 +266,11 @@ def test_request_handler_notags(app, statsd, view) -> None: def test_request_handler_tags(app, statsd, view) -> None: """Test request_handlers logging with tags enabled.""" app.config['STATSD_TAGS'] = ',' - with patch('statsd.StatsClient.incr') as mock_incr, patch( - 'statsd.StatsClient.timing' - ) as mock_timing, app.test_client() as client: + with ( + patch('statsd.StatsClient.incr') as mock_incr, + patch('statsd.StatsClient.timing') as mock_timing, + app.test_client() as client, + ): client.get('/') mock_incr.assert_called_once_with( 'flask_app.request_handlers,endpoint=index,status_code=200' @@ -280,9 +285,11 @@ def test_request_handler_disabled(app, view) -> None: """Test request_handlers logging disabled.""" app.config['STATSD_REQUEST_LOG'] = False Statsd(app) - with patch('statsd.StatsClient.incr') as mock_incr, patch( - 'statsd.StatsClient.timing' - ) as mock_timing, app.test_client() as client: + with ( + patch('statsd.StatsClient.incr') as mock_incr, + patch('statsd.StatsClient.timing') as mock_timing, + app.test_client() as client, + ): client.get('/') mock_incr.assert_not_called() mock_timing.assert_not_called() @@ -290,9 +297,11 @@ def test_request_handler_disabled(app, view) -> None: def test_render_template_notags(app, statsd) -> None: """Test render_template logging with tags disabled.""" - with patch('statsd.StatsClient.incr') as mock_incr, patch( - 'statsd.StatsClient.timing' - ) as mock_timing, app.app_context(): + with ( + patch('statsd.StatsClient.incr') as mock_incr, + patch('statsd.StatsClient.timing') as mock_timing, + app.app_context(), + ): render_template_string("Test template") assert mock_incr.call_count == 2 assert mock_timing.call_count == 2 @@ -311,9 +320,11 @@ def test_render_template_notags(app, statsd) -> None: def test_render_template_tags(app, statsd) -> None: """Test render_template logging with tags enabled.""" app.config['STATSD_TAGS'] = ',' - with patch('statsd.StatsClient.incr') as mock_incr, patch( - 'statsd.StatsClient.timing' - ) as mock_timing, app.app_context(): + with ( + patch('statsd.StatsClient.incr') as mock_incr, + patch('statsd.StatsClient.timing') as mock_timing, + app.app_context(), + ): render_template_string("Test template") assert mock_incr.call_count == 1 assert mock_timing.call_count == 1 @@ -331,9 +342,11 @@ def test_render_template_disabled(app, view) -> None: """Test render_template logging disabled.""" app.config['STATSD_RENDERTEMPLATE_LOG'] = False Statsd(app) - with patch('statsd.StatsClient.incr') as mock_incr, patch( - 'statsd.StatsClient.timing' - ) as mock_timing, app.app_context(): + with ( + patch('statsd.StatsClient.incr') as mock_incr, + patch('statsd.StatsClient.timing') as mock_timing, + app.app_context(), + ): render_template_string("Test template") mock_incr.assert_not_called() mock_timing.assert_not_called() diff --git a/tests/baseframe_tests/utils_test.py b/tests/baseframe_tests/utils_test.py index 60c93f38..1e0e933d 100644 --- a/tests/baseframe_tests/utils_test.py +++ b/tests/baseframe_tests/utils_test.py @@ -1,4 +1,5 @@ """Test utils.""" + # pylint: disable=redefined-outer-name import pytest