1

I am using this approach to get the current directory of a file:

import pathlib
pathlib.Path(__file__).parent.resolve()

Is it possible to extract this string into a function, that will use the path of the caller? My attempt:

# a.py
import bb.b
print(bb.b.get_current_path(__file__)) # OK: path to a.py directory (.)
print(bb.b.get_current_path()) # WRONG: path to b.py directory (bb)
# bb/b.py
import pathlib
def get_current_path(file=__file__):
    return pathlib.Path(file).parent.resolve()

Is it possible to avoid using __file__ in a.py?

1 Answer 1

1

You can use inspect module to inspect the stack. Though it satisfies the given condition

# bb/b.py
import inspect
import pathlib

stack = inspect.stack()
file_importer = stack[6][1]    

def get_current_path(file=file_importer):
    return pathlib.Path(file).parent.resolve()

I'm not sure if import will be always at the frame with the index 6. Search through code_context can be used instead:

file_importer = next(frameinfo[1] for frameinfo in stack
                     if frameinfo[4] and frameinfo[4][0].startswith('import'))

But this approach breaks the possibility to run b.py, so that exception handling of StopIteration is required with desired behaviour.


Both approaches return the direct importer of b.py, e.g., having a file c.py and calling it from a.py returns the path of c.py

# c.py
import bb.b
get_current_path = bb.b.get_current_path
# a.py
import bb.c
print(bb.c.get_current_path(__file__)) # OK: path to a.py directory (.)
print(bb.c.get_current_path()) # WRONG: path to c.py directory (bb)

Hence, depending on further conditions desired behaviour could be reached by processing inspect.stack().

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.