Skip to content

Clarify contents of ConfigDict().__call__().user_values() #3721

@shermanjasonaf

Description

@shermanjasonaf

Summary

According to the Pyomo 6.9.3 documentation of the Pyomo configuration system, the ConfigDict instance method user_values() can be used to iterate over the entries of a ConfigDict instance that have been explicitly set by the user. However, if a ConfigDict instance is obtained using the __call__ method of another ConfigDict instance, then the first iterate of the user_values() method of the new ConfigDict instance may unexpectedly be the new ConfigDict instance itself. This occurs when the argument value to ConfigDict.__call__() is set to a nonempty dict.

Steps to reproduce the issue

Set up a simple ConfigDict:

>>> config = ConfigDict()
>>> config.declare(
...     "filename",
...     ConfigValue(
...         default=None,
...         domain=str,
...         description="Input file name",
...     ),
... )

Obtain a ConfigDict by invoking the __call__ method with a valid nonempty dict:

>>> cfg = config(value={"filename": "example.txt"})

Check user values for the new ConfigDict:

>>> print("User values:")
>>> for val in cfg.user_values():
...     print(f" name={val.name()!r}, value={val.value()!r}, is cfg={val is cfg}")
User values:
 name='', value={'filename': 'example.txt'}, is cfg=True
 name='filename', value='example.txt', is cfg=False

Notice that the first iterate of cfg.user_values() is cfg itself. Our expectation was that the only iterate of cfg.user_values() would be the ConfigValue object associated with the entry called "filename".

However, if a ConfigDict is obtained using config.__call__() with default arguments or with value set to an empty dict, then the user_values() method of the new ConfigDict does not contain the new ConfigDict itself (regardless of whether entries of the ConfigDict are subsequently set by the user):

>>> cfg2 = config({})
>>> cfg2["filename"] = "example.txt"
>>> print("User values:")
>>> for val in cfg2.user_values():
...     print(f" name={val.name()!r}, value={val.value()!r}, is cfg2={val is cfg2}")
User values:
 name='filename', value='example.txt', is cfg2=False

Information on your system

Pyomo version: 6.9.5dev0 (main @ 613f2ad)
Python version: 3.12.7
Operating system: Ubuntu 20.04
How Pyomo was installed (PyPI, conda, source): source

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions