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

Proposal: use entrypoints to make array-api submodules discoverable #244

Closed
Zac-HD opened this issue Aug 25, 2021 · 7 comments · Fixed by #297
Closed

Proposal: use entrypoints to make array-api submodules discoverable #244

Zac-HD opened this issue Aug 25, 2021 · 7 comments · Fixed by #297
Milestone

Comments

@Zac-HD
Copy link

Zac-HD commented Aug 25, 2021

Over in HypothesisWorks/hypothesis#3065, we're working on test tooling that takes an array-api implementation (e.g. numpy.array_api, etc) and returns test helpers which use that implementation. For ergonomics we'd also like to automatically find the array-api implementation, if there is one, for a given module - but as I understand it there's no way to discover that mapping. Yet!

I therefore propose that as part of the Array API standard, packages implementing the API should register an entry point declaring which (sub)module contains the implementation. For example, Numpy would register:

        entry_points={
            'console_scripts': f2py_cmds,
            'array_api': ['numpy = numpy.array_api'],  # new: maps top-level name to array api implementation
        },

Implementations can then be found using importlib.metadata (see here for < py3.7) as follows:

import numpy.array_api
from importlib.metadata import entry_points

try:
    eps = entry_points(group="array_api")
except TypeError:
    # Load-time selection requires Python >= 3.10 or importlib_metadata >= 3.6, so fallback:
    eps = importlib_metadata.entry_points().get("array_api", [])
implementations = {entry.name: entry for entry in eps}

npa = implementations["numpy"].load()
assert npa is numpy.array_api

This allows us to avoid hard-coded lists of known libraries and locations, which will inevitably be both incomplete and out of date as the ecosystem evolves. It also makes it easy to find all installed array-api implementations, supporting a much wider range of purposes than testing 🎉

@rgommers
Copy link
Member

Thanks @Zac-HD! Discoverability sounds like a great idea.

importlib is part of the stdlib, so that sounds fine. For registering an entry-point, my memory is a bit fuzzy about whether it can be done without setuptools. That seems desirable, since it's not a pleasant dependency to require every library to have, and we'll likely move NumPy away from it before distutils disappears from the stdlib.

@Zac-HD
Copy link
Author

Zac-HD commented Aug 25, 2021

https://packaging.python.org/specifications/entry-points/ says:

The entry point file format was originally developed to allow packages built with setuptools to provide integration point metadata that would be read at runtime with importlib.metadata. It is now defined as a PyPA interoperability specification in order to allow build tools other than setuptools to publish importlib.metadata compatible entry point metadata, and runtime libraries other than importlib.metadata to portably read published entry point metadata (potentially with different caching and conflict resolution strategies).

So I think we're set there, though I can't speak to how well other tools support the standard or how to use them.

@Zac-HD Zac-HD changed the title Proposal: use Setuptools entrypoints to make array-api submodules discoverable Proposal: use entrypoints to make array-api submodules discoverable Aug 25, 2021
@Zac-HD
Copy link
Author

Zac-HD commented Aug 25, 2021

CC also @asmeurer - programatic discovery of implementations seems useful for the test suite 😉

@rgommers
Copy link
Member

Cool, thanks. If there are other tools that can do it but need some fixes, or even if we can write a tiny package that does exactly this job and nothing else, then that's fine imho.

@asmeurer
Copy link
Member

We already have __array_namespace__ which allows array objects to signal that they are part of a compliant implementation, but there's no way to get access to all globally installed compliant implementations, so this seems like a good idea. It sounds like there are valid use-cases for tooling like hypothesis that want to provide a generic interface to array APIs, but as producers of arrays rather than consumers.

@honno
Copy link
Member

honno commented Oct 26, 2021

Early last month in the consortium meeting, this was discussed and there seemed to of been consensus that entrypoints would be a good optional feature for this years spec release.

The two immediate use-cases:

  • Hypothesis with entrypoints could enable a user-friendly pattern to access module-bounded Array API strategies, e.g. from hypothesis.extra.array_api import torch as tst would be much nicer than asking the user to "bound" the array module into a strategies namespace
  • The Array API test suite could default to the Array API implementation it can find with entrypoints, so array module developers don't need the cognitive load of "setting" the module to be tested

And as @Zac-HD originally stated, other tools that end up supporting the Array API might find entrypoints useful.

As @rgommers stated, entrypoints only uses features in the 3.8+ standard library. They are already used for NumPy and PyTorch. I made a PR to NumPy which demonstrates how simple this is to support in numpy/numpy#19800, as well as how to test it.

So this should be fine to add to the spec, although I'm not sure where. Being optional saves us from any unforeseen consequences, and down the line folk (i.e. me) can ask array module authors which don't initially adopt it to see if they're interested/even knew about it.

@kgryte
Copy link
Contributor

kgryte commented Nov 1, 2021

@honno I think a reasonable inclusion place would be in the "How to adopt this API" section of the specification. Feel free to submit a PR adding this guidance. :)

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

Successfully merging a pull request may close this issue.

5 participants