1
0
mirror of https://github.com/openSUSE/osc.git synced 2025-01-05 22:36:15 +01:00

Implement get_callback that allows modifying returned value to the Field class

This commit is contained in:
Daniel Mach 2024-01-24 09:49:23 +01:00
parent a8c7661627
commit 8a38a9da82
2 changed files with 39 additions and 2 deletions

View File

@ -10,6 +10,7 @@ import copy
import inspect import inspect
import sys import sys
import types import types
from typing import Callable
from typing import get_type_hints from typing import get_type_hints
# supported types # supported types
@ -76,6 +77,7 @@ class Field(property):
default: Any = NotSet, default: Any = NotSet,
description: Optional[str] = None, description: Optional[str] = None,
exclude: bool = False, exclude: bool = False,
get_callback: Optional[Callable] = None,
**extra, **extra,
): ):
# the default value; it can be a factory function that is lazily evaluated on the first use # the default value; it can be a factory function that is lazily evaluated on the first use
@ -106,6 +108,10 @@ class Field(property):
# whether to exclude this field from export # whether to exclude this field from export
self.exclude = exclude self.exclude = exclude
# optional callback to postprocess returned field value
# it takes (model_instance, value) and returns modified value
self.get_callback = get_callback
# extra fields # extra fields
self.extra = extra self.extra = extra
@ -235,12 +241,18 @@ class Field(property):
def get(self, obj): def get(self, obj):
try: try:
return obj._values[self.name] result = obj._values[self.name]
if self.get_callback is not None:
result = self.get_callback(obj, result)
return result
except KeyError: except KeyError:
pass pass
try: try:
return obj._defaults[self.name] result = obj._defaults[self.name]
if self.get_callback is not None:
result = self.get_callback(obj, result)
return result
except KeyError: except KeyError:
pass pass

View File

@ -291,6 +291,31 @@ class Test(unittest.TestCase):
self.assertEqual(c.field, "new-text") self.assertEqual(c.field, "new-text")
self.assertEqual(c.field2, "text") self.assertEqual(c.field2, "text")
def test_get_callback(self):
class Model(BaseModel):
quiet: bool = Field(
default=False,
)
verbose: bool = Field(
default=False,
# return False if ``quiet`` is True; return the actual value otherwise
get_callback=lambda obj, value: False if obj.quiet else value,
)
m = Model()
self.assertEqual(m.quiet, False)
self.assertEqual(m.verbose, False)
m.quiet = True
m.verbose = True
self.assertEqual(m.quiet, True)
self.assertEqual(m.verbose, False)
m.quiet = False
m.verbose = True
self.assertEqual(m.quiet, False)
self.assertEqual(m.verbose, True)
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()