From abee2cee8853fc99f9eedce18c6680b44d8f3526 Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Fri, 28 Apr 2023 12:49:53 +0200 Subject: [PATCH] Code style improvements (#4683) * fix list comps * mopre comp fixes * reduce computing cost on any() calls * add bugbear * check for clean imports * only allow limited relative imports * fix notification method lookup * fix notification method assigement * rewrite assigment * fix upstream changes to new style * fix upstream change to new coding style --- .pre-commit-config.yaml | 5 +++- InvenTree/InvenTree/fields.py | 2 +- InvenTree/InvenTree/middleware.py | 2 +- InvenTree/InvenTree/models.py | 4 +-- InvenTree/InvenTree/sentry.py | 2 +- InvenTree/InvenTree/serializers.py | 2 +- InvenTree/InvenTree/tasks.py | 2 +- InvenTree/InvenTree/template.py | 2 +- InvenTree/InvenTree/tests.py | 4 +-- InvenTree/build/admin.py | 2 +- InvenTree/build/models.py | 6 ++--- InvenTree/common/files.py | 2 +- InvenTree/common/models.py | 2 +- InvenTree/common/notifications.py | 7 ++--- InvenTree/common/settings.py | 2 +- InvenTree/company/admin.py | 2 +- InvenTree/label/api.py | 2 +- InvenTree/label/apps.py | 2 +- InvenTree/order/admin.py | 4 +-- InvenTree/order/api.py | 5 ++-- InvenTree/order/models.py | 2 +- InvenTree/order/test_api.py | 4 +-- InvenTree/part/admin.py | 4 +-- InvenTree/part/api.py | 4 +-- InvenTree/part/models.py | 20 +++++++------- InvenTree/part/serializers.py | 2 +- InvenTree/part/test_bom_import.py | 8 +++--- InvenTree/plugin/admin.py | 2 +- InvenTree/plugin/base/event/events.py | 2 +- InvenTree/plugin/base/integration/mixins.py | 2 +- InvenTree/plugin/base/label/label.py | 2 +- InvenTree/plugin/mixins/__init__.py | 27 +++++++++---------- InvenTree/plugin/models.py | 2 +- InvenTree/plugin/plugin.py | 6 ++--- .../plugin/samples/event/event_sample.py | 2 +- InvenTree/report/api.py | 2 +- InvenTree/report/templatetags/barcode.py | 10 +++---- InvenTree/stock/admin.py | 2 +- InvenTree/stock/api.py | 2 +- InvenTree/stock/models.py | 16 ++++++----- InvenTree/stock/test_migrations.py | 2 +- InvenTree/users/admin.py | 2 +- docs/main.py | 2 +- setup.cfg | 1 + 44 files changed, 96 insertions(+), 93 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8d1055f531..9ed3e281f1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,9 +18,12 @@ repos: hooks: - id: flake8 additional_dependencies: [ + 'flake8-bugbear', + 'flake8-comprehensions', 'flake8-docstrings', 'flake8-string-format', - 'pep8-naming ', + 'flake8-tidy-imports', + 'pep8-naming' ] - repo: https://github.com/pycqa/isort rev: '5.12.0' diff --git a/InvenTree/InvenTree/fields.py b/InvenTree/InvenTree/fields.py index f0ebb23c9e..d00a419ce7 100644 --- a/InvenTree/InvenTree/fields.py +++ b/InvenTree/InvenTree/fields.py @@ -4,7 +4,7 @@ import sys from decimal import Decimal from django import forms -from django.db import models as models +from django.db import models from django.utils.translation import gettext_lazy as _ from djmoney.forms.fields import MoneyField diff --git a/InvenTree/InvenTree/middleware.py b/InvenTree/InvenTree/middleware.py index dcbf76f32f..c622822f12 100644 --- a/InvenTree/InvenTree/middleware.py +++ b/InvenTree/InvenTree/middleware.py @@ -102,7 +102,7 @@ class AuthRequiredMiddleware(object): '/static/', ] - if path not in urls and not any([path.startswith(p) for p in paths_ignore]): + if path not in urls and not any(path.startswith(p) for p in paths_ignore): # Save the 'next' parameter to pass through to the login view return redirect(f'{reverse_lazy("account_login")}?next={request.path}') diff --git a/InvenTree/InvenTree/models.py b/InvenTree/InvenTree/models.py index 86d561337e..385a5c8c53 100644 --- a/InvenTree/InvenTree/models.py +++ b/InvenTree/InvenTree/models.py @@ -706,7 +706,7 @@ class InvenTreeTree(MPTTModel): Returns: List of category names from the top level to the parent of this category """ - return [a for a in self.get_ancestors()] + return list(self.get_ancestors()) @property def path(self): @@ -884,7 +884,7 @@ def after_error_logged(sender, instance: Error, created: bool, **kwargs): 'inventree.error_log', context=context, targets=users, - delivery_methods=set([common.notifications.UIMessageNotification]), + delivery_methods={common.notifications.UIMessageNotification, }, ) except Exception as exc: diff --git a/InvenTree/InvenTree/sentry.py b/InvenTree/InvenTree/sentry.py index 471624ac4a..88d49e0f0c 100644 --- a/InvenTree/InvenTree/sentry.py +++ b/InvenTree/InvenTree/sentry.py @@ -59,7 +59,7 @@ def report_exception(exc): if settings.SENTRY_ENABLED and settings.SENTRY_DSN: - if not any([isinstance(exc, e) for e in sentry_ignore_errors()]): + if not any(isinstance(exc, e) for e in sentry_ignore_errors()): logger.info(f"Reporting exception to sentry.io: {exc}") try: diff --git a/InvenTree/InvenTree/serializers.py b/InvenTree/InvenTree/serializers.py index 405d2c28bf..26d9ea7528 100644 --- a/InvenTree/InvenTree/serializers.py +++ b/InvenTree/InvenTree/serializers.py @@ -499,7 +499,7 @@ class DataFileUploadSerializer(serializers.Serializer): pass # Extract a list of valid model field names - model_field_names = [key for key in model_fields.keys()] + model_field_names = list(model_fields.keys()) # Provide a dict of available columns from the dataset file_columns = {} diff --git a/InvenTree/InvenTree/tasks.py b/InvenTree/InvenTree/tasks.py index 4831a7fcd4..27469f5270 100644 --- a/InvenTree/InvenTree/tasks.py +++ b/InvenTree/InvenTree/tasks.py @@ -71,7 +71,7 @@ def raise_warning(msg): # If testing is running raise a warning that can be asserted if settings.TESTING: - warnings.warn(msg) + warnings.warn(msg, stacklevel=2) def check_daily_holdoff(task_name: str, n_days: int = 1) -> bool: diff --git a/InvenTree/InvenTree/template.py b/InvenTree/InvenTree/template.py index 38048de343..a07cbca988 100644 --- a/InvenTree/InvenTree/template.py +++ b/InvenTree/InvenTree/template.py @@ -30,7 +30,7 @@ class InvenTreeTemplateLoader(CachedLoader): template_path = str(template.name) # If the template matches any of the skip patterns, reload it without cache - if any([template_path.startswith(d) for d in skip_cache_dirs]): + if any(template_path.startswith(d) for d in skip_cache_dirs): template = BaseLoader.get_template(self, template_name, skip) return template diff --git a/InvenTree/InvenTree/tests.py b/InvenTree/InvenTree/tests.py index d877c8fdc3..8c8ca42892 100644 --- a/InvenTree/InvenTree/tests.py +++ b/InvenTree/InvenTree/tests.py @@ -807,7 +807,7 @@ class TestSettings(helpers.InvenTreeTestCase): 'inventree/data/config.yaml', ] - self.assertTrue(any([opt in str(config.get_config_file()).lower() for opt in valid])) + self.assertTrue(any(opt in str(config.get_config_file()).lower() for opt in valid)) # with env set with self.in_env_context({'INVENTREE_CONFIG_FILE': 'my_special_conf.yaml'}): @@ -822,7 +822,7 @@ class TestSettings(helpers.InvenTreeTestCase): 'inventree/data/plugins.txt', ] - self.assertTrue(any([opt in str(config.get_plugin_file()).lower() for opt in valid])) + self.assertTrue(any(opt in str(config.get_plugin_file()).lower() for opt in valid)) # with env set with self.in_env_context({'INVENTREE_PLUGIN_FILE': 'my_special_plugins.txt'}): diff --git a/InvenTree/build/admin.py b/InvenTree/build/admin.py index 9438526753..9bcfc78327 100644 --- a/InvenTree/build/admin.py +++ b/InvenTree/build/admin.py @@ -4,7 +4,7 @@ from django.contrib import admin from import_export.admin import ImportExportModelAdmin from import_export.fields import Field -import import_export.widgets as widgets +from import_export import widgets from build.models import Build, BuildItem from InvenTree.admin import InvenTreeResource diff --git a/InvenTree/build/models.py b/InvenTree/build/models.py index 2a25af1a2d..dcb31aa0e6 100644 --- a/InvenTree/build/models.py +++ b/InvenTree/build/models.py @@ -875,7 +875,7 @@ class Build(MPTTModel, InvenTree.models.InvenTreeBarcodeMixin, InvenTree.models. # Filter by list of available parts available_stock = available_stock.filter( - part__in=[p for p in available_parts], + part__in=list(available_parts), ) # Filter out "serialized" stock items, these cannot be auto-allocated @@ -884,12 +884,12 @@ class Build(MPTTModel, InvenTree.models.InvenTreeBarcodeMixin, InvenTree.models. if location: # Filter only stock items located "below" the specified location sublocations = location.get_descendants(include_self=True) - available_stock = available_stock.filter(location__in=[loc for loc in sublocations]) + available_stock = available_stock.filter(location__in=list(sublocations)) if exclude_location: # Exclude any stock items from the provided location sublocations = exclude_location.get_descendants(include_self=True) - available_stock = available_stock.exclude(location__in=[loc for loc in sublocations]) + available_stock = available_stock.exclude(location__in=list(sublocations)) """ Next, we sort the available stock items with the following priority: diff --git a/InvenTree/common/files.py b/InvenTree/common/files.py index 5f0e2cb38d..dc3448bf7e 100644 --- a/InvenTree/common/files.py +++ b/InvenTree/common/files.py @@ -181,7 +181,7 @@ class FileManager: for i in range(self.row_count()): - data = [item for item in self.get_row_data(i)] + data = list(self.get_row_data(i)) # Is the row completely empty? Skip! empty = True diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index 1609993897..d53992245e 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -2411,7 +2411,7 @@ class WebhookEndpoint(models.Model): """ return WebhookMessage.objects.create( host=request.get_host(), - header=json.dumps({key: val for key, val in headers.items()}), + header=json.dumps(dict(headers.items())), body=payload, endpoint=self, ) diff --git a/InvenTree/common/notifications.py b/InvenTree/common/notifications.py index a20b5e8a75..fc87725ba4 100644 --- a/InvenTree/common/notifications.py +++ b/InvenTree/common/notifications.py @@ -231,10 +231,7 @@ class MethodStorageClass: return methods -IGNORED_NOTIFICATION_CLS = set([ - SingleNotificationMethod, - BulkNotificationMethod, -]) +IGNORED_NOTIFICATION_CLS = {SingleNotificationMethod, BulkNotificationMethod, } storage = MethodStorageClass() @@ -424,7 +421,7 @@ def trigger_superuser_notification(plugin: PluginConfig, msg: str): 'message': msg, }, targets=users, - delivery_methods=set([UIMessageNotification]), + delivery_methods={UIMessageNotification, }, ) diff --git a/InvenTree/common/settings.py b/InvenTree/common/settings.py index 3e9ce15566..96db99fa63 100644 --- a/InvenTree/common/settings.py +++ b/InvenTree/common/settings.py @@ -30,7 +30,7 @@ def currency_code_mappings(): def currency_codes(): """Returns the current currency codes.""" - return [a for a in settings.CURRENCIES] + return list(settings.CURRENCIES) def stock_expiry_enabled(): diff --git a/InvenTree/company/admin.py b/InvenTree/company/admin.py index dc1aa2ba72..9bc5562aaa 100644 --- a/InvenTree/company/admin.py +++ b/InvenTree/company/admin.py @@ -2,7 +2,7 @@ from django.contrib import admin -import import_export.widgets as widgets +from import_export import widgets from import_export.admin import ImportExportModelAdmin from import_export.fields import Field diff --git a/InvenTree/label/api.py b/InvenTree/label/api.py index ca076cf968..79d48e552f 100644 --- a/InvenTree/label/api.py +++ b/InvenTree/label/api.py @@ -118,7 +118,7 @@ class LabelListView(LabelFilterMixin, ListAPI): continue # Reduce queryset to only valid matches - queryset = queryset.filter(pk__in=[pk for pk in valid_label_ids]) + queryset = queryset.filter(pk__in=list(valid_label_ids)) return queryset diff --git a/InvenTree/label/apps.py b/InvenTree/label/apps.py index a75047a174..758e4964f9 100644 --- a/InvenTree/label/apps.py +++ b/InvenTree/label/apps.py @@ -41,7 +41,7 @@ class LabelConfig(AppConfig): self.create_labels() # pragma: no cover except (AppRegistryNotReady, OperationalError): # Database might not yet be ready - warnings.warn('Database was not ready for creating labels') + warnings.warn('Database was not ready for creating labels', stacklevel=2) def create_labels(self): """Create all default templates.""" diff --git a/InvenTree/order/admin.py b/InvenTree/order/admin.py index 648d71c8d8..97ce316bda 100644 --- a/InvenTree/order/admin.py +++ b/InvenTree/order/admin.py @@ -3,12 +3,12 @@ from django.contrib import admin from django.utils.translation import gettext_lazy as _ -import import_export.widgets as widgets +from import_export import widgets from import_export.admin import ImportExportModelAdmin from import_export.fields import Field -import order.models as models from InvenTree.admin import InvenTreeResource +from order import models class ProjectCodeResourceMixin: diff --git a/InvenTree/order/api.py b/InvenTree/order/api.py index 4f05393aeb..8b87cd26d8 100644 --- a/InvenTree/order/api.py +++ b/InvenTree/order/api.py @@ -14,8 +14,6 @@ from rest_framework import status from rest_framework.exceptions import ValidationError from rest_framework.response import Response -import order.models as models -import order.serializers as serializers from common.models import InvenTreeSetting, ProjectCode from common.settings import settings from company.models import SupplierPart @@ -27,6 +25,7 @@ from InvenTree.mixins import (CreateAPI, ListAPI, ListCreateAPI, RetrieveUpdateDestroyAPI) from InvenTree.status_codes import (PurchaseOrderStatus, ReturnOrderLineStatus, ReturnOrderStatus, SalesOrderStatus) +from order import models, serializers from order.admin import (PurchaseOrderExtraLineResource, PurchaseOrderLineItemResource, PurchaseOrderResource, ReturnOrderResource, SalesOrderExtraLineResource, @@ -1431,7 +1430,7 @@ class OrderCalendarExport(ICalFeed): # Help: # https://django.readthedocs.io/en/stable/ref/contrib/syndication.html - obj = dict() + obj = {} obj['ordertype'] = kwargs['ordertype'] obj['include_completed'] = bool(request.GET.get('include_completed', False)) diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py index 94b3e22fb7..9397063ac3 100644 --- a/InvenTree/order/models.py +++ b/InvenTree/order/models.py @@ -840,7 +840,7 @@ class SalesOrder(TotalPriceMixin, Order): def is_completed(self): """Check if this order is "shipped" (all line items delivered).""" - return self.lines.count() > 0 and all([line.is_completed() for line in self.lines.all()]) + return self.lines.count() > 0 and all(line.is_completed() for line in self.lines.all()) def can_complete(self, raise_error=False, allow_incomplete_lines=False): """Test if this SalesOrder can be completed. diff --git a/InvenTree/order/test_api.py b/InvenTree/order/test_api.py index 42b404316b..64d3430939 100644 --- a/InvenTree/order/test_api.py +++ b/InvenTree/order/test_api.py @@ -13,13 +13,13 @@ from djmoney.money import Money from icalendar import Calendar from rest_framework import status -import order.models as models from common.settings import currency_codes from company.models import Company from InvenTree.api_tester import InvenTreeAPITestCase from InvenTree.status_codes import (PurchaseOrderStatus, ReturnOrderLineStatus, ReturnOrderStatus, SalesOrderStatus, StockStatus) +from order import models from part.models import Part from stock.models import StockItem @@ -1182,7 +1182,7 @@ class SalesOrderTest(OrderTest): idx += 1 # Create some extra lines against this order - for ii in range(3): + for _ in range(3): extra_lines.append( models.SalesOrderExtraLine( order=so, diff --git a/InvenTree/part/admin.py b/InvenTree/part/admin.py index 8f5f6b164a..dbe312a120 100644 --- a/InvenTree/part/admin.py +++ b/InvenTree/part/admin.py @@ -3,13 +3,13 @@ from django.contrib import admin from django.utils.translation import gettext_lazy as _ -import import_export.widgets as widgets +from import_export import widgets from import_export.admin import ImportExportModelAdmin from import_export.fields import Field -import part.models as models from company.models import SupplierPart from InvenTree.admin import InvenTreeResource +from part import models from stock.models import StockLocation diff --git a/InvenTree/part/api.py b/InvenTree/part/api.py index 7144108b3c..3b0cc3000b 100644 --- a/InvenTree/part/api.py +++ b/InvenTree/part/api.py @@ -1140,10 +1140,10 @@ class PartList(PartMixin, APIDownloadMixin, ListCreateAPI): if related is not None: # Only return related results - queryset = queryset.filter(pk__in=[pk for pk in part_ids]) + queryset = queryset.filter(pk__in=list(part_ids)) elif exclude_related is not None: # Exclude related results - queryset = queryset.exclude(pk__in=[pk for pk in part_ids]) + queryset = queryset.exclude(pk__in=list(part_ids)) except (ValueError, Part.DoesNotExist): pass diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 7dd89bf04c..6a714f49d4 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -89,14 +89,15 @@ class PartCategory(MetadataMixin, InvenTreeTree): for child_category in self.children.all(): if kwargs.get('delete_child_categories', False): - child_category.delete_recursive(**dict(delete_child_categories=True, - delete_parts=delete_parts, - parent_category=parent_category)) + child_category.delete_recursive(**{ + "delete_child_categories": True, + "delete_parts": delete_parts, + "parent_category": parent_category}) else: child_category.parent = parent_category child_category.save() - super().delete(*args, **dict()) + super().delete(*args, **{}) def delete(self, *args, **kwargs): """Custom model deletion routine, which updates any child categories or parts. @@ -104,9 +105,10 @@ class PartCategory(MetadataMixin, InvenTreeTree): This must be handled within a transaction.atomic(), otherwise the tree structure is damaged """ with transaction.atomic(): - self.delete_recursive(**dict(delete_parts=kwargs.get('delete_parts', False), - delete_child_categories=kwargs.get('delete_child_categories', False), - parent_category=self.parent)) + self.delete_recursive(**{ + "delete_parts": kwargs.get('delete_parts', False), + "delete_child_categories": kwargs.get('delete_child_categories', False), + "parent_category": self.parent}) if self.parent is not None: # Partially rebuild the tree (cheaper than a complete rebuild) @@ -275,7 +277,7 @@ class PartCategory(MetadataMixin, InvenTreeTree): for result in queryset: subscribers.add(result.user) - return [s for s in subscribers] + return list(subscribers) def is_starred_by(self, user, **kwargs): """Returns True if the specified user subscribes to this category.""" @@ -1195,7 +1197,7 @@ class Part(InvenTreeBarcodeMixin, InvenTreeNotesMixin, MetadataMixin, MPTTModel) for sub in self.category.get_subscribers(): subscribers.add(sub) - return [s for s in subscribers] + return list(subscribers) def is_starred_by(self, user, **kwargs): """Return True if the specified user subscribes to this part.""" diff --git a/InvenTree/part/serializers.py b/InvenTree/part/serializers.py index 3646df6fe5..4a07afc16e 100644 --- a/InvenTree/part/serializers.py +++ b/InvenTree/part/serializers.py @@ -1340,7 +1340,7 @@ class BomImportExtractSerializer(DataFileExtractSerializer): part_columns = ['part', 'part_name', 'part_ipn', 'part_id'] - if not any([col in self.columns for col in part_columns]): + if not any(col in self.columns for col in part_columns): # At least one part column is required! raise serializers.ValidationError(_("No part column specified")) diff --git a/InvenTree/part/test_bom_import.py b/InvenTree/part/test_bom_import.py index d7d3367bb8..4d1d6f29e3 100644 --- a/InvenTree/part/test_bom_import.py +++ b/InvenTree/part/test_bom_import.py @@ -208,7 +208,7 @@ class BomUploadTest(InvenTreeAPITestCase): url, { 'columns': dataset.headers, - 'rows': [row for row in dataset], + 'rows': list(dataset), }, ) @@ -249,7 +249,7 @@ class BomUploadTest(InvenTreeAPITestCase): url, { 'columns': dataset.headers, - 'rows': [row for row in dataset], + 'rows': list(dataset), }, expected_code=201, ) @@ -276,7 +276,7 @@ class BomUploadTest(InvenTreeAPITestCase): url, { 'columns': dataset.headers, - 'rows': [row for row in dataset], + 'rows': list(dataset), }, expected_code=201, ) @@ -308,7 +308,7 @@ class BomUploadTest(InvenTreeAPITestCase): response = self.post( url, { - 'rows': [row for row in dataset], + 'rows': list(dataset), 'columns': dataset.headers, }, expected_code=201, diff --git a/InvenTree/plugin/admin.py b/InvenTree/plugin/admin.py index 253c347e9c..859f78ea89 100644 --- a/InvenTree/plugin/admin.py +++ b/InvenTree/plugin/admin.py @@ -2,8 +2,8 @@ from django.contrib import admin -import plugin.models as models import plugin.registry as pl_registry +from plugin import models def plugin_update(queryset, new_status: bool): diff --git a/InvenTree/plugin/base/event/events.py b/InvenTree/plugin/base/event/events.py index 3b899d4ca9..1301463ffc 100644 --- a/InvenTree/plugin/base/event/events.py +++ b/InvenTree/plugin/base/event/events.py @@ -116,7 +116,7 @@ def allow_table_event(table_name): 'users_', ] - if any([table_name.startswith(prefix) for prefix in ignore_prefixes]): + if any(table_name.startswith(prefix) for prefix in ignore_prefixes): return False ignore_tables = [ diff --git a/InvenTree/plugin/base/integration/mixins.py b/InvenTree/plugin/base/integration/mixins.py index 7faa21b061..46a394fa3a 100644 --- a/InvenTree/plugin/base/integration/mixins.py +++ b/InvenTree/plugin/base/integration/mixins.py @@ -473,7 +473,7 @@ class PanelMixin: # Check for required keys required_keys = ['title', 'content'] - if any([key not in panel for key in required_keys]): + if any(key not in panel for key in required_keys): logger.warning(f"Custom panel for plugin {__class__} is missing a required parameter") continue diff --git a/InvenTree/plugin/base/label/label.py b/InvenTree/plugin/base/label/label.py index d1ff575016..e8d791b87c 100644 --- a/InvenTree/plugin/base/label/label.py +++ b/InvenTree/plugin/base/label/label.py @@ -71,7 +71,7 @@ def print_label(plugin_slug: str, pdf_data, filename=None, label_instance=None, 'label.printing_failed', targets=[user], context=ctx, - delivery_methods=set([common.notifications.UIMessageNotification]) + delivery_methods={common.notifications.UIMessageNotification, }, ) if settings.TESTING: diff --git a/InvenTree/plugin/mixins/__init__.py b/InvenTree/plugin/mixins/__init__.py index 62330c5bbe..f21fd6f1ac 100644 --- a/InvenTree/plugin/mixins/__init__.py +++ b/InvenTree/plugin/mixins/__init__.py @@ -2,20 +2,19 @@ from common.notifications import (BulkNotificationMethod, SingleNotificationMethod) - -from ..base.action.mixins import ActionMixin -from ..base.barcodes.mixins import BarcodeMixin -from ..base.event.mixins import EventMixin -from ..base.integration.AppMixin import AppMixin -from ..base.integration.mixins import (APICallMixin, NavigationMixin, - PanelMixin, SettingsContentMixin, - ValidationMixin) -from ..base.integration.ReportMixin import ReportMixin -from ..base.integration.ScheduleMixin import ScheduleMixin -from ..base.integration.SettingsMixin import SettingsMixin -from ..base.integration.UrlsMixin import UrlsMixin -from ..base.label.mixins import LabelPrintingMixin -from ..base.locate.mixins import LocateMixin +from plugin.base.action.mixins import ActionMixin +from plugin.base.barcodes.mixins import BarcodeMixin +from plugin.base.event.mixins import EventMixin +from plugin.base.integration.AppMixin import AppMixin +from plugin.base.integration.mixins import (APICallMixin, NavigationMixin, + PanelMixin, SettingsContentMixin, + ValidationMixin) +from plugin.base.integration.ReportMixin import ReportMixin +from plugin.base.integration.ScheduleMixin import ScheduleMixin +from plugin.base.integration.SettingsMixin import SettingsMixin +from plugin.base.integration.UrlsMixin import UrlsMixin +from plugin.base.label.mixins import LabelPrintingMixin +from plugin.base.locate.mixins import LocateMixin __all__ = [ 'APICallMixin', diff --git a/InvenTree/plugin/models.py b/InvenTree/plugin/models.py index 3b8c540916..57f80bdecf 100644 --- a/InvenTree/plugin/models.py +++ b/InvenTree/plugin/models.py @@ -102,7 +102,7 @@ class PluginConfig(models.Model): if (self.active is False and self.__org_active is True) or \ (self.active is True and self.__org_active is False): if settings.PLUGIN_TESTING: - warnings.warn('A reload was triggered') + warnings.warn('A reload was triggered', stacklevel=2) registry.reload_plugins() return ret diff --git a/InvenTree/plugin/plugin.py b/InvenTree/plugin/plugin.py index 3fdaa702e2..e531e6a56f 100644 --- a/InvenTree/plugin/plugin.py +++ b/InvenTree/plugin/plugin.py @@ -46,7 +46,7 @@ class MetaBase: # Sound of a warning if old_key worked if value: - warnings.warn(f'Usage of {old_key} was depreciated in 0.7.0 in favour of {key}', DeprecationWarning) + warnings.warn(f'Usage of {old_key} was depreciated in 0.7.0 in favour of {key}', DeprecationWarning, stacklevel=2) # Use __default if still nothing set if (value is None) and __default: @@ -172,7 +172,7 @@ class MixinBase: if not with_base and 'base' in mixins: del mixins['base'] # only return dict - mixins = [a for a in mixins.values()] + mixins = list(mixins.values()) return mixins @@ -366,7 +366,7 @@ class InvenTreePlugin(VersionMixin, MixinBase, MetaBase): try: website = meta['Project-URL'].split(', ')[1] - except [ValueError, IndexError]: + except (ValueError, IndexError, ): website = meta['Project-URL'] return { diff --git a/InvenTree/plugin/samples/event/event_sample.py b/InvenTree/plugin/samples/event/event_sample.py index 9912d5f80c..0b77932068 100644 --- a/InvenTree/plugin/samples/event/event_sample.py +++ b/InvenTree/plugin/samples/event/event_sample.py @@ -23,4 +23,4 @@ class EventPluginSample(EventMixin, InvenTreePlugin): # Issue warning that we can test for if settings.PLUGIN_TESTING: - warnings.warn(f'Event `{event}` triggered') + warnings.warn(f'Event `{event}` triggered', stacklevel=2) diff --git a/InvenTree/report/api.py b/InvenTree/report/api.py index 1ad42b5238..b84da561b7 100644 --- a/InvenTree/report/api.py +++ b/InvenTree/report/api.py @@ -137,7 +137,7 @@ class ReportFilterMixin: valid_report_ids.add(report.pk) # Reduce queryset to only valid matches - queryset = queryset.filter(pk__in=[pk for pk in valid_report_ids]) + queryset = queryset.filter(pk__in=list(valid_report_ids)) return queryset diff --git a/InvenTree/report/templatetags/barcode.py b/InvenTree/report/templatetags/barcode.py index 38152917d5..8593526d15 100644 --- a/InvenTree/report/templatetags/barcode.py +++ b/InvenTree/report/templatetags/barcode.py @@ -40,11 +40,11 @@ def qrcode(data, **kwargs): """ # Construct "default" values - params = dict( - box_size=20, - border=1, - version=1, - ) + params = { + "box_size": 20, + "border": 1, + "version": 1, + } fill_color = kwargs.pop('fill_color', 'black') back_color = kwargs.pop('back_color', 'white') diff --git a/InvenTree/stock/admin.py b/InvenTree/stock/admin.py index 4970254ed0..3efb3fbf9b 100644 --- a/InvenTree/stock/admin.py +++ b/InvenTree/stock/admin.py @@ -3,7 +3,7 @@ from django.contrib import admin from django.utils.translation import gettext_lazy as _ -import import_export.widgets as widgets +from import_export import widgets from import_export.admin import ImportExportModelAdmin from import_export.fields import Field diff --git a/InvenTree/stock/api.py b/InvenTree/stock/api.py index 61b3bbf832..9e8ac14fc8 100644 --- a/InvenTree/stock/api.py +++ b/InvenTree/stock/api.py @@ -1118,7 +1118,7 @@ class StockItemTestResultList(ListCreateDestroyAPIView): # Note that this function is recursive! installed_items = item.get_installed_items(cascade=True) - items += [it for it in installed_items] + items += list(installed_items) queryset = queryset.filter(stock_item__in=items) diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py index 94aa168dc0..46cfb3f4a5 100644 --- a/InvenTree/stock/models.py +++ b/InvenTree/stock/models.py @@ -71,14 +71,15 @@ class StockLocation(InvenTreeBarcodeMixin, MetadataMixin, InvenTreeTree): for child_location in self.children.all(): if kwargs.get('delete_sub_locations', False): - child_location.delete_recursive(**dict(delete_sub_locations=True, - delete_stock_items=delete_stock_items, - parent_location=parent_location)) + child_location.delete_recursive(**{ + "delete_sub_locations": True, + "delete_stock_items": delete_stock_items, + "parent_location": parent_location}) else: child_location.parent = parent_location child_location.save() - super().delete(*args, **dict()) + super().delete(*args, **{}) def delete(self, *args, **kwargs): """Custom model deletion routine, which updates any child locations or items. @@ -87,9 +88,10 @@ class StockLocation(InvenTreeBarcodeMixin, MetadataMixin, InvenTreeTree): """ with transaction.atomic(): - self.delete_recursive(**dict(delete_stock_items=kwargs.get('delete_stock_items', False), - delete_sub_locations=kwargs.get('delete_sub_locations', False), - parent_category=self.parent)) + self.delete_recursive(**{ + "delete_stock_items": kwargs.get('delete_stock_items', False), + "delete_sub_locations": kwargs.get('delete_sub_locations', False), + "parent_category": self.parent}) if self.parent is not None: # Partially rebuild the tree (cheaper than a complete rebuild) diff --git a/InvenTree/stock/test_migrations.py b/InvenTree/stock/test_migrations.py index 650472fd72..af14af6f6d 100644 --- a/InvenTree/stock/test_migrations.py +++ b/InvenTree/stock/test_migrations.py @@ -110,7 +110,7 @@ class TestScheduledForDeletionMigration(MigratorTestCase): scheduled_for_deletion=True, ) - for ii in range(3): + for _ in range(3): StockItem.objects.create( part=part, quantity=200, diff --git a/InvenTree/users/admin.py b/InvenTree/users/admin.py index 693840187d..fac7416955 100644 --- a/InvenTree/users/admin.py +++ b/InvenTree/users/admin.py @@ -21,7 +21,7 @@ class RuleSetInline(admin.TabularInline): can_delete = False verbose_name = 'Ruleset' verbose_plural_name = 'Rulesets' - fields = ['name'] + [option for option in RuleSet.RULE_OPTIONS] + fields = ['name'] + list(RuleSet.RULE_OPTIONS) readonly_fields = ['name'] max_num = len(RuleSet.RULESET_CHOICES) min_num = 1 diff --git a/docs/main.py b/docs/main.py index ea254bfe85..1ba7a2965e 100644 --- a/docs/main.py +++ b/docs/main.py @@ -23,7 +23,7 @@ def define_env(env): for asset in os.listdir(directory): - if any([asset.endswith(x) for x in allowed]): + if any(asset.endswith(x) for x in allowed): assets.append(os.path.join(subdir, asset)) return assets diff --git a/setup.cfg b/setup.cfg index e1269ae43f..46d86e7832 100644 --- a/setup.cfg +++ b/setup.cfg @@ -27,6 +27,7 @@ per-file-ignores = __init__.py: D104 max-complexity = 20 docstring-convention=google +ban-relative-imports = parents [coverage:run] source = ./InvenTree