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(),