mirror of
https://github.com/wassname/ray.git
synced 2026-07-02 02:42:52 +08:00
Treat static methods as class methods instead of instance methods in actors (#6756)
* Treat static methods as class methods rather than instance methods * Add tests for static methods in actors * Revert formatting changes * Readd future imports * Restructure static method check * Documentation enhancements * Fix linting issues
This commit is contained in:
committed by
Edward Oakes
parent
2e972e725a
commit
c480d1d1e4
+8
-1
@@ -211,12 +211,19 @@ class ActorClassMetadata:
|
||||
self.method_signatures = {}
|
||||
self.actor_method_num_return_vals = {}
|
||||
for method_name, method in self.actor_methods:
|
||||
# Whether or not this method requires binding of its first
|
||||
# argument. For class and static methods, we do not want to bind
|
||||
# the first argument, but we do for instance methods
|
||||
is_bound = (ray.utils.is_class_method(method)
|
||||
or ray.utils.is_static_method(self.modified_class,
|
||||
method_name))
|
||||
|
||||
# Print a warning message if the method signature is not
|
||||
# supported. We don't raise an exception because if the actor
|
||||
# inherits from a class that has a method whose signature we
|
||||
# don't support, there may not be much the user can do about it.
|
||||
self.method_signatures[method_name] = signature.extract_signature(
|
||||
method, ignore_first=not ray.utils.is_class_method(method))
|
||||
method, ignore_first=not is_bound)
|
||||
# Set the default number of return values for this method.
|
||||
if hasattr(method, "__ray_num_return_vals__"):
|
||||
self.actor_method_num_return_vals[method_name] = (
|
||||
|
||||
@@ -21,6 +21,7 @@ from ray.utils import (
|
||||
binary_to_hex,
|
||||
is_function_or_method,
|
||||
is_class_method,
|
||||
is_static_method,
|
||||
check_oversized_pickle,
|
||||
decode,
|
||||
ensure_str,
|
||||
@@ -753,7 +754,9 @@ class FunctionActorManager:
|
||||
|
||||
# Execute the assigned method and save a checkpoint if necessary.
|
||||
try:
|
||||
if is_class_method(method):
|
||||
is_bound = (is_class_method(method)
|
||||
or is_static_method(type(actor), method_name))
|
||||
if is_bound:
|
||||
method_returns = method(*args, **kwargs)
|
||||
else:
|
||||
method_returns = method(actor, *args, **kwargs)
|
||||
|
||||
@@ -208,6 +208,55 @@ def test_actor_class_attributes(ray_start_regular):
|
||||
assert ray.get(t.g.remote()) == 3
|
||||
|
||||
|
||||
def test_actor_static_attributes(ray_start_regular):
|
||||
class Grandparent:
|
||||
GRANDPARENT = 2
|
||||
|
||||
@staticmethod
|
||||
def grandparent_static():
|
||||
assert Grandparent.GRANDPARENT == 2
|
||||
return 1
|
||||
|
||||
class Parent1(Grandparent):
|
||||
PARENT1 = 6
|
||||
|
||||
@staticmethod
|
||||
def parent1_static():
|
||||
assert Parent1.PARENT1 == 6
|
||||
return 2
|
||||
|
||||
def parent1(self):
|
||||
assert Parent1.PARENT1 == 6
|
||||
|
||||
class Parent2:
|
||||
PARENT2 = 7
|
||||
|
||||
def parent2(self):
|
||||
assert Parent2.PARENT2 == 7
|
||||
|
||||
@ray.remote
|
||||
class TestActor(Parent1, Parent2):
|
||||
X = 3
|
||||
|
||||
@staticmethod
|
||||
def f():
|
||||
assert TestActor.GRANDPARENT == 2
|
||||
assert TestActor.PARENT1 == 6
|
||||
assert TestActor.PARENT2 == 7
|
||||
assert TestActor.X == 3
|
||||
return 4
|
||||
|
||||
def g(self):
|
||||
assert TestActor.GRANDPARENT == 2
|
||||
assert TestActor.PARENT1 == 6
|
||||
assert TestActor.PARENT2 == 7
|
||||
assert TestActor.f() == 4
|
||||
return TestActor.X
|
||||
|
||||
t = TestActor.remote()
|
||||
assert ray.get(t.g.remote()) == 3
|
||||
|
||||
|
||||
def test_caching_actors(shutdown_only):
|
||||
# Test defining actors before ray.init() has been called.
|
||||
|
||||
|
||||
@@ -127,6 +127,21 @@ def is_class_method(f):
|
||||
return hasattr(f, "__self__") and f.__self__ is not None
|
||||
|
||||
|
||||
def is_static_method(cls, f_name):
|
||||
"""Returns whether the class has a static method with the given name.
|
||||
|
||||
Args:
|
||||
cls: The Python class (i.e. object of type `type`) to
|
||||
search for the method in.
|
||||
f_name: The name of the method to look up in this class
|
||||
and check whether or not it is static.
|
||||
"""
|
||||
for cls in inspect.getmro(cls):
|
||||
if f_name in cls.__dict__:
|
||||
return isinstance(cls.__dict__[f_name], staticmethod)
|
||||
return False
|
||||
|
||||
|
||||
def random_string():
|
||||
"""Generate a random string to use as an ID.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user