Skip to content

Commit

Permalink
Make expensive subpackage imports dynamic.
Browse files Browse the repository at this point in the history
  • Loading branch information
clarkzinzow committed Oct 20, 2022
1 parent 769eda9 commit 486a339
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 16 deletions.
46 changes: 32 additions & 14 deletions python/ray/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# isort: skip_file
import logging
import os
import sys

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -115,7 +116,7 @@ def _configure_system():

import ray._raylet # noqa: E402

from ray._raylet import ( # noqa: E402
from ray._raylet import ( # noqa: E402,F401
ActorClassID,
ActorID,
NodeID,
Expand All @@ -134,7 +135,7 @@ def _configure_system():

_config = _Config()

from ray._private.state import ( # noqa: E402
from ray._private.state import ( # noqa: E402,F401
nodes,
timeline,
cluster_resources,
Expand Down Expand Up @@ -162,23 +163,20 @@ def _configure_system():
# We import ray.actor because some code is run in actor.py which initializes
# some functions in the worker.
import ray.actor # noqa: E402,F401
from ray.actor import method # noqa: E402
from ray.actor import method # noqa: E402,F401

# TODO(qwang): We should remove this exporting in Ray2.0.
from ray.cross_language import java_function, java_actor_class # noqa: E402
from ray.runtime_context import get_runtime_context # noqa: E402
from ray import autoscaler # noqa:E402
from ray import data # noqa: E402,F401
from ray.cross_language import java_function, java_actor_class # noqa: E402,F401
from ray.runtime_context import get_runtime_context # noqa: E402,F401
from ray import internal # noqa: E402,F401
from ray import util # noqa: E402
from ray import util # noqa: E402,F401
from ray import _private # noqa: E402,F401
from ray import workflow # noqa: E402,F401

# We import ClientBuilder so that modules can inherit from `ray.ClientBuilder`.
from ray.client_builder import client, ClientBuilder # noqa: E402
from ray.client_builder import client, ClientBuilder # noqa: E402,F401


class _DeprecationWrapper(object):
class _DeprecationWrapper:
def __init__(self, name, real_worker):
self._name = name
self._real_worker = real_worker
Expand All @@ -201,18 +199,23 @@ def __getattr__(self, attr):
serialization = _DeprecationWrapper("serialization", ray._private.serialization)
state = _DeprecationWrapper("state", ray._private.state)


_subpackages = [
"autoscaler",
"data",
"workflow",
]

__all__ = [
"__version__",
"_config",
"get_runtime_context",
"actor",
"available_resources",
"autoscaler",
"cancel",
"client",
"ClientBuilder",
"cluster_resources",
"data",
"get",
"get_actor",
"get_gpu_ids",
Expand All @@ -237,7 +240,7 @@ def __getattr__(self, attr):
"LOCAL_MODE",
"SCRIPT_MODE",
"WORKER_MODE",
]
] + _subpackages

# ID types
__all__ += [
Expand All @@ -255,6 +258,21 @@ def __getattr__(self, attr):
"PlacementGroupID",
]

if sys.version_info < (3, 7):
# TODO(Clark): Remove this one we drop Python 3.6 support.
from ray import autoscaler # noqa: F401
from ray import data # noqa: F401
from ray import workflow # noqa: F401
else:
# Delay importing of expensive, isolated subpackages.
def __getattr__(name: str):
import importlib

if name in _subpackages:
return importlib.import_module("." + name, __name__)
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")


del os
del logging
del sys
2 changes: 1 addition & 1 deletion python/ray/tests/test_runtime_env_working_dir_4.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ def check(self):
runtime_env = {"py_modules": [S3_PACKAGE_URI]}

# Note: We should set a bigger timeout if downloads the s3 package slowly.
get_timeout = 10
get_timeout = 2

# Start a task with runtime env
if worker_register_timeout:
Expand Down
6 changes: 5 additions & 1 deletion python/ray/tests/test_top_level_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,13 @@ def test_api_functions():
"get_runtime_context",
]

IMPL_FUNCTIONS = ["__getattr__"]

functions = getmembers(ray, isfunction)
function_names = [f[0] for f in functions]
assert set(function_names) == set(PYTHON_API + OTHER_ALLOWED_FUNCTIONS)
assert set(function_names) == set(
PYTHON_API + OTHER_ALLOWED_FUNCTIONS + IMPL_FUNCTIONS
)


def test_non_ray_modules():
Expand Down

0 comments on commit 486a339

Please sign in to comment.