lsst-pex-config 26.0.0a20230400__tar.gz → 29.2025.4500__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. lsst_pex_config-29.2025.4500/COPYRIGHT +4 -0
  2. {lsst-pex-config-26.0.0a20230400/python/lsst_pex_config.egg-info → lsst_pex_config-29.2025.4500}/PKG-INFO +13 -8
  3. lsst_pex_config-29.2025.4500/doc/lsst.pex.config/CHANGES.rst +125 -0
  4. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/doc/lsst.pex.config/field-types.rst +44 -4
  5. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/doc/lsst.pex.config/index.rst +4 -0
  6. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/doc/lsst.pex.config/inspecting-configs.rst +1 -1
  7. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/doc/lsst.pex.config/overview.rst +15 -3
  8. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/doc/lsst.pex.config/registry-intro.rst +6 -6
  9. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/doc/lsst.pex.config/wrapping-cpp-control-objects.rst +2 -2
  10. lsst_pex_config-29.2025.4500/pyproject.toml +196 -0
  11. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst/pex/config/callStack.py +8 -8
  12. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst/pex/config/choiceField.py +5 -4
  13. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst/pex/config/comparison.py +17 -13
  14. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst/pex/config/config.py +211 -149
  15. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst/pex/config/configChoiceField.py +87 -63
  16. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst/pex/config/configDictField.py +100 -30
  17. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst/pex/config/configField.py +24 -23
  18. lsst_pex_config-29.2025.4500/python/lsst/pex/config/configurableActions/__init__.py +23 -0
  19. lsst_pex_config-29.2025.4500/python/lsst/pex/config/configurableActions/_configurableAction.py +69 -0
  20. lsst_pex_config-29.2025.4500/python/lsst/pex/config/configurableActions/_configurableActionField.py +122 -0
  21. lsst_pex_config-29.2025.4500/python/lsst/pex/config/configurableActions/_configurableActionStructField.py +478 -0
  22. lsst_pex_config-29.2025.4500/python/lsst/pex/config/configurableActions/tests.py +101 -0
  23. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst/pex/config/configurableField.py +81 -37
  24. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst/pex/config/convert.py +1 -1
  25. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst/pex/config/dictField.py +96 -65
  26. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst/pex/config/history.py +25 -24
  27. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst/pex/config/listField.py +65 -56
  28. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst/pex/config/rangeField.py +7 -7
  29. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst/pex/config/registry.py +83 -34
  30. lsst_pex_config-29.2025.4500/python/lsst/pex/config/version.py +2 -0
  31. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst/pex/config/wrap.py +22 -14
  32. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500/python/lsst_pex_config.egg-info}/PKG-INFO +13 -8
  33. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst_pex_config.egg-info/SOURCES.txt +26 -1
  34. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst_pex_config.egg-info/requires.txt +0 -2
  35. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/setup.cfg +1 -1
  36. lsst_pex_config-29.2025.4500/tests/testLib.py +37 -0
  37. lsst_pex_config-29.2025.4500/tests/test_Config.py +699 -0
  38. lsst_pex_config-29.2025.4500/tests/test__file__.py +55 -0
  39. lsst_pex_config-29.2025.4500/tests/test_configChoiceField.py +170 -0
  40. lsst_pex_config-29.2025.4500/tests/test_configDictField.py +212 -0
  41. lsst_pex_config-29.2025.4500/tests/test_configurableActions.py +275 -0
  42. lsst_pex_config-29.2025.4500/tests/test_configurableField.py +177 -0
  43. lsst_pex_config-29.2025.4500/tests/test_dictField.py +214 -0
  44. lsst_pex_config-29.2025.4500/tests/test_history.py +89 -0
  45. lsst_pex_config-29.2025.4500/tests/test_listField.py +193 -0
  46. lsst_pex_config-29.2025.4500/tests/test_registry.py +173 -0
  47. lsst_pex_config-29.2025.4500/tests/test_ticket1911.py +81 -0
  48. lsst_pex_config-29.2025.4500/tests/test_ticket1914.py +62 -0
  49. lsst_pex_config-29.2025.4500/tests/test_ticket1915.py +72 -0
  50. lsst_pex_config-29.2025.4500/tests/test_ticket1929.py +74 -0
  51. lsst_pex_config-29.2025.4500/tests/test_ticket1995.py +75 -0
  52. lsst_pex_config-29.2025.4500/tests/test_ticket2818.py +54 -0
  53. lsst_pex_config-29.2025.4500/tests/test_ticketDM-7337.py +55 -0
  54. lsst_pex_config-29.2025.4500/tests/test_unloaded_yaml.py +89 -0
  55. lsst_pex_config-29.2025.4500/tests/test_wrap.py +121 -0
  56. lsst-pex-config-26.0.0a20230400/COPYRIGHT +0 -3
  57. lsst-pex-config-26.0.0a20230400/doc/lsst.pex.config/CHANGES.rst +0 -72
  58. lsst-pex-config-26.0.0a20230400/pyproject.toml +0 -111
  59. lsst-pex-config-26.0.0a20230400/python/lsst/pex/config/version.py +0 -2
  60. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/LICENSE +0 -0
  61. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/MANIFEST.in +0 -0
  62. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/README.rst +0 -0
  63. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/bsd_license.txt +0 -0
  64. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/doc/lsst.pex.config/design-notes.rst +0 -0
  65. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/gpl-v3.0.txt +0 -0
  66. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst/__init__.py +0 -0
  67. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst/pex/__init__.py +0 -0
  68. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst/pex/config/__init__.py +0 -0
  69. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst/pex/config/_doNotImportMe.py +0 -0
  70. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst/pex/config/py.typed +0 -0
  71. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst_pex_config.egg-info/dependency_links.txt +0 -0
  72. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst_pex_config.egg-info/top_level.txt +0 -0
  73. {lsst-pex-config-26.0.0a20230400 → lsst_pex_config-29.2025.4500}/python/lsst_pex_config.egg-info/zip-safe +0 -0
@@ -0,0 +1,4 @@
1
+ Copyright 2008-2014, 2016, 2017, 2019, 2020, 2022-2023 Association of Universities for Research in Astronomy, Inc. (AURA)
2
+ Copyright 2014-2023 The Trustees of Princeton University
3
+ Copyright 2015-2016, 2018-2020, 2022-2023 University of Washington
4
+ Copyright 2015, 2018-2020 The Board of Trustees of the Leland Stanford Junior University, through SLAC National Accelerator Laboratory
@@ -1,26 +1,31 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: lsst-pex-config
3
- Version: 26.0.0a20230400
3
+ Version: 29.2025.4500
4
4
  Summary: A flexible configuration system using Python files.
5
5
  Author-email: Rubin Observatory Data Management <dm-admin@lists.lsst.org>
6
- License: BSD 3-Clause License, GPLv3+
6
+ License-Expression: BSD-3-Clause OR GPL-3.0-or-later
7
7
  Project-URL: Homepage, https://github.com/lsst/pex_config
8
8
  Keywords: lsst
9
9
  Classifier: Intended Audience :: Science/Research
10
- Classifier: License :: OSI Approved :: BSD License
11
- Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
12
10
  Classifier: Operating System :: OS Independent
13
11
  Classifier: Programming Language :: Python :: 3
14
- Classifier: Programming Language :: Python :: 3.8
15
- Classifier: Programming Language :: Python :: 3.9
16
12
  Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
17
16
  Classifier: Topic :: Scientific/Engineering :: Astronomy
17
+ Requires-Python: >=3.10.0
18
18
  Description-Content-Type: text/x-rst
19
- Provides-Extra: test
20
19
  License-File: COPYRIGHT
21
20
  License-File: LICENSE
22
21
  License-File: gpl-v3.0.txt
23
22
  License-File: bsd_license.txt
23
+ Requires-Dist: pyyaml>=5.1
24
+ Requires-Dist: numpy>=1.17
25
+ Provides-Extra: test
26
+ Requires-Dist: pytest>=3.2; extra == "test"
27
+ Requires-Dist: pytest-openfiles>=0.5.0; extra == "test"
28
+ Dynamic: license-file
24
29
 
25
30
  ##########
26
31
  pex_config
@@ -0,0 +1,125 @@
1
+ lsst-pex-config v29.0.0 (2025-03-25)
2
+ ====================================
3
+
4
+ New Features
5
+ ------------
6
+
7
+ - Introduced the ``keyCheck`` callback to ``DictField`` and ``ConfigDictField``, allowing custom key validation during assignment. Added unit tests to ensure functionality. (`DM-48074 <https://rubinobs.atlassian.net/browse/DM-48074>`_)
8
+ - Make the messages emitted by ``compareConfigs`` consistently start with the fully-qualified name of the config field. (`DM-49121 <https://rubinobs.atlassian.net/browse/DM-49121>`_)
9
+
10
+
11
+ lsst-pex-config v28.0.0 (2024-11-21)
12
+ ====================================
13
+
14
+ No significant changes.
15
+
16
+
17
+ lsst-pex-config v27.0.0 (2024-05-29)
18
+ ====================================
19
+
20
+ - Improved all docstrings to make them compliant with Numpydoc.
21
+ - Minor code cleanups driven by Ruff linting. (`DM-42116 <https://rubinobs.atlassian.net/browse/DM-42116>`_)
22
+
23
+ lsst-pex-config v26.0.0 (2023-09-22)
24
+ ====================================
25
+
26
+ New Features
27
+ ------------
28
+
29
+ - Added a dynamic-default callback argument to ``RegistryField``. (`DM-31924 <https://rubinobs.atlassian.net/browse/DM-31924>`_)
30
+ - Introduced ``ConfigurableActions``. These are ``pex_config`` fields and config types which function as a functor, state is set at config time, but the ``ConfigurableActions`` are callable at runtime to produce an action. (`DM-36649 <https://rubinobs.atlassian.net/browse/DM-36649>`_)
31
+
32
+
33
+ API Changes
34
+ -----------
35
+
36
+ - The ``loadFromStream`` and ``loadFromString`` methods now take a dictionary as an optional argument which allows specifying additional variables to use in local scope when reading configs. (`DM-40198 <https://rubinobs.atlassian.net/browse/DM-40198>`_)
37
+
38
+
39
+ Other Changes and Additions
40
+ ---------------------------
41
+
42
+ - There is now a requirement for configuration parameters to have a non-empty docstring. (`DM-4037 <https://rubinobs.atlassian.net/browse/DM-4037>`_)
43
+
44
+
45
+ lsst-pex-config v25.0.0 (2023-02-28)
46
+ ====================================
47
+
48
+ Other Changes and Additions
49
+ ---------------------------
50
+
51
+ - Some sorting now happens when saving config files (via DM-33027). (`DM-35060 <https://rubinobs.atlassian.net/browse/DM-35060>`_)
52
+
53
+
54
+ lsst-pex-config v24.0.0 (2022-08-30)
55
+ ====================================
56
+
57
+ New Features
58
+ ------------
59
+
60
+ * Add support for python typing of Fields. (DM-35312)
61
+ * ``loadFromStream`` now accepts a file-like object. (DM-32733)
62
+
63
+ Removals
64
+ --------
65
+
66
+ * The old ``root`` name in configuration files has been removed. (DM-32759)
67
+ * The Python2 iteration methods (``iterkeys``, etc) have been removed (DM-7148)
68
+
69
+ Other Changes
70
+ -------------
71
+
72
+ * Attempting to pickle a proxy object now fails with a useful error message. (DM-33963)
73
+
74
+ lsst-pex-config v23.0.0 (2021-12-21)
75
+ ====================================
76
+
77
+ Other Changes
78
+ -------------
79
+
80
+ * Internal data structures have been modified to aid Python reference counting. (DM-31507)
81
+
82
+ lsst-pex-config v22.0.0 (2021-07-09)
83
+ ====================================
84
+
85
+ Other Changes
86
+ -------------
87
+
88
+ * Fix some issues with history handling. (DM-27519)
89
+
90
+ lsst-pex-config v21.0.0 (2020-12-08)
91
+ ====================================
92
+
93
+ New Features
94
+ ------------
95
+
96
+ * Configuration objects can now be serialized to YAML. (DM-26008)
97
+
98
+ lsst-pex-config v20.0.0 (2020-06-24)
99
+ ====================================
100
+
101
+ New Features
102
+ ------------
103
+
104
+ * ``__file__`` can now be accessed within a config file.
105
+ This allow the config to acccess another config file relative to this one without having to use an environment variable or ``getPackageDir``. (DM-23359)
106
+
107
+ Bug Fixes
108
+ ---------
109
+
110
+ * Freezing a config no longer affects other instances of that config. (DM-24435)
111
+
112
+ Other Changes
113
+ -------------
114
+
115
+ * It is now possible to print a configuration without the associated imports. (DM-22301)
116
+
117
+ lsst-pex-config v19.0.0 (2019-12-05)
118
+ ====================================
119
+
120
+ New Features
121
+ ------------
122
+
123
+ * Now released under a dual GPLv3 and 3-clause BSD license.
124
+ * Add support for deprecating configuration fields. Such fields are not written out. (DM-20378)
125
+ * ``pex_policy`` and ``daf_base`` are now optional dependencies, and the dependency on the LSST ``utils`` package in testing has been removed. (DM-21064)
@@ -7,7 +7,7 @@ Types of configuration fields
7
7
  .. TODO: improve this page to summarize the purpose of each field, and then have a dedicated section for each field. https://jira.lsstcorp.org/browse/DM-17196
8
8
 
9
9
  Attributes of the configuration object must be subclasses of `Field`.
10
- A number of these are predefined: `Field`, `RangeField`, `ChoiceField`, `ListField`, `ConfigField`, `ConfigChoiceField`, `RegistryField` and `ConfigurableField`.
10
+ A number of these are predefined: `Field`, `RangeField`, `ChoiceField`, `ListField`, `ConfigField`, `ConfigChoiceField`, `RegistryField`, `ConfigurableField`, `~.configurableActions.ConfigurableActionField`, and `~.configurableActions.ConfigurableActionStructField`.
11
11
 
12
12
  Example of `RangeField`:
13
13
 
@@ -17,7 +17,7 @@ Example of `RangeField`:
17
17
  """Parameters for controlling background estimation.
18
18
  """
19
19
  binSize = pexConfig.RangeField(
20
- doc=("How large a region of the sky should be "
20
+ doc=("Define the region of the sky size "
21
21
  "used for each background point."),
22
22
  dtype=int, default=256, min=10
23
23
  )
@@ -31,7 +31,7 @@ Example of `ListField` and `Config` inheritance:
31
31
  """
32
32
  subregionSize = pexConfig.ListField(
33
33
  dtype=int,
34
- doc=("width, height of stack subregion size; make "
34
+ doc=("Width and height of stack subregion size. Make the values "
35
35
  "small enough that a full stack of images will "
36
36
  "fit into memory at once."),
37
37
  length=2,
@@ -44,7 +44,7 @@ Examples of `ChoiceField` and `ConfigField` and the use of the `Config` object's
44
44
  .. code-block:: python
45
45
 
46
46
  class InitialPsfConfig(pexConfig.Config):
47
- """A config that describes the initial PSF used
47
+ """A config that describes the initial PSF used
48
48
  for detection and measurement (before PSF
49
49
  determination is done).
50
50
  """
@@ -78,3 +78,43 @@ Examples of `ChoiceField` and `ConfigField` and the use of the `Config` object's
78
78
  if self.doComputeApCorr and not self.doPsf:
79
79
  raise ValueError("Cannot compute aperture correction "
80
80
  "without doing PSF determination.")
81
+
82
+ Examples of `~.configurableActions.ConfigurableActionField` and `~.configurableActions.ConfigurableActionStructField` making use of `~.configurableActions.ConfigurableAction`\ s in a `Config` object.
83
+
84
+ .. code-block:: python
85
+
86
+ class ExampleAction(pexConfig.configurableActions.ConfigurableAction):
87
+ """A ConfigurableAction that performs a simple calculation"""
88
+
89
+ numerator = pexConfig.Field[float](doc="Numerator for division operation")
90
+ divisor = pexConfig.Field[float](doc="Divisor for division operation")
91
+
92
+ def __call__(self, **kwargs):
93
+ return self.numerator / self.divisor
94
+
95
+
96
+ class ExampleConfig(pexConfig.Config):
97
+ """An example Config class which contains multiple `ConfigurableAction`\ s."""
98
+
99
+ divideAction = pexConfig.configurableActions.ConfigurableActionField(
100
+ doc="A field which points to a single action."
101
+ default=ExampleAction
102
+ )
103
+
104
+ multipleDivisionActions = pexConfig.configurableActions.ConfigurableActionStructField(
105
+ doc="A field which acts as a struct, referring to multiple ConfigurableActions."
106
+ )
107
+
108
+ def setDefaults(self):
109
+ """Example of setting multiple default configurations with `ConfigurableAction`\ s.
110
+ """
111
+ self.divideAction.numerator = 1
112
+ self.divideAction.divisor = 2
113
+
114
+ self.multipleDivisionActions.subDivide1 = ExampleAction()
115
+ self.multipleDivisionActions.subDivide1.numerator = 5
116
+ self.multipleDivisionActions.subDivide1.divisor = 10
117
+
118
+ self.multipleDivisionActions.subDivide2 = ExampleAction()
119
+ self.multipleDivisionActions.subDivide2.numerator = 7
120
+ self.multipleDivisionActions.subDivide2.divisor = 8
@@ -62,3 +62,7 @@ Python API reference
62
62
  .. automodapi:: lsst.pex.config.history
63
63
  :no-main-docstr:
64
64
  :no-inheritance-diagram:
65
+
66
+ .. automodapi:: lsst.pex.config.configurableActions
67
+ :no-main-docstr:
68
+ :no-inheritance-diagram:
@@ -8,7 +8,7 @@ Field access
8
8
  ------------
9
9
 
10
10
  Iterating through a `Config` instance yields the names of the `Field` attributes it contains.
11
- The `Config` class also supports many dictionary-like methods: `~Config.keys`, `~Config.items`, `~Config.iterkeys`, `~Config.iteritems`, and `~Config.itervalues`.
11
+ The `Config` class also supports many dictionary-like methods: `~Config.keys`, `~Config.items`, and `~Config.values`.
12
12
 
13
13
  History
14
14
  -------
@@ -38,7 +38,7 @@ Here is a config class that includes five fields:
38
38
  .. code-block:: python
39
39
 
40
40
  import lsst.pex.config as pexConfig
41
-
41
+
42
42
  class IsrTaskConfig(pexConfig.Config):
43
43
  doWrite = pexConfig.Field(
44
44
  doc="Write output?",
@@ -49,7 +49,7 @@ Here is a config class that includes five fields:
49
49
  dtype=float,
50
50
  default=1.0)
51
51
  saturatedMaskName = pexConfig.Field(
52
- doc="Name of mask plane to use in saturation detection",
52
+ doc="Name of the mask plane to use in saturation detection.",
53
53
  dtype=str,
54
54
  default="SAT")
55
55
  flatScalingType = pexConfig.ChoiceField(
@@ -62,7 +62,7 @@ Here is a config class that includes five fields:
62
62
  "MEDIAN": "Scale by the inverse of the median",
63
63
  })
64
64
  keysToRemoveFromAssembledCcd = pexConfig.ListField(
65
- doc="fields to remove from the metadata of the assembled ccd.",
65
+ doc="Fields to remove from the metadata of the assembled ccd.",
66
66
  dtype=str,
67
67
  default=[])
68
68
 
@@ -167,3 +167,15 @@ Alternatively, if you wish to locate another configuration file using LSST infra
167
167
  from lsst.utils import getPackageDir
168
168
 
169
169
  config.load(os.path.join(getPackageDir("product_x"), "config", "otherconfig.py"))
170
+
171
+ Specialized Config subclasses
172
+ =============================
173
+
174
+ There exists a subclass of `Config` which is designed to be configurable like a standard config, but have a runtime call interface.
175
+ These specialized subclasses are named `~.configurableActions.ConfigurableAction`\ s, or actions for short.
176
+ These actions are not intended to replace other runtime components, but compliment them.
177
+ They provide configuration time mechanics to a simple runtime function.
178
+ This interface allows for both configuration of an action as well as making which action to run configurable.
179
+ These configurations are serialized out in a standard way, and thus allow complete functional states to be completely restored.
180
+ The selection (thus configuration) of which `~.configurableActions.ConfigurableAction`\ s to run is made possible through the use of special `Field`\ s named `~.configurableActions.ConfigurableActionField` and `~.configurableActions.ConfigurableActionStructField`.
181
+ See :doc:`field-types` for more details and examples of both `~.configurableActions.ConfigurableAction`\ s and the corresponding fields.
@@ -6,21 +6,21 @@ Registry and RegistryField for configuring subtasks
6
6
 
7
7
  Example of a `RegistryField` created from a `Registry` object and use of both the `Registry.register` method and the `registerConfigurable` decorator::
8
8
 
9
- psfDeterminerRegistry = pexConfig.makeRegistry("""A registry of PSF determiner factories""")
9
+ psfDeterminerRegistry = pexConfig.makeRegistry("""A registry of PSF determiner factories.""")
10
10
 
11
11
  class PcaPsfDeterminerConfig(pexConfig.Config):
12
12
  spatialOrder = pexConfig.Field(
13
- "spatial order for PSF kernel creation", int, 2)
13
+ "Spatial order for PSF kernel creation.", int, 2)
14
14
  [...]
15
15
 
16
16
  @pexConfig.registerConfigurable("pca", psfDeterminerRegistry)
17
17
  class PcaPsfDeterminer(object):
18
18
  ConfigClass = PcaPsfDeterminerConfig
19
- # associate this Configurable class with its Config class for use
20
- # by the registry
21
- def __init__(self, config, schema=None):
19
+ # Associate this Configurable class with its Config class for use
20
+ # by the registry.
21
+ def __init__(self, config, schema=None, **kwargs):
22
22
  [...]
23
- def determinePsf(self, exposure, psfCandidateList, metadata=None):
23
+ def determinePsf(self, exposure, psfCandidateList, metadata=None, **kwargs):
24
24
  [...]
25
25
 
26
26
  psfDeterminerRegistry.register("shapelet", ShapeletPsfDeterminer)
@@ -4,7 +4,7 @@
4
4
  Wrapping C++ control objects
5
5
  ############################
6
6
 
7
- C++ control objects defined using the ``LSST_CONTROL_FIELD`` macro in `lsst/pex/config.h` can be wrapped using pybind11 and the functions in `lsst.pex.config.wrap`, creating an equivalent Python `Config` object.
7
+ C++ control objects defined using the ``LSST_CONTROL_FIELD`` macro in ``lsst/pex/config.h`` can be wrapped using pybind11 and the functions in `lsst.pex.config.wrap`, creating an equivalent Python `Config` object.
8
8
  The `Config` will automatically create and set values in the C++ object, will provide access to the doc strings from C++, and will even call the C++ class's ``validate`` method, if one exists.
9
9
  This helps to minimize duplication of code.
10
10
 
@@ -15,7 +15,7 @@ For example, here is a C++ control object:
15
15
  struct FooControl {
16
16
  LSST_CONTROL_FIELD(bar, int, "documentation for field 'bar'");
17
17
  LSST_CONTROL_FIELD(baz, double, "documentation for field 'baz'");
18
-
18
+
19
19
  FooControl() : bar(0), baz(0.0) {}
20
20
  };
21
21
 
@@ -0,0 +1,196 @@
1
+ [build-system]
2
+ requires = ["setuptools", "lsst-versions >= 1.3.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "lsst-pex-config"
7
+ requires-python = ">=3.10.0"
8
+ description = "A flexible configuration system using Python files."
9
+ license = "BSD-3-Clause OR GPL-3.0-or-later"
10
+ license-files = ["COPYRIGHT", "LICENSE", "gpl-v3.0.txt", "bsd_license.txt"]
11
+ readme = "README.rst"
12
+ authors = [
13
+ {name="Rubin Observatory Data Management", email="dm-admin@lists.lsst.org"},
14
+ ]
15
+ classifiers = [
16
+ "Intended Audience :: Science/Research",
17
+ "Operating System :: OS Independent",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Topic :: Scientific/Engineering :: Astronomy",
24
+ ]
25
+ keywords = ["lsst"]
26
+ dependencies = [
27
+ "pyyaml >=5.1",
28
+ "numpy >= 1.17",
29
+ ]
30
+ dynamic = ["version"]
31
+
32
+ [project.urls]
33
+ "Homepage" = "https://github.com/lsst/pex_config"
34
+
35
+ [project.optional-dependencies]
36
+ test = [
37
+ "pytest >= 3.2",
38
+ "pytest-openfiles >= 0.5.0",
39
+ ]
40
+
41
+ [tool.setuptools.packages.find]
42
+ where = ["python"]
43
+
44
+ [tool.setuptools]
45
+ zip-safe = true
46
+
47
+ [tool.setuptools.package-data]
48
+ "lsst.pex.config" = ["py.typed"]
49
+
50
+ [tool.setuptools.dynamic]
51
+ version = { attr = "lsst_versions.get_lsst_version" }
52
+
53
+ [tool.black]
54
+ line-length = 110
55
+ target-version = ["py310"]
56
+
57
+ [tool.isort]
58
+ profile = "black"
59
+ line_length = 110
60
+ known_first_party = ["lsst"]
61
+
62
+ [tool.towncrier]
63
+ package = "lsst.pex.config"
64
+ package_dir = "python"
65
+ filename = "doc/lsst.pex.config/CHANGES.rst"
66
+ directory = "doc/changes"
67
+ title_format = "lsst-pex-config {version} ({project_date})"
68
+ issue_format = "`{issue} <https://rubinobs.atlassian.net/browse/{issue}>`_"
69
+
70
+ [[tool.towncrier.type]]
71
+ directory = "feature"
72
+ name = "New Features"
73
+ showcontent = true
74
+
75
+ [[tool.towncrier.type]]
76
+ directory = "api"
77
+ name = "API Changes"
78
+ showcontent = true
79
+
80
+ [[tool.towncrier.type]]
81
+ directory = "bugfix"
82
+ name = "Bug Fixes"
83
+ showcontent = true
84
+
85
+ [[tool.towncrier.type]]
86
+ directory = "perf"
87
+ name = "Performance Enhancement"
88
+ showcontent = true
89
+
90
+ [[tool.towncrier.type]]
91
+ directory = "misc"
92
+ name = "Other Changes and Additions"
93
+ showcontent = true
94
+
95
+ [[tool.towncrier.type]]
96
+ directory = "removal"
97
+ name = "An API Removal or Deprecation"
98
+ showcontent = true
99
+
100
+ [[tool.towncrier.type]]
101
+ directory = "doc"
102
+ name = "Documentation Enhancement"
103
+ showcontent = true
104
+
105
+ [tool.lsst_versions]
106
+ write_to = "python/lsst/pex/config/version.py"
107
+
108
+ [tool.pytest.ini_options]
109
+
110
+ [tool.pydocstyle]
111
+ convention = "numpy"
112
+ # Our coding style does not require docstrings for magic methods (D105)
113
+ # Our docstyle documents __init__ at the class level (D107)
114
+ # We allow methods to inherit docstrings and this is not compatible with D102.
115
+ # Docstring at the very first line is not required
116
+ # D200, D205 and D400 all complain if the first sentence of the docstring does
117
+ # not fit on one line.
118
+ add-ignore = ["D107", "D105", "D102", "D100", "D200", "D205", "D400", "D104"]
119
+
120
+ [tool.ruff]
121
+ line-length = 110
122
+ target-version = "py310"
123
+ exclude = [
124
+ "__init__.py",
125
+ "tests/config/*.py",
126
+ ]
127
+
128
+ [tool.ruff.lint]
129
+ ignore = [
130
+ "N802",
131
+ "N803",
132
+ "N806",
133
+ "N812",
134
+ "N815",
135
+ "N816",
136
+ "N999",
137
+ "D107",
138
+ "D105",
139
+ "D102",
140
+ "D104",
141
+ "D100",
142
+ "D200",
143
+ "D205",
144
+ ]
145
+ select = [
146
+ "E", # pycodestyle
147
+ "F", # pyflakes
148
+ "N", # pep8-naming
149
+ "W", # pycodestyle
150
+ "D", # pydocstyle
151
+ "UP", # pyupgrade
152
+ "I", # isort
153
+ "RUF022", # sort __all__
154
+ "C4", # comprehensions
155
+ "B", # bugbear
156
+ ]
157
+ extend-select = [
158
+ "RUF100", # Warn about unused noqa
159
+ ]
160
+
161
+ [tool.ruff.lint.per-file-ignores]
162
+ "tests/testLib.py" = ["F403", "F405"] # Wildcard imports.
163
+
164
+ [tool.ruff.lint.isort]
165
+ known-first-party = ["lsst"]
166
+
167
+ [tool.ruff.lint.pycodestyle]
168
+ max-doc-length = 79
169
+
170
+ [tool.ruff.lint.pydocstyle]
171
+ convention = "numpy"
172
+
173
+ [tool.ruff.format]
174
+ docstring-code-format = true
175
+ # Formatter does not know about indenting.
176
+ docstring-code-line-length = 69
177
+
178
+ [tool.numpydoc_validation]
179
+ checks = [
180
+ "all", # All except the rules listed below.
181
+ "SA01", # See Also section.
182
+ "EX01", # Example section.
183
+ "SS06", # Summary can go into second line.
184
+ "GL01", # Summary text can start on same line as """
185
+ "GL08", # Do not require docstring.
186
+ "ES01", # No extended summary required.
187
+ "RT01", # Unfortunately our @property trigger this.
188
+ "RT02", # Does not want named return value. DM style says we do.
189
+ "SS05", # pydocstyle is better at finding infinitive verb.
190
+ "SA04", # Do not require descriptions on all See Also entries.
191
+ ]
192
+ exclude = [
193
+ '^__init__$',
194
+ '\._[a-zA-Z_]+$', # Private methods.
195
+ "^test_.*", # Do not test docstrings in test code.
196
+ ]
@@ -25,7 +25,7 @@
25
25
  # You should have received a copy of the GNU General Public License
26
26
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
27
27
 
28
- __all__ = ["getCallerFrame", "getStackFrame", "StackFrame", "getCallStack"]
28
+ __all__ = ["StackFrame", "getCallStack", "getCallerFrame", "getStackFrame"]
29
29
 
30
30
  import inspect
31
31
  import linecache
@@ -42,7 +42,7 @@ def getCallerFrame(relative=0):
42
42
 
43
43
  Returns
44
44
  -------
45
- frame : `__builtin__.Frame`
45
+ frame : `types.FrameType`
46
46
  Frame for the caller.
47
47
 
48
48
  Notes
@@ -50,7 +50,7 @@ def getCallerFrame(relative=0):
50
50
  This function is excluded from the frame.
51
51
  """
52
52
  frame = inspect.currentframe().f_back.f_back # Our caller's caller
53
- for ii in range(relative):
53
+ for _ in range(relative):
54
54
  frame = frame.f_back
55
55
  return frame
56
56
 
@@ -97,7 +97,7 @@ class StackFrame:
97
97
  stack trace by the fact that it does not look up the source code until it
98
98
  is absolutely necessary, reducing the I/O.
99
99
 
100
- See also
100
+ See Also
101
101
  --------
102
102
  getStackFrame
103
103
  """
@@ -127,7 +127,7 @@ class StackFrame:
127
127
 
128
128
  Parameters
129
129
  ----------
130
- frame : `Frame`
130
+ frame : `types.FrameType`
131
131
  Frame object to interpret, such as from `inspect.currentframe`.
132
132
 
133
133
  Returns
@@ -149,7 +149,7 @@ class StackFrame:
149
149
  return cls(filename, lineno, function)
150
150
 
151
151
  def __repr__(self):
152
- return "%s(%s, %s, %s)" % (self.__class__.__name__, self.filename, self.lineno, self.function)
152
+ return f"{self.__class__.__name__}({self.filename}, {self.lineno}, {self.function})"
153
153
 
154
154
  def format(self, full=False):
155
155
  """Format for printing.
@@ -165,9 +165,9 @@ class StackFrame:
165
165
  result : `str`
166
166
  Formatted string.
167
167
  """
168
- result = " File %s:%s (%s)" % (self.filename, self.lineno, self.function)
168
+ result = f" File {self.filename}:{self.lineno} ({self.function})"
169
169
  if full:
170
- result += "\n %s" % (self.content,)
170
+ result += f"\n {self.content}"
171
171
  return result
172
172
 
173
173
 
@@ -56,7 +56,7 @@ class ChoiceField(Field[FieldTypeVar]):
56
56
  A description of why this Field is deprecated, including removal date.
57
57
  If not None, the string is appended to the docstring for this Field.
58
58
 
59
- See also
59
+ See Also
60
60
  --------
61
61
  ConfigChoiceField
62
62
  ConfigDictField
@@ -89,10 +89,11 @@ class ChoiceField(Field[FieldTypeVar]):
89
89
  for choice, choiceDoc in self.allowed.items():
90
90
  if choice is not None and not isinstance(choice, dtype):
91
91
  raise ValueError(
92
- "ChoiceField's allowed choice %s is of incorrect type %s. Expected %s"
93
- % (choice, _typeStr(choice), _typeStr(dtype))
92
+ f"ChoiceField's allowed choice {choice} is of incorrect type "
93
+ f"{_typeStr(choice)}. Expected {_typeStr(dtype)}"
94
94
  )
95
- self.__doc__ += "%s\n %s\n" % ("``{0!r}``".format(str(choice)), choiceDoc)
95
+ # Force to a string so that additional quotes are added with !r
96
+ self.__doc__ += f"``{str(choice)!r}``\n {choiceDoc}\n"
96
97
 
97
98
  self.source = getStackFrame()
98
99