Skip to content
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

How to check if a requirement is met without pkg_resources #450

Closed
HansBug opened this issue Apr 16, 2023 · 4 comments
Closed

How to check if a requirement is met without pkg_resources #450

HansBug opened this issue Apr 16, 2023 · 4 comments
Labels
question Further information is requested

Comments

@HansBug
Copy link

HansBug commented Apr 16, 2023

In our work, we need to use the Python source code to check if the dependencies specified in requirements.txt are fully satisfied. Previously, we used pkg_resources.require like this (https://stackoverflow.com/a/16298328/6995899 ), but now that it has been deprecated, how can we achieve the above functionality in new packages?

@jaraco
Copy link
Member

jaraco commented Apr 18, 2023

importlib metadata doesn't provide this functionality. It seems that packaging does not either. Someone will need to write that functionality, and since it probably will depend on packaging, it probably should be in that package or in something that can depend on it (importlib metadata cannot because it's part of stdlib). This issue has been reported in pypa/packaging-problems#317.

@HansBug
Copy link
Author

HansBug commented Apr 18, 2023

Hi @jaraco, I found the solution without pkg_resources after submitting this issue, here is the code: https://github.com/HansBug/hbutils/blob/main/hbutils/system/python/package.py#L202 .

This is the core function to iterate all the requirements need to be installed:

def _yield_reqs_to_install(req: Requirement, current_extra: str = ''):
    if req.marker and not req.marker.evaluate({'extra': current_extra}):
        return

    try:
        version = importlib_metadata.distribution(req.name).version
    except importlib_metadata.PackageNotFoundError:  # req not installed
        yield req
    else:
        if req.specifier.contains(version):
            for child_req in (importlib_metadata.metadata(req.name).get_all('Requires-Dist') or []):
                child_req_obj = Requirement(child_req)

                need_check, ext = False, None
                for extra in req.extras:
                    if child_req_obj.marker and child_req_obj.marker.evaluate({'extra': extra}):
                        need_check = True
                        ext = extra
                        break

                if need_check:  # check for extra reqs
                    yield from _yield_reqs_to_install(child_req_obj, ext)

        else:  # main version not match
            yield req

@jaraco
Copy link
Member

jaraco commented Apr 18, 2023

Glad you found a solution. You may want to post that over in packaging-problems, as that will help a wider audience.

@HansBug
Copy link
Author

HansBug commented Apr 18, 2023

Glad you found a solution. You may want to post that over in packaging-problems, as that will help a wider audience.

Posted pypa/packaging-problems#664

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants