mirror of
https://github.com/pytorch/pytorch.git
synced 2025-10-20 21:14:14 +08:00
torch/config: fix mock behaviour (#140779)
Mock only replaces the value that was removed, if after deletion, it does not see the attribute. Pull Request resolved: https://github.com/pytorch/pytorch/pull/140779 Approved by: https://github.com/ezyang
This commit is contained in:
committed by
PyTorch MergeBot
parent
878a849c92
commit
241d2259d3
@ -213,6 +213,18 @@ class _ConfigEntry:
|
||||
# environment variables are read at install time
|
||||
env_value_force: Any = _UNSET_SENTINEL
|
||||
env_value_default: Any = _UNSET_SENTINEL
|
||||
# Used to work arounds bad assumptions in unittest.mock.patch
|
||||
# The code to blame is
|
||||
# https://github.com/python/cpython/blob/94a7a4e22fb8f567090514785c69e65298acca42/Lib/unittest/mock.py#L1637
|
||||
# Essentially, mock.patch requires, that if __dict__ isn't accessible
|
||||
# (which it isn't), that after delattr is called on the object, the
|
||||
# object must throw when hasattr is called. Otherwise, it doesn't call
|
||||
# setattr again.
|
||||
# Technically we'll have an intermediate state of hiding the config while
|
||||
# mock.patch is unpatching itself, but it calls setattr after the delete
|
||||
# call so the final state is correct. It's just very unintuitive.
|
||||
# upstream bug - python/cpython#126886
|
||||
hide: bool = False
|
||||
|
||||
def __init__(self, config: Config):
|
||||
self.default = config.default
|
||||
@ -253,11 +265,15 @@ class ConfigModule(ModuleType):
|
||||
else:
|
||||
self._config[name].user_override = value
|
||||
self._is_dirty = True
|
||||
self._config[name].hide = False
|
||||
|
||||
def __getattr__(self, name: str) -> Any:
|
||||
try:
|
||||
config = self._config[name]
|
||||
|
||||
if config.hide:
|
||||
raise AttributeError(f"{self.__name__}.{name} does not exist")
|
||||
|
||||
if config.env_value_force is not _UNSET_SENTINEL:
|
||||
return config.env_value_force
|
||||
|
||||
@ -288,6 +304,7 @@ class ConfigModule(ModuleType):
|
||||
# must support delete because unittest.mock.patch deletes
|
||||
# then recreate things
|
||||
self._config[name].user_override = _UNSET_SENTINEL
|
||||
self._config[name].hide = True
|
||||
|
||||
def _is_default(self, name: str) -> bool:
|
||||
return self._config[name].user_override is _UNSET_SENTINEL
|
||||
|
Reference in New Issue
Block a user