-
Notifications
You must be signed in to change notification settings - Fork 140
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Document the requisite internal structure of module files for Flit building #714
Comments
Thanks, it is helpful to see pain points like this for new users. The key bit of context that I'm not sure anyone says explicitly is that Python packaging is basically all designed around packaging libraries. A scripts is defined as a reference to a function in a library. If you look at installed scripts ( #!/usr/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from IPython import start_ipython
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(start_ipython()) Even pip, which explicitly says that you shouldn't use it as a library, is still structured as a library with a main function. (This is 99% true: the packaging standards do allow packages to install scripts without using an importable main function, and you can still do that using setuptools. But this option is hardly ever used, it doesn't work well with Windows, and the setuptools docs discourage it.) The extra detail for Flit is how it gets the version number from your code. It tries to find a I'll look at how this can be clearer, either in Flit's docs and/or in the packaging user guide. |
Yes, this is what I eventually concluded based on a lot more reading. I'd suggest again that this ought to be made a lot clearer for new users like me :)
This is what I was still pretty confused about - why was Flit actually importing my code? But I'm still not sure I understand: I did put a Thanks much for the explanation, and for all your work on this tool! |
I forgot, it also looks for a module level docstring to use the first line as the short description for the package. If it doesn't get both that and the version, it falls back to importing. If you had a docstring as well, it's possible that the automatic fallback is hiding some bug. The function that tries to get the version & docstring without executing code is here: flit/flit_core/flit_core/common.py Lines 140 to 172 in 432042e
|
Thank you! The problem was that I was putting the module docstring and the I suppose that Flit will only look at
How is Flit used with a single file Another problem: when I set
Apparently there's a requirement that referenced files not be above the module in the filesystem? I suggest that this be documented and / or that Flit fail more gracefully here. Thanks again for bearing with me. |
I was inspired by @takluyver's graciousness in his responses to #664 to report my new user experience with Flit.
Background: I have considerable (hobbyist) experience coding (scripting) in Python (almost ten years of Advent of Code!), but none at all in packaging Python code. Upon seeing Flit included in the tool recommendations of the Python Packaging documentation ("minimal and opinionated" sounded about right to me in this context), I decided to give it a whirl, only to encounter a seemingly bizarre error: Flit was apparently trying to run my script under its own name (and terminating abnormally since the script wasn't being provided its proper arguments).
After a bunch more reading, I concluded that Flit's build process includes the importing of the provided modules, and that Flit (like most Python packaging tools?) apparently expects its provided modules' code to be esconced inside functions (with the possible inclusion of an
if __name__ == "__main__:"
clause), and thus importing the modules shouldn't actually run the code. But I humbly suggest that this may not be quite so obvious to those new to Python packaging, and perhaps Flit should explain more clearly just what sort of code structure it expects provided modules to have. (I did read the "Scripts section" section, but even this leaves unstated the basic requirement that executable code be esconced within functions. Alternatively, if I've badly misunderstood what's going on here, I'll be happy to be set straight.)Thank you for this tool, and I hope to successfully package my first Python project with it soon!
The text was updated successfully, but these errors were encountered: