-
Notifications
You must be signed in to change notification settings - Fork 336
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
[Feature] Pure python package detection #628
Changes from all commits
8ffa7f0
09e44ae
2bb1726
f07d216
186694b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,7 +19,9 @@ | |
from tempfile import mkdtemp | ||
from StringIO import StringIO | ||
from pipes import quote | ||
from email.parser import Parser | ||
import subprocess | ||
import pkg_resources | ||
import os.path | ||
import shutil | ||
import sys | ||
|
@@ -200,10 +202,8 @@ def pip_to_rez_package_name(distribution): | |
|
||
def run_pip_command(command_args, pip_version=None, python_version=None): | ||
"""Run a pip command. | ||
|
||
Args: | ||
command_args (list of str): Args to pip. | ||
|
||
Returns: | ||
`subprocess.Popen`: Pip process. | ||
""" | ||
|
@@ -371,6 +371,22 @@ def pip_install_package(source_name, pip_version=None, python_version=None, | |
_cmd(context=context, command=cmd) | ||
_system = System() | ||
|
||
def pure_python_package(installed_dist): | ||
|
||
true_table = { | ||
"true": True, | ||
"false": False | ||
} | ||
|
||
packages = pkg_resources.find_distributions(destpath) | ||
dist = next((package for package in packages if package.key == installed_dist.key), None) | ||
wheel_data = dist.get_metadata('WHEEL') | ||
# see https://www.python.org/dev/peps/pep-0566/#json-compatible-metadata | ||
wheel_data = Parser().parsestr(wheel_data) | ||
|
||
# see https://www.python.org/dev/peps/pep-0427/#what-s-the-deal-with-purelib-vs-platlib | ||
return true_table[wheel_data["Root-Is-Purelib"]] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe add a little link to https://www.python.org/dev/peps/pep-0427/#what-s-the-deal-with-purelib-vs-platlib or something else that explains a little bit more what's the deal with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense I will add it. |
||
|
||
# Collect resulting python packages using distlib | ||
distribution_path = DistributionPath([destpath]) | ||
distributions = [d for d in distribution_path.get_distributions()] | ||
|
@@ -446,18 +462,26 @@ def make_root(variant, path): | |
shutil.copystat(source_file, destination_file) | ||
|
||
# determine variant requirements | ||
# TODO detect if platform/arch/os necessary, no if pure python | ||
variant_reqs = [] | ||
variant_reqs.append("platform-%s" % _system.platform) | ||
variant_reqs.append("arch-%s" % _system.arch) | ||
variant_reqs.append("os-%s" % _system.os) | ||
|
||
pure = pure_python_package(distribution) | ||
if not pure: | ||
variant_reqs.append("platform-%s" % _system.platform) | ||
variant_reqs.append("arch-%s" % _system.arch) | ||
|
||
if context is None: | ||
# since we had to use system pip, we have to assume system python version | ||
py_ver = '.'.join(map(str, sys.version_info[:2])) | ||
if pure: | ||
py_ver = '.'.join(map(str, sys.version_info[:1])) | ||
else: | ||
py_ver = '.'.join(map(str, sys.version_info[:2])) | ||
else: | ||
python_variant = context.get_resolved_package("python") | ||
py_ver = python_variant.version.trim(2) | ||
|
||
if pure: | ||
py_ver = python_variant.version.trim(1) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm thinking that we shouldn't do this; or, that we do it but only if we know it's safe to do so. "Safe" depends on whether there are markers in the requirements. For eg, if the package requires "foo-1.0 ; python-3.1.*", then the only way we can properly express the package's requirements in rez is if we variant on pthon-MAJOR.MINOR; otherwise we cannot specify foo as a requirement for just that case. I also suspect that the complexity in determining this from the markers isn't worth it, and that we should probably just stick to varianting on python-MAJOR.MINOR. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hello Allan, after discussing the issue with Thorsten we have reached an agreement that we can live without this particular change, trimming the minor version when dealing with pure packages. What is most important for us is the removal of the os as that adds a significant number of rebuilds when dealing with Windows versions (python x plat x arch x os) removing just one of these segments will make our work much much easier. Also. as you mention above it makes sense to keep the minor version since it might be a hard requirement for some packages that will cause other issues. I would like to explore the markers solution down the line so I will take a look and see if there is a way to achieve it, getting rid of the minor version will still be a big improvement if it is reliable. For now I will remove the minor version trimming so that we can continue with the review before the merge. |
||
else: | ||
py_ver = python_variant.version.trim(2) | ||
|
||
variant_reqs.append("python-%s" % py_ver) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A little comment here that points to the documentation about that would be great (like https://www.python.org/dev/peps/pep-0566/#json-compatible-metadata).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense I will add it.