Support for downloading ROMs at install-time & ale-py plugin support #13
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This allows for downloading ROMs at install-time with user intervention requiring them to accept the license.
Download at install-time
Old method using `--install-option`
Here's how it works: If you upload a source distribution of the package to PyPI this forces
setup.py
to get run upon installation. We can hook into theinstall
command and check for a user-provided flag through--install-option
which is natively supported by pip https://pip.pypa.io/en/stable/cli/pip_install/#install-install-option. Thus if the user provides--install-option="--accept-license"
the ROMs will be downloaded at install-time.The advantage of this is that you can provide
--install-option
inrequirements.txt
,pyproject.toml
, or in extras. An example of this is:requirements.txt
Now for personal projects/research code, you can easily install your project with ROMs by default.
This also opens up the possibility for public projects to have extras_require with this option. For example,
This still requires intentionality on the user's behalf and the default package would NOT download ROMs.
ale-py
pluginIf we're downloading ROMs at install-time there's no guarantee
ale-py
would be installed. This is where the plugin system comes into play. AutoROM by default will download ROMs to the newAutoROM.roms
package where we have an entry-point toale-py.roms
that exposes the ROMs installed atAutoROM.roms
.This means that regardless of if
ale-py
was installed whenAutoROM
was installed ROM discovery will work properly onceale-py
is installed. Cool!Using
extras_require
The above method was using
--install-option
but this has numerous disadvantages. For starters, you can only supply--install-option
inrequirements.txt
, not ininstall_require
,extras_require
, etc.This PR now has a new method which is implemented using
extras_require
. Essentially what happens is as follows:Inside of the root
setup.py
we specify the followingextras_require
:Now, when we install
AutoROM
from a source distribution without the extra[accept-rom-license]
setup.py
will be invoked as usual and nothing changes. But when you supply the extra[accept-rom-license]
the subpackagelicense
is built. When this package is built it downloads the ROMs to the appropriate directory during install.Caveats
Relative Package Path
When building the source distribution it actually hardcodes the path in the egg metadata. There's ongoing work to support relative paths for sub-packages like this (see pypa/pip#6658, https://discuss.python.org/t/what-is-the-correct-interpretation-of-path-based-pep-508-uri-reference/2815, pypa/packaging#120).
Currently, I have a script
scripts/build-sdist.sh
which patches this in the egg metadata so the full path isn't leaked. Once these issues have been solved upstream we'll have a more elegant solution here.Calling AutoROM from a subpackage
When
pip
is installing the subpackagelicense
it doesn't yet have access to the mainAutoROM
package. Furthermore, pip creates a temporary directory for each package regardless of where it was originally located. This means we can't just modifysys.path
to look for AutoROM in the appropriate directory. The solution here is to useMANIFEST.in
with a symlink fromlicense/AutoROM.py -> AutoROM.py
. When building the source distribution the symlink is realized and the file is copied tolicense/AutoROM.py
. I think this is the best solution we're going to get.To make this work I removed
checksums.txt
and put it inAutoROM.py
. This is fine for the time being, once multi-agent ALE is upstreamed we won't even need this checksum map.