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
This commit is contained in:
Matthias Mair 2023-04-28 12:49:53 +02:00 committed by GitHub
parent 660a4f8e39
commit abee2cee88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 96 additions and 93 deletions

View File

@ -18,9 +18,12 @@ repos:
hooks: hooks:
- id: flake8 - id: flake8
additional_dependencies: [ additional_dependencies: [
'flake8-bugbear',
'flake8-comprehensions',
'flake8-docstrings', 'flake8-docstrings',
'flake8-string-format', 'flake8-string-format',
'pep8-naming ', 'flake8-tidy-imports',
'pep8-naming'
] ]
- repo: https://github.com/pycqa/isort - repo: https://github.com/pycqa/isort
rev: '5.12.0' rev: '5.12.0'

View File

@ -4,7 +4,7 @@ import sys
from decimal import Decimal from decimal import Decimal
from django import forms 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 django.utils.translation import gettext_lazy as _
from djmoney.forms.fields import MoneyField from djmoney.forms.fields import MoneyField

View File

@ -102,7 +102,7 @@ class AuthRequiredMiddleware(object):
'/static/', '/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 # Save the 'next' parameter to pass through to the login view
return redirect(f'{reverse_lazy("account_login")}?next={request.path}') return redirect(f'{reverse_lazy("account_login")}?next={request.path}')

View File

@ -706,7 +706,7 @@ class InvenTreeTree(MPTTModel):
Returns: Returns:
List of category names from the top level to the parent of this category 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 @property
def path(self): def path(self):
@ -884,7 +884,7 @@ def after_error_logged(sender, instance: Error, created: bool, **kwargs):
'inventree.error_log', 'inventree.error_log',
context=context, context=context,
targets=users, targets=users,
delivery_methods=set([common.notifications.UIMessageNotification]), delivery_methods={common.notifications.UIMessageNotification, },
) )
except Exception as exc: except Exception as exc:

View File

@ -59,7 +59,7 @@ def report_exception(exc):
if settings.SENTRY_ENABLED and settings.SENTRY_DSN: 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}") logger.info(f"Reporting exception to sentry.io: {exc}")
try: try:

View File

@ -499,7 +499,7 @@ class DataFileUploadSerializer(serializers.Serializer):
pass pass
# Extract a list of valid model field names # 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 # Provide a dict of available columns from the dataset
file_columns = {} file_columns = {}

View File

@ -71,7 +71,7 @@ def raise_warning(msg):
# If testing is running raise a warning that can be asserted # If testing is running raise a warning that can be asserted
if settings.TESTING: if settings.TESTING:
warnings.warn(msg) warnings.warn(msg, stacklevel=2)
def check_daily_holdoff(task_name: str, n_days: int = 1) -> bool: def check_daily_holdoff(task_name: str, n_days: int = 1) -> bool:

View File

@ -30,7 +30,7 @@ class InvenTreeTemplateLoader(CachedLoader):
template_path = str(template.name) template_path = str(template.name)
# If the template matches any of the skip patterns, reload it without cache # 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) template = BaseLoader.get_template(self, template_name, skip)
return template return template

View File

@ -807,7 +807,7 @@ class TestSettings(helpers.InvenTreeTestCase):
'inventree/data/config.yaml', '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 env set
with self.in_env_context({'INVENTREE_CONFIG_FILE': 'my_special_conf.yaml'}): with self.in_env_context({'INVENTREE_CONFIG_FILE': 'my_special_conf.yaml'}):
@ -822,7 +822,7 @@ class TestSettings(helpers.InvenTreeTestCase):
'inventree/data/plugins.txt', '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 env set
with self.in_env_context({'INVENTREE_PLUGIN_FILE': 'my_special_plugins.txt'}): with self.in_env_context({'INVENTREE_PLUGIN_FILE': 'my_special_plugins.txt'}):

View File

@ -4,7 +4,7 @@ from django.contrib import admin
from import_export.admin import ImportExportModelAdmin from import_export.admin import ImportExportModelAdmin
from import_export.fields import Field from import_export.fields import Field
import import_export.widgets as widgets from import_export import widgets
from build.models import Build, BuildItem from build.models import Build, BuildItem
from InvenTree.admin import InvenTreeResource from InvenTree.admin import InvenTreeResource

View File

@ -875,7 +875,7 @@ class Build(MPTTModel, InvenTree.models.InvenTreeBarcodeMixin, InvenTree.models.
# Filter by list of available parts # Filter by list of available parts
available_stock = available_stock.filter( 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 # Filter out "serialized" stock items, these cannot be auto-allocated
@ -884,12 +884,12 @@ class Build(MPTTModel, InvenTree.models.InvenTreeBarcodeMixin, InvenTree.models.
if location: if location:
# Filter only stock items located "below" the specified location # Filter only stock items located "below" the specified location
sublocations = location.get_descendants(include_self=True) 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: if exclude_location:
# Exclude any stock items from the provided location # Exclude any stock items from the provided location
sublocations = exclude_location.get_descendants(include_self=True) 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: Next, we sort the available stock items with the following priority:

View File

@ -181,7 +181,7 @@ class FileManager:
for i in range(self.row_count()): 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! # Is the row completely empty? Skip!
empty = True empty = True

View File

@ -2411,7 +2411,7 @@ class WebhookEndpoint(models.Model):
""" """
return WebhookMessage.objects.create( return WebhookMessage.objects.create(
host=request.get_host(), host=request.get_host(),
header=json.dumps({key: val for key, val in headers.items()}), header=json.dumps(dict(headers.items())),
body=payload, body=payload,
endpoint=self, endpoint=self,
) )

View File

@ -231,10 +231,7 @@ class MethodStorageClass:
return methods return methods
IGNORED_NOTIFICATION_CLS = set([ IGNORED_NOTIFICATION_CLS = {SingleNotificationMethod, BulkNotificationMethod, }
SingleNotificationMethod,
BulkNotificationMethod,
])
storage = MethodStorageClass() storage = MethodStorageClass()
@ -424,7 +421,7 @@ def trigger_superuser_notification(plugin: PluginConfig, msg: str):
'message': msg, 'message': msg,
}, },
targets=users, targets=users,
delivery_methods=set([UIMessageNotification]), delivery_methods={UIMessageNotification, },
) )

View File

@ -30,7 +30,7 @@ def currency_code_mappings():
def currency_codes(): def currency_codes():
"""Returns the current currency codes.""" """Returns the current currency codes."""
return [a for a in settings.CURRENCIES] return list(settings.CURRENCIES)
def stock_expiry_enabled(): def stock_expiry_enabled():

View File

@ -2,7 +2,7 @@
from django.contrib import admin 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.admin import ImportExportModelAdmin
from import_export.fields import Field from import_export.fields import Field

View File

@ -118,7 +118,7 @@ class LabelListView(LabelFilterMixin, ListAPI):
continue continue
# Reduce queryset to only valid matches # 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 return queryset

View File

@ -41,7 +41,7 @@ class LabelConfig(AppConfig):
self.create_labels() # pragma: no cover self.create_labels() # pragma: no cover
except (AppRegistryNotReady, OperationalError): except (AppRegistryNotReady, OperationalError):
# Database might not yet be ready # 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): def create_labels(self):
"""Create all default templates.""" """Create all default templates."""

View File

@ -3,12 +3,12 @@
from django.contrib import admin from django.contrib import admin
from django.utils.translation import gettext_lazy as _ 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.admin import ImportExportModelAdmin
from import_export.fields import Field from import_export.fields import Field
import order.models as models
from InvenTree.admin import InvenTreeResource from InvenTree.admin import InvenTreeResource
from order import models
class ProjectCodeResourceMixin: class ProjectCodeResourceMixin:

View File

@ -14,8 +14,6 @@ from rest_framework import status
from rest_framework.exceptions import ValidationError from rest_framework.exceptions import ValidationError
from rest_framework.response import Response from rest_framework.response import Response
import order.models as models
import order.serializers as serializers
from common.models import InvenTreeSetting, ProjectCode from common.models import InvenTreeSetting, ProjectCode
from common.settings import settings from common.settings import settings
from company.models import SupplierPart from company.models import SupplierPart
@ -27,6 +25,7 @@ from InvenTree.mixins import (CreateAPI, ListAPI, ListCreateAPI,
RetrieveUpdateDestroyAPI) RetrieveUpdateDestroyAPI)
from InvenTree.status_codes import (PurchaseOrderStatus, ReturnOrderLineStatus, from InvenTree.status_codes import (PurchaseOrderStatus, ReturnOrderLineStatus,
ReturnOrderStatus, SalesOrderStatus) ReturnOrderStatus, SalesOrderStatus)
from order import models, serializers
from order.admin import (PurchaseOrderExtraLineResource, from order.admin import (PurchaseOrderExtraLineResource,
PurchaseOrderLineItemResource, PurchaseOrderResource, PurchaseOrderLineItemResource, PurchaseOrderResource,
ReturnOrderResource, SalesOrderExtraLineResource, ReturnOrderResource, SalesOrderExtraLineResource,
@ -1431,7 +1430,7 @@ class OrderCalendarExport(ICalFeed):
# Help: # Help:
# https://django.readthedocs.io/en/stable/ref/contrib/syndication.html # https://django.readthedocs.io/en/stable/ref/contrib/syndication.html
obj = dict() obj = {}
obj['ordertype'] = kwargs['ordertype'] obj['ordertype'] = kwargs['ordertype']
obj['include_completed'] = bool(request.GET.get('include_completed', False)) obj['include_completed'] = bool(request.GET.get('include_completed', False))

View File

@ -840,7 +840,7 @@ class SalesOrder(TotalPriceMixin, Order):
def is_completed(self): def is_completed(self):
"""Check if this order is "shipped" (all line items delivered).""" """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): def can_complete(self, raise_error=False, allow_incomplete_lines=False):
"""Test if this SalesOrder can be completed. """Test if this SalesOrder can be completed.

View File

@ -13,13 +13,13 @@ from djmoney.money import Money
from icalendar import Calendar from icalendar import Calendar
from rest_framework import status from rest_framework import status
import order.models as models
from common.settings import currency_codes from common.settings import currency_codes
from company.models import Company from company.models import Company
from InvenTree.api_tester import InvenTreeAPITestCase from InvenTree.api_tester import InvenTreeAPITestCase
from InvenTree.status_codes import (PurchaseOrderStatus, ReturnOrderLineStatus, from InvenTree.status_codes import (PurchaseOrderStatus, ReturnOrderLineStatus,
ReturnOrderStatus, SalesOrderStatus, ReturnOrderStatus, SalesOrderStatus,
StockStatus) StockStatus)
from order import models
from part.models import Part from part.models import Part
from stock.models import StockItem from stock.models import StockItem
@ -1182,7 +1182,7 @@ class SalesOrderTest(OrderTest):
idx += 1 idx += 1
# Create some extra lines against this order # Create some extra lines against this order
for ii in range(3): for _ in range(3):
extra_lines.append( extra_lines.append(
models.SalesOrderExtraLine( models.SalesOrderExtraLine(
order=so, order=so,

View File

@ -3,13 +3,13 @@
from django.contrib import admin from django.contrib import admin
from django.utils.translation import gettext_lazy as _ 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.admin import ImportExportModelAdmin
from import_export.fields import Field from import_export.fields import Field
import part.models as models
from company.models import SupplierPart from company.models import SupplierPart
from InvenTree.admin import InvenTreeResource from InvenTree.admin import InvenTreeResource
from part import models
from stock.models import StockLocation from stock.models import StockLocation

View File

@ -1140,10 +1140,10 @@ class PartList(PartMixin, APIDownloadMixin, ListCreateAPI):
if related is not None: if related is not None:
# Only return related results # 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: elif exclude_related is not None:
# Exclude related results # 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): except (ValueError, Part.DoesNotExist):
pass pass

View File

@ -89,14 +89,15 @@ class PartCategory(MetadataMixin, InvenTreeTree):
for child_category in self.children.all(): for child_category in self.children.all():
if kwargs.get('delete_child_categories', False): if kwargs.get('delete_child_categories', False):
child_category.delete_recursive(**dict(delete_child_categories=True, child_category.delete_recursive(**{
delete_parts=delete_parts, "delete_child_categories": True,
parent_category=parent_category)) "delete_parts": delete_parts,
"parent_category": parent_category})
else: else:
child_category.parent = parent_category child_category.parent = parent_category
child_category.save() child_category.save()
super().delete(*args, **dict()) super().delete(*args, **{})
def delete(self, *args, **kwargs): def delete(self, *args, **kwargs):
"""Custom model deletion routine, which updates any child categories or parts. """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 This must be handled within a transaction.atomic(), otherwise the tree structure is damaged
""" """
with transaction.atomic(): with transaction.atomic():
self.delete_recursive(**dict(delete_parts=kwargs.get('delete_parts', False), self.delete_recursive(**{
delete_child_categories=kwargs.get('delete_child_categories', False), "delete_parts": kwargs.get('delete_parts', False),
parent_category=self.parent)) "delete_child_categories": kwargs.get('delete_child_categories', False),
"parent_category": self.parent})
if self.parent is not None: if self.parent is not None:
# Partially rebuild the tree (cheaper than a complete rebuild) # Partially rebuild the tree (cheaper than a complete rebuild)
@ -275,7 +277,7 @@ class PartCategory(MetadataMixin, InvenTreeTree):
for result in queryset: for result in queryset:
subscribers.add(result.user) subscribers.add(result.user)
return [s for s in subscribers] return list(subscribers)
def is_starred_by(self, user, **kwargs): def is_starred_by(self, user, **kwargs):
"""Returns True if the specified user subscribes to this category.""" """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(): for sub in self.category.get_subscribers():
subscribers.add(sub) subscribers.add(sub)
return [s for s in subscribers] return list(subscribers)
def is_starred_by(self, user, **kwargs): def is_starred_by(self, user, **kwargs):
"""Return True if the specified user subscribes to this part.""" """Return True if the specified user subscribes to this part."""

View File

@ -1340,7 +1340,7 @@ class BomImportExtractSerializer(DataFileExtractSerializer):
part_columns = ['part', 'part_name', 'part_ipn', 'part_id'] 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! # At least one part column is required!
raise serializers.ValidationError(_("No part column specified")) raise serializers.ValidationError(_("No part column specified"))

View File

@ -208,7 +208,7 @@ class BomUploadTest(InvenTreeAPITestCase):
url, url,
{ {
'columns': dataset.headers, 'columns': dataset.headers,
'rows': [row for row in dataset], 'rows': list(dataset),
}, },
) )
@ -249,7 +249,7 @@ class BomUploadTest(InvenTreeAPITestCase):
url, url,
{ {
'columns': dataset.headers, 'columns': dataset.headers,
'rows': [row for row in dataset], 'rows': list(dataset),
}, },
expected_code=201, expected_code=201,
) )
@ -276,7 +276,7 @@ class BomUploadTest(InvenTreeAPITestCase):
url, url,
{ {
'columns': dataset.headers, 'columns': dataset.headers,
'rows': [row for row in dataset], 'rows': list(dataset),
}, },
expected_code=201, expected_code=201,
) )
@ -308,7 +308,7 @@ class BomUploadTest(InvenTreeAPITestCase):
response = self.post( response = self.post(
url, url,
{ {
'rows': [row for row in dataset], 'rows': list(dataset),
'columns': dataset.headers, 'columns': dataset.headers,
}, },
expected_code=201, expected_code=201,

View File

@ -2,8 +2,8 @@
from django.contrib import admin from django.contrib import admin
import plugin.models as models
import plugin.registry as pl_registry import plugin.registry as pl_registry
from plugin import models
def plugin_update(queryset, new_status: bool): def plugin_update(queryset, new_status: bool):

View File

@ -116,7 +116,7 @@ def allow_table_event(table_name):
'users_', '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 return False
ignore_tables = [ ignore_tables = [

View File

@ -473,7 +473,7 @@ class PanelMixin:
# Check for required keys # Check for required keys
required_keys = ['title', 'content'] 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") logger.warning(f"Custom panel for plugin {__class__} is missing a required parameter")
continue continue

View File

@ -71,7 +71,7 @@ def print_label(plugin_slug: str, pdf_data, filename=None, label_instance=None,
'label.printing_failed', 'label.printing_failed',
targets=[user], targets=[user],
context=ctx, context=ctx,
delivery_methods=set([common.notifications.UIMessageNotification]) delivery_methods={common.notifications.UIMessageNotification, },
) )
if settings.TESTING: if settings.TESTING:

View File

@ -2,20 +2,19 @@
from common.notifications import (BulkNotificationMethod, from common.notifications import (BulkNotificationMethod,
SingleNotificationMethod) SingleNotificationMethod)
from plugin.base.action.mixins import ActionMixin
from ..base.action.mixins import ActionMixin from plugin.base.barcodes.mixins import BarcodeMixin
from ..base.barcodes.mixins import BarcodeMixin from plugin.base.event.mixins import EventMixin
from ..base.event.mixins import EventMixin from plugin.base.integration.AppMixin import AppMixin
from ..base.integration.AppMixin import AppMixin from plugin.base.integration.mixins import (APICallMixin, NavigationMixin,
from ..base.integration.mixins import (APICallMixin, NavigationMixin, PanelMixin, SettingsContentMixin,
PanelMixin, SettingsContentMixin, ValidationMixin)
ValidationMixin) from plugin.base.integration.ReportMixin import ReportMixin
from ..base.integration.ReportMixin import ReportMixin from plugin.base.integration.ScheduleMixin import ScheduleMixin
from ..base.integration.ScheduleMixin import ScheduleMixin from plugin.base.integration.SettingsMixin import SettingsMixin
from ..base.integration.SettingsMixin import SettingsMixin from plugin.base.integration.UrlsMixin import UrlsMixin
from ..base.integration.UrlsMixin import UrlsMixin from plugin.base.label.mixins import LabelPrintingMixin
from ..base.label.mixins import LabelPrintingMixin from plugin.base.locate.mixins import LocateMixin
from ..base.locate.mixins import LocateMixin
__all__ = [ __all__ = [
'APICallMixin', 'APICallMixin',

View File

@ -102,7 +102,7 @@ class PluginConfig(models.Model):
if (self.active is False and self.__org_active is True) or \ if (self.active is False and self.__org_active is True) or \
(self.active is True and self.__org_active is False): (self.active is True and self.__org_active is False):
if settings.PLUGIN_TESTING: if settings.PLUGIN_TESTING:
warnings.warn('A reload was triggered') warnings.warn('A reload was triggered', stacklevel=2)
registry.reload_plugins() registry.reload_plugins()
return ret return ret

View File

@ -46,7 +46,7 @@ class MetaBase:
# Sound of a warning if old_key worked # Sound of a warning if old_key worked
if value: 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 # Use __default if still nothing set
if (value is None) and __default: if (value is None) and __default:
@ -172,7 +172,7 @@ class MixinBase:
if not with_base and 'base' in mixins: if not with_base and 'base' in mixins:
del mixins['base'] del mixins['base']
# only return dict # only return dict
mixins = [a for a in mixins.values()] mixins = list(mixins.values())
return mixins return mixins
@ -366,7 +366,7 @@ class InvenTreePlugin(VersionMixin, MixinBase, MetaBase):
try: try:
website = meta['Project-URL'].split(', ')[1] website = meta['Project-URL'].split(', ')[1]
except [ValueError, IndexError]: except (ValueError, IndexError, ):
website = meta['Project-URL'] website = meta['Project-URL']
return { return {

View File

@ -23,4 +23,4 @@ class EventPluginSample(EventMixin, InvenTreePlugin):
# Issue warning that we can test for # Issue warning that we can test for
if settings.PLUGIN_TESTING: if settings.PLUGIN_TESTING:
warnings.warn(f'Event `{event}` triggered') warnings.warn(f'Event `{event}` triggered', stacklevel=2)

View File

@ -137,7 +137,7 @@ class ReportFilterMixin:
valid_report_ids.add(report.pk) valid_report_ids.add(report.pk)
# Reduce queryset to only valid matches # 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 return queryset

View File

@ -40,11 +40,11 @@ def qrcode(data, **kwargs):
""" """
# Construct "default" values # Construct "default" values
params = dict( params = {
box_size=20, "box_size": 20,
border=1, "border": 1,
version=1, "version": 1,
) }
fill_color = kwargs.pop('fill_color', 'black') fill_color = kwargs.pop('fill_color', 'black')
back_color = kwargs.pop('back_color', 'white') back_color = kwargs.pop('back_color', 'white')

View File

@ -3,7 +3,7 @@
from django.contrib import admin from django.contrib import admin
from django.utils.translation import gettext_lazy as _ 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.admin import ImportExportModelAdmin
from import_export.fields import Field from import_export.fields import Field

View File

@ -1118,7 +1118,7 @@ class StockItemTestResultList(ListCreateDestroyAPIView):
# Note that this function is recursive! # Note that this function is recursive!
installed_items = item.get_installed_items(cascade=True) 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) queryset = queryset.filter(stock_item__in=items)

View File

@ -71,14 +71,15 @@ class StockLocation(InvenTreeBarcodeMixin, MetadataMixin, InvenTreeTree):
for child_location in self.children.all(): for child_location in self.children.all():
if kwargs.get('delete_sub_locations', False): if kwargs.get('delete_sub_locations', False):
child_location.delete_recursive(**dict(delete_sub_locations=True, child_location.delete_recursive(**{
delete_stock_items=delete_stock_items, "delete_sub_locations": True,
parent_location=parent_location)) "delete_stock_items": delete_stock_items,
"parent_location": parent_location})
else: else:
child_location.parent = parent_location child_location.parent = parent_location
child_location.save() child_location.save()
super().delete(*args, **dict()) super().delete(*args, **{})
def delete(self, *args, **kwargs): def delete(self, *args, **kwargs):
"""Custom model deletion routine, which updates any child locations or items. """Custom model deletion routine, which updates any child locations or items.
@ -87,9 +88,10 @@ class StockLocation(InvenTreeBarcodeMixin, MetadataMixin, InvenTreeTree):
""" """
with transaction.atomic(): with transaction.atomic():
self.delete_recursive(**dict(delete_stock_items=kwargs.get('delete_stock_items', False), self.delete_recursive(**{
delete_sub_locations=kwargs.get('delete_sub_locations', False), "delete_stock_items": kwargs.get('delete_stock_items', False),
parent_category=self.parent)) "delete_sub_locations": kwargs.get('delete_sub_locations', False),
"parent_category": self.parent})
if self.parent is not None: if self.parent is not None:
# Partially rebuild the tree (cheaper than a complete rebuild) # Partially rebuild the tree (cheaper than a complete rebuild)

View File

@ -110,7 +110,7 @@ class TestScheduledForDeletionMigration(MigratorTestCase):
scheduled_for_deletion=True, scheduled_for_deletion=True,
) )
for ii in range(3): for _ in range(3):
StockItem.objects.create( StockItem.objects.create(
part=part, part=part,
quantity=200, quantity=200,

View File

@ -21,7 +21,7 @@ class RuleSetInline(admin.TabularInline):
can_delete = False can_delete = False
verbose_name = 'Ruleset' verbose_name = 'Ruleset'
verbose_plural_name = 'Rulesets' verbose_plural_name = 'Rulesets'
fields = ['name'] + [option for option in RuleSet.RULE_OPTIONS] fields = ['name'] + list(RuleSet.RULE_OPTIONS)
readonly_fields = ['name'] readonly_fields = ['name']
max_num = len(RuleSet.RULESET_CHOICES) max_num = len(RuleSet.RULESET_CHOICES)
min_num = 1 min_num = 1

View File

@ -23,7 +23,7 @@ def define_env(env):
for asset in os.listdir(directory): 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)) assets.append(os.path.join(subdir, asset))
return assets return assets

View File

@ -27,6 +27,7 @@ per-file-ignores =
__init__.py: D104 __init__.py: D104
max-complexity = 20 max-complexity = 20
docstring-convention=google docstring-convention=google
ban-relative-imports = parents
[coverage:run] [coverage:run]
source = ./InvenTree source = ./InvenTree