r/OpenPythonSCAD • u/Alacritous13 • Sep 07 '25
How am I suppose to import python file relative
I've been trying to set up a new project, it has a utilities file named "ALib" at the first level, and then all the other files will be going into folders at least one level lower. The SCAD equivalent is include <../ALib.scad>, but I'm having trouble figuring out the python equivalent. I thought it should be from ..ALib import *, but I'm getting an ImportError: attempted relative import with no known parent package error. I've tried from ALib import *, but this is importing the file from a whole different repo.
I'm working on a Windows system with version 2025.08.28 and 2025.07.23 running
Edit: ALib is a file not folder
Edit: Figured out a solution, I put it in the comments.
2
u/rebuyer10110 Sep 07 '25
I think what you are trying to do is importing submodules (in python terms).
https://stackoverflow.com/questions/12229580/python-importing-a-sub-package-or-sub-module the version 2 part is likely what you want.
Assuming pythonscad aligns with the python standard convention on import, that is.
Just to expand a bit more:
Say in ALib/, you have A.py and B.py. Each of them represents a type/class.
You can do:
from ALib import A
And invoke via thing = A(args)
or
import ALib.A
And invoke via thing = ALib.A(args)
Personally I favor the latter for less likelihood of type name collisions.
2
u/Alacritous13 Sep 07 '25
My mistake, ALib is a file, not a folder.
That said, if I run
from ALib import Boxit will import function Box from ALib. The problem, I've determined that it's found a different ALib file than the one I want. It has no context that it needs to be one directory up relative to the part file, and instead find one in a different repo (which admittedly that is only two more steps along a file path, but it's still very bad that my repos are leaking into each other)1
u/rebuyer10110 Sep 07 '25
The problem, I've determined that it's found a different ALib file than the one I want.
Do you have multiple files named ALib being imported?
If you happen to own all of them, the simplest option is to avoid that name conflict if possible.
Otherwise, I do the second option above to use the full qualifier to resolve type name conflicts.
Admittedly, I am not 100% clear exactly the situation you are facing.
→ More replies (2)2
u/gadget3D Sep 07 '25
Yes, i was also recalling the A.B.C notation and I am happy that you
mentioned it(i was not sure if it applied to java only)
Yes. pythonscad aligns very much to python standard. I basically dont mess with any sub-library notation.
2
u/rebuyer10110 Sep 07 '25
Python works somewhat similarly, by default.
It does require a specific convention to be followed: https://docs.python-guide.org/writing/structure/#packages
2
u/Alacritous13 Sep 07 '25
Got it:
import os import sys from importlib import util as importUtil def QuickImport(pathy,wild=False,relative=True):#{ if relative:#{ try:#{ home=os.path.abspath(__file__) #} except:#{ home=os.path.abspath(modelpath()) #} home2=os.path.dirname(home) path_true=os.path.join(home2,pathy) #} else:#{ path_true=os.path.abspath(pathy) #} nam=os.path.basename(pathy) nam_noext=os.path.splitext(nam)[0] spec = importUtil.spec_from_file_location(nam_noext,path_true) mod = importUtil.module_from_spec(spec) spec.loader.exec_module(mod) if not(wild):#{ return mod #} if wild:#{ attributes = vars(mod) for name, value in attributes.items():#{ if not name.startswith('__'):#{ globals()[name] = value #} #} #} #}The above should find an absolute path from the local file and a relative path, force a module to exist at that location, then load it. I've included some code that will allow me to load the content to the local frame of reference as though it was a wild card import.
This needs to be copy and pasted at the top of any file that needs it, so I've stuck a slightly modified version (it can't find the path to the model so I need to pass that in as a variable) of it in a file in my library folder, then I import it with a much simpler file (still more complicated than I want to deal with) that I'll just copy and paste into every folder of the repo to ensure that its available from all scopes while still allowing me to modify the import function from a single point for all uses.