skip to Main Content

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

2

Answers


  1. Chosen as BEST ANSWER

    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.


  2. 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.

    Packagenamemodule1f1.py

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

    vLibsite-packagesPackagenamemodule1f1.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

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search