Moving a file does not change the location PyCharm thinks it exists in

Okay, this may be answered by me not understanding something, but I truly feel this is a PyCharm issue unless explained otherwise.

 

Say you have this setup:

Layout

Project
|---A
   |--- SecondProgram.py
   |--- testfile.txt

|---B
   |--- MainProgram.py

 

Contents of testfile.txt

This is a test.

Contents of SecondProgram.py

import os

cwd = os.getcwd()
print(cwd)

filelocation = cwd + '/testfile.txt'
with open(filelocation, 'r') as file:
     print(file.read())

Contents of MainProgram.py

import os

cwd = os.getcwd()
print(cwd)

from Project.A import SecondProgram  #(ignore the PEP-8 rule breaking for not having this on top for now)

First we run SecondProgram.py, and unsurprisingly, we get the text from the testfile printed.

Now if I run the MainProgram.py, a FileNotFoundError is raised as the filelocation variable in the second program is "/.../Project/B"  rather than "/.../ProjectA" as that's where the file was imported. This makes sense, all is normal. But, if I *move* MainProgram.py to the A folder/directory from the B folder/directory,  and run MainProgram.py again, then even though all three files are now in the same directory (so MainProgram should be able to access the testfile as the directory name from os.getcwd() is the same now, it still raises a FileNotFoundError:

FileNotFoundError: [Errno 2] No such file or directory: '/home/.../Program/B/testfile.txt'

Even the os.getcwd() prints out "/home/.../Program/B" rather than "/home/.../Program/A". Why is this the case? The file now exists in the A folder, but os.getcwd() still locates it in the B folder?

 

This becomes even more interesting. If you create a file in B called example1.py with just the import line:

from Project.A import SecondProgram

And you run it, it of course complains saying "FileNotFoundError: [Errno 2] No such file or directory: '/home/..../Project/B/testfile.txt'. If you move it to folder A, it still gives the same error, meaning the file location is not updated to the new folder. But, if we create another file, called example2.py, located again in the B folder, with the exact same import line (so everything is identical as example1.py), and we don't run it at all, but rather immediately move it to the A folder, then run it for the first time in A (remember, it was created in B), it works fine, outputting the text file. If we then move it back to the B folder, and run it a second time, it again compiles, with os.getcwd() reading that it is in the A file, and reading the textfile, even though it's in a very different directory.

Another level: If you open an active session, and try to run example1.py there (remember, this is the file that was run in B, moved to A (where it currently is), and would not read the testfile anymore as the os.getcwd() still thought it was stored in the B, even though it was moved),  it will say:

"ModuleNotFoundError: No module named 'Project'", 

and/or

"ModuleNotFoundError: No module named 'A'"

if both those are removed so all the example1.py file contains is

import SecondProgram

and then compile it in an active session again, then the os.getcwd() finds the correct directory, and the testfile is read, and the print cwd line gives "/home/.../Project/A" in the active session. Even though in Pycharm, the exact same FilleNotFoundError is given as it thinks it's in the B folder (print(cwd) returns "/home/.../Project/B"). Interestingly enough, when you edit the example1.py file to have just "import SecondProgram", or if you leave it as "from Project.A import SecondProgram", no issue with importing the module name is raised by PyCharm, but in an active session, it must be "import SecondProgram" if it is in the A folder.

 

I may not have explained this well, but with a bit of setup, you can play with this yourself and see how weird it is. From what I gather, when a python file is compiled, its directory is recorded is some metadata. If that file is moved to a new location, that metadata is not updated, and this causes very bug prone issues when trying to work with any external files/modules.

 

I found this by having 2 folders with two programs, just like this example. I decided to merge them by moving the MainProgram over to the "A" folder, but now the directory/metadata for MainProgram is not updated. Interestingly, if I ctrl+a and ctrl+v the whole file into a new file (say MainProgramNew.py) in the same new location (folder A), then run it, no issues, os.getcwd works correctly, etc. as expected. But the existing file that was moved to folder "A" still can't read the file as it's trying to parse toe original location rather than the new one. Clearly os.getcwd() is working as intended if in an active session it correctly finds the directory of the moved folder. Why does it not work in PyCharm?

How you move these files (dragging in Pycharm, Right-click -> refactor -> move, moving the file manually in the a terminal) has no effect. Restarting PyCharm does not fix the issue.

There are several layers to this issue, and I hope I'm not going crazy with it. How do I move a file that imports modules that read/write textfiles, and have that moved file update it's location?

 

 

 

1 comment
Comment actions Permalink

Hello, 

 

Thank you for such a detailed description of the behavior, it was easy to reproduce and define a cause. 

The thing is that for every file in a project Run/Debug configuration is being created https://www.jetbrains.com/help/pycharm/run-debug-configuration-python.html#common ,   and Working Directory is specified as a current location of a file.  

In the situation you have faced, after changing the file location, the working directory remains default. I have created a bug on YouTrack, please feel free to vote for it in order to increase a priority and monitor for a resolution:  

https://youtrack.jetbrains.com/issue/PY-38653

 

 

0

Please sign in to leave a comment.