-
Notifications
You must be signed in to change notification settings - Fork 104
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
feat: add pypi-to-conda-name overrides to pyproject parsing #549
base: main
Are you sure you want to change the base?
Conversation
✅ Deploy Preview for conda-lock ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
ready for a first pass @maresb |
i didn't yet add a command line option, but could also do that if you want to tell me the syntax you'd prefer. perhaps something like |
A CLI option doesn't seem to me like a good interface. If you have pip deps, then usually they are coming from a |
yeah, totally fine with me to leave out the cli option |
seem to be some test failures... but I haven't been able to reproduce them locally (macos) |
This looks pretty good. I'm somewhat horrified by the way that A lot of this feels a bit overly-fancy to me like return {**self.local_mappings, **self.remote_mappings} I think it's just less mental effort to understand concrete types. I won't request you to change it, but in case you do make further changes, it'd be nice to go towards that concrete/simple direction. |
happy to change it as you prefer! will have a look at other |
Haha, I think at least some of the CI failures may be a timing issue. Look what just dropped: https://github.com/pandas-dev/pandas/releases/tag/v2.1.3 There's no corresponding conda-forge package yet. Maybe some of the tests need pins. |
ha! |
made some slight adjustments to the module. got rid of the module-level global and removed a duplicated function in |
Might be worth adding in a test to ensure that this functionality doesn't regress |
added, thanks! |
Thanks @tlambert03 for adding the tests! Unfortunately they don't seem to be passing yet. |
thanks. yeah I saw that ... i think there's a fixture/state leakage somewhere (perhaps in the resolver). It works in isolation. need to figure out what other test it's conflicting iwth |
Ah, ya, no pressure. It's always such a pain when tests run locally but not in CI. Good luck and thanks for all your work! |
figured it out. hopefully should pass now 🤞 |
At first glance this looks really great! Unfortunately I'm really slammed with work at the moment, so it might be a bit before I can give this a proper look. |
totally fine. no urgency on my end. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @tlambert03!
I am proposing some cleanups here: tlambert03#1
Also, I'd prefer to leave out the MappingEntry
class until the next PR when we actually implement it. (I don't like having the unused code laying around.)
Then I'd like to take one more pass at this since I am still getting confused by the (pre-existing) indirection.
Clean up lookup.py
not sure I'm following this comment. That class is already there. Are you proposing we remove it and re-add it later? edit: with the removal of the |
Ah, my bad, I was confused. I thought you added it since it matched with one of your initial proposals. Also this was reinforced by observing that it seemed to be extraneous. But now I remember that it was originally the schema for an item in the mapping. As a sort of documentation to make this clear, it would be nice to replace lookup = {canonicalize_name(k): v for k, v in lookup.items()}
for v in lookup.values():
v["pypi_name"] = canonicalize_name(v["pypi_name"])
return lookup with something like: result: Dict[NormalizedName, MappingEntry] = {}
for k, v in lookup.items():
assert k == v["pypi_name"]
pypi_name = canonicalize_name(k)
assert pypi_name == k
conda_name = v["conda_name"]
assert pypi_name not in result
result[pypi_name] = conda_name
return result
Good question. The whole mapping story is very messy. But currently there is only instance of this happening: from collections import defaultdict
from conda_lock.lookup import _lookup_loader
pypi_names = defaultdict(set)
for k, v in _lookup_loader.remote_mappings.items():
pypi_names[v["conda_name"]].add(k)
print({k: v for k, v in pypi_names.items() if len(v) > 1})
# {'pyqt': {'pyqt4', 'pyqt5'}} My suggestion would be to emit a warning and then take a guess. The user could always define a local mapping to break the tie, if local mappings were given priority. 😉 |
Is there anything I can do to help this along? I would really appreciate the ability to disable the default mappings and just manually specify them from pyproject.toml (I find this a lot more convenient than the recent solution of having a separate mapping file provided via a command line argument). I was going to write my own PR, but stumbled across this in my preliminary search. My initial thought was something along the lines of: [tool.conda-lock.dependencies]
pytorch-scatter = {pypi_name = "torch-scatter"} It would also offer a neat way of being explicit about when the PyPI version of a package is preferred. For example, say I want to install opencv-python from PyPI instead of the conda-forge package: [tool.conda-lock.dependencies]
opencv = {source = "pypi", pypi_name = "opencv-python"} I really enjoy using conda-lock, and would love to see the PyPI <-> Conda mapping handling improved by removing the need for another external file. |
i think the core functionality of adding |
@tlambert03, sorry for letting this slip. Do you understand why the tests are failing though? |
Description
Closes #548 by adding support for a
pypi-to-conda-name
section in pyproject.tomlnames present there will override mappings provided by grayskull
Note: in #548, I proposed accepting a string or list of strings (which I do think is a good idea), but the implications of accepting a list of strings breaks the current 1-to-1 mapping behavior between pypi and conda, so I think that's probably best handled in a followup PR. This PR only accepts single string