Script directory not included in sys.path when a ._pth is in use

I am still hoping for a magical incantation I can add to my _pth file that says "please put the directory containing any script I run in sys.path" so I do not have to modify all my scripts. However, it is possible that no such magical incantation exists.

I have found that the following magical incantation, when added to a Python script, achieves the desired results. And, unlike other solutions you may find out there in the wild, this one will work in the context of cx_Freeze and IDLE and in any other context in which the simple file based solutions will not work.

import inspect
import os
import sys

# Add script directory to sys.path.
# This is complicated due to the fact that __file__ is not always defined.

def GetScriptFile():
    """Obtains the full path and file name of the Python script."""
    if hasattr(GetScriptFile, "file"):
        return GetScriptFile.file
    ret = ""
    try:
        # The easy way. Just use __file__.
        # Unfortunately, __file__ is not available when cx_freeze is used or in IDLE.
        ret = os.path.realpath(__file__)
    except NameError:
        # The hard way.
        if len(sys.argv) > 0 and len(sys.argv[0]) > 0 and os.path.isabs(sys.argv[0]):
            ret = os.path.realpath(sys.argv[0])
        else:
            ret = os.path.realpath(inspect.getfile(GetScriptFile))
            if not os.path.exists(ret):
                # If cx_freeze is used the value of the ret variable at this point is in
                # the following format: {PathToExeFile}\{NameOfPythonSourceFile}. This
                # makes it necessary to strip off the file name to get the correct path.
                ret = os.path.dirname(ret)
    GetScriptFile.file = ret
    return GetScriptFile.file

def GetScriptDirectory():
    """Obtains the path to the directory containing the script."""
    if hasattr(GetScriptDirectory, "dir"):
        return GetScriptDirectory.dir
    module_path = GetScriptFile()
    GetScriptDirectory.dir = os.path.dirname(module_path)
    return GetScriptDirectory.dir

sys.path.insert(0, GetScriptDirectory())

By the way, if you wish to see this in action, I have implement it my my Python Which project.

Tags:

Python

Pth