-
Notifications
You must be signed in to change notification settings - Fork 37
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
Replacement for pkg_resources.require()
?
#234
Comments
I made a small change to the repo to refactor a function. With a couple of undocumented functions, you can (I think) do what you want. I did a simple smoke test: $ python3 -m venv venv1
$ python3 -m venv venv2
$ venv1/bin/pip install textual 2>&1 > /dev/null
$ venv2/bin/pip install textual[syntax] 2>&1 > /dev/null The #!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2024 Vinay Sajip. MIT-licensed.
#
import argparse
import os
import sys
DEBUGGING = 'PY_DEBUG' in os.environ
from distlib.database import DistributionPath
from distlib.locators import DistPathLocator
# Undocumented functions imported here
from distlib.markers import interpret_parsed
from distlib.util import parse_requirement
def main():
adhf = argparse.ArgumentDefaultsHelpFormatter
ap = argparse.ArgumentParser(formatter_class=adhf)
aa = ap.add_argument
aa('reqt', metavar='REQT', help='Requirement')
options = ap.parse_args()
distpath = DistributionPath(include_egg=True)
locator = DistPathLocator(distpath)
sreq = options.reqt
r = parse_requirement(sreq)
failures = []
d = locator.locate(sreq)
if d is None:
failures.append(r.name)
else:
print(d)
for s in d.run_requires:
dr = parse_requirement(s)
if dr.marker:
if r.extras:
for e in r.extras:
c = {'extra': e}
try:
v = interpret_parsed(dr.marker, c)
except Exception:
v = False
if v:
dd = locator.locate(dr.name)
if dd:
print(dd)
else:
failures.append(dr.name)
if failures:
print('Not found: %s' % failures)
if __name__ == '__main__':
try:
rc = main()
except KeyboardInterrupt:
rc = 2
except Exception as e:
if DEBUGGING:
s = ' %s:' % type(e).__name__
else:
s = ''
sys.stderr.write('Failed:%s %s\n' % (s, e))
if DEBUGGING: import traceback; traceback.print_exc()
rc = 1
sys.exit(rc) Seems to give the expected results: $ venv1/bin/python test_script6.py foo
Not found: ['foo']
$ venv1/bin/python test_script6.py textual
textual 0.83.0
$ venv1/bin/python test_script6.py textual[syntax]
textual 0.83.0
Not found: ['tree-sitter-languages', 'tree-sitter']
$ venv2/bin/python test_script6.py foo
Not found: ['foo']
$ venv2/bin/python test_script6.py textual
textual 0.83.0
$ venv2/bin/python test_script6.py textual[syntax]
textual 0.83.0
tree-sitter 0.20.4
tree-sitter-languages 1.10.2 You can try out this logic with the latest repo and give me feedback. I can document the undocumented functions and cut a release in due course. |
As far as I can tell, this takes pretty much the same amount of effort as it does currently with
Meanwhile, with the old But as I wrote in pypa/packaging-problems#664 (comment), I personally don't think distlib is the right place for this in any case. |
I agree - in general, the things one might want to do in different branches of the above logic will depend on the exact use case. I put together the above to see how straightforward it would be to do using |
I only wanted to get the discussion started, I do not particularly feel one way or another regarding this topic. Feel free to close whenever you feel like the discussion has run its course. :) |
Is your feature request related to a problem? Please describe.
With setuptools'
pkg_resources
being deprecated, some are looking for replacement solutions.Describe the solution you'd like
It would be nice if
distlib
offered an alternative topkg_resources.require()
.Describe alternatives you've considered
The next best thing right now is probably a mix of
importlib.metadata
andpackaging
, but as far as I understood it does not get all the way there.Additional context
CC: @smheidrich
The text was updated successfully, but these errors were encountered: