Python Forum

Full Version: Python 3.12 cannot import local python files as modules
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3
On a recent installation of Windows 10 I installed Python 3.12, things seemed to be working fine until I had difficulties importing other files. Which was weird considering I had no difficulties doing this on my Linux computer earlier. I thought maybe I was misremembering so I looked up some tutorials online and tried following them but still no luck.
Eventually I resorted to uninstalling Python 3.12 and downgrading to 3.11 to see if that was the issue. Lo and behold, I had no difficulties importing the files. I'm not sure what's causing this. If it's an issue on my computer; uninstalling, reinstalling & repairing does not seem to make any difference on the issue.

To be clear, here is my file structure and the statement I am using to load the module:
/ Project
| / foo
| | - bar.py
| - main.py (The file being executed)
Where "Project" is the root directory of the project, and where the command prompt is located. Likewise, "foo" is the folder containing my module "bar".

Here is my import statement, which works in 3.11 but not 3.12:
from foo import bar;
And from this the only output I get is a ModuleNotFoundError, specifically for foo.

Any ideas? I feel like this is really obvious and I'm just out of the loop
Try to add an empty __init__.py file in directory foo/
(Jul-25-2024, 07:57 AM)Gribouillis Wrote: [ -> ]Try to add an empty __init__.py file in directory foo/

I also tried this. It works on 3.11 without the empty init file, so it would be very odd if 3.12 required that. As well as trying that I also tried moving bar.py to the project root directory and then tried import bar. Neither worked. I even double checked using the os.path builtin module to make sure python was running in the correct directory.
In main.py, just before from foo import bar, add temporarily the statements
import sys
raise RuntimeError(sys.path)
and post the output here
A package most always be in sys.path,this is the first place Python look.
Test with Python 3.12 interpreter,not 3.11.
>>> import sys
>>> sys.path
['', 'C:\\python312\\Scripts\\ptpython.exe', 'G:\\Projects',.....
Can add one time like this.
import sys
sys.path.append('/path/to/Project')
As you see i have now Projects folder in sys.path.
Project/
├── __init__.py
├── foo/
│   └── bar.py
└── main.py
No __init__.py is needed after:
Quote:From Python 3.3+ supports Implicit Namespace Packages that allows to create a package without an __init__.py file.
But i always have one __init__.py under Prospect folder with content to bind package together and lift sub modules.
This make it easier to use the package.
__init__.py:
from . import main
from .foo import bar
Teste package.
>>> import Projects
>>>
>>> Projects.bar.answer_to_life()
42
>>> Projects.main.main_func()
'Now in main func'
Or import like this,see how easy import is now.
>>> from Projects import bar, main
>>>
>>> bar.answer_to_life()
42
>>> main.main_func()
'Now in main func' 
The two files is just this.
main.py:
def main_func():
    return 'Now in main func'
bar.py:
def answer_to_life():
    return 42
(Jul-25-2024, 08:28 AM)Gribouillis Wrote: [ -> ]In main.py, just before from foo import bar, add temporarily the statements
import sys
raise RuntimeError(sys.path)
and post the output here
Traceback (most recent call last):
File "C:\Users\briar\Documents\code\Project\main.py", line 2, in <module>
raise RuntimeError(sys.path) RuntimeError: ['C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python312\\python312.zip', 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python312', 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python312\\Lib', 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages']

(Jul-25-2024, 03:34 PM)snippsat Wrote: [ -> ]A package most always be in sys.path,this is the first place Python look.
Test with Python 3.12 interpreter,not 3.11.
>>> import sys
>>> sys.path
['', 'C:\\python312\\Scripts\\ptpython.exe', 'G:\\Projects',.....
Can add one time like this.
import sys
sys.path.append('/path/to/Project')

This has been the only thing thus far that has fixed the ModuleNotFoundError exception, but it feels kind of hacky and cumbersome to have to specify to Python the directory that I want to import and add it to sys.path. Is there any way to have Python figure this out without having to append to the sys.path manually? Otherwise I'm probably just going to stick with 3.11 which seems to have no problem doing so.
(Jul-26-2024, 04:52 PM)sunflowerdog Wrote: [ -> ]Otherwise I'm probably just going to stick with 3.11 which seems to have no problem doing so.
The strange thing is that the path to your project is not in sys.path when you run main.py. Can you compare with the sys.path that is printed in Python 3.11 ?
Quote:The strange thing is that the path to your project is not in sys.path when you run main.py. Can you compare with the sys.path that is printed in Python 3.11 ?


RuntimeError: ['C:\\Users\\user\\Documents\\code\\Project', 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python311\\python311.zip', 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python311\\DLLs', 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python311\\Lib', 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python311', 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages']

Yeah, I'm not sure why Python 3.11 is adding my project folder to sys.path but 3.12 isn't? To be clear, every time I switch between the two I am uninstalling the current version and then reinstalling the other version, so theoretically each is a fresh installation of Python. But this is odd behavior for a "fresh" installation, maybe it's possible there is some corrupted file somewhere that isn't getting deleted/reinstalled? I have no idea.
If just understand how stuff work with sys.path then this will never be a problem again.
To take a little about this 3 ways.
1.
Environment Variables Path can add folders here permanently to path,
see example under both version find same folders(use PYTHONPATH or just add folders to Path).
G:\div_code
λ py -3.11
Python 3.11.3 (tags/v3.11.3:f3909b8, Apr  4 2023, 23:49:59) [MSC v.1934 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['', 'G:\\Projects', 'G:\\div_code', 'C:\\Python311\\python311.zip', .....]
>>> exit()

G:\div_code
λ py
Python 3.12.2 (tags/v3.12.2:6abddd9, Feb  6 2024, 21:26:36) [MSC v.1937 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['', 'G:\\Projects', 'G:\\div_code', 'C:\\Python312\\python312.zip', .....]
>>> exit()

# Can list python version installed,for me is a long list her some
G:\div_code
λ py --list
-V:3.12          Python 3.12 (64-bit)
 -V:3.11          Python 3.11 (64-bit)
 -V:3.9           Python 3.9 (64-bit)
 -V:3.8           Python 3.8 (64-bit)
....
 -V:ContinuumAnalytics/Anaconda37-64 Anaconda 4.7.12
 -V:ContinuumAnalytics/Anaconda36-32 Anaconda 4.3.14
2.
Look at this post where use site module to add permanently to path.

3.
Virtual environment.
G:\div_code
λ python -m venv project_env

G:\div_code
λ cd project_env\

G:\div_code\project_env
λ G:\div_code\project_env\Scripts\activate.bat

G:\div_code\project_env
(project_env) λ
Now i can just copy folder/files from Project used before,then no path problems as Virtual environment add folder to sys.path automatic,.
G:\div_code\project_env
(project_env) λ python
Python 3.12.2 (tags/v3.12.2:6abddd9, Feb  6 2024, 21:26:36) [MSC v.1937 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from project_env import bar, main
>>>
>>> bar.answer_to_life()
42
>>> main.main_func()
'Now in main func' 
(Jul-26-2024, 05:11 PM)sunflowerdog Wrote: [ -> ]Yeah, I'm not sure why Python 3.11 is adding my project folder to sys.path but 3.12 isn't?
I don't understand it either. It may be a Windows-specific issue but I never use the Windows OS.

It is not very satisfactory but you could add the following lines in your sitecustomize or your usercustomize module to force the inclusion of the main script's directory in sys.path

from pathlib import Path
import sys

if sys.argv:
    sys.path.insert(0, str(Path(sys.argv[0]).resolve().parent))
Pages: 1 2 3