modularml / mojo

The Mojo Programming Language
https://docs.modular.com/mojo/manual/
Other
23.1k stars 2.59k forks source link

[Feature Request] Please add a way to import modules dynamically by Path #449

Open osbm opened 1 year ago

osbm commented 1 year ago

Review Mojo's priorities

What is your request?

Please add a way to import a module by a path.

The syntax could be (comment lines for importing everything to the global namespace)

import "../folder1/script1.py" as script1
# from "../folder1/script1.py" import *

or (if you want to turn import into a soft-keyword)

script1 = import("../folder1/script1.py")
# import("../folder1/script1.py", to_global_namespace=True)

What is your motivation for this change?

It is by far the most irritating downside of Python. It causes many many questions in StackOverflow and workarounds are always made in a hacky way.

I do not consider my syntax suggestion a perfect solution. I suggested them just to explain what I wanted.

Any other details?

No response

drunkwcodes commented 1 year ago

It has been doable by adjusting PYTHONPATH or sys.path.

https://stackoverflow.com/questions/12257747/permanently-adding-a-file-path-to-sys-path-in-python

IMO mojo may refer this, not being too different. Python import function maybe needs to be enhanced and polished, not making it more messy.

I met some problems in PySide qt app, it has some ImportError when using relative imports. I catched the error and used regular imports instead. Then it seldom bothers me. I think relative import can be strengthened and more useful in mojo.

osbm commented 1 year ago

I know it is doable but it's rather hacky and version dependent. I was referring to this popular question, not permanently adding files to the sys.path.

I can see that they are willing to change the syntax of python. And IMO this would be a fine addition.

drunkwcodes commented 1 year ago

No. It's ugly, as ugly as url import in the discussions. And it's error prone.

Current machinery is more flexible and more immune to change. Just add path to sys.path and let import function do its jobs.

https://stackoverflow.com/a/129374

This answer is fine.

osbm commented 1 year ago

I know the current sys.path method is working. Why do you keep suggesting that?

I just requested a more intuitive way to do it. You can still use sys.path method. Why are you so against adding a new feature that won't affect you in any way?

Let's say you want to import two of your own scripts that are both named main.py but they are in different folders. I put one different print function in each of these scripts. First, i tried:

import sys
sys.path.append("../folder1")
import main as main1
sys.path.remove("../folder1")
sys.path.append("../../folder2")
import main as main2

Only runs the first module. I don't even know the solution to that. I believe this is actually needed because almost all the deep learning repositories have similar naming traditions. (such as "train.py", "preprocessing.py", and "utils.py")

And what happens when an installed module and a script have the same name?. Just look at the answers. Are they not "ugly"?

Let's not forget this is a brand-new programming language. No Python interpreter will be expected to run Mojo code. Literally no need for backward compatibility. They can fix the mistakes and shortcomings of Python.

drunkwcodes commented 1 year ago

The naming thing is no-brainer. Those duplicate names are easy to be avoided.

Even if you insist that There are two "main.py" in the project, you can add their upper layer folders to sys.path to distinguish them with different package names.

So simple.

The strength becomes the "shortcomings" in your mouth...

And why I insist of sys.path is that it is the only way to make sense.

Though here is mojo, the zen of python is good in here too.

gryznar commented 1 year ago

This proposition may be threatet the same way as importing from url. It looks like it brings some opportunities unavailable via adding to path, so I am on it

drunkwcodes commented 1 year ago

Don't be a troll! Pythonistas.

I still did not figure out why we can not use relative imports when the script is run as"__main__". The __file__ path attribute is still available and the top-level package can even be determined by the existence of __init__.py. GPT's answer is in vague.

@osbm Why you use the path when relative import is available? You must have questions about relative imports, don't you?

osbm commented 1 year ago

You must have questions about relative imports, don't you?

I am guessing this is a derogatory way of saying "You don't understand relative imports". It does not matter if I understand "relative imports". This request isn't about relative imports. It's about importing a module using a path string. relative or absolute.

If it was up to me I would deprecate the sys.path method. It's an unnecessarily complex way to do things.

drunkwcodes commented 1 year ago

@osbm I mean the demands from you is beyond current situation.

The reaffirm makes me tend to loop my replies. But I'm wondering what if we all use path string. The path is too fixed to let facade pattern grows.

Look at the beautiful flask framework, which let us import everything we need from just flask.

And look at those double quotes around the path strings. So weird. Just like we would accept illegal module name like space chars in them.

And if you want to import the same package from different paths, you have to write try, except by yourself.

How do you avoid these?