Description
What happened + What you expected to happen
Description:
When using Ray actors with classes defined in a nested package (e.g., mypkg.plugins.my_plugin.MyPlugin), the Ray worker resolves the module to the package's init.py instead of the actual module file when using import(self.class.module).file. This causes issues for code that needs to locate the source file of a class.
Environment:
Python version: 3.11.13
Ray version: 2.44.0
OS: Linux 5.15.0-139-generic #149~20.04.1-Ubuntu SMP Wed Apr 16 08:29:56 UTC 2025 x86_64
Zip file with full repro attached:
ray_repro_bug.zip
Notes:
This bug also appears in larger projects and breaks code that needs to locate the source file of a class using import(self.class.module).file.
The bug is reproducible with the attached script.
Versions / Dependencies
Environment:
Python version: 3.11.13
Ray version: 2.44.0
OS: Linux 5.15.0-139-generic #149~20.04.1-Ubuntu SMP Wed Apr 16 08:29:56 UTC 2025 x86_64
Reproduction script
Minimal Reproduction
Directory structure:
ray_repro/
├── main.py
└── mypkg/
├── init.py
└── plugins/
├── init.py
└── my_plugin.py
mypkg/plugins/my_plugin.py:
class MyPlugin:
def init(self):
import sys
print(f"[PLUGIN] file = {file}")
print(f"[PLUGIN] name = {name}")
print(f"[PLUGIN] sys.path = {sys.path}")
print(f"[PLUGIN] self.class = {self.class}")
print(f"[PLUGIN] self.class.module = {self.class.module}")
try:
print(f"[PLUGIN] import file = {import(self.class.module).file}")
except Exception as e:
print(f"[PLUGIN] import file error: {e}")
main.py:
import ray
import sys
from mypkg.plugins.my_plugin import MyPlugin
@ray.remote
class PluginActor:
def init(self):
self.plugin = MyPlugin()
if name == "main":
ray.init()
print("[MAIN] sys.path =", sys.path)
actor = PluginActor.remote()
ray.get(actor.init.remote())
ray.shutdown()
How to run:
PYTHONPATH=ray_repro python ray_repro/main.py
Observed Output:
[PLUGIN] file = /.../ray_repro/mypkg/plugins/my_plugin.py
[PLUGIN] name = mypkg.plugins.my_plugin
[PLUGIN] self.class.module = mypkg.plugins.my_plugin
[PLUGIN] import file = /.../ray_repro/mypkg/init.py # <-- Should be my_plugin.py!
Expected Output:
import file = .../my_plugin.py (not init.py)
Environment:
Issue Severity
Medium: It is a significant difficulty but I can work around it.