Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions pyomo/common/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -1600,7 +1600,13 @@ def __call__(

# ... and set the value, if appropriate
if value is not NOTSET:
ans.set_value(value)
# Change in response to Pyomo/pyomo#3721
# If setting a ConfigDict from a (nonempty) dict during __call__,
# do not mark the container itself as user-set; only the children.
if isinstance(ans, ConfigDict) and isinstance(value, dict):
ans.set_value(value, _mark_container_userSet=False)
else:
ans.set_value(value)
return ans

def name(self, fully_qualified=False):
Expand Down Expand Up @@ -2580,7 +2586,7 @@ def value(self, accessValue=True):
self._userAccessed = True
return {cfg._name: cfg.value(accessValue) for cfg in self._data.values()}

def set_value(self, value, skip_implicit=False):
def set_value(self, value, skip_implicit=False, _mark_container_userSet=True):
if value is None:
return self
if isinstance(value, str):
Expand Down Expand Up @@ -2631,7 +2637,9 @@ def set_value(self, value, skip_implicit=False):
self.reset()
self.set_value(_old_data)
raise
self._userSet = True
# Change in response to Pyomo/pyomo#3721
if _mark_container_userSet:
self._userSet = True
return self

def reset(self):
Expand Down
18 changes: 18 additions & 0 deletions pyomo/common/tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -1599,6 +1599,24 @@ def test_UserValues_declare_subBlock(self):
test = '\n'.join(x.name(True) for x in self.config.user_values())
self.assertEqual(test, "")

def test_userValues_call_nonempty(self):
# See bug report in Pyomo/pyomo#3721
default = ConfigDict()
default.declare("filename", ConfigValue(default=None, domain=str))
cfg = default(value={"filename": "example.txt"})
names = [x.name(True) for x in cfg.user_values()]
self.assertEqual(names, ["filename"])
self.assertTrue(all(x is not cfg for x in cfg.user_values()))

def test_userValues_call_empty_then_set(self):
# See bug report in Pyomo/pyomo#3721
default = ConfigDict()
default.declare("filename", ConfigValue(default=None, domain=str))
cfg = default({})
cfg["filename"] = "example.txt"
names = [x.name(True) for x in cfg.user_values()]
self.assertEqual(names, ["filename"])

@unittest.skipIf(not yaml_available, "Test requires PyYAML")
def test_parseDisplayAndValue_default(self):
test = _display(self.config)
Expand Down
Loading