python / cpython

The Python programming language
https://www.python.org
Other
63.33k stars 30.31k forks source link

In considering the current directory for importing modules, Python does not honour the output of os.getcwd() #62267

Closed 061a0c5b-88b1-4bb5-a974-3b904e78871b closed 11 years ago

061a0c5b-88b1-4bb5-a974-3b904e78871b commented 11 years ago
BPO 18067
Nosy @bitdancer
Superseder
  • bpo-6386: importing yields unexpected results when initial script is a symbolic link
  • Files
  • symlink-bug.tar.gz: Tarball of directory tree illustrating the problem
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields: ```python assignee = None closed_at = created_at = labels = ['extension-modules', 'type-bug'] title = 'In considering the current directory for importing modules, Python does not honour the output of os.getcwd()' updated_at = user = 'https://bugs.python.org/jamadagni' ``` bugs.python.org fields: ```python activity = actor = 'r.david.murray' assignee = 'none' closed = True closed_date = closer = 'r.david.murray' components = ['Extension Modules'] creation = creator = 'jamadagni' dependencies = [] files = ['30386'] hgrepos = [] issue_num = 18067 keywords = [] message_count = 2.0 messages = ['190098', '190104'] nosy_count = 2.0 nosy_names = ['r.david.murray', 'jamadagni'] pr_nums = [] priority = 'normal' resolution = 'duplicate' stage = 'resolved' status = 'closed' superseder = '6386' type = 'behavior' url = 'https://bugs.python.org/issue18067' versions = [] ```

    061a0c5b-88b1-4bb5-a974-3b904e78871b commented 11 years ago

    Hello. I first asked about this at https://groups.google.com/d/topic/comp.lang.python/ZOGwXGU_TV0/discussion and am only posting this issue due to no reply there.

    I am using Python 2.7.4 and Python 3.3.1 (default packages) on Kubuntu Raring. On both I experience this same bug.

    This bug has to do with a Python script called via a symlink. To illustrate it I have included a minimal test case tarball as an attachment. Just run sh test.sh at root of the extracted tree to see what's happening.

    I am quite unpleasantly surprised that when one calls a Python script via a symlink, and that script asks for a module to be imported, Python searches the directory in which the *target of the link exists, and uses the version of the library present *there if any, and raises an exception if not. It even follows a chain of symlinks. Any version of the library present in the same directory as the (user-called) symlink is ignored. This is totally counter-intuitive behaviour and should be treated as a bug and fixed.

    This is all the more frustrating since running print(os.getcwd()) from the same script correctly prints the current directory in which the *symlink* and not its target exists. (See output of the attached scripts.)

    Now the symlink is only a user-level file system convenience indicating that I create a virtual file in one place pointing to another file elsewhere. Whatever the rest of the contents of the directory containing the other file is immaterial to me -- I am only interested in the one file I am symlinking to.

    I am executing a script from a given directory. os.getcwd() correctly prints the path of that directory. I also have a library in that same directory for the script to import. I would expect Python to honour the output of os.getcwd() in doing import too.

    I read through http://docs.python.org/3/reference/import.html and didn't seem to find any explanation for the current illogical behaviour. (Please point out if I have missed it.)

    (Note that the same behaviour does not happen with hardlinks, probably since the filesystem itself shows the whole file as existing at the current location.)

    Output of the test.sh script:

    **** Trying english/run.py ****
    CWD: /tmp/symlink-bug/english
    Hello Shriramana!
    **** Trying english/run-link.py symlinked to ./run.py ****
    CWD: /tmp/symlink-bug/english
    Traceback (most recent call last):
      File "run-link.py", line 3, in <module>
        from greet import greet
    ImportError: No module named greet
    **** Trying english/run-link-link.py symlinked to ./run-link.py symlinked to english/run.py ****
    CWD: /tmp/symlink-bug/english
    Hello Shriramana!
    **** Trying sanskrit/run-slink.py symlinked to english/run.py ****
    CWD: /tmp/symlink-bug/sanskrit
    Hello Shriramana!
    **** Trying sanskrit/run-hlink.py hardlinked to english/run.py ****
    CWD: /tmp/symlink-bug/sanskrit
    Namaste Shriramana!

    Expected output: (see esp items marked 1 and 2 below):

    Trying english/run.py CWD: /tmp/symlink-bug/english Hello Shriramana! 1 Trying english/run-link.py symlinked to ./run.py CWD: /tmp/symlink-bug/english Hello Shriramana! Trying english/run-link-link.py symlinked to ./run-link.py symlinked to english/run.py CWD: /tmp/symlink-bug/english Hello Shriramana! 2 Trying sanskrit/run-slink.py symlinked to english/run.py CWD: /tmp/symlink-bug/sanskrit Namaste Shriramana! Trying sanskrit/run-hlink.py hardlinked to english/run.py CWD: /tmp/symlink-bug/sanskrit Namaste Shriramana!

    bitdancer commented 11 years ago

    This is a duplicate of bpo-6386, which does contain an explanation of the behavior.