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

Update distutils.core.setup/run_setup to better match setuptools.build_meta. #71

Merged
merged 8 commits into from
Nov 22, 2021

Conversation

abravalheri
Copy link
Contributor

@abravalheri abravalheri commented Nov 21, 2021

Motivation

I noticed that setuptools.build_meta "re-implements" the run_setup function (there are differences between the 2 functions, e.g. distutils.core.run_setup wraps the code in a try...except, but the main idea behind both look similar to me).

There is one major difference: setuptools use tokenize.open and replaces \r\n with \n.
I went through setuptools commit history but did not find any comments/commit messages explaining exactly why, but I assume that it improves encoding detection.

My intention with this PR is to update the distutils code using the same technique as used in setuptools, so eventually the same function could be used.

Changes

  • Use the same tokenize.open technique as employed by setuptools.build_meta in distutils.core.run_setup.
  • Additionally, I refactored the origin setup function and split out run_commands, this way, one can use dist = run_setup("setup.py", stop_after="config") to get the configuration and later run run_commands(dist).
  • I also added some tests.

Side note

In terms of implications for setuptools, I imagine that eventually we could build the "new-static-config-style" distribution objects directly from the setup.cfg/pyproject.toml and then run them with run_commands, instead of always creating a setup.py stub.

Similarly, when setup.py is found, dist = run_setup("setup.py", stop_after="config") could be used to obtain the dist object and then revert to the same flow as a setup.cfg/pyproject.toml-only project...

(Basically a change in the mental model, instead of making setup.cfg/pyproject.toml use the same flow as setup.py one, we can make a setup.py use the same flow as setup.cfg).

Adds a unit test for that scenario
`setuptools.build_meta` uses `tokenize.open` instead of open
(and replaces `\r\n` with `\n`) when exec-ing `setup.py` files.

It seems that the advantage of using `tokenize.open` is that it supports
automatic encoding detection.
This allows reusing the function for already made distribution objects.
@abravalheri abravalheri marked this pull request as ready for review November 21, 2021 13:47
try:
try:
sys.argv[0] = script_name
if script_args is not None:
sys.argv[1:] = script_args
with open(script_name, 'rb') as f:
exec(f.read(), g)
_open = getattr(tokenize, 'open', open)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If Python < 3.2 is not supported, this getattr could also be dropped.
I was not sure about which version distutils is targetting.

Copy link
Member

Choose a reason for hiding this comment

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

It should be the same as setuptools, so this could be dropped.

Copy link
Member

@FFY00 FFY00 left a comment

Choose a reason for hiding this comment

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

This looks good to me, thanks! But I want @jaraco to have a look, just as a sanity check, before merging.

@abravalheri
Copy link
Contributor Author

Thank you very much @FFY00 for the review.

I updated he code to use tokenize.open directly, since it is available on Python >= 3.2

Copy link
Member

@jaraco jaraco left a comment

Choose a reason for hiding this comment

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

This change is dangerously close to an enhancement. For context, I'd like to limit feature enhancements for distutils to only the most urgent (platform compatibility) until distutils is merged into Setuptools and maintained there. The reason is that the current state of affairs means that most users are using distutils from the stdlib and not from this repo. Until SETUPTOOLS_USE_DISTUTILS=local becomes the default, this code is largely un-validated in the wild. Limiting the divergence of this repo with stdlib distutils will limit the amount of divergence and thus surprise when this distutils becomes default.

That said, this change is primarily about aligning with Setuptools, whose technique is proven and verified in the wild, so this change will actually aid in distutils adoption and limit the amount of divergence.

For that reason, let's proceed.

distutils/dist.py Outdated Show resolved Hide resolved
@jaraco jaraco merged commit 85db7a4 into pypa:main Nov 22, 2021
@abravalheri abravalheri deleted the use-tokenize branch November 22, 2021 15:23
@abravalheri
Copy link
Contributor Author

Thank you very much @jaraco. I will keep that in mind, and I totally understand what you explained.

jaraco added a commit that referenced this pull request Jul 1, 2023
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 this pull request may close these issues.

3 participants