remove unneeded branches

fixes SIM102
This commit is contained in:
Matthias Mair 2024-08-20 01:17:35 +02:00
parent 372e3d417e
commit f74d41bc07
No known key found for this signature in database
GPG Key ID: A593429DDA23B66A
24 changed files with 289 additions and 258 deletions

View File

@ -115,9 +115,8 @@ def exception_handler(exc, context):
log_error(context['request'].path)
if response is not None:
# Convert errors returned under the label '__all__' to 'non_field_errors'
if '__all__' in response.data:
if response is not None and '__all__' in response.data:
response.data['non_field_errors'] = response.data['__all__']
del response.data['__all__']

View File

@ -184,8 +184,11 @@ def getSplashScreen(custom=True):
"""Return the InvenTree splash screen, or a custom splash if available."""
static_storage = StaticFilesStorage()
if custom and settings.CUSTOM_SPLASH:
if static_storage.exists(settings.CUSTOM_SPLASH):
if (
custom
and settings.CUSTOM_SPLASH
and static_storage.exists(settings.CUSTOM_SPLASH)
):
return static_storage.url(settings.CUSTOM_SPLASH)
# No custom splash screen

View File

@ -34,8 +34,7 @@ class Command(BaseCommand):
if x and x.path:
img_paths.append(x.path)
if len(img_paths) > 0:
if all(os.path.exists(path) for path in img_paths):
if len(img_paths) > 0 and all(os.path.exists(path) for path in img_paths):
# All images exist - skip further work
return

View File

@ -28,8 +28,10 @@ def get_token_from_request(request):
if auth_header := request.headers.get(k, None):
auth_header = auth_header.strip().lower().split()
if len(auth_header) > 1:
if auth_header[0].strip().lower().replace(':', '') in token_keys:
if (
len(auth_header) > 1
and auth_header[0].strip().lower().replace(':', '') in token_keys
):
token = auth_header[1]
return token

View File

@ -63,8 +63,11 @@ def init_sentry(dsn, sample_rate, tags):
def report_exception(exc):
"""Report an exception to sentry.io."""
if settings.SENTRY_ENABLED and settings.SENTRY_DSN:
if not any(isinstance(exc, e) for e in sentry_ignore_errors()):
if (
settings.SENTRY_ENABLED
and settings.SENTRY_DSN
and not any(isinstance(exc, e) for e in sentry_ignore_errors())
):
logger.info('Reporting exception to sentry.io: %s', exc)
try:

View File

@ -50,9 +50,8 @@ def check_provider(provider):
if not app:
return False
if allauth.app_settings.SITES_ENABLED:
# At least one matching site must be specified
if not app.sites.exists():
if allauth.app_settings.SITES_ENABLED and not app.sites.exists():
logger.error('SocialApp %s has no sites configured', app)
return False

View File

@ -136,12 +136,11 @@ def inventree_in_debug_mode(*args, **kwargs):
@register.simple_tag()
def inventree_show_about(user, *args, **kwargs):
"""Return True if the about modal should be shown."""
if get_global_setting('INVENTREE_RESTRICT_ABOUT'):
# Return False if the user is not a superuser, or no user information is provided
if not user or not user.is_superuser:
return False
return True
return not (
(get_global_setting('INVENTREE_RESTRICT_ABOUT') and not user)
or not user.is_superuser
)
@register.simple_tag()

View File

@ -69,9 +69,8 @@ class AllowedURLValidator(validators.URLValidator):
# Determine if 'strict' URL validation is required (i.e. if the URL must have a schema prefix)
strict_urls = get_global_setting('INVENTREE_STRICT_URLS', cache=False)
if not strict_urls:
# Allow URLs which do not have a provided schema
if '://' not in value:
if not strict_urls and '://' not in value:
# Validate as if it were http
value = 'http://' + value

View File

@ -426,18 +426,19 @@ class SetPasswordView(AjaxUpdateView):
old_password = request.POST.get('old_password', '')
user = self.request.user
if valid:
# Passwords must match
if p1 != p2:
if valid and p1 != p2:
error = _('Password fields must match')
form.add_error('enter_password', error)
form.add_error('confirm_password', error)
valid = False
if valid:
# Old password must be correct
if user.has_usable_password() and not user.check_password(old_password):
if (
valid
and user.has_usable_password()
and not user.check_password(old_password)
):
form.add_error('old_password', _('Wrong password provided'))
valid = False

View File

@ -444,8 +444,7 @@ class SettingsTest(InvenTreeTestCase):
# Any fields marked as 'boolean' must have a default value specified
setting = InvenTreeSetting.get_setting_object(key)
if setting.is_bool():
if setting.default_value not in [True, False]:
if setting.is_bool() and setting.default_value not in [True, False]:
raise ValueError(
f'Non-boolean default value specified for {key}'
) # pragma: no cover

View File

@ -730,8 +730,11 @@ class SupplierPart(
raise ValidationError({'pack_quantity': e.messages})
# Ensure that the linked manufacturer_part points to the same part!
if self.manufacturer_part and self.part:
if self.manufacturer_part.part != self.part:
if (
self.manufacturer_part
and self.part
and self.manufacturer_part.part != self.part
):
raise ValidationError({
'manufacturer_part': _(
'Linked manufacturer part must reference the same base part'
@ -1049,8 +1052,12 @@ class SupplierPriceBreak(common.models.PriceBreak):
)
def after_save_supplier_price(sender, instance, created, **kwargs):
"""Callback function when a SupplierPriceBreak is created or updated."""
if InvenTree.ready.canAppAccessDatabase() and not InvenTree.ready.isImportingData():
if instance.part and instance.part.part:
if (
InvenTree.ready.canAppAccessDatabase()
and not InvenTree.ready.isImportingData()
and instance.part
and instance.part.part
):
instance.part.part.schedule_pricing_update(create=True)
@ -1061,6 +1068,10 @@ def after_save_supplier_price(sender, instance, created, **kwargs):
)
def after_delete_supplier_price(sender, instance, **kwargs):
"""Callback function when a SupplierPriceBreak is deleted."""
if InvenTree.ready.canAppAccessDatabase() and not InvenTree.ready.isImportingData():
if instance.part and instance.part.part:
if (
InvenTree.ready.canAppAccessDatabase()
and not InvenTree.ready.isImportingData()
and instance.part
and instance.part.part
):
instance.part.part.schedule_pricing_update(create=False)

View File

@ -1350,10 +1350,8 @@ class OrderCalendarExport(ICalFeed):
# No login yet - check in headers
if 'authorization' in request.headers:
auth = request.headers['authorization'].split()
if len(auth) == 2:
# NOTE: We are only support basic authentication for now.
#
if auth[0].lower() == 'basic':
if len(auth) == 2 and auth[0].lower() == 'basic':
uname, passwd = base64.b64decode(auth[1]).decode('ascii').split(':')
user = authenticate(username=uname, password=passwd)
if user is not None and user.is_active:

View File

@ -232,16 +232,17 @@ class Order(
super().clean()
# Check if a responsible owner is required for this order type
if self.REQUIRE_RESPONSIBLE_SETTING:
if get_global_setting(self.REQUIRE_RESPONSIBLE_SETTING, backup_value=False):
if not self.responsible:
if (
self.REQUIRE_RESPONSIBLE_SETTING
and get_global_setting(self.REQUIRE_RESPONSIBLE_SETTING, backup_value=False)
and not self.responsible
):
raise ValidationError({
'responsible': _('Responsible user or group must be specified')
})
# Check that the referenced 'contact' matches the correct 'company'
if self.company and self.contact:
if self.contact.company != self.company:
if self.company and self.contact and self.contact.company != self.company:
raise ValidationError({
'contact': _('Contact does not match selected company')
})
@ -783,9 +784,8 @@ class PurchaseOrder(TotalPriceMixin, Order):
# Extract optional packaging field
packaging = kwargs.get('packaging', None)
if not packaging:
# Default to the packaging field for the linked supplier part
if line.part:
if not packaging and line.part:
packaging = line.part.packaging
# Extract optional barcode field
@ -866,8 +866,9 @@ class PurchaseOrder(TotalPriceMixin, Order):
line.save()
# Has this order been completed?
if len(self.pending_line_items()) == 0:
if get_global_setting('PURCHASEORDER_AUTO_COMPLETE', True):
if len(self.pending_line_items()) == 0 and get_global_setting(
'PURCHASEORDER_AUTO_COMPLETE', True
):
self.received_by = user
self.complete_order() # This will save the model
@ -1455,9 +1456,12 @@ class PurchaseOrderLineItem(OrderLineItem):
"""
super().clean()
if self.order.supplier and self.part:
# Supplier part *must* point to the same supplier!
if self.part.supplier != self.order.supplier:
if (
self.order.supplier
and self.part
and self.part.supplier != self.order.supplier
):
raise ValidationError({'part': _('Supplier part must match supplier')})
def __str__(self):

View File

@ -91,8 +91,9 @@ def ExportBom(
bom_items.append(item)
if cascade and item.sub_part.assembly:
if max_levels is None or level < max_levels:
if (
cascade and item.sub_part.assembly and max_levels is None
) or level < max_levels:
add_items(item.sub_part.bom_items.all().order_by('id'), level + 1)
top_level_items = part.get_bom_items().order_by('id')

View File

@ -515,8 +515,10 @@ class Part(
if self.active:
raise ValidationError(_('Cannot delete this part as it is still active'))
if not get_global_setting('PART_ALLOW_DELETE_FROM_ASSEMBLY', cache=False):
if BomItem.objects.filter(sub_part=self).exists():
if (
not get_global_setting('PART_ALLOW_DELETE_FROM_ASSEMBLY', cache=False)
and BomItem.objects.filter(sub_part=self).exists()
):
raise ValidationError(
_('Cannot delete this part as it is used in an assembly')
)
@ -711,12 +713,11 @@ class Part(
'revision': _('Revision code must be specified')
})
if get_global_setting('PART_REVISION_ASSEMBLY_ONLY'):
if not self.assembly or not self.revision_of.assembly:
if (
get_global_setting('PART_REVISION_ASSEMBLY_ONLY') and not self.assembly
) or not self.revision_of.assembly:
raise ValidationError({
'revision_of': _(
'Revisions are only allowed for assembly parts'
)
'revision_of': _('Revisions are only allowed for assembly parts')
})
# Cannot have a revision of a "template" part
@ -2753,12 +2754,14 @@ class PartPricing(common.models.MetaMixin):
sub_part_min = self.convert(sub_part_pricing.overall_min)
sub_part_max = self.convert(sub_part_pricing.overall_max)
if sub_part_min is not None:
if bom_item_min is None or sub_part_min < bom_item_min:
if (
sub_part_min is not None and bom_item_min is None
) or sub_part_min < bom_item_min:
bom_item_min = sub_part_min
if sub_part_max is not None:
if bom_item_max is None or sub_part_max > bom_item_max:
if (
sub_part_max is not None and bom_item_max is None
) or sub_part_max > bom_item_max:
bom_item_max = sub_part_max
# Update cumulative totals
@ -2962,12 +2965,10 @@ class PartPricing(common.models.MetaMixin):
v_min = self.convert(v.pricing.overall_min)
v_max = self.convert(v.pricing.overall_max)
if v_min is not None:
if variant_min is None or v_min < variant_min:
if (v_min is not None and variant_min is None) or v_min < variant_min:
variant_min = v_min
if v_max is not None:
if variant_max is None or v_max > variant_max:
if (v_max is not None and variant_max is None) or v_max > variant_max:
variant_max = v_max
if self.variant_cost_min != variant_min or self.variant_cost_max != variant_max:
@ -3800,8 +3801,11 @@ def post_save_part_parameter_template(sender, instance, created, **kwargs):
"""Callback function when a PartParameterTemplate is created or saved."""
import part.tasks as part_tasks
if InvenTree.ready.canAppAccessDatabase() and not InvenTree.ready.isImportingData():
if not created:
if (
InvenTree.ready.canAppAccessDatabase()
and not InvenTree.ready.isImportingData()
and not created
):
# Schedule a background task to rebuild the parameters against this template
InvenTree.tasks.offload_task(
part_tasks.rebuild_parameters, instance.pk, force_async=True
@ -3922,10 +3926,13 @@ class PartParameter(InvenTree.models.InvenTreeMetadataModel):
except ValueError:
self.data_numeric = None
if self.data_numeric is not None and type(self.data_numeric) is float:
# Prevent out of range numbers, etc
# Ref: https://github.com/inventree/InvenTree/issues/7593
if math.isnan(self.data_numeric) or math.isinf(self.data_numeric):
if (
self.data_numeric is not None
and type(self.data_numeric) is float
and math.isnan(self.data_numeric)
) or math.isinf(self.data_numeric):
self.data_numeric = None
part = models.ForeignKey(
@ -4509,8 +4516,11 @@ def update_bom_build_lines(sender, instance, created, **kwargs):
def update_pricing_after_edit(sender, instance, created, **kwargs):
"""Callback function when a part price break is created or updated."""
# Update part pricing *unless* we are importing data
if InvenTree.ready.canAppAccessDatabase() and not InvenTree.ready.isImportingData():
if instance.part:
if (
InvenTree.ready.canAppAccessDatabase()
and not InvenTree.ready.isImportingData()
and instance.part
):
instance.part.schedule_pricing_update(create=True)
@ -4526,8 +4536,11 @@ def update_pricing_after_edit(sender, instance, created, **kwargs):
def update_pricing_after_delete(sender, instance, **kwargs):
"""Callback function when a part price break is deleted."""
# Update part pricing *unless* we are importing data
if InvenTree.ready.canAppAccessDatabase() and not InvenTree.ready.isImportingData():
if instance.part:
if (
InvenTree.ready.canAppAccessDatabase()
and not InvenTree.ready.isImportingData()
and instance.part
):
instance.part.schedule_pricing_update(create=False)

View File

@ -563,8 +563,11 @@ class BarcodeSOAllocate(BarcodeView):
sales_order = kwargs['sales_order']
shipment = self.get_shipment(**kwargs)
if stock_item is not None and line_item is not None:
if stock_item.part != line_item.part:
if (
stock_item is not None
and line_item is not None
and stock_item.part != line_item.part
):
result['error'] = _('Stock item does not match line item')
raise ValidationError(result)
@ -587,8 +590,11 @@ class BarcodeSOAllocate(BarcodeView):
'quantity': quantity,
}
if stock_item is not None and quantity is not None:
if stock_item.unallocated_quantity() < quantity:
if (
stock_item is not None
and quantity is not None
and stock_item.unallocated_quantity() < quantity
):
response['error'] = _('Insufficient stock available')
raise ValidationError(response)

View File

@ -477,8 +477,9 @@ class SupplierBarcodeMixin(BarcodeMixin):
location := supplier_part.part.get_default_location()
):
pass
elif StockLocation.objects.count() <= 1:
if not (location := StockLocation.objects.first()):
elif StockLocation.objects.count() <= 1 and not (
location := StockLocation.objects.first()
):
no_stock_locations = True
response = {

View File

@ -195,14 +195,12 @@ class PluginsRegistry:
for plugin in self.plugins.values():
if plugin.mixin_enabled(mixin):
if active is not None:
# Filter by 'active' status of plugin
if active != plugin.is_active():
if active is not None and active != plugin.is_active():
continue
if builtin is not None:
# Filter by 'builtin' status of plugin
if builtin != plugin.is_builtin:
if builtin is not None and builtin != plugin.is_builtin:
continue
result.append(plugin)
@ -396,9 +394,8 @@ class PluginsRegistry:
collected_plugins.append(item)
# From this point any plugins are considered "external" and only loaded if plugins are explicitly enabled
if settings.PLUGINS_ENABLED:
# Check if not running in testing mode and apps should be loaded from hooks
if (not settings.PLUGIN_TESTING) or (
if (settings.PLUGINS_ENABLED and (not settings.PLUGIN_TESTING)) or (
settings.PLUGIN_TESTING and settings.PLUGIN_TESTING_SETUP
):
# Collect plugins from setup entry points

View File

@ -66,17 +66,19 @@ class SampleValidatorPlugin(SettingsMixin, ValidationMixin, InvenTreePlugin):
# Print debug message to console (intentional)
print('Validating model instance:', instance.__class__, f'<{instance.pk}>')
if isinstance(instance, part.models.BomItem):
if self.get_setting('BOM_ITEM_INTEGER'):
if float(instance.quantity) != int(instance.quantity):
self.raise_error({
'quantity': 'Bom item quantity must be an integer'
})
if (
isinstance(instance, part.models.BomItem)
and self.get_setting('BOM_ITEM_INTEGER')
and float(instance.quantity) != int(instance.quantity)
):
self.raise_error({'quantity': 'Bom item quantity must be an integer'})
if isinstance(instance, part.models.Part):
# If the part description is being updated, prevent it from being reduced in length
if deltas and 'description' in deltas:
if (
isinstance(instance, part.models.Part)
and deltas
and 'description' in deltas
):
old_desc = deltas['description']['old']
new_desc = deltas['description']['new']
@ -126,13 +128,11 @@ class SampleValidatorPlugin(SettingsMixin, ValidationMixin, InvenTreePlugin):
These examples are silly, but serve to demonstrate how the feature could be used
"""
if self.get_setting('SERIAL_MUST_BE_PALINDROME'):
if serial != serial[::-1]:
if self.get_setting('SERIAL_MUST_BE_PALINDROME') and serial != serial[::-1]:
self.raise_error('Serial must be a palindrome')
if self.get_setting('SERIAL_MUST_MATCH_PART'):
# Serial must start with the same letter as the linked part, for some reason
if serial[0] != part.name[0]:
if self.get_setting('SERIAL_MUST_MATCH_PART') and serial[0] != part.name[0]:
self.raise_error('Serial number must start with same letter as part')
def validate_batch_code(self, batch_code: str, item):

View File

@ -700,17 +700,15 @@ class StockItem(
# The 'supplier_part' field must point to the same part!
try:
if self.supplier_part is not None:
if self.supplier_part.part != self.part:
if self.supplier_part is not None and self.supplier_part.part != self.part:
raise ValidationError({
'supplier_part': _(
f"Part type ('{self.supplier_part.part}') must be {self.part}"
)
})
if self.part is not None:
# A part with a serial number MUST have the quantity set to 1
if self.serial:
if self.part is not None and self.serial:
if self.quantity > 1:
raise ValidationError({
'quantity': _(

View File

@ -795,14 +795,11 @@ class InstallStockItemSerializer(serializers.Serializer):
parent_item = self.context['item']
parent_part = parent_item.part
# Check if the selected part is in the Bill of Materials of the parent item
if get_global_setting(
'STOCK_ENFORCE_BOM_INSTALLATION', backup_value=True, cache=False
):
# Check if the selected part is in the Bill of Materials of the parent item
if not parent_part.check_if_part_in_bom(stock_item.part):
raise ValidationError(
_('Selected part is not in the Bill of Materials')
)
) and not parent_part.check_if_part_in_bom(stock_item.part):
raise ValidationError(_('Selected part is not in the Bill of Materials'))
return stock_item

View File

@ -95,9 +95,8 @@ class OwnerList(ListAPI):
if not search_match:
continue
if is_active is not None:
# Skip any users which do not match the required *is_active* value
if (
if is_active is not None and (
result.owner_type.name == 'user'
and result.owner_id not in matching_user_ids
):

View File

@ -34,8 +34,9 @@ logger = logging.getLogger('inventree')
# string representation of a user
def user_model_str(self):
"""Function to override the default Django User __str__."""
if get_global_setting('DISPLAY_FULL_NAMES', cache=True):
if self.first_name or self.last_name:
if (
get_global_setting('DISPLAY_FULL_NAMES', cache=True) and self.first_name
) or self.last_name:
return f'{self.first_name} {self.last_name}'
return self.username
@ -421,8 +422,9 @@ class RuleSet(models.Model):
# Work out which roles touch the given table
for role in cls.RULESET_NAMES:
if table in cls.get_ruleset_models()[role]:
if check_user_role(user, role, permission):
if table in cls.get_ruleset_models()[role] and check_user_role(
user, role, permission
):
return True
# Check for children models which inherits from parent role
@ -430,9 +432,8 @@ class RuleSet(models.Model):
# Get child model name
parent_child_string = f'{parent}_{child}'
if parent_child_string == table:
# Check if parent role has change permission
if check_user_role(user, parent, 'change'):
if parent_child_string == table and check_user_role(user, parent, 'change'):
return True
# Print message instead of throwing an error

View File

@ -628,8 +628,10 @@ def export_records(
model_name = entry.get('model', None)
# Ignore any temporary settings (start with underscore)
if model_name in ['common.inventreesetting', 'common.inventreeusersetting']:
if entry['fields'].get('key', '').startswith('_'):
if model_name in [
'common.inventreesetting',
'common.inventreeusersetting',
] and entry['fields'].get('key', '').startswith('_'):
continue
if model_name == 'auth.group':