Centralized all drill_marks stuff

- Now we reuse code from drill_marks.py
- Added the options validation
- Updated the help
This commit is contained in:
Salvador E. Tropea 2022-06-10 07:39:27 -03:00
parent 66c9e21865
commit ef98248b32
6 changed files with 73 additions and 72 deletions

View File

@ -1469,7 +1469,7 @@ Notes:
- `output`: [string='Custom_report.txt'] File name for the custom report.
- `dnf_filter`: [string|list(string)='_none'] Name of the filter to mark components as not fitted.
A short-cut to use for simple cases where a variant is an overkill.
- `drill_marks`: [string='full'] what to use to indicate the drill places, can be none, small or full (for real scale).
- `drill_marks`: [string='full'] [none,small,full] What to use to indicate the drill places, can be none, small or full (for real scale).
- `edge_cut_extension`: [string=''] Used to configure the edge cuts layer extension for Protel mode. Include the dot.
- `exclude_edge_layer`: [boolean=true] Do not include the PCB edge layer.
- `exclude_pads_from_silkscreen`: [boolean=false] Do not plot the component pads in the silk screen (KiCad 5.x only).
@ -1694,7 +1694,7 @@ Notes:
- `output`: [string='Custom_report.txt'] File name for the custom report.
- `dnf_filter`: [string|list(string)='_none'] Name of the filter to mark components as not fitted.
A short-cut to use for simple cases where a variant is an overkill.
- `drill_marks`: [string='full'] what to use to indicate the drill places, can be none, small or full (for real scale).
- `drill_marks`: [string='full'] [none,small,full] What to use to indicate the drill places, can be none, small or full (for real scale).
- `edge_cut_extension`: [string=''] Used to configure the edge cuts layer extension for Protel mode. Include the dot.
- `exclude_edge_layer`: [boolean=true] Do not include the PCB edge layer.
- `exclude_pads_from_silkscreen`: [boolean=false] Do not plot the component pads in the silk screen (KiCad 5.x only).
@ -2067,7 +2067,7 @@ Notes:
- `colored_vias`: [boolean=true] Plot vias in a different color. Like KiCad GUI does.
- `dnf_filter`: [string|list(string)='_none'] Name of the filter to mark components as not fitted.
A short-cut to use for simple cases where a variant is an overkill.
- `drill_marks`: [string='full'] What to use to indicate the drill places, can be none, small or full (for real scale).
- `drill_marks`: [string='full'] [none,small,full] What to use to indicate the drill places, can be none, small or full (for real scale).
- `frame_plot_mechanism`: [string='internal'] [gui,internal,plot] Plotting the frame from Python is problematic.
This option selects a workaround strategy.
gui: uses KiCad GUI to do it. Is slow but you get the correct frame.
@ -2181,7 +2181,7 @@ Notes:
- `output`: [string='Custom_report.txt'] File name for the custom report.
- `dnf_filter`: [string|list(string)='_none'] Name of the filter to mark components as not fitted.
A short-cut to use for simple cases where a variant is an overkill.
- `drill_marks`: [string='full'] what to use to indicate the drill places, can be none, small or full (for real scale).
- `drill_marks`: [string='full'] [none,small,full] What to use to indicate the drill places, can be none, small or full (for real scale).
- `edge_cut_extension`: [string=''] Used to configure the edge cuts layer extension for Protel mode. Include the dot.
- `exclude_edge_layer`: [boolean=true] Do not include the PCB edge layer.
- `exclude_pads_from_silkscreen`: [boolean=false] Do not plot the component pads in the silk screen (KiCad 5.x only).
@ -2212,7 +2212,7 @@ Notes:
Use the boolean true value to disable the output you are extending.
- `dnf_filter`: [string|list(string)='_none'] Name of the filter to mark components as not fitted.
A short-cut to use for simple cases where a variant is an overkill.
- `drill_marks`: [string='full'] what to use to indicate the drill places, can be none, small or full (for real scale).
- `drill_marks`: [string='full'] [none,small,full] What to use to indicate the drill places, can be none, small or full (for real scale).
- `edge_cut_extension`: [string=''] Used to configure the edge cuts layer extension for Protel mode. Include the dot.
- `exclude_edge_layer`: [boolean=true] Do not include the PCB edge layer.
- `exclude_pads_from_silkscreen`: [boolean=false] Do not plot the component pads in the silk screen (KiCad 5.x only).
@ -2251,14 +2251,14 @@ Notes:
- **`options`**: [dict] Options for the `pdf_pcb_print` output.
* Valid keys:
- **`plot_sheet_reference`**: [boolean=true] Include the title-block.
- **`scaling`**: [number=1.0] Scale factor (0 means autoscaling).
- **`scaling`**: [number=1.0] Scale factor (0 means autoscaling). You should disable `plot_sheet_reference` when using it.
- **`separated`**: [boolean=false] Print layers in separated pages.
- `color_theme`: [string='_builtin_classic'] Selects the color theme. Onlyu applies to KiCad 6.
To use the KiCad 6 default colors select `_builtin_default`.
Usually user colors are stored as `user`, but you can give it another name.
- `dnf_filter`: [string|list(string)='_none'] Name of the filter to mark components as not fitted.
A short-cut to use for simple cases where a variant is an overkill.
- `drill_marks`: [string='full'] What to use to indicate the drill places, can be none, small or full (for real scale).
- `drill_marks`: [string='full'] [none,small,full] What to use to indicate the drill places, can be none, small or full (for real scale).
- `force_edge_cuts`: [boolean=true] Only useful for KiCad 6 when printing in one page, you can disable the edge here.
KiCad 5 forces it by default, and you can't control it from config files.
Same for KiCad 6 when printing to separated pages.
@ -2411,7 +2411,7 @@ Notes:
- `output`: [string='Custom_report.txt'] File name for the custom report.
- `dnf_filter`: [string|list(string)='_none'] Name of the filter to mark components as not fitted.
A short-cut to use for simple cases where a variant is an overkill.
- `drill_marks`: [string='full'] what to use to indicate the drill places, can be none, small or full (for real scale).
- `drill_marks`: [string='full'] [none,small,full] What to use to indicate the drill places, can be none, small or full (for real scale).
- `edge_cut_extension`: [string=''] Used to configure the edge cuts layer extension for Protel mode. Include the dot.
- `exclude_edge_layer`: [boolean=true] Do not include the PCB edge layer.
- `exclude_pads_from_silkscreen`: [boolean=false] Do not plot the component pads in the silk screen (KiCad 5.x only).
@ -2457,13 +2457,7 @@ Notes:
- **`dir`**: [string='./'] Output directory for the generated files.
If it starts with `+` the rest is concatenated to the default dir.
- **`name`**: [string=''] Used to identify this particular output definition.
- `category`: [string|list(string)=''] The category for this output. If not specified an internally defined category is used.
Categories looks like file system paths, i.e. PCB/fabrication/gerber.
- `disable_run_by_default`: [string|boolean] Use it to disable the `run_by_default` status of other output.
Useful when this output extends another and you don't want to generate the original.
Use the boolean true value to disable the output you are extending.
- `extends`: [string=''] Copy the `options` section from the indicated output.
- `options`: [dict] Options for the `boardview` output.
- **`options`**: [dict] Options for the `boardview` output.
* Valid keys:
- **`lib`**: [string='QR'] Short name for the library.
- **`output`**: [string='%f-%i%I%v.%x'] Filename for the output (%i=qr, %x=lib). Affected by global options.
@ -2479,6 +2473,12 @@ Notes:
- `size_units`: [string='millimeters'] [millimeters,inches] Units used for the size.
- `reference`: [string='QR'] The reference prefix.
- `use_sch_dir`: [boolean=true] Generate the libs relative to the schematic/PCB dir.
- `category`: [string|list(string)=''] The category for this output. If not specified an internally defined category is used.
Categories looks like file system paths, i.e. PCB/fabrication/gerber.
- `disable_run_by_default`: [string|boolean] Use it to disable the `run_by_default` status of other output.
Useful when this output extends another and you don't want to generate the original.
Use the boolean true value to disable the output you are extending.
- `extends`: [string=''] Copy the `options` section from the indicated output.
- `output_id`: [string=''] Text to use for the %I expansion content. To differentiate variations of this output.
- `priority`: [number=90] [0,100] Priority for this output. High priority outputs are created first.
Internally we use 10 for low priority, 90 for high priority and 50 for most outputs.
@ -2670,7 +2670,7 @@ Notes:
- `output`: [string='Custom_report.txt'] File name for the custom report.
- `dnf_filter`: [string|list(string)='_none'] Name of the filter to mark components as not fitted.
A short-cut to use for simple cases where a variant is an overkill.
- `drill_marks`: [string='full'] what to use to indicate the drill places, can be none, small or full (for real scale).
- `drill_marks`: [string='full'] [none,small,full] What to use to indicate the drill places, can be none, small or full (for real scale).
- `edge_cut_extension`: [string=''] Used to configure the edge cuts layer extension for Protel mode. Include the dot.
- `exclude_edge_layer`: [boolean=true] Do not include the PCB edge layer.
- `exclude_pads_from_silkscreen`: [boolean=false] Do not plot the component pads in the silk screen (KiCad 5.x only).
@ -2718,14 +2718,14 @@ Notes:
- **`output`**: [string='%f-%i%I%v.%x'] Filename for the output SVG (%i=layers, %x=svg). Affected by global options.
- *output_name*: Alias for output.
- **`plot_sheet_reference`**: [boolean=true] Include the title-block.
- **`scaling`**: [number=1.0] Scale factor (0 means autoscaling).
- **`scaling`**: [number=1.0] Scale factor (0 means autoscaling). You should disable `plot_sheet_reference` when using it.
- **`separated`**: [boolean=false] Print layers in separated pages.
- `color_theme`: [string='_builtin_classic'] Selects the color theme. Onlyu applies to KiCad 6.
To use the KiCad 6 default colors select `_builtin_default`.
Usually user colors are stored as `user`, but you can give it another name.
- `dnf_filter`: [string|list(string)='_none'] Name of the filter to mark components as not fitted.
A short-cut to use for simple cases where a variant is an overkill.
- `drill_marks`: [string='full'] What to use to indicate the drill places, can be none, small or full (for real scale).
- `drill_marks`: [string='full'] [none,small,full] What to use to indicate the drill places, can be none, small or full (for real scale).
- `enable_ki5_page_fix`: [boolean=true] Enable workaround for KiCad 5 bug.
- `enable_ki6_page_fix`: [boolean=true] Enable workaround for KiCad 6 bug #11033.
- `force_edge_cuts`: [boolean=true] Only useful for KiCad 6 when printing in one page, you can disable the edge here.

View File

@ -439,7 +439,7 @@ outputs:
# [string|list(string)='_none'] Name of the filter to mark components as not fitted.
# A short-cut to use for simple cases where a variant is an overkill
dnf_filter: '_none'
# [string='full'] what to use to indicate the drill places, can be none, small or full (for real scale)
# [string='full'] [none,small,full] What to use to indicate the drill places, can be none, small or full (for real scale)
drill_marks: 'full'
# [string=''] Used to configure the edge cuts layer extension for Protel mode. Include the dot
edge_cut_extension: ''
@ -652,7 +652,7 @@ outputs:
# [string|list(string)='_none'] Name of the filter to mark components as not fitted.
# A short-cut to use for simple cases where a variant is an overkill
dnf_filter: '_none'
# [string='full'] what to use to indicate the drill places, can be none, small or full (for real scale)
# [string='full'] [none,small,full] What to use to indicate the drill places, can be none, small or full (for real scale)
drill_marks: 'full'
# [string=''] Used to configure the edge cuts layer extension for Protel mode. Include the dot
edge_cut_extension: ''
@ -1013,7 +1013,7 @@ outputs:
# [string|list(string)='_none'] Name of the filter to mark components as not fitted.
# A short-cut to use for simple cases where a variant is an overkill
dnf_filter: '_none'
# [string='full'] What to use to indicate the drill places, can be none, small or full (for real scale)
# [string='full'] [none,small,full] What to use to indicate the drill places, can be none, small or full (for real scale)
drill_marks: 'full'
# [boolean=false] Add the `Edge.Cuts` to all the pages
force_edge_cuts: false
@ -1187,7 +1187,7 @@ outputs:
# [string|list(string)='_none'] Name of the filter to mark components as not fitted.
# A short-cut to use for simple cases where a variant is an overkill
dnf_filter: '_none'
# [string='full'] what to use to indicate the drill places, can be none, small or full (for real scale)
# [string='full'] [none,small,full] What to use to indicate the drill places, can be none, small or full (for real scale)
drill_marks: 'full'
# [string=''] Used to configure the edge cuts layer extension for Protel mode. Include the dot
edge_cut_extension: ''
@ -1239,7 +1239,7 @@ outputs:
# [string|list(string)='_none'] Name of the filter to mark components as not fitted.
# A short-cut to use for simple cases where a variant is an overkill
dnf_filter: '_none'
# [string='full'] What to use to indicate the drill places, can be none, small or full (for real scale)
# [string='full'] [none,small,full] What to use to indicate the drill places, can be none, small or full (for real scale)
drill_marks: 'full'
# [boolean=true] Only useful for KiCad 6 when printing in one page, you can disable the edge here.
# KiCad 5 forces it by default, and you can't control it from config files.
@ -1256,7 +1256,7 @@ outputs:
# `output_name` is an alias for `output`
# [boolean=true] Include the title-block
plot_sheet_reference: true
# [number=1.0] Scale factor (0 means autoscaling)
# [number=1.0] Scale factor (0 means autoscaling). You should disable `plot_sheet_reference` when using it
scaling: 1.0
# [boolean=false] Print layers in separated pages
separated: false
@ -1364,7 +1364,7 @@ outputs:
# [string|list(string)='_none'] Name of the filter to mark components as not fitted.
# A short-cut to use for simple cases where a variant is an overkill
dnf_filter: '_none'
# [string='full'] what to use to indicate the drill places, can be none, small or full (for real scale)
# [string='full'] [none,small,full] What to use to indicate the drill places, can be none, small or full (for real scale)
drill_marks: 'full'
# [string=''] Used to configure the edge cuts layer extension for Protel mode. Include the dot
edge_cut_extension: ''
@ -1611,7 +1611,7 @@ outputs:
# [string|list(string)='_none'] Name of the filter to mark components as not fitted.
# A short-cut to use for simple cases where a variant is an overkill
dnf_filter: '_none'
# [string='full'] what to use to indicate the drill places, can be none, small or full (for real scale)
# [string='full'] [none,small,full] What to use to indicate the drill places, can be none, small or full (for real scale)
drill_marks: 'full'
# [string=''] Used to configure the edge cuts layer extension for Protel mode. Include the dot
edge_cut_extension: ''
@ -1662,7 +1662,7 @@ outputs:
# [string|list(string)='_none'] Name of the filter to mark components as not fitted.
# A short-cut to use for simple cases where a variant is an overkill
dnf_filter: '_none'
# [string='full'] What to use to indicate the drill places, can be none, small or full (for real scale)
# [string='full'] [none,small,full] What to use to indicate the drill places, can be none, small or full (for real scale)
drill_marks: 'full'
# [boolean=true] Enable workaround for KiCad 5 bug
enable_ki5_page_fix: true
@ -1683,7 +1683,7 @@ outputs:
# `output_name` is an alias for `output`
# [boolean=true] Include the title-block
plot_sheet_reference: true
# [number=1.0] Scale factor (0 means autoscaling)
# [number=1.0] Scale factor (0 means autoscaling). You should disable `plot_sheet_reference` when using it
scaling: 1.0
# [boolean=false] Print layers in separated pages
separated: false

View File

@ -1,37 +1,47 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 Salvador E. Tropea
# Copyright (c) 2020 Instituto Nacional de Tecnología Industrial
# Copyright (c) 2020-2022 Salvador E. Tropea
# Copyright (c) 2020-2022 Instituto Nacional de Tecnología Industrial
# License: GPL-3.0
# Project: KiBot (formerly KiPlot)
from pcbnew import (PCB_PLOT_PARAMS)
from pcbnew import PCB_PLOT_PARAMS
from .error import KiPlotConfigurationError
from .out_any_layer import AnyLayerOptions
from .macros import macros, document # noqa: F401
from . import log
logger = log.get_logger()
# Mappings to KiCad values
DRILL_MARKS_MAP = {
'none': PCB_PLOT_PARAMS.NO_DRILL_SHAPE,
'small': PCB_PLOT_PARAMS.SMALL_DRILL_SHAPE,
'full': PCB_PLOT_PARAMS.FULL_DRILL_SHAPE,
}
# Mappings from KiCad values
DRILL_MARKS_REV_MAP = {
PCB_PLOT_PARAMS.NO_DRILL_SHAPE: 'none',
PCB_PLOT_PARAMS.SMALL_DRILL_SHAPE: 'small',
PCB_PLOT_PARAMS.FULL_DRILL_SHAPE: 'full',
}
DRILL_MARKS_HELP = "[none,small,full] What to use to indicate the drill places, can be none, small or full (for real scale)"
def drill_marks_setter(val):
if val not in DRILL_MARKS_MAP:
raise KiPlotConfigurationError("Unknown drill mark type: {}".format(val))
return val
def drill_marks_help(self):
self._drill_marks = 'full'
self.set_doc('drill_marks', " [string='full'] "+DRILL_MARKS_HELP)
class DrillMarks(AnyLayerOptions):
""" This class provides the drill_marks attribute.
Used by DXF, HPGL, PDF, PS and SVG formats. """
# Mappings to KiCad values
_drill_marks_map = {
'none': PCB_PLOT_PARAMS.NO_DRILL_SHAPE,
'small': PCB_PLOT_PARAMS.SMALL_DRILL_SHAPE,
'full': PCB_PLOT_PARAMS.FULL_DRILL_SHAPE,
}
_drill_marks_rev_map = {
PCB_PLOT_PARAMS.NO_DRILL_SHAPE: 'none',
PCB_PLOT_PARAMS.SMALL_DRILL_SHAPE: 'small',
PCB_PLOT_PARAMS.FULL_DRILL_SHAPE: 'full',
}
def __init__(self):
super().__init__()
with document:
self._drill_marks = 'full'
""" what to use to indicate the drill places, can be none, small or full (for real scale) """
drill_marks_help(self)
@property
def drill_marks(self):
@ -39,13 +49,11 @@ class DrillMarks(AnyLayerOptions):
@drill_marks.setter
def drill_marks(self, val):
if val not in self._drill_marks_map:
raise KiPlotConfigurationError("Unknown drill mark type: {}".format(val))
self._drill_marks = val
self._drill_marks = drill_marks_setter(val)
def config(self, parent):
super().config(parent)
self._drill_marks = DrillMarks._drill_marks_map[self._drill_marks]
self._drill_marks = DRILL_MARKS_MAP[self._drill_marks]
def _configure_plot_ctrl(self, po, output_dir):
super()._configure_plot_ctrl(po, output_dir)
@ -54,4 +62,4 @@ class DrillMarks(AnyLayerOptions):
def read_vals_from_po(self, po):
super().read_vals_from_po(po)
self._drill_marks = DrillMarks._drill_marks_rev_map[po.GetDrillMarksType()]
self._drill_marks = DRILL_MARKS_REV_MAP[po.GetDrillMarksType()]

View File

@ -16,7 +16,7 @@ from . import log
logger = log.get_logger()
def filter(v):
def do_filter(v):
return inspect.isclass(v) or not (callable(v) or isinstance(v, (dict, list)))
@ -125,7 +125,9 @@ class Optionable(object):
# Map known attributes and avoid mapping private ones
if (k[0] == '_') or (k not in attrs):
if self._unkown_is_error:
raise KiPlotConfigurationError("Unknown {}option `{}`".format(self._error_context, k))
valid = list(filter(lambda x: x[0] != '_', attrs.keys()))
raise KiPlotConfigurationError("Unknown {}option `{}`. Valid options: {}".
format(self._error_context, k, valid))
logger.warning(W_UNKOPS + "Unknown {}option `{}`".format(self._error_context, k))
continue
# Check the data type
@ -203,7 +205,7 @@ class Optionable(object):
def get_attrs_for(self):
""" Returns all attributes """
return dict(inspect.getmembers(self, filter))
return dict(inspect.getmembers(self, do_filter))
def get_attrs_gen(self):
""" Returns a (key, val) iterator on public attributes """

View File

@ -6,13 +6,13 @@
import os
from shutil import rmtree
from .pre_base import BasePreFlight
from .error import KiPlotConfigurationError
from .gs import GS
from .kiplot import check_script, exec_with_retry, add_extra_options
from .misc import CMD_PCBNEW_PRINT_LAYERS, URL_PCBNEW_PRINT_LAYERS, PDF_PCB_PRINT, kiauto_dependency
from .out_base import VariantOptions
from .registrable import RegDependency
from .macros import macros, document, output_class # noqa: F401
from .drill_marks import drill_marks_help, drill_marks_setter
from .layer import Layer
from . import log
@ -24,17 +24,12 @@ def register_deps(pre):
class Any_PCB_PrintOptions(VariantOptions):
# Mappings to KiCad config values. They should be the same used in drill_marks.py
_drill_marks_map = {'none': 0, 'small': 1, 'full': 2}
def __init__(self):
with document:
self.output_name = None
""" {output} """
self.scaling = 1.0
""" *Scale factor (0 means autoscaling). You should disable `plot_sheet_reference` when using it """
self._drill_marks = 'full'
""" What to use to indicate the drill places, can be none, small or full (for real scale) """
self.plot_sheet_reference = True
""" *Include the title-block """
self.monochrome = False
@ -56,6 +51,7 @@ class Any_PCB_PrintOptions(VariantOptions):
""" Selects the color theme. Onlyu applies to KiCad 6.
To use the KiCad 6 default colors select `_builtin_default`.
Usually user colors are stored as `user`, but you can give it another name """
drill_marks_help(self)
super().__init__()
@property
@ -64,13 +60,11 @@ class Any_PCB_PrintOptions(VariantOptions):
@drill_marks.setter
def drill_marks(self, val):
if val not in self._drill_marks_map:
raise KiPlotConfigurationError("Unknown drill mark type: {}".format(val))
self._drill_marks = val
self._drill_marks = drill_marks_setter(val)
def config(self, parent):
super().config(parent)
self._drill_marks = Any_PCB_PrintOptions._drill_marks_map[self._drill_marks]
self._drill_marks = Any_PCB_PrintOptions.DRILL_MARKS_MAP[self._drill_marks]
def filter_components(self, board, force_copy):
if not self._comps and not force_copy:

View File

@ -28,6 +28,7 @@ from .kiplot import check_script, exec_with_retry, add_extra_options
from .registrable import RegDependency
from .create_pdf import create_pdf_from_pages
from .macros import macros, document, output_class # noqa: F401
from .drill_marks import DRILL_MARKS_MAP, drill_marks_setter, drill_marks_help
from .layer import Layer, get_priority
from . import __version__
from . import log
@ -223,7 +224,6 @@ class PagesOptions(Optionable):
class PCB_PrintOptions(VariantOptions):
# Mappings to KiCad config values. They should be the same used in drill_marks.py
_drill_marks_map = {'none': 0, 'small': 1, 'full': 2}
_pad_colors = {'pad_color': 'pad_through_hole',
'via_color': 'via_through',
'micro_via_color': 'via_micro',
@ -237,8 +237,6 @@ class PCB_PrintOptions(VariantOptions):
""" *Filename for the output (%i=assembly, %x=pdf)/(%i=assembly_page_NN, %x=svg)"""
self.hide_excluded = False
""" Hide components in the Fab layer that are marked as excluded by a variant """
self._drill_marks = 'full'
""" What to use to indicate the drill places, can be none, small or full (for real scale) """
self.color_theme = '_builtin_classic'
""" *Selects the color theme. Only applies to KiCad 6.
To use the KiCad 6 default colors select `_builtin_default`.
@ -295,6 +293,7 @@ class PCB_PrintOptions(VariantOptions):
""" Color for the background when `add_background` is enabled """
self.background_image = ''
""" Background image, must be an SVG, only when `add_background` is enabled """
drill_marks_help(self)
super().__init__()
self._expand_id = 'assembly'
@ -304,9 +303,7 @@ class PCB_PrintOptions(VariantOptions):
@drill_marks.setter
def drill_marks(self, val):
if val not in self._drill_marks_map:
raise KiPlotConfigurationError("Unknown drill mark type: {}".format(val))
self._drill_marks = val
self._drill_marks = drill_marks_setter(val)
def config(self, parent):
super().config(parent)
@ -324,7 +321,7 @@ class PCB_PrintOptions(VariantOptions):
la.color = layer_id2color[la._id]
else:
la.color = "#000000"
self._drill_marks = PCB_PrintOptions._drill_marks_map[self._drill_marks]
self._drill_marks = DRILL_MARKS_MAP[self._drill_marks]
self._expand_ext = self.format.lower()
for member, color in self._pad_colors.items():
if getattr(self, member):