@@ -41,9 +41,10 @@ class PartsTablePart(Block):
4141 """An interface mixin for a part that is selected from a table, defining parameters to allow manual part selection
4242 as well as matching parts."""
4343
44- def __init__ (self , * args : Any , part : StringLike = "" , ** kwargs : Any ) -> None :
44+ def __init__ (self , * args : Any , part : StringLike = "" , excluded_parts : ArrayStringLike = [], ** kwargs : Any ) -> None :
4545 super ().__init__ (* args , ** kwargs )
4646 self .part = self .ArgParameter (part )
47+ self .excluded_parts = self .ArgParameter (excluded_parts )
4748 self .actual_part = self .Parameter (StringExpr ())
4849 self .matching_parts = self .Parameter (ArrayStringExpr ())
4950
@@ -56,12 +57,17 @@ class PartsTableSelector(PartsTablePart, GeneratorBlock, PartsTableBase):
5657 def __init__ (self , * args : Any , ** kwargs : Any ) -> None :
5758 super ().__init__ (* args , ** kwargs )
5859 self .generator_param (self .part )
60+ self .generator_param (self .excluded_parts )
5961
6062 def _row_filter (self , row : PartsTableRow ) -> bool :
6163 """Returns whether the candidate row satisfies the requirements (should be kept).
6264 Only called within generate(), so has access to GeneratorParam.get().
6365 Subclasses should chain this by and-ing with a super() call."""
64- return not self .get (self .part ) or (self .get (self .part ) == row [self .PART_NUMBER_COL ])
66+ part = self .get (self .part )
67+ excluded_parts = self .get (self .excluded_parts )
68+ return ((not part ) or (part == row [self .PART_NUMBER_COL ])) and (
69+ (not excluded_parts ) or (row [self .PART_NUMBER_COL ] not in excluded_parts )
70+ )
6571
6672 def _table_postprocess (self , table : PartsTable ) -> PartsTable :
6773 """Optional postprocessing step that takes a table and returns a transformed table.
0 commit comments