2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-07-01 03:00:54 +00:00

Docstring checks in QC checks (#3089)

* Add pre-commit to the stack

* exclude static

* Add locales to excludes

* fix style errors

* rename pipeline steps

* also wait on precommit

* make template matching simpler

* Use the same code for python setup everywhere

* use step and cache for python setup

* move regular settings up into general envs

* just use full update

* Use invoke instead of static references

* make setup actions more similar

* use python3

* refactor names to be similar

* fix runner version

* fix references

* remove incidential change

* use matrix for os

* Github can't do this right now

* ignore docstyle errors

* Add seperate docstring test

* update flake call

* do not fail on docstring

* refactor setup into workflow

* update reference

* switch to action

* resturcture

* add bash statements

* remove os from cache

* update input checks

* make code cleaner

* fix boolean

* no relative paths

* install wheel by python

* switch to install

* revert back to simple wheel

* refactor import export tests

* move setup keys back to not disturbe tests

* remove docstyle till that is fixed

* update references

* continue on error

* add docstring test

* use relativ action references

* Change step / job docstrings

* update to merge

* reformat comments 1

* fix docstrings 2

* fix docstrings 3

* fix docstrings 4

* fix docstrings 5

* fix docstrings 6

* fix docstrings 7

* fix docstrings 8

* fix docstirns 9

* fix docstrings 10

* docstring adjustments

* update the remaining docstrings

* small docstring changes

* fix function name

* update support files for docstrings

* Add missing args to docstrings

* Remove outdated function

* Add docstrings for the 'build' app

* Make API code cleaner

* add more docstrings for plugin app

* Remove dead code for plugin settings
No idea what that was even intended for

* ignore __init__ files for docstrings

* More docstrings

* Update docstrings for the 'part' directory

* Fixes for related_part functionality

* Fix removed stuff from merge 99676ee

* make more consistent

* Show statistics for docstrings

* add more docstrings

* move specific register statements to make them clearer to understant

* More docstrings for common

* and more docstrings

* and more

* simpler call

* docstrings for notifications

* docstrings for common/tests

* Add docs for common/models

* Revert "move specific register statements to make them clearer to understant"

This reverts commit ca96654622.

* use typing here

* Revert "Make API code cleaner"

This reverts commit 24fb68bd3e.

* docstring updates for the 'users' app

* Add generic Meta info to simple Meta classes

* remove unneeded unique_together statements

* More simple metas

* Remove unnecessary format specifier

* Remove extra json format specifiers

* Add docstrings for the 'plugin' app

* Docstrings for the 'label' app

* Add missing docstrings for the 'report' app

* Fix build test regression

* Fix top-level files

* docstrings for InvenTree/InvenTree

* reduce unneeded code

* add docstrings

* and more docstrings

* more docstrings

* more docstrings for stock

* more docstrings

* docstrings for order/views

* Docstrings for various files in the 'order' app

* Docstrings for order/test_api.py

* Docstrings for order/serializers.py

* Docstrings for order/admin.py

* More docstrings for the order app

* Add docstrings for the 'company' app

* Add unit tests for rebuilding the reference fields

* Prune out some more dead code

* remove more dead code

Co-authored-by: Oliver Walters <oliver.henry.walters@gmail.com>
This commit is contained in:
Matthias Mair
2022-06-01 17:37:39 +02:00
committed by GitHub
parent 66a6915213
commit 0c97a50e47
223 changed files with 4416 additions and 6980 deletions

View File

@ -1,6 +1,4 @@
"""
JSON serializers for Part app
"""
"""DRF data serializers for Part app."""
import imghdr
from decimal import Decimal
@ -37,17 +35,10 @@ from .models import (BomItem, BomItemSubstitute, Part, PartAttachment,
class CategorySerializer(InvenTreeModelSerializer):
""" Serializer for PartCategory """
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
"""Serializer for PartCategory."""
def get_starred(self, category):
"""
Return True if the category is directly "starred" by the current user
"""
"""Return True if the category is directly "starred" by the current user."""
return category in self.context.get('starred_categories', [])
url = serializers.CharField(source='get_absolute_url', read_only=True)
@ -59,6 +50,7 @@ class CategorySerializer(InvenTreeModelSerializer):
starred = serializers.SerializerMethodField()
class Meta:
"""Metaclass defining serializer fields"""
model = PartCategory
fields = [
'pk',
@ -76,11 +68,10 @@ class CategorySerializer(InvenTreeModelSerializer):
class CategoryTree(InvenTreeModelSerializer):
"""
Serializer for PartCategory tree
"""
"""Serializer for PartCategory tree."""
class Meta:
"""Metaclass defining serializer fields"""
model = PartCategory
fields = [
'pk',
@ -90,11 +81,10 @@ class CategoryTree(InvenTreeModelSerializer):
class PartAttachmentSerializer(InvenTreeAttachmentSerializer):
"""
Serializer for the PartAttachment class
"""
"""Serializer for the PartAttachment class."""
class Meta:
"""Metaclass defining serializer fields"""
model = PartAttachment
fields = [
@ -113,13 +103,12 @@ class PartAttachmentSerializer(InvenTreeAttachmentSerializer):
class PartTestTemplateSerializer(InvenTreeModelSerializer):
"""
Serializer for the PartTestTemplate class
"""
"""Serializer for the PartTestTemplate class."""
key = serializers.CharField(read_only=True)
class Meta:
"""Metaclass defining serializer fields"""
model = PartTestTemplate
fields = [
@ -135,9 +124,7 @@ class PartTestTemplateSerializer(InvenTreeModelSerializer):
class PartSalePriceSerializer(InvenTreeModelSerializer):
"""
Serializer for sale prices for Part model.
"""
"""Serializer for sale prices for Part model."""
quantity = InvenTreeDecimalField()
@ -155,6 +142,7 @@ class PartSalePriceSerializer(InvenTreeModelSerializer):
price_string = serializers.CharField(source='price', read_only=True)
class Meta:
"""Metaclass defining serializer fields"""
model = PartSellPriceBreak
fields = [
'pk',
@ -167,9 +155,7 @@ class PartSalePriceSerializer(InvenTreeModelSerializer):
class PartInternalPriceSerializer(InvenTreeModelSerializer):
"""
Serializer for internal prices for Part model.
"""
"""Serializer for internal prices for Part model."""
quantity = InvenTreeDecimalField()
@ -187,6 +173,7 @@ class PartInternalPriceSerializer(InvenTreeModelSerializer):
price_string = serializers.CharField(source='price', read_only=True)
class Meta:
"""Metaclass defining serializer fields"""
model = PartInternalPriceBreak
fields = [
'pk',
@ -199,8 +186,8 @@ class PartInternalPriceSerializer(InvenTreeModelSerializer):
class PartThumbSerializer(serializers.Serializer):
"""
Serializer for the 'image' field of the Part model.
"""Serializer for the 'image' field of the Part model.
Used to serve and display existing Part images.
"""
@ -209,12 +196,10 @@ class PartThumbSerializer(serializers.Serializer):
class PartThumbSerializerUpdate(InvenTreeModelSerializer):
""" Serializer for updating Part thumbnail """
"""Serializer for updating Part thumbnail."""
def validate_image(self, value):
"""
Check that file is an image.
"""
"""Check that file is an image."""
validate = imghdr.what(value)
if not validate:
raise serializers.ValidationError("File is not an image")
@ -223,6 +208,7 @@ class PartThumbSerializerUpdate(InvenTreeModelSerializer):
image = InvenTreeAttachmentSerializerField(required=True)
class Meta:
"""Metaclass defining serializer fields"""
model = Part
fields = [
'image',
@ -230,9 +216,10 @@ class PartThumbSerializerUpdate(InvenTreeModelSerializer):
class PartParameterTemplateSerializer(InvenTreeModelSerializer):
""" JSON serializer for the PartParameterTemplate model """
"""JSON serializer for the PartParameterTemplate model."""
class Meta:
"""Metaclass defining serializer fields"""
model = PartParameterTemplate
fields = [
'pk',
@ -242,11 +229,12 @@ class PartParameterTemplateSerializer(InvenTreeModelSerializer):
class PartParameterSerializer(InvenTreeModelSerializer):
""" JSON serializers for the PartParameter model """
"""JSON serializers for the PartParameter model."""
template_detail = PartParameterTemplateSerializer(source='template', many=False, read_only=True)
class Meta:
"""Metaclass defining serializer fields"""
model = PartParameter
fields = [
'pk',
@ -258,13 +246,14 @@ class PartParameterSerializer(InvenTreeModelSerializer):
class PartBriefSerializer(InvenTreeModelSerializer):
""" Serializer for Part (brief detail) """
"""Serializer for Part (brief detail)"""
thumbnail = serializers.CharField(source='get_thumbnail_url', read_only=True)
stock = serializers.FloatField(source='total_stock')
class Meta:
"""Metaclass defining serializer fields"""
model = Part
fields = [
'pk',
@ -288,19 +277,20 @@ class PartBriefSerializer(InvenTreeModelSerializer):
class PartSerializer(InvenTreeModelSerializer):
""" Serializer for complete detail information of a part.
"""Serializer for complete detail information of a part.
Used when displaying all details of a single component.
"""
def get_api_url(self):
"""Return the API url associated with this serializer"""
return reverse_lazy('api-part-list')
def __init__(self, *args, **kwargs):
"""
Custom initialization method for PartSerializer,
so that we can optionally pass extra fields based on the query.
"""
"""Custom initialization method for PartSerializer:
- Allows us to optionally pass extra fields based on the query.
"""
self.starred_parts = kwargs.pop('starred_parts', [])
category_detail = kwargs.pop('category_detail', False)
@ -317,12 +307,10 @@ class PartSerializer(InvenTreeModelSerializer):
@staticmethod
def annotate_queryset(queryset):
"""
Add some extra annotations to the queryset,
performing database queries as efficiently as possible,
to reduce database trips.
"""
"""Add some extra annotations to the queryset.
Performing database queries as efficiently as possible, to reduce database trips.
"""
# Annotate with the total 'in stock' quantity
queryset = queryset.annotate(
in_stock=Coalesce(
@ -444,10 +432,7 @@ class PartSerializer(InvenTreeModelSerializer):
return queryset
def get_starred(self, part):
"""
Return "true" if the part is starred by the current user.
"""
"""Return "true" if the part is starred by the current user."""
return part in self.starred_parts
# Extra detail for the category
@ -477,6 +462,7 @@ class PartSerializer(InvenTreeModelSerializer):
)
class Meta:
"""Metaclass defining serializer fields"""
model = Part
partial = True
fields = [
@ -522,14 +508,13 @@ class PartSerializer(InvenTreeModelSerializer):
class PartRelationSerializer(InvenTreeModelSerializer):
"""
Serializer for a PartRelated model
"""
"""Serializer for a PartRelated model."""
part_1_detail = PartSerializer(source='part_1', read_only=True, many=False)
part_2_detail = PartSerializer(source='part_2', read_only=True, many=False)
class Meta:
"""Metaclass defining serializer fields"""
model = PartRelated
fields = [
'pk',
@ -541,12 +526,13 @@ class PartRelationSerializer(InvenTreeModelSerializer):
class PartStarSerializer(InvenTreeModelSerializer):
""" Serializer for a PartStar object """
"""Serializer for a PartStar object."""
partname = serializers.CharField(source='part.full_name', read_only=True)
username = serializers.CharField(source='user.username', read_only=True)
class Meta:
"""Metaclass defining serializer fields"""
model = PartStar
fields = [
'pk',
@ -558,13 +544,12 @@ class PartStarSerializer(InvenTreeModelSerializer):
class BomItemSubstituteSerializer(InvenTreeModelSerializer):
"""
Serializer for the BomItemSubstitute class
"""
"""Serializer for the BomItemSubstitute class."""
part_detail = PartBriefSerializer(source='part', read_only=True, many=False)
class Meta:
"""Metaclass defining serializer fields"""
model = BomItemSubstitute
fields = [
'pk',
@ -575,15 +560,14 @@ class BomItemSubstituteSerializer(InvenTreeModelSerializer):
class BomItemSerializer(InvenTreeModelSerializer):
"""
Serializer for BomItem object
"""
"""Serializer for BomItem object."""
price_range = serializers.CharField(read_only=True)
quantity = InvenTreeDecimalField(required=True)
def validate_quantity(self, quantity):
"""Perform validation for the BomItem quantity field"""
if quantity <= 0:
raise serializers.ValidationError(_("Quantity must be greater than zero"))
@ -615,9 +599,11 @@ class BomItemSerializer(InvenTreeModelSerializer):
available_variant_stock = serializers.FloatField(read_only=True)
def __init__(self, *args, **kwargs):
# part_detail and sub_part_detail serializers are only included if requested.
# This saves a bunch of database requests
"""Determine if extra detail fields are to be annotated on this serializer
- part_detail and sub_part_detail serializers are only included if requested.
- This saves a bunch of database requests
"""
part_detail = kwargs.pop('part_detail', False)
sub_part_detail = kwargs.pop('sub_part_detail', False)
include_pricing = kwargs.pop('include_pricing', False)
@ -640,6 +626,7 @@ class BomItemSerializer(InvenTreeModelSerializer):
@staticmethod
def setup_eager_loading(queryset):
"""Prefetch against the provided queryset to speed up database access"""
queryset = queryset.prefetch_related('part')
queryset = queryset.prefetch_related('part__category')
queryset = queryset.prefetch_related('part__stock_items')
@ -663,18 +650,15 @@ class BomItemSerializer(InvenTreeModelSerializer):
@staticmethod
def annotate_queryset(queryset):
"""
Annotate the BomItem queryset with extra information:
"""Annotate the BomItem queryset with extra information:
Annotations:
available_stock: The amount of stock available for the sub_part Part object
"""
"""
Construct an "available stock" quantity:
available_stock = total_stock - build_order_allocations - sales_order_allocations
"""
build_order_filter = Q(build__status__in=BuildStatus.ACTIVE_CODES)
sales_order_filter = Q(
line__order__status__in=SalesOrderStatus.OPEN,
@ -799,8 +783,7 @@ class BomItemSerializer(InvenTreeModelSerializer):
return queryset
def get_purchase_price_range(self, obj):
""" Return purchase price range """
"""Return purchase price range."""
try:
purchase_price_min = obj.purchase_price_min
except AttributeError:
@ -830,8 +813,7 @@ class BomItemSerializer(InvenTreeModelSerializer):
return purchase_price_range
def get_purchase_price_avg(self, obj):
""" Return purchase price average """
"""Return purchase price average."""
try:
purchase_price_avg = obj.purchase_price_avg
except AttributeError:
@ -846,6 +828,7 @@ class BomItemSerializer(InvenTreeModelSerializer):
return purchase_price_avg
class Meta:
"""Metaclass defining serializer fields"""
model = BomItem
fields = [
'allow_variants',
@ -877,7 +860,7 @@ class BomItemSerializer(InvenTreeModelSerializer):
class CategoryParameterTemplateSerializer(InvenTreeModelSerializer):
""" Serializer for PartCategoryParameterTemplate """
"""Serializer for PartCategoryParameterTemplate."""
parameter_template = PartParameterTemplateSerializer(many=False,
read_only=True)
@ -885,6 +868,7 @@ class CategoryParameterTemplateSerializer(InvenTreeModelSerializer):
category_detail = CategorySerializer(source='category', many=False, read_only=True)
class Meta:
"""Metaclass defining serializer fields"""
model = PartCategoryParameterTemplate
fields = [
'pk',
@ -896,11 +880,10 @@ class CategoryParameterTemplateSerializer(InvenTreeModelSerializer):
class PartCopyBOMSerializer(serializers.Serializer):
"""
Serializer for copying a BOM from another part
"""
"""Serializer for copying a BOM from another part."""
class Meta:
"""Metaclass defining serializer fields"""
fields = [
'part',
'remove_existing',
@ -919,10 +902,7 @@ class PartCopyBOMSerializer(serializers.Serializer):
)
def validate_part(self, part):
"""
Check that a 'valid' part was selected
"""
"""Check that a 'valid' part was selected."""
return part
remove_existing = serializers.BooleanField(
@ -950,10 +930,7 @@ class PartCopyBOMSerializer(serializers.Serializer):
)
def save(self):
"""
Actually duplicate the BOM
"""
"""Actually duplicate the BOM."""
base_part = self.context['part']
data = self.validated_data
@ -968,13 +945,12 @@ class PartCopyBOMSerializer(serializers.Serializer):
class BomImportUploadSerializer(DataFileUploadSerializer):
"""
Serializer for uploading a file and extracting data from it.
"""
"""Serializer for uploading a file and extracting data from it."""
TARGET_MODEL = BomItem
class Meta:
"""Metaclass defining serializer fields"""
fields = [
'data_file',
'part',
@ -994,7 +970,7 @@ class BomImportUploadSerializer(DataFileUploadSerializer):
)
def save(self):
"""The uploaded data file has been validated, accept the submitted data"""
data = self.validated_data
if data.get('clear_existing_bom', False):
@ -1005,12 +981,15 @@ class BomImportUploadSerializer(DataFileUploadSerializer):
class BomImportExtractSerializer(DataFileExtractSerializer):
"""
"""Serializer class for exatracting BOM data from an uploaded file.
The parent class DataFileExtractSerializer does most of the heavy lifting here.
"""
TARGET_MODEL = BomItem
def validate_extracted_columns(self):
"""Validate that the extracted columns are correct"""
super().validate_extracted_columns()
part_columns = ['part', 'part_name', 'part_ipn', 'part_id']
@ -1020,7 +999,7 @@ class BomImportExtractSerializer(DataFileExtractSerializer):
raise serializers.ValidationError(_("No part column specified"))
def process_row(self, row):
"""Process a single row from the loaded BOM file"""
# Skip any rows which are at a lower "level"
level = row.get('level', None)
@ -1089,8 +1068,7 @@ class BomImportExtractSerializer(DataFileExtractSerializer):
class BomImportSubmitSerializer(serializers.Serializer):
"""
Serializer for uploading a BOM against a specified part.
"""Serializer for uploading a BOM against a specified part.
A "BOM" is a set of BomItem objects which are to be validated together as a set
"""
@ -1098,7 +1076,10 @@ class BomImportSubmitSerializer(serializers.Serializer):
items = BomItemSerializer(many=True, required=True)
def validate(self, data):
"""Validate the submitted BomItem data:
- At least one line (BomItem) is required
"""
items = data['items']
if len(items) == 0:
@ -1109,7 +1090,11 @@ class BomImportSubmitSerializer(serializers.Serializer):
return data
def save(self):
"""POST: Perform final save of submitted BOM data:
- By this stage each line in the BOM has been validated
- Individually 'save' (create) each BomItem line
"""
data = self.validated_data
items = data['items']