Module inside module error, python - python

I created a File named StringPlay.py, and called it upon a file ScanTheFile.py then called a function in ScanTheFile.py in another file named Controller.py. But it raise an error that StringPlay.py does not exist
In ScanTheFile.py
import StringPlay as SP
def TNews(FileFirstLine):
FileLine = SP.RemoveSpases(FileFirstLine)
if True:
Statement
return(FileLine)
In Controller.py
from HelpFiles import StringPlay as SP
from HelpFiles import ScanTheFile as StF
File1 = open("TextFiles\File1.txt")
print(Stf.TNews(File1.readline()))
When this is executed it raises a Message Stating that in ScanTheFile.py in Line 1:
File "C:\Users\***\My Documents\Python\HelpFiles\ScanTheFile.py", line 1, in <module>
import StringPlay as SP
ImportError: No module named 'StringPlay'
But when ScanTheFile.py is being executed there's no problem.
This is my directory structure
My Documents\Python
My Documents\Python\Controller.py
My Documents\Python\HelpFiles
My Documents\Python\HelpFiles\ScanTheFile.py
My Documents\Python\HelpFiles\StringPlay.py
My Documents\Python\TextFiles
My Documents\Python\TextFiles\File1.txt
My Documents\Python\TextFiles\File2.txt

You are having this problem because when you run Controller.py you are running it in say C:\...\My Documents when you call from HelpFiles import ScanTheFile as StF you are telling python to look in C:\...\My Documents\HelpFiles for a file named ScanTheFile.py.
It finds this file and runs it in C:\...\My Documents so when it hits the line in ScanTheFile.py:
import StringPlay as SP
it looks in C:\...\My Documents for StringPlay.py which from what I can gather exists in C:\...\My Documents\HelpFiles.
Since you are already importing StringPlay.py explicitly in Controller.py I would say just change ScanTheFile.py to only import StringPlay.py when it is the file being run directly, and not imported:
ScanTheFile.py
if __name__ == "__main__":
import StringPlay as SP
def TNews(FileFirstLine):
FileLine = SP.RemoveSpases(FileFirstLine)
if True:
Statement
return(FileLine)

You are importing from HelpFiles which is basically a folder not a file. To put it simply, in python if you want to import something from a folder, it has to be a package unless you add the path to the folder to python path explicitly.
So, to solve the problem you are having make HelpFiles a package by putting an empty file with name __init__.py in that folder which should look something like this
.
└── My Document
└── Python
├── Controller.py
├── HelpFiles
│   ├── __init__.py
│   ├── ScanTheFile.py
│   └── StringPlay.py
└── TextFiles
├── File1.txt
└── File2.txt

Related

Impossible to import a package I made. "ModuleNotFoundError"

I have a project organized like so :
application
├── app
│ └── package
└── __init__.py
│ └── functions.py
└── app2
└── some_folder
└── file_2.py
My "functions.py" contains a basic function:
#functions.py
def add(x,y):
return x+y
The file "_init_.py" is empty
I want to use the "add" function in my "file_2.py" file, so I write:
#file_2.py
from application.app.package.functions import add
print(add(2,3))
But it returns an error message:
ModuleNotFoundError: No module named 'application'
it is the same if i try any of these:
from app.package.functions import add
from package.functions import add
from functions import add
Does anyone know where the problem comes from? I'm doing exactly like in this tutorial so I don't understand what's wrong
tutorial's link
Thank you for your help
One way to import functions.add is to import sys and use sys.path.insert()
after that you can import add from functions:
import sys
sys.path.insert(1, 'the/local/path/to/package')
from functions import add
print(add(1,2))

ModuleNotFoundError: No module named

I know that this topic has been dealt with many times already, and I have read all the answers and it seems that I did it right. but I don't understand what is wrong.
python_project:
Chronos
├── extractionScripts
│ ├── __init__.py
│ └── peps.py
└── helperfunctions
├── __init__.py
└── generallHelper.py
└── pos.py
└── logging.py
I have two folders (extractionScripts and helperFunctions).
when I try to import modules from the helperFunctions into the peps.py , I get the error -
from helperFunctions.invoiceHeader import *
ModuleNotFoundError: No module named 'helperFunctions'
peps.py
import re
import sys
print (sys.path)
from helperFunctions.generallHelper import *
from helperFunctions.pos import *
from helperFunctions.logging import *
print (sys.path) shows
['C:\\Users\\djoni\\Desktop\\Sixt\\Chronos\\extractionScripts', 'C:\\Users\\djoni\\Desktop\\Sixt\\Chronos\\helperFunctions', 'C:\\Users\\djoni\\AppData\\Local\\Programs\\Python\\Python310\\python310.zip', 'C:\\Users\\djoni\\AppData\\Local\\Programs\\Python\\Python310\\DLLs', 'C:\\Users\\djoni\\AppData\\Local\\Programs\\Python\\Python310\\lib', 'C:\\Users\\djoni\\AppData\\Local\\Programs\\Python\\Python310', 'C:\\Users\\djoni\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages']
in other topics they wrote that there should be an init file, or the path should be added to the sys file, but I have them.
When you import any module in Python , Python search in the sys.path list that has all modules
have a look in your sys.path you won't see the Chronos File so in the file you try to import in it put this
import sys
from pathlib import Path
path_to_Chronos = Path(__file__).parent.parent
print(path_to_Chronos ) # Check this Right
sys.path.append(path_to_Chronos)
# then import and you will find it works
Pro Check your names
this is how you want to import it
from helperFunctions.generallHelper import *
from helperFunctions.pos import *
from helperFunctions.logging import *
but Do you see how you name it
└── helperfunctions
├── __init__.py
└── generallHelper.py
└── pos.py
└── logging.py
F it is the Problem ...

pdoc3 or Sphinx for directory with nested module

My code directory looks like below. I need to generate documentation for all the modules like for sub1,sub2,submoduleA1,submoduleB1 and so on.
Also as shown for submoduleB2.py: all the modules imports from other modules/submodules
<workspace>
└── toolbox (main folder)
├── __init__.py
│
├── sub
│ ├── __init__.py
│ ├── sub1.py
│ └── sub2.py
│
├── subpackageA
│ ├── __init__.py
│ ├── submoduleA1.py
│ └── submoduleA2.py
│
└── subpackageB
├── __init__.py
├── submoduleB1.py
└── submoduleB2.py code[from sub import sub1
from subpackageA import submoduleA2 and so on]
code structure for submoduleB2.py
from __future__ import absolute_import, division
import copy
import logging
import numpy as np
import pandas as pd
from dc.dc import DataCleaning
from sub.sub1 import ToolboxLogger
from subpackageA import pan
LOGGER = ToolboxLogger(
"MATH_FUNCTIONS", enableconsolelog=True, enablefilelog=False, loglevel=logging.DEBUG
).logger
"""
Calculations also take into account units of the tags that are passed in
"""
def spread(tag_list):
"""
Returns the spread of a set of actual tag values
:param tag_list: List of tag objects
:type tag_list: list
:return: Pandas Series of spreads
:rtype: Pandas Series
:example:
>>> tag_list = [tp.RH1_ogt_1,
tp.RH1_ogt_2,
tp.RH1_ogt_3,
tp.RH1_ogt_4,
tp.RH1_ogt_5,
tp.RH1_ogt_6]
>>> spread = pan.spread(tag_list)
"""
# use the same units for everything
units_to_use = tag_list[0].units
idxs = tag_list[0].actuals.index
spread_df = pd.DataFrame(index=idxs)
spread_series = spread_df.max(axis=1).copy()
return Q_(spread_series, units_to_use)
I tried to run the pdoc command using anaconda prompt by navigating it to the toolbox folder and executed the below command
pdoc --html --external-links --all-submodules preprocess/toolbox/subpackageA
after executing this command a "subpackageA" folder was created under toolbox with index.html file but it was all blank
Then i tried to generate documentation by providing specific module name
pdoc --html --external-links --all-submodules preprocess/toolbox/submoduleB2.py
but received this below error:
File "C:\Users\preprocess/toolbox/submoduleB2.py", line 16, in
from sub import sub1
ImportError: No module named sub.sub1
Can you please tell me how to generate the documentation using pdoc for complete directory?
Or is there any other package which will auto generate the documentation?
I even tried Sphnix, but faced issues in adding the module/submodule paths in config file
It appears that pdoc3 is throwing that kind of error for a module if it cannot find an import into that module in the python path. One solution is to put
import os, sys
syspath = os.path.dirname(os.path.abspath(__file__))
sys.path.append(path)
into the __init__.py files in each of the subdirectories.

How can I get module name automatically from __init__.py or conftest.py?

I am running multiple tests in a tests package, and I want to print each module name in the package, without duplicating code.
So, I wanted to insert some code to __init__.py or conftest.py that will give me the executing module name.
Let's say my test modules are called: checker1, checker2, etc...
My directory structure is like this:
tests_dir/
├── __init__.py
├── conftest.py
├── checker1
├── checker2
└── checker3
So, inside __init__.py I tried inserting:
def module_name():
return os.path.splitext(__file__)[0]
But it still gives me __init__.py from each file when I call it.
I also tried using a fixture inside conftest.py, like:
#pytest.fixture(scope='module')
def module_name(request):
return request.node.name
But it seems as if I still need to define a function inside each module to get module_name as a parameter.
What is the best method of getting this to work?
Edit:
In the end, what I did is explained here:
conftest.py
#pytest.fixture(scope='module', autouse=True)
def module_name(request):
return request.node.name
example for a test file with a test function. The same needs to be added to each file and every function:
checker1.py
from conftest import *
def test_columns(expected_res, actual_res, module_name):
expected_cols = expected_res.columns
actual_cols = actual_res.columns
val = expected_cols.difference(actual_cols) # verify all expected cols are in actual_cols
if not val.empty:
log.error('[{}]: Expected columns are missing: {}'.format(module_name, val.values))
assert val.empty
Notice the module_name fixture I added to the function's parameters.
expected_res and actual_res are pandas Dataframes from excel file.
log is a Logger object from logging package
In each module (checker1, checker2, checker3, conftest.py), in the main function, execute
print(__name__)
When the __init__.py file imports those packages, it should print the module name along with it.
Based on your comment, you can perhaps modify the behaviour in the __init__.py file for local imports.
__init.py__
import sys, os
sys.path.append(os.path.split(__file__)[0])
def my_import(module):
print("Module name is {}".format(module))
exec("import {}".format(module))
testerfn.py
print(__name__)
print("Test")
Directory structure
tests_dir/
├── __init__.py
└── testerfn.py
Command to test
import tests_dir
tests_dir.my_import("testerfn")

How to access the current executing module's attributes from other modules?

I have several 'app'-modules (which are being started by a main-application)
and a utility module with some functionality:
my_utility/
├── __init__.py
└── __main__.py
apps/
├── app1/
│ ├── __init__.py
│ └── __main__.py
├── app2/
│ ├── __init__.py
│ └── __main__.py
...
main_app.py
The apps are being started like this (by the main application):
python3 -m <app-name>
I need to provide some meta information (tied to the module) about each app which is readable by the main_app and the apps themselves:
apps/app1/__init__.py:
meta_info = {'min_platform_version': '1.0',
'logger_name': 'mm1'}
... and use it like this:
apps/app1/__main__.py:
from my_utility import handle_meta_info
# does something with meta_info (checking, etc.)
handle_meta_info()
main_app.py:
mod = importlib.import_module('app1')
meta_inf = getattr(mod, 'meta_info')
do_something(meta_inf)
The Problem
I don't know how to access meta_info from within the apps. I know I can
import the module itself and access meta_info:
apps/app1/__main__.py:
import app1
do_something(app1.meta_info)
But this is only possible if I know the name of the module. From inside another module - e.g. my_utility I don't know how to access the module which has been started in the first place (or it's name).
my_utility/__main__.py:
def handle_meta_info():
import MAIN_MODULE <-- don't know, what to import here
do_something(MAIN_MODULE.meta_info)
In other words
I don't know how to access meta_info from within an app's process (being started via python3 -m <name> but from another module which does not know the name of the 'root' module which has been started
Approaches
Always provide the module name when calling meta-info-functions (bad, because it's verbose and redundant)
from my_utility import handle_meta_info
handle_meta_info('app1')
add meta_info to __builtins__ (generally bad to pollute global space)
Parse the command line (ugly)
Analyze the call stack on import my_utility (dangerous, ugly)
The solution I'd like to see
It would be nice to be able to either access the "main" modules global space OR know it's name (to import)
my_utility/__main__.py:
def handle_meta_info():
do_something(__main_module__.meta_info)
OR
def handle_meta_info():
if process_has_been_started_as_module():
mod = importlib.import_module(name_of_main_module())
meta_inf = getattr(mod, 'meta_info')
do_something(meta_inf)
Any ideas?
My current (bloody) solution:
Inside my_utility I use psutil to get the command line the module has been started with (why not sys.argv? Because). There I extract the module name. This way I attach the desired meta information to my_utility (so I have to load it only once).
my_utility/__init__.py:
def __get_executed_modules_meta_info__() -> dict:
def get_executed_module_name()
from psutil import Process
from os import getpid
_cmdline = Process(getpid()).cmdline
try:
# normal case: app has been started via 'python3 -m <app>'
return _cmdline[_cmdline.index('-m') + 1]
except ValueError:
return None
from importlib import import_module
try:
_main_module = import_module(get_module_name())
return import_module(get_executed_module_name()).meta_info
except AttributeError:
return {}
__executed_modules_meta_info__ = __get_executed_modules_meta_info__()

Categories