Transcrypt icon indicating copy to clipboard operation
Transcrypt copied to clipboard

importing from the current source directory fails

Open warrenchopin opened this issue 5 years ago • 8 comments

Let's say you have two files in lib1/ directory

lib1/ code1.py code2.py

You can import something in code2.py from code1.py using '.' dotation notifying the current directory.

in code1.py:

from .code2 import Class2

But transcypt fails the import when it is executed in the top directory.

Error while compiling (offending file last): Import error, can't find any of:

So I have to modify all source files in subdirectory to import starting from the top directory. in code1.py:

from lib1.code2 import Class2

It makes source ugly when project size grows, and it requires a lot of work to modify source code whenever copying/moving/modifying directory. I hope that this bug is fixed soon.

Buy the way, please let me know if there is an easy way to go around this problem.

warrenchopin avatar Aug 27 '19 16:08 warrenchopin

So I created app.py which will be my entry point and a lib1 folder containing code1.py and code2.py.

app.py
lib1/
-- __init__.py
-- code1.py
-- code2.py

in code1.py:

from .code2 import Obj

class Code(Obj):
    pass

in code2.py

class Obj:
    pass

I then tried to import from lib1 in app.py:

from lib1.code1 import Code
o = Code()

It works fine with python 3.7, but fails in transcrypt, using transcrypt -n -b app:

Error while compiling (offending file last):
        File 'C:/Users/a.cox/Desktop/tmp/app.py', line 1, at import of:
        File 'lib1.code1', line 1, namely:

        Import error, can't find any of:
                C:/Users/a.cox/Desktop/tmp/code2/Obj.py
                C:/Users/a.cox/Desktop/tmp/code2/Obj.js

It seems transcrypt replaces relative import like .code2 to CurrentWorkingDirectoryPath/code2 instead of CurrentWorkingDirectoryPath/PathToPackage/code2.

It seems the only way for a package to have subpackages is if all the subpackage's modules use full references to the top most directory, references that will need to be updated if the package name changes or if it is used in another project as a lib (thus becoming a subpackage itself).

AlexECX avatar Aug 30 '19 17:08 AlexECX

To answer @warrenchopin's question, you could play around with the -xp argument. With the current example, I was able to compile using transcrypt -xp ./lib1 app. If you want to add another level and have from mypackage.lib1 import code1, you will have to:

  1. import code1 and code2 in lib1/__init__.py, as you would do in python:
#from . import code1, code2  <-- this won't work in transcrypt until relative import is fixed
import code1    #Use these instead
import code2
  1. Add your package's path, as well as the path of all the subpackages it uses, to the transcrypt command: C:\MyProject> transcrypt -xp ./MyPackagePath$./MyPackagePath/lib1 app

This will create something like this:

...
app.js
code1.js
code2.js
mypackage.lib1.js

where mypackage.lib1.js will import from code1.js and code2.js. It should work, but ideally -xp shouldn't be needed and transcrypt should generate mypackage.lib1.code1.js and mypackage.lib1.code2.js, preventing name clashes for modules of the same name in different packages.

AlexECX avatar Aug 30 '19 18:08 AlexECX

Transcrypt seems to have massive problems finding modules. I am unable to import functools because it has several submodules. I tried to work around this by using cachetools from pip, but it also falls afoul of the same problem.

Zireael07 avatar Dec 31 '19 20:12 Zireael07

@Zireael07 It is not possible to import built-in modules that have not been adapted for transcrypt. The transpiler will actually not search in python's built-in modules folder, so it cannot find functools.

AlexECX avatar Dec 31 '19 20:12 AlexECX

Yes, that's why I later tried cachetools, but it falls afoul of the submodules problem (Transcrypt thinks ttl.py is somewhere in

                C:/Program Files/Python37/lib/site-packages/transcrypt/modules/ttl.py
                C:/Program Files/Python37/lib/site-packages/transcrypt/modules/ttl.js
                C:/Users/Kasia/Documents/hello/ttl.py
                C:/Users/Kasia/Documents/hello/ttl.js
                C:/Program Files/Python37/lib/site-packages/ttl.py
                C:/Program Files/Python37/lib/site-packages/ttl.js

while it is in C:/Program Files/Python37/lib/site-packages/**cachetools/**ttl.py

As you already mentioned, transcrypt seems to be missing the path to module bit when searching.

Zireael07 avatar Dec 31 '19 20:12 Zireael07

I doubt cachetools would work with transcrypt. Using built-in modules or 3rd party packages not built with transcrypt in mind is risky because there is a high chance that they have one or more things that do not not conform to transcrypt's restrictions.

AlexECX avatar Dec 31 '19 20:12 AlexECX

Yeah, I'm slowly finding that out (I was able to work around the path problem with the -xp commandline switch), but the main problem is the fact that transcrypt is handling module importing really badly.

Zireael07 avatar Dec 31 '19 20:12 Zireael07

I think this is related to relative imports not currently being supported by Transcrypt as discussed in issue: https://github.com/QQuick/Transcrypt/issues/260

JennaSys avatar Feb 17 '22 01:02 JennaSys