mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Refactor/cleanup root detection (#4102)
## What type of PR is this? (check all applicable) - [ X] Refactor - [ ] Feature - [ ] Bug Fix - [ ] Optimization - [ ] Documentation Update - [ ] Community Node Submission ## Have you discussed this change with the InvokeAI team? - [ ] Yes - [ X] No, because: invisible change ## Have you updated all relevant documentation? - [ X] Yes - [ ] No ## Description There was a problem in 3.0.1 with root resolution. If INVOKEAI_ROOT were set to "." (or any relative path), then the location of root would change if the code did an os.chdir() after config initialization. I fixed this in a quick and dirty way for 3.0.1.post3. This PR cleans up the code with a little refactoring. ## Related Tickets & Documents <!-- For pull requests that relate or close an issue, please include them below. For example having the text: "closes #1234" would connect the current pull request to issue 1234. And when we merge the pull request, Github will automatically close the issue. --> - Related Issue # - Closes # ## QA Instructions, Screenshots, Recordings <!-- Please provide steps on how to test changes, any hardware or software specifications as well as any other pertinent information. --> ## Added/updated tests? - [ ] Yes - [ ] No : _please replace this line with details on why tests have not been included_ ## [optional] Are there any post deployment tasks we need to perform?
This commit is contained in:
commit
818c55cd53
@ -274,7 +274,7 @@ class InvokeAISettings(BaseSettings):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def _excluded(self) -> List[str]:
|
def _excluded(self) -> List[str]:
|
||||||
# internal fields that shouldn't be exposed as command line options
|
# internal fields that shouldn't be exposed as command line options
|
||||||
return ["type", "initconf", "cached_root"]
|
return ["type", "initconf"]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _excluded_from_yaml(self) -> List[str]:
|
def _excluded_from_yaml(self) -> List[str]:
|
||||||
@ -290,7 +290,6 @@ class InvokeAISettings(BaseSettings):
|
|||||||
"restore",
|
"restore",
|
||||||
"root",
|
"root",
|
||||||
"nsfw_checker",
|
"nsfw_checker",
|
||||||
"cached_root",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
@ -356,7 +355,7 @@ class InvokeAISettings(BaseSettings):
|
|||||||
def _find_root() -> Path:
|
def _find_root() -> Path:
|
||||||
venv = Path(os.environ.get("VIRTUAL_ENV") or ".")
|
venv = Path(os.environ.get("VIRTUAL_ENV") or ".")
|
||||||
if os.environ.get("INVOKEAI_ROOT"):
|
if os.environ.get("INVOKEAI_ROOT"):
|
||||||
root = Path(os.environ.get("INVOKEAI_ROOT")).resolve()
|
root = Path(os.environ["INVOKEAI_ROOT"])
|
||||||
elif any([(venv.parent / x).exists() for x in [INIT_FILE, LEGACY_INIT_FILE]]):
|
elif any([(venv.parent / x).exists() for x in [INIT_FILE, LEGACY_INIT_FILE]]):
|
||||||
root = (venv.parent).resolve()
|
root = (venv.parent).resolve()
|
||||||
else:
|
else:
|
||||||
@ -403,7 +402,7 @@ class InvokeAIAppConfig(InvokeAISettings):
|
|||||||
xformers_enabled : bool = Field(default=True, description="Enable/disable memory-efficient attention", category='Memory/Performance')
|
xformers_enabled : bool = Field(default=True, description="Enable/disable memory-efficient attention", category='Memory/Performance')
|
||||||
tiled_decode : bool = Field(default=False, description="Whether to enable tiled VAE decode (reduces memory consumption with some performance penalty)", category='Memory/Performance')
|
tiled_decode : bool = Field(default=False, description="Whether to enable tiled VAE decode (reduces memory consumption with some performance penalty)", category='Memory/Performance')
|
||||||
|
|
||||||
root : Path = Field(default=_find_root(), description='InvokeAI runtime root directory', category='Paths')
|
root : Path = Field(default=None, description='InvokeAI runtime root directory', category='Paths')
|
||||||
autoimport_dir : Path = Field(default='autoimport', description='Path to a directory of models files to be imported on startup.', category='Paths')
|
autoimport_dir : Path = Field(default='autoimport', description='Path to a directory of models files to be imported on startup.', category='Paths')
|
||||||
lora_dir : Path = Field(default=None, description='Path to a directory of LoRA/LyCORIS models to be imported on startup.', category='Paths')
|
lora_dir : Path = Field(default=None, description='Path to a directory of LoRA/LyCORIS models to be imported on startup.', category='Paths')
|
||||||
embedding_dir : Path = Field(default=None, description='Path to a directory of Textual Inversion embeddings to be imported on startup.', category='Paths')
|
embedding_dir : Path = Field(default=None, description='Path to a directory of Textual Inversion embeddings to be imported on startup.', category='Paths')
|
||||||
@ -424,7 +423,6 @@ class InvokeAIAppConfig(InvokeAISettings):
|
|||||||
log_level : Literal[tuple(["debug","info","warning","error","critical"])] = Field(default="info", description="Emit logging messages at this level or higher", category="Logging")
|
log_level : Literal[tuple(["debug","info","warning","error","critical"])] = Field(default="info", description="Emit logging messages at this level or higher", category="Logging")
|
||||||
|
|
||||||
version : bool = Field(default=False, description="Show InvokeAI version and exit", category="Other")
|
version : bool = Field(default=False, description="Show InvokeAI version and exit", category="Other")
|
||||||
cached_root : Path = Field(default=None, description="internal use only", category="DEPRECATED")
|
|
||||||
# fmt: on
|
# fmt: on
|
||||||
|
|
||||||
def parse_args(self, argv: List[str] = None, conf: DictConfig = None, clobber=False):
|
def parse_args(self, argv: List[str] = None, conf: DictConfig = None, clobber=False):
|
||||||
@ -472,15 +470,12 @@ class InvokeAIAppConfig(InvokeAISettings):
|
|||||||
"""
|
"""
|
||||||
Path to the runtime root directory
|
Path to the runtime root directory
|
||||||
"""
|
"""
|
||||||
# we cache value of root to protect against it being '.' and the cwd changing
|
if self.root:
|
||||||
if self.cached_root:
|
|
||||||
root = self.cached_root
|
|
||||||
elif self.root:
|
|
||||||
root = Path(self.root).expanduser().absolute()
|
root = Path(self.root).expanduser().absolute()
|
||||||
else:
|
else:
|
||||||
root = self.find_root()
|
root = self.find_root().expanduser().absolute()
|
||||||
self.cached_root = root
|
self.root = root # insulate ourselves from relative paths that may change
|
||||||
return self.cached_root
|
return root
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def root_dir(self) -> Path:
|
def root_dir(self) -> Path:
|
||||||
|
@ -84,6 +84,21 @@ def test_env_override():
|
|||||||
assert conf.max_cache_size == 20
|
assert conf.max_cache_size == 20
|
||||||
|
|
||||||
|
|
||||||
|
def test_root_resists_cwd():
|
||||||
|
previous = os.environ["INVOKEAI_ROOT"]
|
||||||
|
cwd = Path(os.getcwd()).resolve()
|
||||||
|
|
||||||
|
os.environ["INVOKEAI_ROOT"] = "."
|
||||||
|
conf = InvokeAIAppConfig.get_config()
|
||||||
|
conf.parse_args([])
|
||||||
|
assert conf.root_path == cwd
|
||||||
|
|
||||||
|
os.chdir("..")
|
||||||
|
assert conf.root_path == cwd
|
||||||
|
os.environ["INVOKEAI_ROOT"] = previous
|
||||||
|
os.chdir(cwd)
|
||||||
|
|
||||||
|
|
||||||
def test_type_coercion():
|
def test_type_coercion():
|
||||||
conf = InvokeAIAppConfig().get_config()
|
conf = InvokeAIAppConfig().get_config()
|
||||||
conf.parse_args(argv=["--root=/tmp/foobar"])
|
conf.parse_args(argv=["--root=/tmp/foobar"])
|
||||||
|
Loading…
Reference in New Issue
Block a user