-
-
Notifications
You must be signed in to change notification settings - Fork 243
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
Stop requiring __file__
in Python packages
#69
Comments
I am having a similar issue, just when I am trying to import a package, for example numpy. So I am not sure how to change my code not to depend on file as the only line of code I have is "import numpy" I have this issue when I use the repl mode, the eval mode, and when I try to run a script |
The warning instructs them to look for more info at #69.
I chose the library for this demo like so: * Went to https://pypi.org/ and looked at "Trending projects". * Tried each one, using example code from its README. * Went with the first one that worked. In the sample that happened to give me today, this was the 4th on the list: * `cpp-demangle` was first, and failed at `pip install` time with an error about `setuptools_rust`. I think it just doesn't build from source in a stock environment; I get the same error with `pip install .`, in a fresh venv, after cloning the source. * `pygrok` failed at import time, trying to use `__file__`. See indygreg/PyOxidizer#69. * `python-whois` failed at import time: imports `past`, which imports `lib2to3`, which uses `__file__`. * `area` works.
Is there a recommended strategy for patching these modules locally to try and get them to work with PyOxidizer? Currently I am unable to find a way to build when I use a module that contains the I have set up a venv, downloaded all the packages that I am using locally, and have tried to monkey patch the Is it possible to somehow search and replace the |
Ok, after doing some more digging around the repo, I found the solution offered for the
Now, the python application that I am developing lives in a virtualenv, so originally I was just using that virtualenv to dictate what packages needed to be rolled up. Is there an equivalent command for |
Try making a minor (e.g. whitespace) change to the toml file |
Running a file with |
Having a similar problem, PyInstaller uses this workaround:
Because, in the user mind, if a tool cannot package a script that was working if not packaged, is a tool fault and not a "that library is accessing an optional attribute without checking". |
It would be nice if there was the ability to specify in the toml how Workaround strategies would include:
Likely others exist too. |
For any maintainer of a package which has been directed to read this issue for PyOxidizer compatibility, if your use of
It would be good to know what standardised method of loading package data does work. (update: #53 suggests that |
Assuming __file__ exists breaks packaging netaddr with PyOxidirzer[1]. Initially I wanted to use pkgutil.get_data()[2] as it's been in the Python standard library since Python 2.6 but it always reads and returns the whole resource and I decided I don't like reading whole out.txt and iab.txt in OUI and IAB constructors just to read few small bits of data. importlib.resources provides an API[3] that should in the usual cases cases[4] avoid loading whole resources into memory. Maybe IAB and OUI constructors shouldn't read files and the API needs to be rethought but that's an issue for another day. Granted, this is a tradeoff, as we have a dependency now which means slighly more network traffic and slightly more complexity, but all things considered I think that's better than the alternative. (Ironically this introduces a new piece of code using __file__ but this should be benign as it's not in the code that'll be present in a PyOxidizer-produced binary. It's necessary to have that setup.py hack as netaddr can't be imported without importlib_resources or importlib.resources present now so it can't be unconditionally imported from setup.py where importlib_resources may not be installed yet). Fixes GH-188. [1] indygreg/PyOxidizer#69 [2] https://docs.python.org/2/library/pkgutil.html#pkgutil.get_data [3] https://docs.python.org/3.9/library/importlib.html#importlib.resources.open_binary [4] https://gitlab.com/python-devs/importlib_resources/-/blob/2707fb7384e76cda715de14bea5956339969950f/importlib_resources/_py3.py#L24
Assuming __file__ exists breaks packaging netaddr with PyOxidirzer[1]. Initially I wanted to use pkgutil.get_data()[2] as it's been in the Python standard library since Python 2.6 but it always reads and returns the whole resource and I decided I don't like reading whole out.txt and iab.txt in OUI and IAB constructors just to read few small bits of data. importlib.resources provides an API[3] that should in the usual cases cases[4] avoid loading whole resources into memory. Maybe IAB and OUI constructors shouldn't read files and the API needs to be rethought but that's an issue for another day. Granted, this is a tradeoff, as we have a dependency now which means slighly more network traffic and slightly more complexity, but all things considered I think that's better than the alternative. (Ironically this introduces a new piece of code using __file__ but this should be benign as it's not in the code that'll be present in a PyOxidizer-produced binary. It's necessary to have that setup.py hack as netaddr can't be imported without importlib_resources or importlib.resources present now so it can't be unconditionally imported from setup.py where importlib_resources may not be installed yet). Fixes GH-188. [1] indygreg/PyOxidizer#69 [2] https://docs.python.org/2/library/pkgutil.html#pkgutil.get_data [3] https://docs.python.org/3.9/library/importlib.html#importlib.resources.open_binary [4] https://gitlab.com/python-devs/importlib_resources/-/blob/2707fb7384e76cda715de14bea5956339969950f/importlib_resources/_py3.py#L24
Why it have alot of problem? it need installation of tons of programs than don't work properly |
So, I think I'll put this here even though I think it also goes in #73.
But, I don't think the fix works for pyoxidizer. I'm still getting what I think is basically related to
I don't understand the intricacies of Is this a pyoxidizer problem or a problem with certifi's usage of |
same issue here, cant really import anything beyond stdlib because of the error ```TypeError: expected str, bytes or os.PathLike object, not NoneType
|
The Problem
Many Python modules and scripts use
__file__
to derive the filesystem path to the current file.As documented at https://docs.python.org/3/reference/datamodel.html (search for
__file__
),__file__
is optional (the__file__
attribute may be missing for certain types of modules).However, because Python has traditionally relied on filesystem-based imports and hasn't had a stable story around non-module resource handling, ,
__file__
is almost always defined and has been used to locate and load files next to Python source files for seemingly forever. This is arguably tolerable. But reliance on__file__
undermines tools - like PyOxidizer - which don't import Python modules from the filesystem. This in turn constrains the flexibility and utility of the larger Python ecosystem.The Solution
Python code should be rewritten to not assume the existence of
__file__
. By doing so, Python code will be more compatible with more Python execution environments (such as PyOxidizer), and this benefits the overall Python ecosystem.Instructions for writing portable Python code that doesn't rely on
__file__
can be found at https://pyoxidizer.readthedocs.io/en/latest/packaging_pitfalls.html#reliance-on-file.This Issue
This issue can serve as a focal point for tracking and coordinating Python packages and tools which currently rely on
__file__
but shouldn't. If you file a GitHub issue against a project that relies on__file__
, you can reference this issue by typingindygreg/PyOxidizer#69
and provide Python project maintainers with enough context to make informed decisions about the use of__file__
in their projects.The text was updated successfully, but these errors were encountered: