0

I have had an issue I couldn't resolve now for a while, and I feel like it's a trivial issue when it comes to Debugging packages using VScode. When I have a complex project I set up a setup.py file and create a package, I use this package inside of my package to reference to different modules. For example:

.
└── project_root
    ├── module1
    │   ├── f1.py
    │   ├── f2.py
    │   └── __init__.py
    ├── module2
    │   ├── f1.py
    │   ├── f2.py
    │   └── __init__.py
    └── module3
        ├── f1.py
        ├── f2.py
        └── __init__.py

############# IMPORTING CLASSES/METHODS ##################
### for example inside modules3.f1:
from project_root.module1.f2 import some_class

I always use a virtual environment. If I install my setup file with pip install . the importing of the file works as expected. Unfortunately, when it comes down to debugging, it will only respect the breakpoints of the files inside my virtual environment <virtual env name>/lib64/python3.8/site-packages/<package_name> and not the ones I'm working on in the project_root.

So I have basically 2 questions:

a) Is there a way to tell VSCode to use my <project_root> files instead of the virtual env package for my package?

b) I'm creating a package because otherwise, I have problems referencing files in parent directories. Is there a better approach to creating complicated code structures than immediately setting up a setup.py and ultimately resolving my debugging issue?

My VScode launch.json is setup like this:

{
    // 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",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal",
            "cwd": "${fileDirname}",
            "args": ["-d"],
            "justMyCode":false  
            // add env
            "env": {
                "MODE": "True"
            }
        }
    ]
}

############ UPDATE ############################## I hope this image describes my problem better. I setup virtual environment, set breakpoints in the Identical files, in my "working directory" and inside the virtual env (v/lib/python3.8/site-packages/Packagename/module1/f1.py). Then I execute my script in the debugger and the breakpoint in the V env will activate and not the one in the working dir. enter image description here

  • How can I reproduce your problem? Please clarify your specific problem or provide additional details to highlight exactly what you need. – JialeDu Sep 28 '22 at 08:45
  • I updated the questions, i Hope that describes my problem better – Andy Parzyszek Sep 28 '22 at 15:28
  • How do you debug your code after setting `launch.json`? Did you debug from the **Run and Debug** panel? And now, I know what you are asking . But sorry I can't reproduce your problem, so can you provide a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) – JialeDu Sep 29 '22 at 09:46
  • here is a git repo with the example from above: https://github.com/N0talent/vscode_example. In the readme are the setup instructions and how I execute to get this problem. – Andy Parzyszek Sep 29 '22 at 13:30

2 Answers2

0

Reason

Because when you use pip to install the Packagename in the virtual environment, in your Packagename/module3/f2.py script, from Packagename.module1.f1 import function1 is actually imported from the virtual environment, and function1 in the virtual environment is used.

And in the import method of your example, the function1 under Packagename/module1/f1.py cannot be imported. (Because they are in different folders)

Solution

If you want Packagename/module3/f2.py to use function1 under Packagename/module1/f1.py, your import statement should be from module1.f1 import function1. And because it is a way to import other folders, you need to specify the path at the beginning of the code (see the test case below)

Here are some test cases (take the git repo you provided as an example)

First we run the code (f2.py) without using pip to install Packagename in a virtual environment

enter image description here

We will get ModuleNotFoundError:... error because python cannot import functions under different folders at this point.

Then create a virtual environment and use the command pip install . to install Packagename in the virtual environment. (Running f2.py now does what is happening in your question)

In order to more clearly show which function1 is used in f2.py, I made the following modifications to the function1 in the two files.

Packagename\module1\f1.py

def function1(x, y):
    print(x * y)

v\Lib\site-packages\Packagename\module1\f1.py

def function1(x, y):
    print(x + y)

Now, run f2.py and get the addition result. So obviously it's using function1 in the virtual environment

enter image description here

How can I make it use function1 under Packagename/module1/f1.py in this case?

Use the sys.path.append() method to specify the path at the beginning of the code

import sys
sys.path.append("./Packagename")
from module1.f1 import function1
function1(2,3)

enter image description here

Get the multiplication result

Note: use the import method above. If you use the import method of from Packagename.module1.f1 import function1, even if the path is specified above the code, python will first use the package installed in the virtual environment.

enter image description here

If your virtual environment does not have the Packagename package installed, the from Packagename.module1.f1 import function1 import method is available.

Original code without virtual environment installed enter image description here

Uninstall Packagename in the virtual environment enter image description here

JialeDu
  • 6,021
  • 2
  • 5
  • 24
  • Thanks for the great answer! Is there a way to add the `import sys; sys.path.append("./")` in some way to the launch.json. Basically, allowing me to debug my whole package without having to add those two lines on every file during development, and then remove it in every file for production - Ultimately "simulating" an installed package. – Andy Parzyszek Sep 30 '22 at 13:24
0

Thank you @JialeDu for pointing me in the right direction.

The solution i was looking for can be found in this post: Visual Studio Code - How to add multiple paths to python path?

Solution

Answer to this problem is to remove the package from the Libary like stated below by @JialeDu and update the launch.json file. Update the launch.json file to:

{
    // 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",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal",
            "cwd": "${workspaceFolder}",    //  <- THIS NEEDS TO BE 'workspaceFolder'
            "justMyCode":false,
            // add env
            "env": {
                "PYTHONPATH": "./"  // <- this is Equivalent to 'import sys; sys.path.append("./")'
            }
        }
    ]
}

Setting up launch.json this way gives you access to all the modules in your Workspace directory.