i2y/mochi

`mochi <filename>` skips module loading machinery, doesn't fill in the blanks

Opened this issue · 1 comments

Basically, if someone does mochi blahblah.mochi and uses __loader__, or __file__, or tries to import something script-relative (which I assume relies on __file__) within blahblah.mochi, problems can happen.

in addition, using __file__ to load script-relative files is fairly common practice ( http://stackoverflow.com/a/1270970 )


Best options (in my opinion) to fix the problem would either be

  1. load the module loader, then use runpy to automatically load the script using the pre-existing import mechanics
  2. replicate the module loading mechanics into mochi.core:main

(2) does come at a maintainance cost however


when / if I have free time any time soon, I'll give (1) a shot, and I'll make a pull request for it



Below is just to show effects, please feel free to delete as its not that relevant (its more to prove that it has an effect)


1.py:

f = list(globals().items())  # disconnect it from the view
f = filter(lambda x: x[0].startswith('__'), f)
f = filter(lambda x: not x[0]=='__builtins__', f)
for x in f: print(x)
print('------------------------------')
import withinfile

withinfile is the same, sans import

1.mochi

printall = -> ($1 |> map(print) |> doall)
globals().items()
    |> filter(->$1[0].startswith('__'))
    |> filter(->$1[0] != '__builtins__')
    |> printall
print('------------------------------')
import withinfilemoch

withinfilemoch.mochi is the same sans import


relevant tree output

path
\---1\
    |   1.mochi
    |   1.py
    |   withinfile.py
    |   withinfile.pyc
    |   withinfilemoch.mochi
    |   withinfilemoch.pyc
    \---__pycache__\
            withinfile.cpython-35.pyc

and the output of executing such things

D:\path>py -3 1/1.py

    ('__name__', '__main__') ('__package__', None)
    ('__spec__', None)
    ('__loader__', <_frozen_importlib_external.SourceFileLoader object at 0x00E05AD0>)
    ('__file__', '1/1.py')
    ('__cached__', None)

    ------------------------------

    ('__name__', 'withinfile') ('__package__', '')
    ('__spec__', ModuleSpec(name = 'withinfile',
                            loader = <_frozen_importlib_external.SourceFileLoader object at 0x00E90A30>,
                            origin = 'D:\\path\\1\\withinfile.py'))
    ('__loader__', <_frozen_importlib_external.SourceFileLoader object at 0x00E90A30>)
    ('__file__', 'D:\\path\\1\\withinfile.py')
    ('__cached__', 'D:\\path\\1\\__pycache__\\withinfile.cpython-35.pyc')

============================================================

D:\Socialery\Documents\GitHub\AoC>mochi 1/1.mochi

    ('__name__', '__main__') ('__package__', None)
    ('__spec__', None)
    ('__loader__', None)
    ('__file__', 'C:\\Python35\\lib\\operator.py')
    ('__cached__', 'C:\\Python35\\lib\\__pycache__\\operator.cpython-35.pyc')
    48 other dunders from the operator module
    ------------------------------
    Traceback (most recent call last):
      File "..\site-packages\mochi\core\main.py", line 321, in main
        load_file(args.file, global_env)
      File "..\site-packages\mochi\core\main.py", line 56, in load_file
        return exec(compile_file(path), env)
      File "1/1.mochi", line 8, in <module>
        print('------------------------------')
    ImportError: No module named 'withinfilemoch'

D:\path>cd 1
D:\path\1>mochi 1.mochi

    ('__name__', '__main__') ('__package__', None)
    ('__spec__', None)
    ('__loader__', None)
    ('__file__', 'C:\\Python35\\lib\\operator.py')
    ('__cached__', 'C:\\Python35\\lib\\__pycache__\\operator.cpython-35.pyc')
    ------------------------------
    ('__name__', 'withinfilemoch') ('__package__', '')
    ('__file__', 'D:\\path\\1\\withinfilemoch.pyc')
    ('__spec__', ModuleSpec(name = 'withinfilemoch',
                            loader = <_frozen_importlib_external.SourcelessFileLoader object at 0x0373AF30>,
                            origin = 'D:\\path\\1\\withinfilemoch.pyc'))
    ('__doc__', None)
    ('__loader__', <_frozen_importlib_external.SourcelessFileLoader object at 0x0373AF30>)
    ('__cached__', 'D:\\path\\1\\withinfilemoch.pyc')
    ------------------------------
    >>>>>>>>>>>
    D:\path\1\withinfilemoch.mochi
    <<<<<<<<<<<
i2y commented

Thank you for a detailed bug report.

when / if I have free time any time soon, I'll give (1) a shot, and I'll make a pull request for it

That would be great!
It would help us if you would do so.