fable-compiler / Fable

F# to JavaScript, TypeScript, Python, Rust and Dart Compiler
http://fable.io/
MIT License
2.92k stars 300 forks source link

[Python] Generates `.fs.py` when `outDir` option is not provided #3616

Open MangelMaxime opened 11 months ago

MangelMaxime commented 11 months ago

Description

Hello @dbrattli,

The python target seems to be the only to not generates .fs.py when outDir is not provided.

Is there a reason for that or this is just something forgotten / not known at the time ?

It would be nice if we could generate .fs.py files as it allows IDE/Editors like VSCode to nest the files together to not pollute too much the explorer.

CleanShot 2023-11-27 at 15 33 16@2x

dbrattli commented 11 months ago

Yes, files are modules in Python so files cannot contain dots in their name (only underscores), since that would Python think there's a submodule when importing them i.e that the name before the dot is a folder and the name after the dot is a file. https://peps.python.org/pep-0008/#package-and-module-names

MangelMaxime commented 11 months ago

Got it.

I suppose using _fs.py suffix would not conflict with Python naming and still allow for file nesting to work.

dbrattli commented 11 months ago

Using _fs.py would be an option. I didn't think about it at the time. But I suppose it will still not be grouped like above?

MangelMaxime commented 11 months ago

But I suppose it will still not be grouped like above?

It will in VSCode, you can configure the rule for nesting the file, in this case using the following works:

"*.fs": "${basename}_fs.py",

If we do implement this feature, I will send a update to Ionide as it is missing others nesting rules.

smoothdeveloper commented 11 months ago

@MangelMaxime, the main issue with this, as I understand it, is that it precludes authoring python libraries in F#.

all the modules will have _fs suffix for python consumers.

MangelMaxime commented 11 months ago

@smoothdeveloper all the modules will have _fs suffix for python consumers.

Not necessarily, if you provide --outDir or -e py then the generated files with have .py extension. This is the same behaviour as JavaScript target.

dbrattli commented 11 months ago

Another problem with Python is that all the compiled files must be within the same subdir. If not, then Python cannot import them. That means that e.g imported projects will have to be installed (site-packages, or other sys.path) or we need to use a package manager like e.g Poetry to setup the path relative dependencies to them. Then we enforce the users of Fable to also use Poetry (which we don't do today). We could of course just leave it alone and say that the main program expects to be able to import the dependencies somehow, but then many examples with projet references will fail. https://github.com/fable-compiler/Fable/blob/main/src/Fable.Cli/Main.fs#L163

PS: There's btw a (hidden) feature that if fable lib is set to be in site packages e.g --fableLib site-packages then we will not install fable library and expect it to be installed some how from PyPI (not updated in a while 😬 ). https://github.com/fable-compiler/Fable.Python/issues/39

smoothdeveloper commented 11 months ago

@dbrattli, I'm not yet sensibilized with all the ways python works with loading modules, I think people actually update sys.path or %PYTHONPATH% when needing to load modules from separate locations.

I tried poetry but the thing generated some attributes in my pyproject.toml, then it made pip install . fail for sake of missing readme.md file with the whole backtrace displayed...

I'd be worried about forcing people to install fable packages (in site-packages) by default (dll hell), or to force usage of poetry by default (it is probably nice but I think people using it know how to configure it without need for fable to do anything).

I'd rather see a FAQ with guidance how to update sys.path, pointers to python official documentation around the topic, and maybe some extra pointers on how to work in achieving the same with poetry, but not as something we force nor recommend, at least for now.

If python users adopt fable, and start suggesting better integration with poetry, then we'd consider what this looks like, but I doubt this should remove the "you can make a fable (or any python) code base file system layout work by handling sys.paths, like is highlighted in the official docs" approach, with a small example and ELI5 comments.

Does that sound reasonable? I'm not a python expert, and for now, loading fable generated code and the fable standard library in both a structure of scripts (in same tree) or jupyter notebook worked without doing anything (I have a pyproject.toml and init.py files at the right locations though).