Full path to import works but file reference doesn't - python

Looking at this behave tutorial I find that in file features/steps/step_tutorial06.py, if I use from company_model import CompanyModel as is in the example I get Unresolved reference 'company_model' but if I use from features.steps.company_model import CompanyModel it works. Why is this and is there any way around this?
This is in PyCharm.

It's called a Relative import. This is because PyCharm launches python from Project directory and not from the directory you are working in.
However, to get rid of this long from features.steps.company_model import CompanyModel, you can use from .company_model import CompanyModel since both files are in same directory.

because project structure starts from the folder features in pycharm. Hence it is appearing in that format.

Related

VS Code throws ModuleNotFoundError despite folder available

I'm working on creating a Python/PySpark library using VS Code. My goal is to debug in VS Code and create a .whl package to be installed in a Databricks cluster. I face the following situations:
if I use from checkenginelib.pysparkdq._constraints._Constraint import _Constraint I get a ModuleNotFoundError in VS Code and a module not found error in Databricks
if I use from pysparkdq._constraints._Constraint import _Constraint I get a ModuleNotFoundError in VS Code but all imports work well in Databricks
if I use from _constraints._Constraint import _Constraint I get no error in VS Code but I get a module not found error in Databricks
Because your module dqengine is not in the top level folder, it is probably not in your PYTHONPATH variable, which VSCode has probably added the path to DATA QUALITY ENGINE
Either:
Move it to the top level folder (Data quality engine)
add the path to check_engine_lib to PYTHONPATH.
Or as #franjefriten says, add an __init__ to check-engine-lib and do
from check-engine-lib.dqengine.validate_df import *
From what I see, you are working in ./DATA-QUALITY-ENGINE/check-engine-lib/dqengine/validate_df. You have to import it the following way:
from check-engine-lib.dqengine.validate_df import *
That should work. Also you need to create a \__init__.py file to import other files as modules
As the comment said, when the method you need to import is in the same directory as the current file, you only need to import it directly.
from validate_df import _Constraint

Python is not looking at current directory for imports, which is causing issues for generated protobuf files

In my project, no matter where I am or where the file I'm trying to import from is in, I have to specify the path, which is fine.
Ex: import protos.example as example, even when I'm already in the protos directory. So when the generated files are made, they naturally just say import example_pb2 as example__pb2, but with the way it is forcing me to put the full path, that natural way of generating doesn't work because it has to be import protos.generated.example_pb2.
How can I change this to where it automatically searches the current directory before needing to specify the location?
Found the fix. I'm using Pycharm , not sure how this works in other IDEs. Right click the folder that has the generated files and mark it as sources. That solves the generated files not being able to see each other. Then in any file where you reference the generated files, put
import sys
sys.path.append(r'generated')
and then your imports should work as expected

How can I import python custom class in Anaconda (Jupyter notebook)

I don't manage to find how import custom class in Python with the Jupyter notebook in anaconda.
In my work folder I have a file 'user.ipynb' that contains a class name User. In an other file in the same folder, I try to import this class with : from user import User.
I get this error: ImportError: No module named user.
I tried to create a file ' _ _init__.py' and _ _init__.ipynb in this folder but it doesn't work.
Do you know how I could do this ?
Thank you in advance
Python modules are either files named *.py or directories with an __init__.py in them. user.ipynb is neither, it's an IPython (Jupyter) notebook, so it is not a module and you can't import it.
The easiest way to get this to work is to convert the notebook to a .py file (this can be done using the export function) and then you'll be able to import it.
An alternative is to provide code that lets you import notebooks directly; such code is available here. Looks like a lot of bother, though. I'm not sure why they didn't just bake this in; it seems like it would be useful.

How to call a python file, that needs to import packages?

I'm following a tutorial to call python code from a C++ program from the python docs.
Everything works just fine when trying to call the multiply example. Now if I add a line to the python source code importing a library, lets say openpyxl,
from openpyxl import load_workbook
I receive an error from python
ImportError: No module named openpyxl
I thought if I import a system library, I wouldn't have any problems, but I also get an error if I try to import datetime.
I don't have any error if I import the file from the python console. The openpyxl library is installed in my system.
So my question is: how to import python source code that needs to import packages?
EDIT: Ok, I forgot to mention something, I have not been completely honest with you guys, I'm sorry.
Trying to run the example I run into a problem: I couldn't make python found my multiply.py file, and the line PyImport_Import always return null.
My solution was to add the path in which I knew my python source was by using PySys_SetPath. The problem is that I just realized that this function doesn't append a new directory, it just overwrites the PYTHONPATH. So now python can find multiply.py, but absolutly anything else.
Of course I've deleted that line but now I have another question, why does python can't find my source if the file is just in the same directory of the C++ compiled program?
The I realized that my sys.path from my python console was a little different from the path showed in my embedded python: the first one had at the beginning of the list an empty string ''. I'm not a python expert, but when I add that line to my path I could import the multiply.py so it seems that was the reason I couldn't import modules that were located to relative to my executable was the missing of this empty path -but still don't know what it means-.
I have to thank to #paul-evans who give me the idea of adding the path to find my files.
This is what PYTHONPATH is for. You can set it as an environment variable containing a list module directories, or in the code itself something like:
import sys
sys.path.append("path/to/openpyxl/module")

Calling modules in python

So Im a beginner to python/programming and came upon this code in a tutorial, which Im having trouble understanding.
from pythonds.basic.stack import Stack
What I did was , I went to the site-packages folder in my python directory (which holds all modules). There I could find the directory structure to be : -
pythonds/basic/stack.py
The file stack.py has a "class Stack" inside it.
So am I correct in interpreting/relating the import command to this directory structure ?
Also , whenever such a long chaining of modules happen in python, can it always be understood in such a manner.
In command line, you can do like this:
C:\Python27\Lib>pip intall pythonds
Then this module can work.
Not all the time.
It's probably better to not try and compare the directory structure with the module path, unless you have to debug modules or install them manually.
Sometimes, your PYTHONPATH will be extended to include subdirectories in site-packages, and then there'll be an extra subdirectory.
Other times, there can be an __init__.py file in the pythonds/basic/ directory (there likely is), that can contain
from .stack import Stack
in which case the import path could be
from pythonds.basic import Stack
Your understanding is right.
import pythonds.basic.stack
This will make all the classes in the module accessible by your script. Whereas,
from pythonds.basic.stack import Stack
will make only the Stack class accessible by your script.

Categories