diff --git a/.pylintrc b/.pylintrc index 4a708564b..53284edee 100644 --- a/.pylintrc +++ b/.pylintrc @@ -64,7 +64,7 @@ ignore-patterns=^\.# # manipulated during runtime and thus existing member attributes cannot be # deduced by static analysis). It supports qualified module names, as well as # Unix pattern matching. -ignored-modules=sentencepiece.*,comfy.api +ignored-modules=sentencepiece.*,comfy.api,comfy.cmd.folder_paths # Python code to execute, usually for sys.path manipulation such as # pygtk.require(). diff --git a/comfy/api_server/routes/internal/internal_routes.py b/comfy/api_server/routes/internal/internal_routes.py index d5b8ed744..09971a0c6 100644 --- a/comfy/api_server/routes/internal/internal_routes.py +++ b/comfy/api_server/routes/internal/internal_routes.py @@ -3,7 +3,7 @@ from typing import Optional from aiohttp import web from ...services.file_service import FileService -from ....cmd.folder_paths import models_dir, user_directory, output_directory, folder_names_and_paths +from ....cmd.folder_paths import models_dir, user_directory, output_directory, folder_names_and_paths # pylint: disable=import-error class InternalRoutes: diff --git a/comfy/app/frontend_management.py b/comfy/app/frontend_management.py index aedf3dcd9..7491f8c36 100644 --- a/comfy/app/frontend_management.py +++ b/comfy/app/frontend_management.py @@ -15,7 +15,7 @@ import requests from typing_extensions import NotRequired from ..cli_args import DEFAULT_VERSION_STRING -from ..cmd.folder_paths import add_model_folder_path +from ..cmd.folder_paths import add_model_folder_path # pylint: disable=import-error from ..component_model.files import get_package_as_path REQUEST_TIMEOUT = 10 # seconds diff --git a/comfy/client/embedded_comfy_client.py b/comfy/client/embedded_comfy_client.py index df6473663..e4896d61e 100644 --- a/comfy/client/embedded_comfy_client.py +++ b/comfy/client/embedded_comfy_client.py @@ -3,12 +3,10 @@ from __future__ import annotations import asyncio import gc import json -import os import threading import uuid from asyncio import get_event_loop from multiprocessing import RLock -from pathlib import Path from typing import Optional from opentelemetry import context, propagate @@ -18,7 +16,7 @@ from opentelemetry.trace import Status, StatusCode from .client_types import V1QueuePromptResponse from ..api.components.schema.prompt import PromptDict from ..cli_args_types import Configuration -from ..cmd.folder_paths import init_default_paths +from ..cmd.folder_paths import init_default_paths # pylint: disable=import-error from ..cmd.main_pre import tracer from ..component_model.executor_types import ExecutorToClientProgress from ..component_model.make_mutable import make_mutable diff --git a/comfy/cmd/folder_paths.py b/comfy/cmd/folder_paths.py index cc1790858..88df4e164 100644 --- a/comfy/cmd/folder_paths.py +++ b/comfy/cmd/folder_paths.py @@ -416,13 +416,13 @@ init_default_paths(_folder_names_and_paths()) __all__ = [ "supported_pt_extensions", "extension_mimetypes_cache", - "base_path", - "folder_names_and_paths", - "models_dir", - "user_directory", - "output_directory", - "temp_directory", - "input_directory", + "base_path", # pylint: disable=undefined-all-variable + "folder_names_and_paths", # pylint: disable=undefined-all-variable + "models_dir", # pylint: disable=undefined-all-variable + "user_directory", # pylint: disable=undefined-all-variable + "output_directory", # pylint: disable=undefined-all-variable + "temp_directory", # pylint: disable=undefined-all-variable + "input_directory", # pylint: disable=undefined-all-variable # Public functions "init_default_paths", diff --git a/comfy/cmd/folder_paths.pyi b/comfy/cmd/folder_paths.pyi new file mode 100644 index 000000000..b1957a098 --- /dev/null +++ b/comfy/cmd/folder_paths.pyi @@ -0,0 +1,109 @@ +import os +from pathlib import Path +from typing import Optional, List, Literal, Tuple, Union, Dict + +from comfy.cli_args_types import Configuration +from comfy.component_model.folder_path_types import FolderNames, SaveImagePathTuple + +# Variables +base_path: str +folder_names_and_paths: FolderNames +models_dir: str +user_directory: str +output_directory: str +temp_directory: str +input_directory: str +supported_pt_extensions: set[str] + + +# Functions +def init_default_paths( + folder_names_and_paths: FolderNames, + configuration: Optional[Configuration] = ..., + create_all_directories: bool = ... +) -> None: ... + + +def map_legacy(folder_name: str) -> str: ... + + +def set_output_directory(output_dir: Union[str, Path]) -> None: ... + + +def set_temp_directory(temp_dir: Union[str, Path]) -> None: ... + + +def set_input_directory(input_dir: Union[str, Path]) -> None: ... + + +def get_output_directory() -> str: ... + + +def get_temp_directory() -> str: ... + + +def get_input_directory() -> str: ... + + +def get_user_directory() -> str: ... + + +def set_user_directory(user_dir: Union[str, Path]) -> None: ... + + +def get_directory_by_type(type_name: str) -> Optional[str]: ... + + +def annotated_filepath(name: str) -> Tuple[str, Optional[str]]: ... + + +def get_annotated_filepath(name: str, default_dir: Optional[str] = ...) -> str: ... + + +def exists_annotated_filepath(name: str) -> bool: ... + + +def add_model_folder_path( + folder_name: str, + full_folder_path: Optional[str] = ..., + extensions: Optional[Union[set[str], frozenset[str]]] = ..., + is_default: bool = ... +) -> str: ... + + +def get_folder_paths(folder_name: str) -> List[str]: ... + + +def recursive_search( + directory: str, + excluded_dir_names: Optional[List[str]] = ... +) -> Tuple[List[str], Dict[str, float]]: ... + + +def filter_files_extensions(files: List[str], extensions: set[str]) -> List[str]: ... + + +def get_full_path(folder_name: str, filename: str) -> Optional[Union[str, bytes, os.PathLike]]: ... + + +def get_full_path_or_raise(folder_name: str, filename: str) -> str: ... + + +def get_filename_list(folder_name: str) -> List[str]: ... + + +def get_save_image_path( + filename_prefix: str, + output_dir: str, + image_width: int = 0, + image_height: int = 0 +) -> SaveImagePathTuple: ... + + +def create_directories(paths: Optional[FolderNames] = ...) -> None: ... + + +def invalidate_cache(folder_name: str) -> None: ... + + +def filter_files_content_types(files: List[str], content_types: List[Literal["image", "video", "audio"]]) -> List[str]: ... diff --git a/comfy/component_model/module_property.py b/comfy/component_model/module_property.py index 2673a3f16..3d6c18b5e 100644 --- a/comfy/component_model/module_property.py +++ b/comfy/component_model/module_property.py @@ -31,10 +31,7 @@ def create_module_properties(): return func() name = func.__name__ - if name.startswith('_'): - properties[name[1:]] = wrapper - else: - raise ValueError("Property function names must start with an underscore") + properties[name[1:]] = wrapper module = sys.modules[func.__module__] patch_module(module) diff --git a/comfy/model_downloader.py b/comfy/model_downloader.py index c75a3c7d5..4ebf9c594 100644 --- a/comfy/model_downloader.py +++ b/comfy/model_downloader.py @@ -21,7 +21,7 @@ from safetensors.torch import save_file from .cli_args import args from .cmd import folder_paths -from .cmd.folder_paths import add_model_folder_path, supported_pt_extensions +from .cmd.folder_paths import add_model_folder_path, supported_pt_extensions # pylint: disable=import-error from .component_model.deprecation import _deprecate_method from .component_model.files import canonicalize_path from .interruption import InterruptProcessingException diff --git a/comfy/model_filemanager/download_models.py b/comfy/model_filemanager/download_models.py index 1cd34ac52..4c7b7b8a6 100644 --- a/comfy/model_filemanager/download_models.py +++ b/comfy/model_filemanager/download_models.py @@ -12,7 +12,7 @@ from typing import Callable, Any, Optional, Awaitable, Dict import aiohttp -from ..cmd.folder_paths import folder_names_and_paths, get_folder_paths +from ..cmd.folder_paths import folder_names_and_paths, get_folder_paths # pylint: disable=import-error class DownloadStatusType(Enum):