diff --git a/osc/conf.py b/osc/conf.py index 49d30d28..07dfc0b9 100644 --- a/osc/conf.py +++ b/osc/conf.py @@ -1324,6 +1324,10 @@ def _model_to_rst(cls, title=None, description=None, sections=None, output_file= if field.default is None: return None + if field.default_is_lazy: + # lazy default may return different results under different circumstances -> return nothing + return None + ini_type = field.extra.get("ini_type", None) if ini_type: return None diff --git a/osc/util/models.py b/osc/util/models.py index 633479b1..f0926000 100644 --- a/osc/util/models.py +++ b/osc/util/models.py @@ -79,6 +79,9 @@ class Field(property): # model sets it to None if it equals to NotSet (for better usability) self.default = default + # a flag indicating, whether the default is a callable with lazy evalution + self.default_is_lazy = callable(self.default) + # whether the field was set self.is_set = False diff --git a/tests/test_models.py b/tests/test_models.py index 082b4fae..e3d6895e 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -60,6 +60,19 @@ class Test(unittest.TestCase): self.assertRaises(TypeError, TestModel) + def test_lazy_default(self): + class TestModel(BaseModel): + field: List[str] = Field(default=lambda: ["string"]) + + m = TestModel() + self.assertEqual(m.field, ["string"]) + + def test_lazy_default_invalid_type(self): + class TestModel(BaseModel): + field: List[str] = Field(default=lambda: None) + + self.assertRaises(TypeError, TestModel) + def test_is_set(self): class TestModel(BaseModel): field: Optional[str] = Field()