-
-
Notifications
You must be signed in to change notification settings - Fork 82
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
PackageMetadataNotFound for editable package installed outside of site dirs #364
Comments
Thanks for the report. You're correct that importlib_metadata (and importlib.metadata) does not have any awareness of egg-link files, and that's by design. Instead, the current design expects the metadata file to be present somewhere on sys.path (for typical file system and zip file loaders), but also provides extensibility for other loaders to provide the metadata through another mechanism. However, this project does intend to support editable installs and .pth files, including And I can confirm that it does:
The There is an open issue already (the only other open issue #112) about a particular weakness in editable installs for src-layout projects. I expect that issue to be addressed as Setuptools figures out the solution to PEP 660 (pypa/setuptools#2816), but until then, this project is open to someone to work out a solution/workaround for the issue here. Since I suspect this report is a duplicate of that previous one, I'm going to mark it as such, but if what you're experiencing isn't related to a src-layout editable install, then please provide more detail here about how one could replicate the failure you're experiencing. |
Thanks for the prompt reply. Yes, to workaround this issue, I can place the source directory that contains the .egg-info metadata into my PYTHONPATH. That's a bit problematic when you have several such projects. That's the beauty of simply using the site-packages in your path and .egg-link or easy-install.pth stubs to find the editable src directories. That's the intent of the links. An example of this issue in one such project I'm working on has a console_script entry point that fails to execute because it can't find its own package.
This occurs whether I have my package under a src dir or directly at the top level of my project dir. How can I get importlib.metadata to following the easy-install.pth link? |
@jaraco could you please re-open this? Not sure why it was immediately closed before I could respond. Thank you. The issue I'm experiencing occurs regardless of how the package source is laid out, as the open issue you referred to relates to the use of src. if importlib.metadata requires that the source dir with the .egg-info metadata is in the PYTHONPATH, then it doesn't truly support the --editable option properly (either through .egg-link or easy-install.pth). These links are what make editable installs possible, so I'm not sure how importlib.metadata can ignore them all together. Unless my issue is somehow strictly related to entry points (such as the console_scripts in my example), or importlib.metadata provides some other facility I'm not aware of to process links to editable installations. Can you clarify? |
You're welcome. You lucked out that you happened to report the issue shortly before I got engaged on this project for some maintenance :)
So it's a known issue in the former case, but not so much in the latter case. How are you installing the package? For example, when I install using pip, console scripts work fine:
The way it works is that
Because that
So in my environment, the issue doesn't occur. Scripts execute fine even under an editable install. What's different about your environment? |
OK great thank you. Here's what I'm doing. Keep in my mind this as on my work's server, which I don't have root privileges on. But I have tried python 3.10.1 through brew with the same results. To test this out I created a very simple package called pyproject.toml
setup.py
setup.cfg
All pretty much boiler plate stuff. I created a directory to install it into as a test at
echo $PYTHONPATH (using python3.8, which is what the host has installed. But again, this issue occurs with 3.10.1)
ls ~/install/lib/python3.8/site-packages
less easy-install.pth
ls ~/install/bin
./mypkg
|
@jaraco The one obvious difference is the use of --prefix. I've noticed that when using --user, it automatically adds the package source dir (which contains the .egg-info) to the PYTHONPATH. Naturally that works, but avoids ever having to dereference the link found in easy-install.pth. I'm guessing when you installed your package in the example above that its similarly creating these paths automatically for you? That of course would obscure the inability of importlib to properly follow the editable stubs. |
Thanks for clarifying. Yes, I do think
But it's no surprise that the metadata isn't found, because even without doing an editable install, Python doesn't find packages installed to a prefix by default:
The problem is, the packages in Are you saying that this prefix technique worked for you in the past and stopped working at some point? |
@jaraco shouldn't that work fine by adding the prefix/lib/python*/site-packages path to PYTHONPATH? It works for me when I don't use --editable and only --prefix when setting the PYTHONPATH to that prefix's site-packages dir, as you'd expect. It's really the inability to follow the stub links in either easy-install.pth or .egg-link that prevents importlib.metadata from working with --editable. This problem seems to be masked when --prefix is not used Yes, it worked prior to importlib.metadata becoming the standard. python 3.6 and package_resources handled the stub links to the editable source code just fine. |
I see. No, it doesn't work. That's because I encountered this same problem when authoring The 'egg-link' support is a deprecated technique. It's only used by Setuptools and only works if pkg_resources is employed. Even if importlib_metadata were to support this non-standard mechanism of linking develop installs, it would still fail to honor installs from other build tools like flit. That's why importlib metadata is not planning to implement that behavior. My best recommendation for you is to do one of the following (in decreasing order of my preference):
Does that clarify? |
@jaraco thanks this clarifies a lot. Ashame .pth stubs aren't invoked when in a path found in the $PYTHONPATH. Feel like that would be a sensible expectation. I use venv when doing local development, but I do IC design, and for each chip we have a separate project work area that I'd like to install python packages to, using --prefix. For our own python packages these need to be installed --editable, since we could be making changes to them from their source dirs. I like the idea of using sitecustomize.py. I noticed when testing out this contrived example with python 3.6.8, that it had installed a site.py file into my site-packages directory. This actually allowed python 3.8.3 to work by pointing to that site-packages directory instead. I'm curious why setuptools created that site.py file for me for python 3.6 but not 3.8 |
It looks like it was an intentional change rooted in pypa/setuptools#2165. |
ok thank you. I guess one last question. Is there a convenient way to generate such a sitecustomize.py file? |
You're welcome to call |
@jaraco thank you. I guess I'm confused what is even supposed to live in sitecustomize.py. I thought adding the ~/install/lib/python3.8/site-packages/sitecustomize.py
|
Yes, I should think that would work. It may be that it doesn't resolve |
@jaraco I've also tried using a full absolute path with the same results. I tried printing the site packages and user site packages before and after adding that sitedir in my sitecustomize.py. Nothing changed. It didn't add the directory I passed to addsitedir()
|
The site.py source code makes sense and does process the .pth files in that directory. So I need to trace the code and see why it's not working |
I too am having trouble implementing my recommendation, so I'm investigating too. |
Oh, interesting. I'm seeing that no |
I don't know what made me think that the |
@jaraco yeah for some reason I have to call I traced the problem to, as it fails to find that dir.
starts with this section of the
and then from this section of code in the
It reads each line from the .pth file. That makepath function joins the paths found in the .pth file to the sitedir path. So it expects the paths located in the .pth file to be relative to the sitedir, which is not the case. The paths written to easy-install.pth via setup.py develop are absolute. I think I'll just have my |
Okay. I learned some things. Most importantly:
After learning that, I was able to successfully perform an editable install into a prefix and have the metadata be honored:
I think that means if you pass I've got to break for the night, but I wish you luck. |
@jaraco Thank you very much! This got me to a workable solution. The |
Here's a import os
import io
import sys
try:
names = os.listdir('.')
except OSError:
pass
names = [name for name in names if name.endswith(".pth")]
for name in sorted(names):
try:
f = io.TextIOWrapper(io.open_code(name), encoding="utf-8")
except OSError:
pass
with f:
for n, line in enumerate(f):
if line.startswith("#"):
continue
if line.strip() == "":
continue
try:
if line.startswith(("import ", "import\t")):
exec(line)
continue
line = line.rstrip()
if os.path.exists(line):
sys.path.append(line)
except Exception:
print("Error processing line {:d} of {}:\n".format(n+1, name),
file=sys.stderr)
import traceback
for record in traceback.format_exception(*sys.exc_info()):
for line in record.splitlines():
print(' '+line, file=sys.stderr)
print("\nRemainder of file ignored", file=sys.stderr)
break |
When installing a package using --editable, pip creates an .egg-link file and an easy-install.pth file in your site-packages dir that points to the source dir, which by defaults contains your .egg-info metadata. This worked just fine with the older pkg_resources package, as it references the .egg-link file to find your package's .egg-info. You can even see it handle .egg-link files in its init.py source. However, the newer importlib_metadata does not seem to be aware of .egg-link or easy-install.pth files at all. I don't even see it mentioned in the source. The only solution is to include the source dir that contains the .egg-info metadata into your PYTHONPATH, which defeats the purpose of having the .egg-link or easy-install.pth pointer in the first place.
Given that importlib_metadata doesn't appear to even process .egg-link files, is there some new 'pip install', 'setuptools', etc install process that creates editable links that importlib_metadata can understand? If not, this omission seems like a bug that would affect anyone using editable installations that make use of .egg-link pointers.
The text was updated successfully, but these errors were encountered: