diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 269ddddee9..5735afeb8b 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -18,6 +18,12 @@ repos:
rev: '4.0.1'
hooks:
- id: flake8
+ additional_dependencies: [
+ 'flake8-bugbear',
+ 'flake8-docstrings',
+ 'flake8-string-format',
+ 'pep8-naming ',
+ ]
- repo: https://github.com/pycqa/isort
rev: '5.10.1'
hooks:
diff --git a/InvenTree/InvenTree/api_tester.py b/InvenTree/InvenTree/api_tester.py
index 052e1c31a4..08952a7df1 100644
--- a/InvenTree/InvenTree/api_tester.py
+++ b/InvenTree/InvenTree/api_tester.py
@@ -105,8 +105,12 @@ class InvenTreeAPITestCase(UserMixin, APITestCase):
return actions
- def get(self, url, data={}, expected_code=200):
+ def get(self, url, data=None, expected_code=200):
"""Issue a GET request."""
+ # Set default - see B006
+ if data is None:
+ data = {}
+
response = self.client.get(url, data, format='json')
if expected_code is not None:
diff --git a/InvenTree/InvenTree/apps.py b/InvenTree/InvenTree/apps.py
index c8a8589ae8..764f1748a6 100644
--- a/InvenTree/InvenTree/apps.py
+++ b/InvenTree/InvenTree/apps.py
@@ -136,7 +136,7 @@ class InvenTreeConfig(AppConfig):
logger.info("Exchange backend not found - updating")
update = True
- except:
+ except Exception:
# Some other error - potentially the tables are not ready yet
return
diff --git a/InvenTree/InvenTree/exchange.py b/InvenTree/InvenTree/exchange.py
index 52f6b06725..684802c52e 100644
--- a/InvenTree/InvenTree/exchange.py
+++ b/InvenTree/InvenTree/exchange.py
@@ -43,12 +43,16 @@ class InvenTreeExchange(SimpleExchangeBackend):
context = ssl.create_default_context(cafile=certifi.where())
response = urlopen(url, timeout=5, context=context)
return response.read()
- except:
+ except Exception:
# Returning None here will raise an error upstream
return None
- def update_rates(self, base_currency=currency_code_default()):
+ def update_rates(self, base_currency=None):
"""Set the requested currency codes and get rates."""
+ # Set default - see B008
+ if base_currency is None:
+ base_currency = currency_code_default()
+
symbols = ','.join(currency_codes())
try:
diff --git a/InvenTree/InvenTree/helpers.py b/InvenTree/InvenTree/helpers.py
index 2a7f6f57c2..69369c9f3b 100644
--- a/InvenTree/InvenTree/helpers.py
+++ b/InvenTree/InvenTree/helpers.py
@@ -95,7 +95,7 @@ def TestIfImage(img):
try:
Image.open(img).verify()
return True
- except:
+ except Exception:
return False
diff --git a/InvenTree/InvenTree/management/commands/rebuild_models.py b/InvenTree/InvenTree/management/commands/rebuild_models.py
index b93d1b4627..87aa378f0b 100644
--- a/InvenTree/InvenTree/management/commands/rebuild_models.py
+++ b/InvenTree/InvenTree/management/commands/rebuild_models.py
@@ -17,7 +17,7 @@ class Command(BaseCommand):
from part.models import Part
Part.objects.rebuild()
- except:
+ except Exception:
print("Error rebuilding Part objects")
# Part category
@@ -26,7 +26,7 @@ class Command(BaseCommand):
from part.models import PartCategory
PartCategory.objects.rebuild()
- except:
+ except Exception:
print("Error rebuilding PartCategory objects")
# StockItem model
@@ -35,7 +35,7 @@ class Command(BaseCommand):
from stock.models import StockItem
StockItem.objects.rebuild()
- except:
+ except Exception:
print("Error rebuilding StockItem objects")
# StockLocation model
@@ -44,7 +44,7 @@ class Command(BaseCommand):
from stock.models import StockLocation
StockLocation.objects.rebuild()
- except:
+ except Exception:
print("Error rebuilding StockLocation objects")
# Build model
@@ -53,5 +53,5 @@ class Command(BaseCommand):
from build.models import Build
Build.objects.rebuild()
- except:
+ except Exception:
print("Error rebuilding Build objects")
diff --git a/InvenTree/InvenTree/metadata.py b/InvenTree/InvenTree/metadata.py
index 473438b5df..924d528fc0 100644
--- a/InvenTree/InvenTree/metadata.py
+++ b/InvenTree/InvenTree/metadata.py
@@ -137,7 +137,7 @@ class InvenTreeMetadata(SimpleMetadata):
if callable(default):
try:
default = default()
- except:
+ except Exception:
continue
serializer_info[name]['default'] = default
diff --git a/InvenTree/InvenTree/middleware.py b/InvenTree/InvenTree/middleware.py
index 60df027bf5..c00d5dc5c5 100644
--- a/InvenTree/InvenTree/middleware.py
+++ b/InvenTree/InvenTree/middleware.py
@@ -98,7 +98,7 @@ class AuthRequiredMiddleware(object):
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('{}?next={}'.format(reverse_lazy('account_login'), request.path))
+ return redirect(f'{reverse_lazy("account_login")}?next={request.path}')
else:
# Return a 401 (Unauthorized) response code for this request
diff --git a/InvenTree/InvenTree/models.py b/InvenTree/InvenTree/models.py
index a2b775f71b..2a089685ef 100644
--- a/InvenTree/InvenTree/models.py
+++ b/InvenTree/InvenTree/models.py
@@ -133,7 +133,7 @@ def extract_int(reference, clip=0x7fffffff):
ref = result.groups()[0]
try:
ref_int = int(ref)
- except:
+ except Exception:
ref_int = 0
# Ensure that the returned values are within the range that can be stored in an IntegerField
@@ -276,7 +276,7 @@ class InvenTreeAttachment(models.Model):
os.rename(old_file, new_file)
self.attachment.name = os.path.join(self.getSubdir(), fn)
self.save()
- except:
+ except Exception:
raise ValidationError(_("Error renaming file"))
class Meta:
diff --git a/InvenTree/InvenTree/serializers.py b/InvenTree/InvenTree/serializers.py
index 22235bd3d8..aea55fbbd9 100644
--- a/InvenTree/InvenTree/serializers.py
+++ b/InvenTree/InvenTree/serializers.py
@@ -47,7 +47,7 @@ class InvenTreeMoneySerializer(MoneyField):
try:
if amount is not None and amount is not empty:
amount = Decimal(amount)
- except:
+ except Exception:
raise ValidationError({
self.field_name: [_("Must be a valid number")],
})
@@ -120,7 +120,7 @@ class InvenTreeModelSerializer(serializers.ModelSerializer):
if callable(value):
try:
value = value()
- except:
+ except Exception:
continue
data[field_name] = value
@@ -150,7 +150,7 @@ class InvenTreeModelSerializer(serializers.ModelSerializer):
if callable(value):
try:
value = value()
- except:
+ except Exception:
continue
initials[field_name] = value
@@ -302,7 +302,7 @@ class InvenTreeDecimalField(serializers.FloatField):
# Convert the value to a string, and then a decimal
try:
return Decimal(str(data))
- except:
+ except Exception:
raise serializers.ValidationError(_("Invalid value"))
@@ -423,7 +423,7 @@ class DataFileUploadSerializer(serializers.Serializer):
if self.TARGET_MODEL:
try:
model_fields = self.TARGET_MODEL.get_import_fields()
- except:
+ except Exception:
pass
# Extract a list of valid model field names
@@ -515,7 +515,7 @@ class DataFileExtractSerializer(serializers.Serializer):
if self.TARGET_MODEL:
try:
model_fields = self.TARGET_MODEL.get_import_fields()
- except:
+ except Exception:
model_fields = {}
rows = []
@@ -568,7 +568,7 @@ class DataFileExtractSerializer(serializers.Serializer):
if self.TARGET_MODEL:
try:
model_fields = self.TARGET_MODEL.get_import_fields()
- except:
+ except Exception:
model_fields = {}
cols_seen = set()
diff --git a/InvenTree/InvenTree/tasks.py b/InvenTree/InvenTree/tasks.py
index 35893af2c9..da257f49cf 100644
--- a/InvenTree/InvenTree/tasks.py
+++ b/InvenTree/InvenTree/tasks.py
@@ -242,7 +242,7 @@ def update_exchange_rates():
# Apps not yet loaded!
logger.info("Could not perform 'update_exchange_rates' - App registry not ready")
return
- except: # pragma: no cover
+ except Exception: # pragma: no cover
# Other error?
return
@@ -251,7 +251,7 @@ def update_exchange_rates():
backend = ExchangeBackend.objects.get(name='InvenTreeExchange')
except ExchangeBackend.DoesNotExist:
pass
- except: # pragma: no cover
+ except Exception: # pragma: no cover
# Some other error
logger.warning("update_exchange_rates: Database not ready")
return
diff --git a/InvenTree/InvenTree/tests.py b/InvenTree/InvenTree/tests.py
index c31be5bfce..07422b98f3 100644
--- a/InvenTree/InvenTree/tests.py
+++ b/InvenTree/InvenTree/tests.py
@@ -417,7 +417,7 @@ class CurrencyTests(TestCase):
update_successful = False
# Note: the update sometimes fails in CI, let's give it a few chances
- for idx in range(10):
+ for _ in range(10):
InvenTree.tasks.update_exchange_rates()
rates = Rate.objects.all()
@@ -469,12 +469,20 @@ class TestSettings(helpers.InvenTreeTestCase):
superuser = True
- def in_env_context(self, envs={}):
+ def in_env_context(self, envs=None):
"""Patch the env to include the given dict."""
+ # Set default - see B006
+ if envs is None:
+ envs = {}
+
return mock.patch.dict(os.environ, envs)
- def run_reload(self, envs={}):
+ def run_reload(self, envs=None):
"""Helper function to reload InvenTree."""
+ # Set default - see B006
+ if envs is None:
+ envs = {}
+
from plugin import registry
with self.in_env_context(envs):
diff --git a/InvenTree/InvenTree/validators.py b/InvenTree/InvenTree/validators.py
index bd4c6d1485..c66cd0b0cc 100644
--- a/InvenTree/InvenTree/validators.py
+++ b/InvenTree/InvenTree/validators.py
@@ -92,7 +92,7 @@ def validate_sales_order_reference(value):
def validate_tree_name(value):
"""Prevent illegal characters in tree item names."""
- for c in "!@#$%^&*'\"\\/[]{}<>,|+=~`\"":
+ for c in "!@#$%^&*'\"\\/[]{}<>,|+=~`\"": # noqa: P103
if c in str(value):
raise ValidationError(_('Illegal character in name ({x})'.format(x=c)))
diff --git a/InvenTree/InvenTree/version.py b/InvenTree/InvenTree/version.py
index 3bcb3293bb..6ee0f00261 100644
--- a/InvenTree/InvenTree/version.py
+++ b/InvenTree/InvenTree/version.py
@@ -99,7 +99,7 @@ def inventreeCommitHash():
try:
return str(subprocess.check_output('git rev-parse --short HEAD'.split()), 'utf-8').strip()
- except: # pragma: no cover
+ except Exception: # pragma: no cover
return None
@@ -114,5 +114,5 @@ def inventreeCommitDate():
try:
d = str(subprocess.check_output('git show -s --format=%ci'.split()), 'utf-8').strip()
return d.split(' ')[0]
- except: # pragma: no cover
+ except Exception: # pragma: no cover
return None
diff --git a/InvenTree/InvenTree/views.py b/InvenTree/InvenTree/views.py
index c2463f0b5e..2088d5bc20 100644
--- a/InvenTree/InvenTree/views.py
+++ b/InvenTree/InvenTree/views.py
@@ -527,7 +527,7 @@ class AjaxDeleteView(AjaxMixin, UpdateView):
"""Return object matched to the model of the calling class."""
try:
self.object = self.model.objects.get(pk=self.kwargs['pk'])
- except:
+ except Exception:
return None
return self.object
@@ -691,14 +691,14 @@ class SettingsView(TemplateView):
try:
backend = ExchangeBackend.objects.get(name='InvenTreeExchange')
ctx["rates_updated"] = backend.last_update
- except:
+ except Exception:
ctx["rates_updated"] = None
# load locale stats
STAT_FILE = os.path.abspath(os.path.join(settings.BASE_DIR, 'InvenTree/locale_stats.json'))
try:
ctx["locale_stats"] = json.load(open(STAT_FILE, 'r'))
- except:
+ except Exception:
ctx["locale_stats"] = {}
# Forms and context for allauth
diff --git a/InvenTree/build/api.py b/InvenTree/build/api.py
index 6703c9a511..5d095d9e8f 100644
--- a/InvenTree/build/api.py
+++ b/InvenTree/build/api.py
@@ -223,7 +223,7 @@ class BuildUnallocate(generics.CreateAPIView):
try:
ctx['build'] = Build.objects.get(pk=self.kwargs.get('pk', None))
- except:
+ except Exception:
pass
ctx['request'] = self.request
@@ -243,7 +243,7 @@ class BuildOrderContextMixin:
try:
ctx['build'] = Build.objects.get(pk=self.kwargs.get('pk', None))
- except:
+ except Exception:
pass
return ctx
diff --git a/InvenTree/build/migrations/0032_auto_20211014_0632.py b/InvenTree/build/migrations/0032_auto_20211014_0632.py
index 8842e25cc7..ea6d5c954d 100644
--- a/InvenTree/build/migrations/0032_auto_20211014_0632.py
+++ b/InvenTree/build/migrations/0032_auto_20211014_0632.py
@@ -21,7 +21,7 @@ def build_refs(apps, schema_editor):
if result and len(result.groups()) == 1:
try:
ref = int(result.groups()[0])
- except: # pragma: no cover
+ except Exception: # pragma: no cover
ref = 0
build.reference_int = ref
diff --git a/InvenTree/build/models.py b/InvenTree/build/models.py
index cc81fd7f26..cbcfc72c87 100644
--- a/InvenTree/build/models.py
+++ b/InvenTree/build/models.py
@@ -1244,13 +1244,13 @@ class BuildItem(models.Model):
try:
# Try to extract the thumbnail
thumb_url = self.stock_item.part.image.thumbnail.url
- except:
+ except Exception:
pass
if thumb_url is None and self.bom_item and self.bom_item.sub_part:
try:
thumb_url = self.bom_item.sub_part.image.thumbnail.url
- except:
+ except Exception:
pass
if thumb_url is not None:
diff --git a/InvenTree/build/test_api.py b/InvenTree/build/test_api.py
index bd969bcea9..c565506eae 100644
--- a/InvenTree/build/test_api.py
+++ b/InvenTree/build/test_api.py
@@ -195,7 +195,7 @@ class BuildTest(BuildAPITest):
self.assertEqual(self.build.incomplete_outputs.count(), 0)
# Create some more build outputs
- for ii in range(10):
+ for _ in range(10):
self.build.create_build_output(10)
# Check that we are in a known state
diff --git a/InvenTree/common/apps.py b/InvenTree/common/apps.py
index 664fc430e2..16897db534 100644
--- a/InvenTree/common/apps.py
+++ b/InvenTree/common/apps.py
@@ -27,5 +27,5 @@ class CommonConfig(AppConfig):
if common.models.InvenTreeSetting.get_setting('SERVER_RESTART_REQUIRED', backup_value=False, create=False):
logger.info("Clearing SERVER_RESTART_REQUIRED flag")
common.models.InvenTreeSetting.set_setting('SERVER_RESTART_REQUIRED', False, None)
- except:
+ except Exception:
pass
diff --git a/InvenTree/common/files.py b/InvenTree/common/files.py
index 5a4c5a975c..786b49e782 100644
--- a/InvenTree/common/files.py
+++ b/InvenTree/common/files.py
@@ -142,7 +142,7 @@ class FileManager:
guess = self.guess_header(header, threshold=95)
# Check if already present
guess_exists = False
- for idx, data in enumerate(headers):
+ for _idx, data in enumerate(headers):
if guess == data['guess']:
guess_exists = True
break
diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py
index 82f6603a66..bf991fe370 100644
--- a/InvenTree/common/models.py
+++ b/InvenTree/common/models.py
@@ -571,7 +571,7 @@ class BaseInvenTreeSetting(models.Model):
# If a valid class has been found, see if it has registered an API URL
try:
return model_class.get_api_url()
- except:
+ except Exception:
pass
return None
diff --git a/InvenTree/common/views.py b/InvenTree/common/views.py
index 3fbbceee37..b356c5cb94 100644
--- a/InvenTree/common/views.py
+++ b/InvenTree/common/views.py
@@ -495,8 +495,12 @@ class FileManagementAjaxView(AjaxView):
self.storage.current_step = self.steps.first
return self.renderJsonResponse(request)
- def renderJsonResponse(self, request, form=None, data={}, context=None):
+ def renderJsonResponse(self, request, form=None, data=None, context=None):
"""Always set the right templates before rendering."""
+ # Set default - see B006
+ if data is None:
+ data = {}
+
self.setTemplate()
return super().renderJsonResponse(request, form=form, data=data, context=context)
diff --git a/InvenTree/company/views.py b/InvenTree/company/views.py
index b967d8e0d2..4716e8408b 100644
--- a/InvenTree/company/views.py
+++ b/InvenTree/company/views.py
@@ -151,7 +151,7 @@ class CompanyImageDownloadFromURL(AjaxUpdateView):
try:
self.image = Image.open(response.raw).convert()
self.image.verify()
- except:
+ except Exception:
form.add_error('url', _("Supplied URL is not a valid image file"))
return
diff --git a/InvenTree/label/api.py b/InvenTree/label/api.py
index 2816572bd5..311e3fe53b 100644
--- a/InvenTree/label/api.py
+++ b/InvenTree/label/api.py
@@ -363,7 +363,7 @@ class StockLocationLabelList(LabelListView, StockLocationLabelMixin):
# Filter string defined for the StockLocationLabel object
try:
filters = InvenTree.helpers.validateFilterString(label.filters)
- except: # pragma: no cover
+ except Exception: # pragma: no cover
# Skip if there was an error validating the filters...
continue
diff --git a/InvenTree/label/test_api.py b/InvenTree/label/test_api.py
index 25277c964b..3c94c89fb6 100644
--- a/InvenTree/label/test_api.py
+++ b/InvenTree/label/test_api.py
@@ -22,8 +22,12 @@ class TestReportTests(InvenTreeAPITestCase):
list_url = reverse('api-stockitem-testreport-list')
- def do_list(self, filters={}):
+ def do_list(self, filters=None):
"""Helper function to request list of labels with provided filters"""
+ # Set default - see B006
+ if filters is None:
+ filters = {}
+
response = self.client.get(self.list_url, filters, format='json')
self.assertEqual(response.status_code, 200)
diff --git a/InvenTree/order/api.py b/InvenTree/order/api.py
index 7b78033da8..4303979d42 100644
--- a/InvenTree/order/api.py
+++ b/InvenTree/order/api.py
@@ -295,7 +295,7 @@ class PurchaseOrderContextMixin:
# Pass the purchase order through to the serializer for validation
try:
context['order'] = models.PurchaseOrder.objects.get(pk=self.kwargs.get('pk', None))
- except:
+ except Exception:
pass
context['request'] = self.request
@@ -857,7 +857,7 @@ class SalesOrderContextMixin:
try:
ctx['order'] = models.SalesOrder.objects.get(pk=self.kwargs.get('pk', None))
- except:
+ except Exception:
pass
return ctx
@@ -1050,7 +1050,7 @@ class SalesOrderShipmentComplete(generics.CreateAPIView):
ctx['shipment'] = models.SalesOrderShipment.objects.get(
pk=self.kwargs.get('pk', None)
)
- except:
+ except Exception:
pass
return ctx
diff --git a/InvenTree/order/migrations/0052_auto_20211014_0631.py b/InvenTree/order/migrations/0052_auto_20211014_0631.py
index fda4335e08..94a591d3d6 100644
--- a/InvenTree/order/migrations/0052_auto_20211014_0631.py
+++ b/InvenTree/order/migrations/0052_auto_20211014_0631.py
@@ -20,7 +20,7 @@ def build_refs(apps, schema_editor):
if result and len(result.groups()) == 1:
try:
ref = int(result.groups()[0])
- except: # pragma: no cover
+ except Exception: # pragma: no cover
ref = 0
order.reference_int = ref
@@ -37,7 +37,7 @@ def build_refs(apps, schema_editor):
if result and len(result.groups()) == 1:
try:
ref = int(result.groups()[0])
- except: # pragma: no cover
+ except Exception: # pragma: no cover
ref = 0
order.reference_int = ref
diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py
index e46c7a5339..bba4e91909 100644
--- a/InvenTree/order/models.py
+++ b/InvenTree/order/models.py
@@ -154,7 +154,7 @@ class Order(MetadataMixin, ReferenceIndexingMixin):
notes = MarkdownxField(blank=True, verbose_name=_('Notes'), help_text=_('Order notes'))
- def get_total_price(self, target_currency=currency_code_default()):
+ def get_total_price(self, target_currency=None):
"""Calculates the total price of all order lines, and converts to the specified target currency.
If not specified, the default system currency is used.
@@ -162,6 +162,10 @@ class Order(MetadataMixin, ReferenceIndexingMixin):
If currency conversion fails (e.g. there are no valid conversion rates),
then we simply return zero, rather than attempting some other calculation.
"""
+ # Set default - see B008
+ if target_currency is None:
+ target_currency = currency_code_default()
+
total = Money(0, target_currency)
# gather name reference
diff --git a/InvenTree/part/api.py b/InvenTree/part/api.py
index cfac04fa03..9e50cabe3a 100644
--- a/InvenTree/part/api.py
+++ b/InvenTree/part/api.py
@@ -606,7 +606,7 @@ class PartCopyBOM(generics.CreateAPIView):
try:
ctx['part'] = Part.objects.get(pk=self.kwargs.get('pk', None))
- except:
+ except Exception:
pass
return ctx
@@ -1042,12 +1042,12 @@ class PartList(APIDownloadMixin, generics.ListCreateAPIView):
try:
manufacturer = Company.objects.get(pk=request.data.get('manufacturer', None))
- except:
+ except Exception:
manufacturer = None
try:
supplier = Company.objects.get(pk=request.data.get('supplier', None))
- except:
+ except Exception:
supplier = None
mpn = str(request.data.get('MPN', '')).strip()
diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py
index 436745eadb..912541fbc0 100644
--- a/InvenTree/part/models.py
+++ b/InvenTree/part/models.py
@@ -593,7 +593,7 @@ class Part(MetadataMixin, MPTTModel):
try:
latest = int(latest)
return latest
- except:
+ except Exception:
# not an integer so 0
return 0
@@ -610,7 +610,7 @@ class Part(MetadataMixin, MPTTModel):
# Attempt to turn into an integer
try:
latest = int(latest)
- except:
+ except Exception:
pass
if type(latest) is int:
@@ -2283,7 +2283,7 @@ class PartTestTemplate(models.Model):
def validate_template_name(name):
"""Prevent illegal characters in "name" field for PartParameterTemplate."""
- for c in "!@#$%^&*()<>{}[].,?/\\|~`_+-=\'\"":
+ for c in "!@#$%^&*()<>{}[].,?/\\|~`_+-=\'\"": # noqa: P103
if c in str(name):
raise ValidationError(_(f"Illegal character in template name ({c})"))
diff --git a/InvenTree/part/serializers.py b/InvenTree/part/serializers.py
index 57a840855e..c2e674db89 100644
--- a/InvenTree/part/serializers.py
+++ b/InvenTree/part/serializers.py
@@ -902,7 +902,7 @@ class BomImportExtractSerializer(DataFileExtractSerializer):
if level != 1:
# Skip this row
return None
- except:
+ except Exception:
pass
# Attempt to extract a valid part based on the provided data
@@ -954,7 +954,7 @@ class BomImportExtractSerializer(DataFileExtractSerializer):
if quantity <= 0:
row['errors']['quantity'] = _('Quantity must be greater than zero')
- except:
+ except Exception:
row['errors']['quantity'] = _('Invalid quantity')
return row
diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py
index e48c6f89c6..4f250959ed 100644
--- a/InvenTree/part/templatetags/inventree_extras.py
+++ b/InvenTree/part/templatetags/inventree_extras.py
@@ -412,7 +412,7 @@ def primitive_to_javascript(primitive):
else:
# Wrap with quotes
- return format_html("'{}'", primitive)
+ return format_html("'{}'", primitive) # noqa: P103
@register.filter
@@ -458,7 +458,7 @@ def authorized_owners(group):
def object_link(url_name, pk, ref):
"""Return highlighted link to object."""
ref_url = reverse(url_name, kwargs={'pk': pk})
- return mark_safe('{}'.format(ref_url, ref))
+ return mark_safe(f'{ref}')
@register.simple_tag()
diff --git a/InvenTree/part/test_api.py b/InvenTree/part/test_api.py
index 0df4fefc72..1c8aa694d3 100644
--- a/InvenTree/part/test_api.py
+++ b/InvenTree/part/test_api.py
@@ -1285,7 +1285,7 @@ class PartAPIAggregationTest(InvenTreeAPITestCase):
self.assertEqual(data['stock_item_count'], 4)
# Add some more stock items!!
- for i in range(100):
+ for _ in range(100):
StockItem.objects.create(part=self.part, quantity=5)
# Add another stock item which is assigned to a customer (and shouldn't count)
@@ -1628,7 +1628,7 @@ class BomItemTest(InvenTreeAPITestCase):
Part.objects.rebuild()
# Create some stock items for this new part
- for jj in range(ii):
+ for _ in range(ii):
StockItem.objects.create(
part=variant,
location=loc,
diff --git a/InvenTree/part/test_bom_import.py b/InvenTree/part/test_bom_import.py
index 71f47510a1..73410ea350 100644
--- a/InvenTree/part/test_bom_import.py
+++ b/InvenTree/part/test_bom_import.py
@@ -228,7 +228,7 @@ class BomUploadTest(InvenTreeAPITestCase):
components = Part.objects.filter(component=True)
- for idx, cmp in enumerate(components):
+ for idx, _ in enumerate(components):
dataset.append([
f"Component {idx}",
10,
@@ -257,7 +257,7 @@ class BomUploadTest(InvenTreeAPITestCase):
dataset.headers = ['part_ipn', 'quantity']
- for idx, cmp in enumerate(components):
+ for idx, _ in enumerate(components):
dataset.append([
f"CMP_{idx}",
10,
diff --git a/InvenTree/part/test_part.py b/InvenTree/part/test_part.py
index 46f1473983..fea5cf6012 100644
--- a/InvenTree/part/test_part.py
+++ b/InvenTree/part/test_part.py
@@ -190,7 +190,7 @@ class PartTest(TestCase):
try:
part.save()
self.assertTrue(False) # pragma: no cover
- except:
+ except Exception:
pass
self.assertEqual(Part.objects.count(), n + 1)
diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py
index e2698044f6..d67e72f4cc 100644
--- a/InvenTree/part/views.py
+++ b/InvenTree/part/views.py
@@ -618,7 +618,7 @@ class PartImageDownloadFromURL(AjaxUpdateView):
try:
self.image = Image.open(response.raw).convert()
self.image.verify()
- except:
+ except Exception:
form.add_error('url', _("Supplied URL is not a valid image file"))
return
diff --git a/InvenTree/plugin/apps.py b/InvenTree/plugin/apps.py
index 374be254e5..405b8cfcd2 100644
--- a/InvenTree/plugin/apps.py
+++ b/InvenTree/plugin/apps.py
@@ -39,7 +39,7 @@ class PluginAppConfig(AppConfig):
if InvenTreeSetting.get_setting('PLUGIN_ON_STARTUP', create=False):
# make sure all plugins are installed
registry.install_plugin_file()
- except: # pragma: no cover
+ except Exception: # pragma: no cover
pass
# get plugins and init them
diff --git a/InvenTree/plugin/base/integration/mixins.py b/InvenTree/plugin/base/integration/mixins.py
index 2a41074b29..b4565e0dbc 100644
--- a/InvenTree/plugin/base/integration/mixins.py
+++ b/InvenTree/plugin/base/integration/mixins.py
@@ -200,7 +200,7 @@ class ScheduleMixin:
try:
from django_q.models import Schedule
- for key, task in self.scheduled_tasks.items():
+ for key, _ in self.scheduled_tasks.items():
task_name = self.get_task_name(key)
diff --git a/InvenTree/plugin/helpers.py b/InvenTree/plugin/helpers.py
index 247ae72654..f776bf95b8 100644
--- a/InvenTree/plugin/helpers.py
+++ b/InvenTree/plugin/helpers.py
@@ -169,7 +169,7 @@ class GitStatus:
def get_modules(pkg):
"""Get all modules in a package."""
context = {}
- for loader, name, ispkg in pkgutil.walk_packages(pkg.__path__):
+ for loader, name, _ in pkgutil.walk_packages(pkg.__path__):
try:
module = loader.find_module(name).load_module(name)
pkg_names = getattr(module, '__all__', None)
diff --git a/InvenTree/plugin/registry.py b/InvenTree/plugin/registry.py
index 574cf654ff..7443191cb6 100644
--- a/InvenTree/plugin/registry.py
+++ b/InvenTree/plugin/registry.py
@@ -382,7 +382,7 @@ class PluginsRegistry:
if settings.PLUGIN_TESTING or InvenTreeSetting.get_setting('ENABLE_PLUGINS_SCHEDULE'):
- for slug, plugin in plugins:
+ for _, plugin in plugins:
if plugin.mixin_enabled('schedule'):
config = plugin.plugin_config()
@@ -437,7 +437,7 @@ class PluginsRegistry:
apps_changed = False
# add them to the INSTALLED_APPS
- for slug, plugin in plugins:
+ for _, plugin in plugins:
if plugin.mixin_enabled('app'):
plugin_path = self._get_plugin_path(plugin)
if plugin_path not in settings.INSTALLED_APPS:
@@ -522,7 +522,7 @@ class PluginsRegistry:
# remove model from admin site
try:
admin.site.unregister(model)
- except: # pragma: no cover
+ except Exception: # pragma: no cover
pass
models += [model._meta.model_name]
except LookupError: # pragma: no cover
diff --git a/InvenTree/plugin/samples/integration/custom_panel_sample.py b/InvenTree/plugin/samples/integration/custom_panel_sample.py
index a3228582e6..0ef2086029 100644
--- a/InvenTree/plugin/samples/integration/custom_panel_sample.py
+++ b/InvenTree/plugin/samples/integration/custom_panel_sample.py
@@ -113,7 +113,7 @@ class CustomPanelSample(PanelMixin, SettingsMixin, InvenTreePlugin):
'icon': 'fa-user',
'content_template': 'panel_demo/childless.html', # Note that the panel content is rendered using a template file!
})
- except: # pragma: no cover
+ except Exception: # pragma: no cover
pass
return panels
diff --git a/InvenTree/plugin/templatetags/plugin_extras.py b/InvenTree/plugin/templatetags/plugin_extras.py
index 35d4db5e17..94ccef8116 100644
--- a/InvenTree/plugin/templatetags/plugin_extras.py
+++ b/InvenTree/plugin/templatetags/plugin_extras.py
@@ -57,7 +57,7 @@ def safe_url(view_name, *args, **kwargs):
"""
try:
return reverse(view_name, args=args, kwargs=kwargs)
- except:
+ except Exception:
return None
diff --git a/InvenTree/report/api.py b/InvenTree/report/api.py
index 79c2d098e5..96a6cd34e5 100644
--- a/InvenTree/report/api.py
+++ b/InvenTree/report/api.py
@@ -289,7 +289,7 @@ class StockItemTestReportList(ReportListView, StockItemReportMixin):
# Filter string defined for the report object
try:
filters = InvenTree.helpers.validateFilterString(report.filters)
- except:
+ except Exception:
continue
for item in items:
@@ -528,7 +528,7 @@ class PurchaseOrderReportList(ReportListView, OrderReportMixin):
# Filter string defined for the report object
try:
filters = InvenTree.helpers.validateFilterString(report.filters)
- except:
+ except Exception:
continue
for o in orders:
@@ -607,7 +607,7 @@ class SalesOrderReportList(ReportListView, OrderReportMixin):
# Filter string defined for the report object
try:
filters = InvenTree.helpers.validateFilterString(report.filters)
- except:
+ except Exception:
continue
for o in orders:
diff --git a/InvenTree/report/apps.py b/InvenTree/report/apps.py
index 9e91627e62..1b1e402746 100644
--- a/InvenTree/report/apps.py
+++ b/InvenTree/report/apps.py
@@ -75,14 +75,14 @@ class ReportConfig(AppConfig):
enabled=True
)
- except:
+ except Exception:
pass
def create_default_test_reports(self):
"""Create database entries for the default TestReport templates, if they do not already exist."""
try:
from .models import TestReport
- except: # pragma: no cover
+ except Exception: # pragma: no cover
# Database is not ready yet
return
@@ -101,7 +101,7 @@ class ReportConfig(AppConfig):
"""Create database entries for the default BuildReport templates (if they do not already exist)"""
try:
from .models import BuildReport
- except: # pragma: no cover
+ except Exception: # pragma: no cover
# Database is not ready yet
return
diff --git a/InvenTree/stock/api.py b/InvenTree/stock/api.py
index c955fa12d6..53205dd7b9 100644
--- a/InvenTree/stock/api.py
+++ b/InvenTree/stock/api.py
@@ -99,7 +99,7 @@ class StockItemContextMixin:
try:
context['item'] = StockItem.objects.get(pk=self.kwargs.get('pk', None))
- except:
+ except Exception:
pass
return context
@@ -830,7 +830,7 @@ class StockList(APIDownloadMixin, generics.ListCreateAPIView):
if part.tree_id is not None:
queryset = queryset.filter(part__tree_id=part.tree_id)
- except:
+ except Exception:
pass
# Filter by 'allocated' parts?
@@ -1144,7 +1144,7 @@ class StockItemTestResultList(generics.ListCreateAPIView):
"""Set context before returning serializer."""
try:
kwargs['user_detail'] = str2bool(self.request.query_params.get('user_detail', False))
- except:
+ except Exception:
pass
kwargs['context'] = self.get_serializer_context()
@@ -1186,12 +1186,12 @@ class StockTrackingList(generics.ListAPIView):
"""Set context before returning serializer."""
try:
kwargs['item_detail'] = str2bool(self.request.query_params.get('item_detail', False))
- except:
+ except Exception:
pass
try:
kwargs['user_detail'] = str2bool(self.request.query_params.get('user_detail', False))
- except:
+ except Exception:
pass
kwargs['context'] = self.get_serializer_context()
@@ -1219,7 +1219,7 @@ class StockTrackingList(generics.ListAPIView):
part = Part.objects.get(pk=deltas['part'])
serializer = PartBriefSerializer(part)
deltas['part_detail'] = serializer.data
- except:
+ except Exception:
pass
# Add location detail
@@ -1228,7 +1228,7 @@ class StockTrackingList(generics.ListAPIView):
location = StockLocation.objects.get(pk=deltas['location'])
serializer = StockSerializers.LocationSerializer(location)
deltas['location_detail'] = serializer.data
- except:
+ except Exception:
pass
# Add stockitem detail
@@ -1237,7 +1237,7 @@ class StockTrackingList(generics.ListAPIView):
stockitem = StockItem.objects.get(pk=deltas['stockitem'])
serializer = StockSerializers.StockItemSerializer(stockitem)
deltas['stockitem_detail'] = serializer.data
- except:
+ except Exception:
pass
# Add customer detail
@@ -1246,7 +1246,7 @@ class StockTrackingList(generics.ListAPIView):
customer = Company.objects.get(pk=deltas['customer'])
serializer = CompanySerializer(customer)
deltas['customer_detail'] = serializer.data
- except:
+ except Exception:
pass
# Add purchaseorder detail
@@ -1255,7 +1255,7 @@ class StockTrackingList(generics.ListAPIView):
order = PurchaseOrder.objects.get(pk=deltas['purchaseorder'])
serializer = PurchaseOrderSerializer(order)
deltas['purchaseorder_detail'] = serializer.data
- except:
+ except Exception:
pass
if request.is_ajax():
diff --git a/InvenTree/stock/migrations/0061_auto_20210511_0911.py b/InvenTree/stock/migrations/0061_auto_20210511_0911.py
index 887bff0ea8..b788d29eae 100644
--- a/InvenTree/stock/migrations/0061_auto_20210511_0911.py
+++ b/InvenTree/stock/migrations/0061_auto_20210511_0911.py
@@ -56,7 +56,7 @@ def update_history(apps, schema_editor):
try:
deltas['quantity']: float(q)
updated = True
- except:
+ except Exception:
print(f"WARNING: Error converting quantity '{q}'")
@@ -89,7 +89,7 @@ def update_history(apps, schema_editor):
# Ensure that 'quantity' is stored too in this case
deltas['quantity'] = float(q)
- except:
+ except Exception:
print(f"WARNING: Error converting removed quantity '{removed}'")
else:
print(f"Could not decode '{title}'")
@@ -168,7 +168,7 @@ def update_history(apps, schema_editor):
# Ensure that 'quantity' is stored too in this case
deltas['quantity'] = float(q)
- except:
+ except Exception:
print(f"WARNING: Error converting added quantity '{added}'")
else:
diff --git a/InvenTree/stock/migrations/0069_auto_20211109_2347.py b/InvenTree/stock/migrations/0069_auto_20211109_2347.py
index 748ac8d4cd..e4e8128f1c 100644
--- a/InvenTree/stock/migrations/0069_auto_20211109_2347.py
+++ b/InvenTree/stock/migrations/0069_auto_20211109_2347.py
@@ -25,7 +25,7 @@ def update_serials(apps, schema_editor):
if result and len(result.groups()) == 1:
try:
serial = int(result.groups()[0])
- except:
+ except Exception:
serial = 0
diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py
index c3801dee42..5093ce9bcb 100644
--- a/InvenTree/stock/models.py
+++ b/InvenTree/stock/models.py
@@ -1300,8 +1300,12 @@ class StockItem(MetadataMixin, MPTTModel):
item.save()
@transaction.atomic
- def copyTestResultsFrom(self, other, filters={}):
+ def copyTestResultsFrom(self, other, filters=None):
"""Copy all test results from another StockItem."""
+ # Set default - see B006
+ if filters is None:
+ filters = {}
+
for result in other.test_results.all().filter(**filters):
# Create a copy of the test result by nulling-out the pk
diff --git a/InvenTree/stock/tests.py b/InvenTree/stock/tests.py
index edeea46486..ec197e9f8b 100644
--- a/InvenTree/stock/tests.py
+++ b/InvenTree/stock/tests.py
@@ -90,7 +90,7 @@ class StockTest(InvenTreeTestCase):
build = Build.objects.create(reference='12345', part=part, title='A test build', quantity=1)
# Add some stock items which are "building"
- for i in range(10):
+ for _ in range(10):
StockItem.objects.create(
part=part, build=build,
quantity=10, is_building=True
@@ -439,7 +439,7 @@ class StockTest(InvenTreeTestCase):
serial=i,
quantity=1,
)
- except:
+ except Exception:
pass
item_next = item.get_next_serialized_item()
@@ -616,7 +616,7 @@ class StockTest(InvenTreeTestCase):
# - C32 should move directly under A
# Add some stock items to B3
- for i in range(10):
+ for _ in range(10):
StockItem.objects.create(
part=Part.objects.get(pk=1),
quantity=10,
diff --git a/InvenTree/users/models.py b/InvenTree/users/models.py
index 48b35e4562..24c8a6d062 100644
--- a/InvenTree/users/models.py
+++ b/InvenTree/users/models.py
@@ -538,14 +538,14 @@ class Owner(models.Model):
try:
owners.append(cls.objects.get(owner_id=user.pk, owner_type=user_type))
- except: # pragma: no cover
+ except Exception: # pragma: no cover
pass
for group in user.groups.all():
try:
owner = cls.objects.get(owner_id=group.pk, owner_type=group_type)
owners.append(owner)
- except: # pragma: no cover
+ except Exception: # pragma: no cover
pass
return owners
diff --git a/ci/check_js_templates.py b/ci/check_js_templates.py
index 5fd7521c55..54cd274afb 100644
--- a/ci/check_js_templates.py
+++ b/ci/check_js_templates.py
@@ -24,7 +24,7 @@ print("=================================")
def check_invalid_tag(data):
-
+ """Check for invalid tags."""
pattern = r"{%(\w+)"
err_count = 0
@@ -42,7 +42,7 @@ def check_invalid_tag(data):
def check_prohibited_tags(data):
-
+ """Check for prohibited tags."""
allowed_tags = [
'if',
'elif',
diff --git a/ci/version_check.py b/ci/version_check.py
index c9f05a1a13..1b0aed83ff 100644
--- a/ci/version_check.py
+++ b/ci/version_check.py
@@ -1,6 +1,6 @@
-"""
-Ensure that the release tag matches the InvenTree version number:
+"""Ensure that the release tag matches the InvenTree version number.
+Behaviour:
master / main branch:
- version number must end with 'dev'
diff --git a/docker/gunicorn.conf.py b/docker/gunicorn.conf.py
index 291f3ff198..50f9f70084 100644
--- a/docker/gunicorn.conf.py
+++ b/docker/gunicorn.conf.py
@@ -1,3 +1,5 @@
+"""Gunicorn configuration for InvenTree."""
+
import logging
import multiprocessing
import os
diff --git a/setup.cfg b/setup.cfg
index 3386be2230..e1269ae43f 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -19,6 +19,8 @@ ignore =
D202,
# - D415 - First line should end with a period, question mark, or exclamation point
D415,
+ # - B009 - Do not call getattr with a constant attribute value
+ B009
exclude = .git,__pycache__,*/migrations/*,*/lib/*,*/bin/*,*/media/*,*/static/*,InvenTree/plugins/*
per-file-ignores =
# Do not enforce docstring on __init__
diff --git a/tasks.py b/tasks.py
index a9036e460b..e7600ae520 100644
--- a/tasks.py
+++ b/tasks.py
@@ -1,3 +1,5 @@
+"""Tasks for automating certain actions and interacting with InvenTree from the CLI."""
+
import json
import os
import pathlib
@@ -8,7 +10,7 @@ from invoke import task
def apps():
- """Returns a list of installed apps"""
+ """Returns a list of installed apps."""
return [
'build',
'common',
@@ -43,12 +45,13 @@ def managePyPath():
return os.path.join(managePyDir(), 'manage.py')
-def manage(c, cmd, pty=False):
+def manage(c, cmd, pty: bool = False):
"""Runs a given command against django's "manage.py" script.
Args:
- c - Command line context
- cmd - django command to run
+ c: Command line context.
+ cmd: Django command to run.
+ pty (bool, optional): Run an interactive session. Defaults to False.
"""
c.run('cd "{path}" && python3 manage.py {cmd}'.format(
path=managePyDir(),