mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
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:
parent
660a4f8e39
commit
abee2cee88
@ -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'
|
||||||
|
@ -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
|
||||||
|
@ -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}')
|
||||||
|
@ -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:
|
||||||
|
@ -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:
|
||||||
|
@ -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 = {}
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
@ -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'}):
|
||||||
|
@ -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
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
)
|
)
|
||||||
|
@ -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, },
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -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():
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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."""
|
||||||
|
@ -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:
|
||||||
|
@ -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))
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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."""
|
||||||
|
@ -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"))
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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):
|
||||||
|
@ -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 = [
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
@ -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',
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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')
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user