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

PEP-517 source distribution support #954

Merged
merged 14 commits into from
Sep 11, 2018
Merged

Conversation

gaborbernat
Copy link
Member

@gaborbernat gaborbernat commented Aug 30, 2018

create a .package virtual environment to perform build operations inside

@asottile @nicoddemus @obestwalter feel free to take a look at it and try to find holes in it 👍 base implementation there, just need to add documentation and some more tests 💯

FYI @pfmoore (we probably will switch over pip once pip will have pep-517 support and build command - that being said I find this level a support a bit more generic e.g. python version selection). With this tox should finally allow users to specify their packaging dependencies, and use other than setuptools.

on it

Resolves #573 and #820.

@gaborbernat gaborbernat force-pushed the pep-517/8 branch 3 times, most recently from 1fc779d to 17d57d1 Compare August 30, 2018 13:30
@pfmoore
Copy link

pfmoore commented Aug 30, 2018

Nice! I'll try to find some time to take a proper look at this. (FYI, the initial implementation of PEP 517 in pip won't include a pip build command, but pip wheel will use PEP 517, I don't know if that's sufficient for you).

@gaborbernat gaborbernat force-pushed the pep-517/8 branch 6 times, most recently from 9c18663 to dee1481 Compare August 30, 2018 18:28
@codecov
Copy link

codecov bot commented Aug 30, 2018

Codecov Report

Merging #954 into master will decrease coverage by 1.01%.
The diff coverage is 69.07%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #954      +/-   ##
==========================================
- Coverage   92.77%   91.75%   -1.02%     
==========================================
  Files          13       13              
  Lines        2393     2473      +80     
  Branches      416      433      +17     
==========================================
+ Hits         2220     2269      +49     
- Misses        109      137      +28     
- Partials       64       67       +3
Impacted Files Coverage Δ
src/tox/_pytestplugin.py 92.65% <100%> (ø) ⬆️
src/tox/session.py 91.82% <100%> (+0.01%) ⬆️
src/tox/venv.py 93.19% <100%> (-0.32%) ⬇️
src/tox/package.py 71.31% <59.15%> (-17.98%) ⬇️
src/tox/config.py 95.74% <93.75%> (-0.05%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 9335906...ba9572f. Read the comment docs.

@gaborbernat gaborbernat force-pushed the pep-517/8 branch 7 times, most recently from b288d32 to bcbc2ab Compare August 31, 2018 17:18
@gaborbernat gaborbernat added the feature:new something does not exist yet, but should label Aug 31, 2018
@gaborbernat gaborbernat changed the title [WIP] PEP-517 source distribution support PEP-517 source distribution support Aug 31, 2018
@asottile
Copy link
Contributor

I'll take a look at this later today -- excited for this!

Copy link
Member Author

@gaborbernat gaborbernat left a comment

Choose a reason for hiding this comment

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

left some comments as questions for reviewers, reminders for myself

config.isolated_build = reader.getbool("isolated_build", False)
if config.isolated_build is True:
name = ".package"
if name not in config.envconfigs:
Copy link
Member Author

Choose a reason for hiding this comment

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

the build env name should be configurable

if pkg_requirement.key not in toml_require:
package_venv.envconfig.deps.append(DepConfig(requirement, None))

if not session.setupenv(package_venv):
Copy link
Member Author

Choose a reason for hiding this comment

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

here we are recreating the env maybe instead just install new dependencies and finalize again the env

Copy link
Contributor

Choose a reason for hiding this comment

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

recreate is certainly the safest option here -- does the PEP have any suggestions for this?

build_requires = get_build_requires(build_info, package_venv, session)
for requirement in build_requires:
pkg_requirement = pkg_resources.Requirement(requirement)
if pkg_requirement.key not in toml_require:
Copy link
Member Author

Choose a reason for hiding this comment

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

note here we might potentially have a issue that this requirement might differ from the first, maybe check for it and raise if that's the case

build_info.backend_module,
build_info.backend_object,
"sdist",
str(config.distdir).replace("\\", "\\\\"),
Copy link
Member Author

Choose a reason for hiding this comment

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

instead of the replace mark the output build directory as a raw string


@pytest.mark.network
@need_git
@pytest.mark.skipif(sys.version_info < (3, 0), reason="flit is Python 3 only")
Copy link
Member Author

Choose a reason for hiding this comment

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

in CI instead of skip should raise instead

Copy link
Contributor

Choose a reason for hiding this comment

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

xfail maybe then?

@@ -0,0 +1,18 @@
import subprocess
Copy link
Member Author

Choose a reason for hiding this comment

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

@asottile @Nicodeamus stolen this from pip any better way of doing this?

Copy link
Contributor

Choose a reason for hiding this comment

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

this seems fine, maybe a bit overkill to generalize. pre-commit does a similar thing

Copy link
Contributor

Choose a reason for hiding this comment

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

actually -- is this even worth it? I don't think we package our tests so you'd have to be running from a git checkout? I guess maybe not for OS vendors 🤔

tox.ini Outdated
known_first_party = tox
known_third_party = apiclient,git,httplib2,oauth2client,packaging,pkg_resources,pluggy,py,pytest,setuptools,six
known_first_party = tox,tests
known_third_party = apiclient,git,httplib2,oauth2client,packaging,pkg_resources,pluggy,py,pytest,setuptools,six,tests,toml
Copy link
Member Author

Choose a reason for hiding this comment

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

@asottile for some reason tests shows up as third party even though it is marked as first party

Copy link
Contributor

Choose a reason for hiding this comment

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

you'll want to change --application-directories from src to src:. here

Copy link
Contributor

@asottile asottile 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 comments, feel free to dismiss most of them, some of them are just me talking to myself.

I jotted down these notes while going through, some probably (?) need addressing -- not sure:

needs documentation:

  • isolated_build setting
  • .package environment name
  • maybe an example which shows how to configure the executable for the .package environment (and/or other useful things to override there?)

question:

  • does the .package environment leak into tox --listenvs (or whatever the option is called) -- (either way) should it?
  • is .package a good enough name to avoid conflicts (probably)? if not maybe .tox-package?

Will wheel support want to make N .package environments -- does this enable that or make it more difficult?

Overall seems fine!

name: {
"__init__.py": textwrap.dedent(
"""
\"\"\" module {} \"\"\"
Copy link
Contributor

Choose a reason for hiding this comment

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

probably avoid the escape sequences by making either the inner or outer a triple-single-quoted string

@@ -1005,6 +1005,13 @@ def __init__(self, config, inipath): # noqa
)

config.skipsdist = reader.getbool("skipsdist", all_develop)
config.isolated_build = reader.getbool("isolated_build", False)
if config.isolated_build is True:
Copy link
Contributor

Choose a reason for hiding this comment

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

I assume the idea with this branch is to make the .package environment user-configurable through tox.ini -- which cases does it make sense for that to be configurable? (alternatively: should tox have an opinion about how they configure the .package environment?)

I can see one usecase, wanted to configure the executable

report.error("FAIL could not package project - v = {!r}".format(v))
path = build_package(config, report, session)
except tox.exception.InvocationError as exception:
report.error("FAIL could not package project - v = {!r}".format(exception))
Copy link
Contributor

Choose a reason for hiding this comment

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

<3 ty

def build_isolated(config, report, session):
build_info = get_build_info(config.setupdir, report)
package_venv = session.getvenv(".package")
package_venv.envconfig.deps_matches_subset = True
Copy link
Contributor

Choose a reason for hiding this comment

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

clever, a patch!

package_venv = session.getvenv(".package")
package_venv.envconfig.deps_matches_subset = True

package_venv.envconfig.deps = [DepConfig(r, None) for r in build_info.requires]
Copy link
Contributor

Choose a reason for hiding this comment

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

since we're invariably clobbering deps = here, should we error if the user configured deps in their tox.ini? (might be difficult to implement now that I think about it, due to environment inheritance)

tox-pip-extensions for instance does this if the install_command is manually set (since it patches it out)

tox.ini Outdated
known_first_party = tox
known_third_party = apiclient,git,httplib2,oauth2client,packaging,pkg_resources,pluggy,py,pytest,setuptools,six
known_first_party = tox,tests
known_third_party = apiclient,git,httplib2,oauth2client,packaging,pkg_resources,pluggy,py,pytest,setuptools,six,tests,toml
Copy link
Contributor

Choose a reason for hiding this comment

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

you'll want to change --application-directories from src to src:. here

def linesep_bytes():
if isinstance(os.linesep, bytes):
return os.linesep
return os.linesep.encode("utf-8")
Copy link
Contributor

Choose a reason for hiding this comment

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

can probably just use os.linesep.encode() -- in python2 this'll go through the ASCII encoding .decode().encode() but that's probably fine?

@@ -56,7 +60,14 @@ def test_broken_py_path_local_join_workaround_on_Windows(self, tmpdir, initproj,
initproj("spam-666", src_root=src_root)

init_file = tmpdir.join("spam", "spam", "__init__.py")
assert init_file.read_binary() == b"__version__ = '666'"
expected = b'""" module spam """' + linesep_bytes() + b"__version__ = '666'"
Copy link
Contributor

Choose a reason for hiding this comment

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

hail satan ig

@@ -18,7 +18,7 @@

Copy link
Contributor

Choose a reason for hiding this comment

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

worth moving all the tests in this PR? is the distinction between "unit" and not actually enforced / definitive / useful? is the extra typing worth it?

@@ -0,0 +1,18 @@
import subprocess
Copy link
Contributor

Choose a reason for hiding this comment

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

actually -- is this even worth it? I don't think we package our tests so you'd have to be running from a git checkout? I guess maybe not for OS vendors 🤔

@gaborbernat
Copy link
Member Author

gaborbernat commented Sep 1, 2018

@asottile

needs documentation: isolated_build setting, .package environment name
maybe an example which shows how to configure the executable for the .package environment (and/or other useful things to override there?)

Added some: the config flags plus an example page related to packaging.

does the .package environment leak into tox --listenvs (or whatever the option is called) -- (either way) should it?

It probably does, we need to filter it out. Will do and add test for it.

is .package a good enough name to avoid conflicts (probably)? if not maybe .tox-package?

Given that now it's configurable it's good enough I think especially with the . start to make it private/hidden so to say.

Will wheel support want to make N .package environments -- does this enable that or make it more difficult?

Wheel support will have to do the n separate package environments. Going from there maybe we should instead make the isolated_build a choice so people can swap out to other alternatives/options; such as the wheel instead of sdist. I would say the way we have packaging plugabble should be fairly easy to add wheel support later on (no way around it - will have to create up to n separate build envs though - n is the number of unique binary type - e.g. 2 if only py2 and py3, but with abi and other parameters can be a lot more).

@gaborbernat
Copy link
Member Author

gaborbernat commented Sep 9, 2018

This now is mostly complete. Will merge in on Monday unless we find something significant until then. Will re-read https://www.python.org/dev/peps/pep-0517/ before that to make sure we did not miss anything.

Python.org
The official home of the Python Programming Language

@obestwalter
Copy link
Member

obestwalter commented Nov 2, 2018

Better later than never: thank you @gaborbernat for your great work on this and thank you @asottile for reviewing 🎆 🎆 🎆

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature:new something does not exist yet, but should
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add support for PEP-517
4 participants