4

I'm doing some learning python tutorials on Lynda. The tutorial has the script creating the files in the same directory as the script, as one would expect.

For whatever reason, though, my installation is creating the file and looking to read the file (using the path object) in the project root, or two directories up.

The script I am running is C:\Users\user\Development\Ex_Files_Learning_Python\Exercise Files\Ch4

The script looks like this:

import os
from os import path
import datetime
from datetime import date, time, timedelta
import time


def main():
  # Print the name of the OS
  print(os.name)

  # Check for item existence and type
  print("Item exists: " + str(path.exists("textfile.txt")))
  print("Item is a file: " + str(path.isfile("textfile.txt")))
  print("Item is a directory: " + str(path.isdir("textfile.txt")))
  # Work with file paths
  print("Item path" + str(path.realpath("textfile.txt")))
  print("Item path and name: " + str(path.split(path.realpath("textfile.txt"))))

  # Get the modification time


  # Calculate how long ago the item was modified



if __name__ == "__main__":
  main()

Its output is

nt
Item exists: False
Item is a file: False
Item is a directory: False
Item pathC:\Users\user\Development\Ex_Files_Learning_Python\textfile.txt
Item path and name: ('C:\\Users\\user\\Development\\Ex_Files_Learning_Python', 'textfile.txt')

So as you can see, it assumes its path is the project root, two directories up. I had the same problem in my previous exercise, creating a file. When i used open() on a file object, it created the file two directories up in the root of the project.

Any pointers are appreciated.

Update: I've established that this is happening because I'm using the VSCode terminal. How do I instruct the VSCode terminal to run the program from the cwd of the file i'm editing and debugging, rather than the project root?

For the record, here's my launch.json for the debugger

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Current File (Integrated Terminal)",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal"
        },
        {
            "name": "Python: Remote Attach",
            "type": "python",
            "request": "attach",
            "port": 5678,
            "host": "localhost",
            "pathMappings": [
                {
                    "localRoot": ".",
                    "remoteRoot": "."
                }
            ]
        },
        {
            "name": "Python: Module",
            "type": "python",
            "request": "launch",
            "module": "enter-your-module-name-here",
            "console": "integratedTerminal"
        },
        {
            "name": "Python: Django",
            "type": "python",
            "request": "launch",
            "program": "${workspaceFolder}/manage.py",
            "console": "integratedTerminal",
            "args": [
                "runserver",
                "--noreload",
                "--nothreading"
            ],
            "django": true
        },
        {
            "name": "Python: Flask",
            "type": "python",
            "request": "launch",
            "module": "flask",
            "env": {
                "FLASK_APP": "app.py"
            },
            "args": [
                "run",
                "--no-debugger",
                "--no-reload"
            ],
            "jinja": true
        },
        {
            "name": "Python: Current File (External Terminal)",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "externalTerminal"
        }
    ]
}
KinsDotNet
  • 1,500
  • 5
  • 25
  • 53
  • 1
    if you're in `C:\users\user\Development\Ex_Files_Learning_Python` and do `python "Exercise Files\Ch4.py"`, you'll get this behavior. You can reroot to the Python file if you like: `os.chdir(__file__)` – Adam Smith Feb 01 '19 at 01:04
  • Thanks, see my update @AdamSmith It's the VSCode terminal that's defaulting to the root directory. Trying now to figure out how to fix that. On another note, I could be wrong because I haven't tried it, but wouldn't your workaround of rerooting fail because it uses a attempts to change directories to a file path, rather than a directory? – KinsDotNet Feb 01 '19 at 01:25
  • Oh yeah it totally would. `os.chdir(os.path.dirname(__file__))` then :). There is a way to change those settings in `vscode`, but it depends on how you've loaded the file (is it part of a project, etc) – Adam Smith Feb 01 '19 at 01:26
  • @AdamSmith I opened it as part of a project. I opened the directory, then open the project files from the sidebar. – KinsDotNet Feb 01 '19 at 01:30

4 Answers4

4

According to https://code.visualstudio.com/docs/python/settings-reference :

python.terminal.executeInFileDir
false
Indicates whether to run a file in the file's directory instead of the current folder.

So presumably just set python.terminal.executeInFileDir to true.

Adam Smith
  • 52,157
  • 12
  • 73
  • 112
  • 1
    I realize now that this affects the terminal window, but not the debugger. Your answer is right, but I'm going to update with another answer on changing the debugger. – KinsDotNet Feb 01 '19 at 04:00
1

If you're running the script from the terminal, you're probably running:

python "Exercise Files\Ch4\my_script.py"

Or something similar.

Instead, change folders first and then run it on the terminal:

cd "Exercise Files\Ch4"
python my_script.py

Or, to avoid all this manual directory switching, explicitly change the working directory in your script.

Grismar
  • 27,561
  • 4
  • 31
  • 54
  • I've established that this is happening because I'm using the VSCode terminal. How do I instruct the VSCode terminal to run the program from the cwd of the file i'm editing and debugging, rather than the project root? – KinsDotNet Feb 01 '19 at 01:29
  • Better to explicitly specify the filepath :) – Adam Smith Feb 01 '19 at 01:30
  • You say that "that this is happening because I'm using the VSCode terminal", but you're not telling us what you're doing exactly. My suggestion was that you're probably starting Python from this working directory yourself, which is why your script finds itself running there. For more information on how to set up a Python scripting environment with VSCode, check https://code.visualstudio.com/docs/python/python-tutorial – Grismar Feb 01 '19 at 01:33
  • @Grismar I was telling you that you are correct. The terminal IS launching the script from project root. That means I now have to get it running from the cwd of the file. Thank you for that documentation. I suppose I'll read it and post whatever answer I find as my own answer. – KinsDotNet Feb 01 '19 at 01:37
  • I'm sorry, but there was no offense implied and I do not enjoy being accused of gaslighting when I'm answering a question. I kindly suggest you reread the above to confirm your accusation was unwarranted. – Grismar Feb 01 '19 at 01:44
1

This is my fault, as I did not clarify that I was trying to modify the debugger terminal in VSCode. @Adam Smith's answer is right for the majority of cases dealing with the standard terminal.

If, however, you're trying to run the file from the debugger, the answer is to set "cwd" to an empty string, ie "" in launch.json (current debugger configuration)

https://code.visualstudio.com/docs/python/debugging#_cwd

KinsDotNet
  • 1,500
  • 5
  • 25
  • 53
0

What you need to use is the __file__ built-in variable that Python associates with the current Python file name.

see what does the __file__ variable mean/do?

This should work if you're on Python 3.

pathlib.Path is on Python 3 and serves to manipulate file paths.

  from pathlib import Path                            
  myfilepath = Path(Path(__file__).resolve()).parent / "textfile.txt"
                    ^            ^
                    find the currrent script location
                                             ^ get its parent directory
                                                        ^ add your file name

and this the script

import os
from os import path
import datetime
from datetime import date, time, timedelta
import time


def main():
  # Print the name of the OS
  print(os.name)

  from pathlib import Path
  myfilepath = Path(Path(__file__).resolve()).parent / "textfile.txt"

  # Check for item existence and type
  print("Item exists: " + str(path.exists(myfilepath)))
  print("Item is a file: " + str(path.isfile(myfilepath)))
  print("Item is a directory: " + str(path.isdir(myfilepath)))
  # Work with file paths
  print("Item path" + str(path.realpath(myfilepath)))
  print("Item path and name: " + str(path.split(path.realpath(myfilepath))))

  # Get the modification time


  # Calculate how long ago the item was modified

main()

output:

posix
Item exists: True
Item is a file: True
Item is a directory: False
Item path/Users/jluc/kds2/wk/explore/textfile.txt
Item path and name: ('/Users/jluc/kds2/wk/explore', 'textfile.txt')

If you're on Python 2, you get the same results by using this instead:

(os.path.join("foo", "bar") will return foo\bar on Windows or foo/bar on Linux/macOs.

#from pathlib import Path
myfilepath = os.path.join(os.path.dirname(__file__), "textfile.txt")
                          ^ get parent directory
                                                     ^ append your filename
JL Peyret
  • 10,917
  • 2
  • 54
  • 73