Note that tracing stack would be a possibility here, but it could cause some serious trouble ( like confusing 'garbage collector', or may not even work in eggs )
I believe the cleanest way would be to pass the caller to the rel_path function.
However, as you may know, there is usually an ugly way of doing things in python. You can do for example something like this:
consider following two scripts:
# relpath.py
import os
def rel_path(path):
if os.path.isfile(__name__):
return os.path.relpath(path, start=__name__)
print("Warning: %s is not a file: returning path relative to the current working dir" % __name__, file=sys.stderr)
return os.path.relpath(path)
# caller.py
import importlib.util
spec = importlib.util.spec_from_file_location(name=__file__, location="/workspace/relpath.py")
rel = importlib.util.module_from_spec(spec)
spec.loader.exec_module(rel)
print(rel.rel_path("/tmp"))
What we did here: when loading the module using importlib.util, we passed the name=__file__
, which gave our module the name consisting of the caller script path. Hence we needn't pass it as an argument to the relpath.py.
Note that this is not clean solution and might not be readable for future developers reading your code. I just wanted to demonstrate the possibilities of python.