Importing module named same as package - python-3.x

I have ran into this so many times. Always struggle and forget. This time I ax. This is python3.
repo/
setup.py
abyss/
__init__.py
abyss.py
some.py
# abyss.py
from abyss import some
print(some.x)
# some.py
x = 2
when i run ./abyss/abyss.py I get
ImportError: cannot import name 'some' from 'abyss'

some.py is at the same level that abyss.py, so just using import some works.

Related

Problem with this "minimalistic" python packaging that has an import in source code

I'm not a programmer, and my audience/users are not programmers either. So I'm trying to have the most minimalistic setup for my python package. I liked this structure below, which is endorsed in this video:
python-mypackage/
└── src/
└── mypackage.py
The file mypackage.py:
import numpy as np
class myclass():
def __init__(self, var_a, var_b):
self.var_a = var_a
self.var_b = var_b
def mult(self):
return np.matmul(self.var_a, self.var_b)
When I build this with python setup.py bdist_wheel, with the setup.py:
from setuptools import setup
setup(
name='mypackage',
version='0.0.1',
description='Test package',
py_modules=["mypackage"],
package_dir={'': 'src'},
)
and install it with pip with pip install -e ., I get a NameError: name 'np' is not defined if I run
from mypackage import myclass
test = myclass([1,2], [3,4])
#Returns, NameError: name 'np' is not defined
But for a reason I don't understand, if I have mypackage.py:
import numpy as np
def mult(var_a, var_b):
return np.matmul(var_a, var_b)
And I build it and pip install it, the code below works:
from mypackage import mult
mult([1,2], [3,4])
#Returns 11
Is this behavior correct? Or do I have something funky in my installation? If it's normal, how do I correct the import failure of numpy in the class case (I know that if I do from mypackage import * will work, but I rather do the from mypackage import myclass)?
I'm sure there's maybe best programming practices with __init__.py and __main__.py files, but I rather stay away from them since I think they make the folder organization a little hard to follow for fellow non-programmers. But if there's no way around it without a __init__.py and/or __main__.py files, that would be good to know too.
I'm under the impression that this was an installation error of some sort. When I did a new environment and reinstalled everything, I was able to call myclass without error using from mypackage import myclass

Problem importing python file from folder above

I know theres heaps of questions and answers for this, I tried multitude stackoverflow links but none of these seem to help.
My project structure is:
volume_price_analysis/
README.md
TODO.md
build/
docs/
requirements.txt
setup.py
vpa/
__init__.py
database_worker.py
utils.py
test/
__init__.py
test_utils.py
input/
input_file.txt
I want to load utils.py inside test_utils.py
my test_utils.py is:
import unittest
import logging
import os
from .vpa import utils
class TestUtils(unittest.TestCase):
def test_read_file(self):
input_dir = os.path.join(os.path.join(os.getcwd()+"/test/input"))
file_name = "input_file.txt"
with open(os.path.join(input_dir+"/"+file_name)) as f:
file_contents = f.read()
f.close()
self.assertEqual(file_contents, "Hello World!\n")
if __name__ == '__main__':
unittest.main()
I want to run (say inside test folder):
python3 -m test_utils.py
I can not do that, I get a bunch of errors regarding imports of utils (tried many iterations of . , no ., from this import that etc.. etc..
Why is this so bloody complicated?
I am using Python 3.7 if that helps.
As per this answer, you can do it using importlib,
in spec = importlib.util.spec_from_file_location("module.name", "/path/to/file.py") ,instead of path/to/file, you can use ../utils.py. Also, since you are already importing a package named utils (from importlib), you should call one of them by other name, ie. dont keep module.name as utils or import importlib.utils as something else.
I figured it out, turns out python prefers you to run your code from top level folder, in my case volume_price_analysis folder, all I had to do was make a shell script that calls
python3 -m unittest vpa.test.test_utils
And inside test_utils I can import whatever I want as long as I remember that I am executing the code from main folder so loading utils.py would be
from vpa import utils inside test_utils

Python3 test folder import problems

Trying to write tests in Python3 with the folder structure
package/
__init.py__
Foo.py
Bar.py
test/
__init.py__
test_Foo.py
Foo.py
import Bar
test_Foo.py
import Foo
Running python3 -m unittest results in No module named Foo
If I changed it to
from package import Foo
It will resolve, but in Foo.py it'll have the error No module named 'Bar'
If I change Foo.py to
from package import Bar
The test will run without error, but running python3 Foo.py will result in No module named 'package'
I've gone through various answers about this kind of problems, like this one
Running unittest with typical test directory structure
and this
Python3 import modules from folder to another folder
and none of them address this issue
your project root (and also the working directory!) need to be the parent of package.
Then every import will be in the form import package.module or from package import module.
if you run python packgae/Foo.py or python -m package.Foo it should work.
Also take a look at pypa - sample project to see the recommended Python project structure.

python module import error - python-mode [VIM]

I am trying to import a module from another directory and run the script using python-mode. I am encountering, module not found error, but the module is present in the location and my sys.path shows the module path has been added successfully. I am having hard time troubleshooting/fixing. Could some one shed some light on this?
import numpy as np
import sys
sys.path.append('./extnsn/')
from extnsn import FX
The error stack is:
Feat/mFeat/feat_Xt_v2.py|7 error| in from
extnsn import FX ImportError: No module named 'extnsn'
My directory structure is:
Feat
|
|--mFeat
|
|--feat_Xt_v2.py
|
|--extnsn
|
|--__init__.py
|--FX.py
The extnsn directory has a __init__.py with the following:
from extnsn import FX
FX.py is the module name, for information.
sys.path contains the appended path as ./extnsn/ as the last entry in the list.
What makes me conclude this is not path issue is that, the program runs fine, if executed from atom with script plugin.
Any help is much appreciated.
EDIT:
This doesn't seem to be an issue with just python-mode, rather the way how vim invoke the python interpretor and execute the buffer. I tried with the following command without python-mode and the issue is the same.
To import a module or a package you have to add to sys.path its parent directory. In your case if you've added ./extnsn/ to sys.path you cannot import extnsn (it cannot be found in sys.path) but you can import FX directly:
import FX
But as FX seems to be a module in a package extnsn you better add to sys.path the parent directory of extnsn, i.e. Feat:
sys.path.append('../Feat')
from extnsn import FX

Importing submodules

I am new to python and i m having a really bad time to overcome a problem with the importing system.
Lets say i have the file system presented below:
/src
/src/main.py
/src/submodules/
/src/submodules/submodule.py
/src/submodules/subsubmodules
/src/submodules/subsubmodules/subsubmodule.py
All the folders (src, submodules, subsubmodules) have and empty __init__.py file.
In submodule.py i have:
from subsubmodules import subsubmodule
In main.py i have:
from submodules import submodule
When i run submodule.py python accepts the import. But when i run main.py python raises error for the import of subsubmodule.py because /src/submodules/subsubmodules/ folder is not in the path.
Only solution is to change the import of submodule.py to
from submodules.subsubmodules import subsubmodule
This seems to me as an awful solution because after that i cannot run submodule.py and i m sure that something else is the key to that.
An other solution is to add the following code to the __init__.py file:
import os
import sys
import inspect
cmd_subfolder = os.path.split(inspect.getfile(inspect.currentframe()))[0]
if cmd_subfolder not in sys.path:
sys.path.insert(0, cmd_subfolder)
Is there any way to do this using just the importing system of python and not other methods that do it manually using, for example sys.path or other modules like os, inspect etc..?
How can i import modules without caring about the modules they import?
You can run subsubmodule.py as
python3 -m submodule.subsubmodules.subsubmodule
If you want a shorter way to invoke it, you're free to add a shell or Python script for that on the top level of your package.
This is how imports work in Python 3; there are reasons for that.
You can avoid this issue by using sys.path in your program.
sys.path.insert(0, './lib')
import subsubmodule
For this code, you can put all your imports to a lib folder.
You can read the official documentation on Python packages where this is explained in depth.

Resources