Shortcuts

torch.package.package_exporter 的源代码

```html
import collections
import importlib.machinery
import io
import linecache
import pickletools
import platform
import types
from collections import defaultdict, OrderedDict
from dataclasses import dataclass
from enum import Enum
from importlib.machinery import SourceFileLoader
from pathlib import Path
from typing import (
    Any,
    BinaryIO,
    Callable,
    cast,
    DefaultDict,
    Dict,
    List,
    Optional,
    Sequence,
    Set,
    Union,
)

import torch
from torch.serialization import location_tag, normalize_storage_type
from torch.types import Storage
from torch.utils.hooks import RemovableHandle

from ._digraph import DiGraph
from ._importlib import _normalize_path
from ._mangling import demangle, is_mangled
from ._package_pickler import create_pickler
from ._stdlib import is_stdlib_module
from .find_file_dependencies import find_files_source_depends_on
from .glob_group import GlobGroup, GlobPattern
from .importer import Importer, OrderedImporter, sys_importer

__all__ = [
    "PackagingErrorReason",
    "EmptyMatchError",
    "PackagingError",
    "PackageExporter",
]

_gate_torchscript_serialization = True

ActionHook = Callable[["PackageExporter", str], None]


class _ModuleProviderAction(Enum):
    """表示 :class:`PackageExporter` 可以对模块执行的操作之一。

    请参阅 :meth:`PackageExporter.extern` 及其相关方法,了解这些操作的作用描述。
    """

    INTERN = 1
    EXTERN = 2
    MOCK = 3
    DENY = 4
    # 特殊情况:当一个模块被模拟时,PackageExporter 会写出一个
    # `_mock` 模块,该模块实现了我们的模拟存根。如果我们重新打包代码,
    # 我们可能会遇到来自原始包的 `_mock` 模块。如果遇到,
    # 只需忽略它并写出一个 `_mock` 模块一次。
    REPACKAGED_MOCK_MODULE = 5
    # 特殊情况:PackageImporter 添加了一个假模块
    # (`torch_package_importer`),允许打包的代码访问它。不要
    # 重新导出这个模块。
    SKIP = 6


class PackagingErrorReason(Enum):
    """列出依赖项可能打包失败的不同原因。

    当 :class:`PackagingError` 被引发时,此枚举用于提供良好的错误信息。
    """

    def __repr__(self):
        return f"<{self.__class__.__name__}.{self.name}>"

    IS_EXTENSION_MODULE = (
        "模块是一个 C 扩展模块。torch.package 仅支持 Python 模块。"
    )
    NO_DUNDER_FILE = "模块没有定义 __file__。"
    SOURCE_FILE_NOT_FOUND = (
        "模块有一个 __file__,但我们无法在文件系统中找到它。"
    )
    DEPENDENCY_RESOLUTION_FAILED = "依赖解析失败。"
    NO_ACTION = (
        "模块没有匹配任何操作模式。请将其 extern、mock 或 intern。"
    )
    DENIED = "模块被一个模式拒绝。"
    MOCKED_BUT_STILL_USED = (
        "模块被模拟,但仍在包中使用。"
        "如果对象应该在包中,请将模拟的模块 intern 或 extern。"
    )


@dataclass
class _PatternInfo:
    """保存 :class:`PackageExporter` 特定的信息,关于如何执行匹配。"""

    # 对匹配此模式的模块采取的操作。
    action: _ModuleProviderAction
    # 用户在指定模式时给出的 `allow_empty` 的值。
    allow_empty: bool
    # 此模式在打包期间是否已被匹配。
    was_matched: bool

    def __init__(self, action, allow_empty):
        self.action = action
        self.allow_empty = allow_empty
        self.was_matched = False


[docs]class EmptyMatchError(Exception): """当一个 mock 或 extern 被标记为 ``allow_empty=False``,并且在打包期间没有匹配到任何模块时,抛出此异常。""" pass
[docs]class PackagingError(Exception): """当导出一个包时出现问题时,会引发此异常。 ``PackageExporter`` 会尝试收集所有错误,并一次性呈现给您。 """ def __init__(self, dependency_graph: DiGraph, debug=False): # 按原因对错误进行分组。 broken: Dict[PackagingErrorReason, List[str]] = defaultdict(list) for module_name, attrs in dependency_graph.nodes.items(): error = attrs.get("error") if error <span class="
优云智算