Miguel Rodríguez
Miguel Rodríguez

Reputation: 39

How to fix ModuleNotFoundError in Python with Visual Studio Code

I'm developing a basic manager of students' degrees for learning Python, also I'm coding in VS Code and with python 3.7.3 enviroment.

I have created a package named clases inside of which are __init__.py and NotaParcial.py files, inside NotaParcial.py is just one class named NotaParcial too.

The problem appears when I try to use the class from other package using the syntax form clases.NotaParcial import *

I have tried already put an __init__.py file in the package.

The error message is:

Exception has occurred: ModuleNotFoundError
No module named 'clases'
  File "C:\Users\Usuario\OneDrive\Ingenieria\Semestre 3\Parcial 1\Modelamiento de software\Tareas\PySAcademico\prueba\prueba.py", line 1, in <module>
    from clases.moduloNotaParcial import NotaParcial
  File "C:\Users\Usuario\AppData\Local\Programs\Python\Python37\Lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Users\Usuario\AppData\Local\Programs\Python\Python37\Lib\runpy.py", line 96, in _run_module_code
    mod_name, mod_spec, pkg_name, script_name)
  File "C:\Users\Usuario\AppData\Local\Programs\Python\Python37\Lib\runpy.py", line 263, in run_path
    pkg_name=pkg_name, script_name=fname)

I've tried to call the class from a file located in a superior path of the package and it works. I've tried use Visual Studio 2017 Community to repeat the process and in that IDE, it works and the problem doesn't appear.

Upvotes: 2

Views: 19772

Answers (4)

Neha Duggirala
Neha Duggirala

Reputation: 51

I found the following article which has a detailed explanation how to fix this in VSCode:

Python Relative Imports in VSCode

  1. To fix ModuleNotFoundError add launch.json.
  2. To fix auto-completion add settings.json.

.vscode/launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Module",
            "type": "python",
            "request": "launch",
            "module": "my_code.main",
            "env": {"PYTHONPATH": "${workspaceFolder}/libs/"}
        }
    ]
}

.vscode/settings.json

{
    "python.analysis.extraPaths": ["${workspaceFolder}/libs/"]
}

Upvotes: 0

FrankyHollywood
FrankyHollywood

Reputation: 1773

In order to debug main.py VSCode needs to know explicit library paths. This can be done by setting the environment ('env') variable in launch.json. First step is create a 'launch.json' inside the .vscode folder.

/
├── .vscode/
│   └── launch.json
├── mySubdir/
│   └── myLib.py
└── main.py

If main.py wants to import myLib.py as module, VSCode can only do this if mySubDir is part of the Python path.

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Current File",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal",
            "cwd": "${fileDirname}",
            "env": {"PYTHONPATH": "${workspaceFolder}/mySubdir${pathSeparator}${env:PYTHONPATH}"},
        }
    ]
}

{workspaceFolder} and {pathSeparator} are predefined variables which will be substituted by VSCode.


edit: I noticed '{pathSeparator}' doesn't work well in Linux, so there I use ':' instead.

This thread gives a more extensive explanation: How to correctly set PYTHONPATH for Visual Studio Code


edit 2: If the problem occurs for an installed package do the following:

  1. find the package location

    $ python

    >>> import modulename

    >>> print(modulename.file)

  2. Once you know the location: Open settings (ctrl + ,) Search "pylance" or find it under "Extensions > Pylance" Find the "Extra Paths" config item Use "add item" to a add a path to the parent folder of the module (for example '/home/dev/miniconda3/lib/python3.12/site-packages')

  3. Add the parent path to the python section in launch.json, for example:

    "env": { "PYTHONPATH": "/home/dev/miniconda3/lib/python3.12/site-packages" }

Upvotes: 2

YetAnotherDuck
YetAnotherDuck

Reputation: 316

First things first, There is a guideline available which mentions about capitalizing here

I would recommend using a styleguide. It makes coding weirdly enough much easier.

Back to your class. There are multiple ways of writing a module and I would love to give you two different examples. One of them is to write a module like class which is basically a folder. Everything in that folder belongs to that class. This keeps everything together and depending on your file structure organized as well.

Imagine having the following file structure

  • someclass [folder]
    • __init__.py [file]
  • run.py [folder]

Note that someclass doesnt contain any capital letters which is important for the import in the run.py file. More about that later. You might be wondering what is in the __init__.py.

class NotaParcial(object):
    ... 

Note: The class name always starts with a capital letter. while coding it reminds you that you are working with a class object.

In order to import the NotaParcial class in our run.py we simple do:

from someclass import NotaParcial

The someclass after the from keyword represents the folder which you are importing from. the NotaParcial class is the class which is available in the __init__.py. The __init__.py initialized the folder its in as a module.

This works nice when working with setuptools if you create a package.

Now, lets imagine we have your situation, we would like to import a class from a file which is not named __init__.py. __init__.py is still required, more info here.

  • someclass [folder]
    • __init__.py [file] [EMPTY]
    • super_duper_scraper.py [file]
  • run.py [folder]

The __init__.py is empty which is enough for us, our example class moved to super_duper_scraper.py. In order to import the same class from the previous example you have to import it like this:

from someclass.super_duper_scraper import NotaParcial

When understanding this, you should be able to resolve your exception: Exception has occurred: ModuleNotFoundError No module named 'clases'

Upvotes: 1

youDaily
youDaily

Reputation: 1384

I think you just need remove the clases. from the import statement.

just like that,

from NotaParcial import *

Upvotes: 0

Related Questions