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

skip get_requires for setuptools projects #41

Merged
merged 24 commits into from
Jun 12, 2024

Conversation

jameslamb
Copy link
Member

@jameslamb jameslamb commented Jun 6, 2024

fixes #39

As of this change rapids-build-backend will do the following when asked to build a wheel for a project using setuptools as its build backend:

  • skip running setuptools.build_meta.get_requires_for_*() methods
  • raise an error if it appears that the project has a setup.py that is passing setup_requires to setuptools.setup()

See #39 for a lot more details.

Notes for Reviewers

How I tested this

Added new unit tests here.

Built from source on this branch in rapidsai/ucx-py#1044 and saw CI pass...things work as expected, based on a quick scan of the logs there. (ignore the failing docs build there, that'll pass once we've published new rapids-build-backend wheels).

(ucx-py build link)

Thoughts on releasing

This change is "breaking" in the sense that it changes the behavior in a user-visible way, but not in the practical sense... there are 0 projects currently using rapids-build-backend that should be affected by this change.

So I think that we should release rapids-build-backend with this change in it as v0.3.1, not v0.4.0, to avoid a round of PRs to update the existing rapids-build-backend pins across projects already using it.

@jameslamb jameslamb added breaking Introduces a breaking change improvement Improves an existing functionality labels Jun 6, 2024
@jameslamb jameslamb added non-breaking Introduces a non-breaking change breaking Introduces a breaking change and removed breaking Introduces a breaking change non-breaking Introduces a non-breaking change labels Jun 10, 2024
jameslamb added a commit to jameslamb/ucx-py that referenced this pull request Jun 10, 2024
@jameslamb jameslamb changed the title WIP: skip get_requires for setuptools projects skip get_requires for setuptools projects Jun 10, 2024
@jameslamb jameslamb marked this pull request as ready for review June 10, 2024 20:19
@jameslamb jameslamb requested review from a team as code owners June 10, 2024 20:19
@jameslamb jameslamb requested review from KyleFromNVIDIA and vyasr and removed request for a team June 10, 2024 20:19
@jameslamb jameslamb requested a review from bdice June 10, 2024 21:12
Copy link
Contributor

@vyasr vyasr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than creating a new examples directory for tests, can you reuse the existing templates? I would expect the existing dependencies.yaml and pyproject.toml files to work out of the box (although maybe you'll have to generalize dependencies.yaml, not sure). Adding setup.py there will allow you to also parametrize the tests so that you can test packages with setup.py in more scenarios (e.g. with setup_requires, setup_requires in a comment, etc).

rapids_build_backend/utils.py Show resolved Hide resolved
rapids_build_backend/impls.py Show resolved Hide resolved
rapids_build_backend/impls.py Show resolved Hide resolved
rapids_build_backend/impls.py Outdated Show resolved Hide resolved
rapids_build_backend/impls.py Outdated Show resolved Hide resolved
tests/test_packages.py Show resolved Hide resolved
@jameslamb jameslamb requested a review from a team as a code owner June 11, 2024 15:54
@jameslamb jameslamb requested a review from vyasr June 11, 2024 16:22
Copy link
Contributor

@vyasr vyasr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bunch of nitpicking on my part, but overall this looks ready to me.

README.md Show resolved Hide resolved
Comment on lines 331 to 346
("", False),
("from setuptools import setup\n\nsetup()\n", False),
# 'setup_requires' in a comment on its own line
("from setuptools import setup\n# setup_requires\n\nsetup()\n", False),
# 'setup_requires' actually passed into setup(), on the same line
("from setuptools import setup\nsetup(setup_requires=[])\n", True),
# 'setup_requires' actually passed into setup(), on its own line
(
"from setuptools import setup\nsetup(\n setup_requires=['rmm']\n)\n# setup_requires\n", # noqa: E501
True,
),
# 'setup_requires' actually passed into setup(), via a dictionary
(
"from setuptools import setup\nopts={'setup_requires': ['rmm']}\nsetup(**opts)\n", # noqa: E501
True,
),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a big deal, but this parametrization is hard to read. You might consider doing something like creating a list of multiline strings or something and then using zip(contents, errors) instead.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah you're right. I just tried reformatting it by removing "should this raise an error?" from the parameterization completely and splitting it into 2 tests (one with cases that shouldn't result in an error, one with cases that should).

I think it's a lot easier to read and understand now:

image

tests/test_impls.py Outdated Show resolved Hide resolved
package_dir = tmp_path / "pkg"
os.makedirs(package_dir)

template_args = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nit: This is my fault for creating this pattern (I assume it was me), but on second read it's certainly a bit strange to use the same template args for all the generate_from_template calls. It would probably be cleaner to have just the necessary ones for each file.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah as far as I can tell, there's 0 sharing of template arguments across the files, so it should be possible to instead do something like:

template_values = {
   "pyproject.toml": {
       "name": "something",
       "build_backend": "setuptools.build_meta
   },
   "dependencies.yaml": {
       "dependencies": {
            "cu11": ["cupy-cuda11x>=12.0.0"],
            "cu12": ["cupy-cuda12x>=12.0.0"],
        }
   }
}
generate_from_template(package_dir, template_args)

Where the top-level keys are the files to use and the dictionary passed after each one is the template arguments.

However... I'd rather not do that refactoring as part of this PR. I don't think that's THAT much better than the current state, at least with the small number of tests we currently have here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The three new tests are similar enough that I suspect you could convert them to a single parametrized test fairly easily, but I could be wrong.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the sets of assertions are different enough, and the setup before that small enough, to justify separate test cases.

They could get put into one parameterized test but that test would end like this:

if first_thing_being tested:
   # assertions
elif second_thing_being_testing:
   # other assertions
else:
   # third set of assertions

I think it's a little easier to follow the logic by keeping these new tests as separate cases.

@jameslamb
Copy link
Member Author

I pushed a new commit to the ucx-py PR that's building from this branch (rapidsai/ucx-py#1044), to test that this is still working. It is: https://github.com/rapidsai/ucx-py/actions/runs/9469286911/job/26087647602?pr=1044

@jameslamb
Copy link
Member Author

I just snuck a --file_key to --file-key change for rapidsai/dependency-file-generator#89 on here too, to get one closer to finishing that work. Think that's small and non-controversial enough to include here.

@jameslamb
Copy link
Member Author

Alright I think all the comments have been addressed, so gonna merge this and keep moving forward. Thanks everyone!

@jameslamb jameslamb merged commit 5e21884 into rapidsai:main Jun 12, 2024
7 checks passed
@jameslamb jameslamb deleted the setuptools branch June 12, 2024 13:02
@jameslamb jameslamb mentioned this pull request Jun 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking Introduces a breaking change improvement Improves an existing functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[RFC] handling CUDA-suffixed dependencies needed at setuptools.setup() time
3 participants