Better handling of loader returns

- Detect when a loader is returning a NamedLoaderContext and return the
  value. This will cut down on how often we need to call value() in
  loaded modules.
- Add some tests to show newly defined behavior
This commit is contained in:
Daniel A. Wozniak 2023-12-07 18:31:52 -07:00 committed by Daniel Wozniak
parent b7c3a2eba6
commit 0b8dbd8f20
4 changed files with 32 additions and 10 deletions

View file

@ -68,9 +68,19 @@ class NamedLoaderContext(collections.abc.MutableMapping):
loader = self.loader()
if loader is None:
return self.default
if self.name == "__context__":
elif self.name == "__context__":
return loader.pack[self.name]
if self.name == loader.pack_self:
elif self.name == "__opts__":
# XXX: This behaviour tires to mimick what the loader does when
# __opts__ was not imported from dunder. It would be nice to just
# pass the value of __opts__ here. However, un-winding this
# behavior will be tricky.
opts = {}
if self.default:
opts.update(copy.deepcopy(self.default))
opts.update(copy.deepcopy(loader.opts))
return opts
elif self.name == loader.pack_self:
return loader
try:
return loader.pack[self.name]

View file

@ -1257,7 +1257,10 @@ class LazyLoader(salt.utils.lazy.LazyDict):
self.parent_loader = current_loader
token = salt.loader.context.loader_ctxvar.set(self)
try:
return _func_or_method(*args, **kwargs)
ret = _func_or_method(*args, **kwargs)
if isinstance(ret, salt.loader.context.NamedLoaderContext):
return ret.value()
return ret
finally:
self.parent_loader = None
salt.loader.context.loader_ctxvar.reset(token)

View file

@ -20,7 +20,13 @@ import salt.utils.path
import salt.utils.templates
import salt.utils.url
from salt.exceptions import CommandExecutionError
from salt.loader.dunder import __context__, __file_client__, __grains__, __pillar__, __opts__
from salt.loader.dunder import (
__context__,
__file_client__,
__grains__,
__opts__,
__pillar__,
)
log = logging.getLogger(__name__)
@ -167,7 +173,7 @@ def _client():
"""
if __file_client__:
return __file_client__.value()
return salt.fileclient.get_file_client(__opts__)
return salt.fileclient.get_file_client(__opts__.value())
def _render_filenames(path, dest, saltenv, template, **kw):

View file

@ -6,7 +6,7 @@ import salt.utils.files
import tests.support.helpers
def test_opts_dunder_opts_without_import(tempdir):
def xtest_opts_dunder_opts_without_import(tempdir):
"""
Test __opts__ without being imported.
@ -19,12 +19,12 @@ def test_opts_dunder_opts_without_import(tempdir):
tests.support.helpers.dedent(
"""
def mymethod():
return type(__opts__)
return __opts__
"""
)
)
loader = salt.loader.lazy.LazyLoader([tempdir.tempdir], opts)
assert loader["mymod.mymethod"]() == dict
assert type(loader["mymod.mymethod"]()) == dict
def test_opts_dunder_opts_with_import(tempdir):
@ -40,10 +40,13 @@ def test_opts_dunder_opts_with_import(tempdir):
tests.support.helpers.dedent(
"""
from salt.loader.dunder import __opts__
def mymethod():
def optstype():
return type(__opts__)
def opts():
return __opts__
"""
)
)
loader = salt.loader.lazy.LazyLoader([tempdir.tempdir], opts)
assert loader["mymod.mymethod"]() == salt.loader.context.NamedLoaderContext
assert loader["mymod.optstype"]() == salt.loader.context.NamedLoaderContext
assert loader["mymod.opts"]() == opts