Spaces:
Paused
Paused
| # Copyright (c) Meta Platforms, Inc. and affiliates. | |
| # All rights reserved. | |
| # | |
| # This source code is licensed under the license found in the | |
| # LICENSE file in the root directory of this source tree. | |
| import os.path as osp | |
| import subprocess | |
| def is_installed(package: str) -> bool: | |
| """Check package whether installed. | |
| Args: | |
| package (str): Name of package to be checked. | |
| """ | |
| # When executing `import mmengine.runner`, | |
| # pkg_resources will be imported and it takes too much time. | |
| # Therefore, import it in function scope to save time. | |
| import importlib.util | |
| import pkg_resources | |
| from pkg_resources import get_distribution | |
| # refresh the pkg_resources | |
| # more datails at https://github.com/pypa/setuptools/issues/373 | |
| importlib.reload(pkg_resources) | |
| try: | |
| get_distribution(package) | |
| return True | |
| except pkg_resources.DistributionNotFound: | |
| spec = importlib.util.find_spec(package) | |
| if spec is None: | |
| return False | |
| elif spec.origin is not None: | |
| return True | |
| else: | |
| return False | |
| def get_installed_path(package: str) -> str: | |
| """Get installed path of package. | |
| Args: | |
| package (str): Name of package. | |
| Example: | |
| >>> get_installed_path('mmcls') | |
| >>> '.../lib/python3.7/site-packages/mmcls' | |
| """ | |
| import importlib.util | |
| from pkg_resources import DistributionNotFound, get_distribution | |
| # if the package name is not the same as module name, module name should be | |
| # inferred. For example, mmcv-full is the package name, but mmcv is module | |
| # name. If we want to get the installed path of mmcv-full, we should concat | |
| # the pkg.location and module name | |
| try: | |
| pkg = get_distribution(package) | |
| except DistributionNotFound as e: | |
| # if the package is not installed, package path set in PYTHONPATH | |
| # can be detected by `find_spec` | |
| spec = importlib.util.find_spec(package) | |
| if spec is not None: | |
| if spec.origin is not None: | |
| return osp.dirname(spec.origin) | |
| else: | |
| # `get_installed_path` cannot get the installed path of | |
| # namespace packages | |
| raise RuntimeError( | |
| f'{package} is a namespace package, which is invalid ' | |
| 'for `get_install_path`') | |
| else: | |
| raise e | |
| possible_path = osp.join(pkg.location, package) | |
| if osp.exists(possible_path): | |
| return possible_path | |
| else: | |
| return osp.join(pkg.location, package2module(package)) | |
| def package2module(package: str): | |
| """Infer module name from package. | |
| Args: | |
| package (str): Package to infer module name. | |
| """ | |
| from pkg_resources import get_distribution | |
| pkg = get_distribution(package) | |
| if pkg.has_metadata('top_level.txt'): | |
| module_name = pkg.get_metadata('top_level.txt').split('\n')[0] | |
| return module_name | |
| else: | |
| raise ValueError(f'can not infer the module name of {package}') | |
| def call_command(cmd: list) -> None: | |
| try: | |
| subprocess.check_call(cmd) | |
| except Exception as e: | |
| raise e # type: ignore | |
| def install_package(package: str): | |
| if not is_installed(package): | |
| call_command(['python', '-m', 'pip', 'install', package]) | |