Skip to content
This repository was archived by the owner on Aug 25, 2024. It is now read-only.

Commit 2c606bf

Browse files
committed
base: Add make_config
Signed-off-by: John Andersen <[email protected]>
1 parent 33eb5f8 commit 2c606bf

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3030
`contextlib` exit stacks. Provides temporary file creation.
3131
- Automatic releases to PyPi via GitHub Actions
3232
- Automatic documentation deployment to GitHub Pages
33+
- Function to create a config class dynamically, analogous to `make_dataclass`
3334
### Changed
3435
- CLI tests and integration tests derive from `AsyncExitStackTestCase`
3536
### Fixed

dffml/base.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,9 +216,51 @@ def config(cls):
216216
datacls._replace = lambda self, *args, **kwargs: dataclasses.replace(
217217
self, *args, **kwargs
218218
)
219+
datacls._asdict = lambda self, *args, **kwargs: dataclasses.asdict(
220+
self, *args, **kwargs
221+
)
219222
return datacls
220223

221224

225+
def make_config(cls_name: str, fields, *args, namespace=None, **kwargs):
226+
"""
227+
Function to create a dataclass
228+
"""
229+
if namespace is None:
230+
namespace = {}
231+
namespace.setdefault("_fromdict", classmethod(_fromdict))
232+
namespace.setdefault(
233+
"_replace",
234+
lambda self, *args, **kwargs: dataclasses.replace(
235+
self, *args, **kwargs
236+
),
237+
)
238+
namespace.setdefault(
239+
"_asdict",
240+
lambda self, *args, **kwargs: dataclasses.asdict(
241+
self, *args, **kwargs
242+
),
243+
)
244+
kwargs["eq"] = True
245+
kwargs["init"] = True
246+
# Ensure non-default arguments always come before default arguments
247+
fields_non_default = []
248+
fields_default = []
249+
for name, cls, field in fields:
250+
if (
251+
field.default is not dataclasses.MISSING
252+
or field.default_factory is not dataclasses.MISSING
253+
):
254+
fields_default.append((name, cls, field))
255+
else:
256+
fields_non_default.append((name, cls, field))
257+
fields = fields_non_default + fields_default
258+
# Create dataclass
259+
return dataclasses.make_dataclass(
260+
cls_name, fields, *args, namespace=namespace, **kwargs
261+
)
262+
263+
222264
class ConfigurableParsingNamespace(object):
223265
def __init__(self):
224266
self.dest = None

0 commit comments

Comments
 (0)