Exemple #1
0
 def finalize_options(self):
     if parse_version(wheel.__version__) >= parse_version('0.34.0'):
         self.plat_name = get_platform(self.bdist_dir)
     else:
         self.plat_name = get_platform()
     if not sys.platform.startswith('win'):
         self.python_tag = "py2.py3"
     bdist_wheel.finalize_options(self)
Exemple #2
0
  def FromCurrentSystem(cls):
    """Fill a Uname from the currently running platform."""
    uname = platform.uname()
    fqdn = socket.getfqdn()
    if fqdn == _LOCALHOST:
      # Avoid returning 'localhost' when there is a better value to use.
      fqdn = socket.gethostname()
    system = uname[0]
    architecture, _ = platform.architecture()
    if system == "Windows":
      service_pack = platform.win32_ver()[2]
      kernel = uname[3]  # 5.1.2600
      release = uname[2]  # XP, 2000, 7
      version = uname[3] + service_pack  # 5.1.2600 SP3, 6.1.7601 SP1
    elif system == "Darwin":
      kernel = uname[2]  # 12.2.0
      release = "OSX"  # OSX
      version = platform.mac_ver()[0]  # 10.8.2
    elif system == "Linux":
      kernel = uname[2]  # 3.2.5
      release = distro.name()
      version = distro.version()

    # Emulate PEP 425 naming conventions - e.g. cp27-cp27mu-linux_x86_64.
    if pep425tags:
      try:
        # 0.33.6
        pep_platform = pep425tags.get_platform()
      except TypeError:
        # 0.34.2
        pep_platform = pep425tags.get_platform(None)
      pep425tag = "%s%s-%s-%s" % (
          pep425tags.get_abbr_impl(), pep425tags.get_impl_ver(),
          str(pep425tags.get_abi_tag()).lower(), pep_platform)
    else:
      # For example: windows_7_amd64
      pep425tag = "%s_%s_%s" % (system, release, architecture)

    return cls(
        system=system,
        architecture=architecture,
        release=release,
        version=version,
        machine=uname[4],  # x86, x86_64
        kernel=kernel,
        fqdn=fqdn,
        pep425tag=pep425tag,
    )
Exemple #3
0
 def main_loop(self, queue, timeout=300):
     """
     The main messaging loop. Sends the initial request, and dispatches
     replies via :meth:`handle_reply`. Implements a *timeout* for responses
     from the master and raises :exc:`MasterTimeout` if *timeout* seconds
     are exceeded.
     """
     msg, data = 'HELLO', [
         self.config.timeout,
         pep425tags.get_impl_ver(),
         pep425tags.get_abi_tag(),
         pep425tags.get_platform(), self.label
     ]
     while True:
         queue.send_msg(msg, data)
         start = time()
         while True:
             self.systemd.watchdog_ping()
             if queue.poll(1):
                 msg, data = queue.recv_msg()
                 msg, data = self.handle_reply(msg, data)
                 break
             elif time() - start > timeout:
                 self.logger.warning('Timed out waiting for master')
                 raise MasterTimeout()
Exemple #4
0
 def test_simple(self, monkeypatch):
     dirname = os.path.dirname(__file__)
     dylib_dir = os.path.join(dirname, "testdata",
                              "macosx_minimal_system_version")
     monkeypatch.setattr(distutils.util, "get_platform",
                         return_factory("macosx-10.14-x86_64"))
     assert get_platform(dylib_dir) == "macosx_10_14_x86_64"
    def get_tag(self):
        # bdist sets self.plat_name if unset, we should only use it for purepy
        # wheels if the user supplied it.
        if self.plat_name_supplied:
            plat_name = self.plat_name
        elif self.root_is_pure:
            plat_name = 'any'
        else:
            plat_name = self.plat_name or get_platform()
            if plat_name in ('linux-x86_64',
                             'linux_x86_64') and sys.maxsize == 2147483647:
                plat_name = 'linux_i686'
        plat_name = plat_name.replace('-', '_').replace('.', '_')

        if self.root_is_pure:
            if self.universal:
                impl = 'py2.py3'
            else:
                impl = self.python_tag
            tag = (impl, 'none', plat_name)
        else:
            impl_name = get_abbr_impl()
            impl_ver = get_impl_ver()
            # PEP 3149
            abi_tag = str(get_abi_tag()).lower()
            tag = (impl_name + impl_ver, abi_tag, plat_name)
            supported_tags = pep425tags.get_supported(
                supplied_platform=plat_name if self.
                plat_name_supplied else None)
            # XXX switch to this alternate implementation for non-pure:
            assert tag == supported_tags[0], "%s != %s" % (tag,
                                                           supported_tags[0])
        return tag
Exemple #6
0
 def get_tag(self):
     plat_name = self.plat_name or get_platform()
     if plat_name in ('linux-x86_64', 'linux_x86_64') \
        and sys.maxsize == (1 << 31) - 1:
         plat_name = 'linux_i686'
     plat_name = plat_name.replace('-', '_').replace('.', '_')
     return ('py2.py3', 'none', plat_name)
Exemple #7
0
 def main_loop(self, queue, timeout=300):
     """
     The main messaging loop. Sends the initial request, and dispatches
     replies via :meth:`handle_reply`. Implements a *timeout* for responses
     from the master and raises :exc:`MasterTimeout` if *timeout* seconds
     are exceeded.
     """
     request = [
         'HELLO', self.config.timeout,
         pep425tags.get_impl_ver(),
         pep425tags.get_abi_tag(),
         pep425tags.get_platform(), self.label
     ]
     while True:
         queue.send_pyobj(request)
         start = time()
         while True:
             self.systemd.watchdog_ping()
             if queue.poll(60000):
                 reply, *args = queue.recv_pyobj()
                 request = self.handle_reply(reply, *args)
                 break
             elif time() - start > timeout:
                 self.logger.warning('Timed out waiting for master')
                 if self.builder:
                     self.logger.warning('Discarding current build')
                     self.builder.clean()
                     self.builder = None
                 self.slave_id = None
                 raise MasterTimeout()
    def get_tag(self):
        # bdist sets self.plat_name if unset, we should only use it for purepy
        # wheels if the user supplied it.
        if self.plat_name_supplied:
            plat_name = self.plat_name
        elif self.root_is_pure:
            plat_name = 'any'
        else:
            plat_name = self.plat_name or get_platform()
            if plat_name in ('linux-x86_64', 'linux_x86_64') and sys.maxsize == 2147483647:
                plat_name = 'linux_i686'
        plat_name = plat_name.replace('-', '_').replace('.', '_')


        if self.root_is_pure:
            if self.universal:
                impl = 'py2.py3'
            else:
                impl = self.python_tag
            tag = (impl, 'none', plat_name)
        else:
            impl_name = get_abbr_impl()
            impl_ver = get_impl_ver()
            # PEP 3149
            abi_tag = str(get_abi_tag()).lower()
            tag = (impl_name + impl_ver, abi_tag, plat_name)
            supported_tags = pep425tags.get_supported(
                supplied_platform=plat_name if self.plat_name_supplied else None)
            # XXX switch to this alternate implementation for non-pure:
            assert tag == supported_tags[0], "%s != %s" % (tag, supported_tags[0])
        return tag
Exemple #9
0
 def test_bump_platform_tag_by_env_variable(self, monkeypatch, capsys):
     dirname = os.path.dirname(__file__)
     dylib_dir = os.path.join(dirname, "testdata",
                              "macosx_minimal_system_version")
     monkeypatch.setattr(distutils.util, "get_platform",
                         return_factory("macosx-10.9-x86_64"))
     monkeypatch.setattr(
         os, "walk",
         return_factory([
             (dylib_dir, [],
              ["test_lib_10_6.dylib", "test_lib_10_6_fat.dylib"])
         ]))
     assert get_platform(dylib_dir) == "macosx_10_9_x86_64"
     monkeypatch.setenv("MACOSX_DEPLOYMENT_TARGET", "10.10")
     assert get_platform(dylib_dir) == "macosx_10_10_x86_64"
     captured = capsys.readouterr()
     assert captured.err == ""
Exemple #10
0
 def finalize_options(self):
     bdist_wheel.finalize_options(self)
     self.root_is_pure = True
     self.plat_name_supplied = True
     self.plat_name = get_platform()
     self.universal = not sys.platform.startswith('win')
     if not self.universal:
         self.python_tag = 'py' + str(sys.version_info[0])
Exemple #11
0
 def test_version_bump(self, monkeypatch, capsys):
     dirname = os.path.dirname(__file__)
     dylib_dir = os.path.join(dirname, "testdata",
                              "macosx_minimal_system_version")
     monkeypatch.setattr(distutils.util, "get_platform",
                         return_factory("macosx-10.9-x86_64"))
     assert get_platform(dylib_dir) == "macosx_10_14_x86_64"
     captured = capsys.readouterr()
     assert "[WARNING] This wheel needs a higher macOS version than" in captured.err
Exemple #12
0
 def test_bugfix_release_platform_tag(self, monkeypatch, capsys):
     dirname = os.path.dirname(__file__)
     dylib_dir = os.path.join(dirname, "testdata",
                              "macosx_minimal_system_version")
     monkeypatch.setattr(distutils.util, "get_platform",
                         return_factory("macosx-10.9-x86_64"))
     monkeypatch.setattr(
         os, "walk",
         return_factory([(dylib_dir, [], [
             "test_lib_10_6.dylib", "test_lib_10_6_fat.dylib",
             "test_lib_10_10_10.dylib"
         ])]))
     assert get_platform(dylib_dir) == "macosx_10_10_x86_64"
     captured = capsys.readouterr()
     assert "This wheel needs a higher macOS version than" in captured.err
     monkeypatch.setenv("MACOSX_DEPLOYMENT_TARGET", "10.9")
     assert get_platform(dylib_dir) == "macosx_10_10_x86_64"
     captured = capsys.readouterr()
     assert "This wheel needs a higher macOS version than" in captured.err
Exemple #13
0
 def test_warning_on_to_low_env_variable(self, monkeypatch, capsys):
     dirname = os.path.dirname(__file__)
     dylib_dir = os.path.join(dirname, "testdata",
                              "macosx_minimal_system_version")
     monkeypatch.setattr(distutils.util, "get_platform",
                         return_factory("macosx-10.9-x86_64"))
     monkeypatch.setenv("MACOSX_DEPLOYMENT_TARGET", "10.8")
     monkeypatch.setattr(
         os, "walk",
         return_factory([
             (dylib_dir, [],
              ["test_lib_10_6.dylib", "test_lib_10_6_fat.dylib"])
         ]))
     assert get_platform(dylib_dir) == "macosx_10_9_x86_64"
     captured = capsys.readouterr()
     assert "MACOSX_DEPLOYMENT_TARGET is set to a lower value (10.8) than the" in captured.err
Exemple #14
0
 def test_information_about_problematic_files_python_version(
         self, monkeypatch, capsys):
     dirname = os.path.dirname(__file__)
     dylib_dir = os.path.join(dirname, "testdata",
                              "macosx_minimal_system_version")
     monkeypatch.setattr(distutils.util, "get_platform",
                         return_factory("macosx-10.9-x86_64"))
     monkeypatch.setattr(
         os, "walk",
         return_factory([
             (dylib_dir, [],
              ["test_lib_10_6.dylib", "test_lib_10_10_fat.dylib"])
         ]))
     assert get_platform(dylib_dir) == "macosx_10_10_x86_64"
     captured = capsys.readouterr()
     assert "[WARNING] This wheel needs a higher macOS version than" in captured.err
     assert "the version your Python interpreter is compiled against." in captured.err
     assert "test_lib_10_10_fat.dylib" in captured.err
Exemple #15
0
 def test_information_about_problematic_files_env_variable(
         self, monkeypatch, capsys):
     dirname = os.path.dirname(__file__)
     dylib_dir = os.path.join(dirname, "testdata",
                              "macosx_minimal_system_version")
     monkeypatch.setattr(distutils.util, "get_platform",
                         return_factory("macosx-10.9-x86_64"))
     monkeypatch.setenv("MACOSX_DEPLOYMENT_TARGET", "10.8")
     monkeypatch.setattr(
         os, "walk",
         return_factory([
             (dylib_dir, [],
              ["test_lib_10_6.dylib", "test_lib_10_10_fat.dylib"])
         ]))
     assert get_platform(dylib_dir) == "macosx_10_10_x86_64"
     captured = capsys.readouterr()
     assert "[WARNING] This wheel needs a higher macOS version than" in captured.err
     assert "is set in MACOSX_DEPLOYMENT_TARGET variable." in captured.err
     assert "test_lib_10_10_fat.dylib" in captured.err
Exemple #16
0
    def FromCurrentSystem(cls):
        """Fill a Uname from the currently running platform."""
        uname = platform.uname()
        fqdn = socket.getfqdn()
        system = uname[0]
        architecture, _ = platform.architecture()
        if system == "Windows":
            service_pack = platform.win32_ver()[2]
            kernel = uname[3]  # 5.1.2600
            release = uname[2]  # XP, 2000, 7
            version = uname[3] + service_pack  # 5.1.2600 SP3, 6.1.7601 SP1
        elif system == "Darwin":
            kernel = uname[2]  # 12.2.0
            release = "OSX"  # OSX
            version = platform.mac_ver()[0]  # 10.8.2
        elif system == "Linux":
            kernel = uname[2]  # 3.2.5
            release = platform.linux_distribution()[0]  # Ubuntu
            version = platform.linux_distribution()[1]  # 12.04

        # Emulate PEP 425 naming conventions - e.g. cp27-cp27mu-linux_x86_64.
        if pep425tags:
            pep425tag = "%s%s-%s-%s" % (
                pep425tags.get_abbr_impl(),
                pep425tags.get_impl_ver(),
                str(pep425tags.get_abi_tag()).lower(),
                pep425tags.get_platform(),
            )
        else:
            # For example: windows_7_amd64
            pep425tag = "%s_%s_%s" % (system, release, architecture)

        return cls(
            system=system,
            architecture=architecture,
            node=uname[1],
            release=release,
            version=version,
            machine=uname[4],  # x86, x86_64
            kernel=kernel,
            fqdn=fqdn,
            pep425tag=pep425tag,
        )
    def _generate_snapshot_bdist_wheel_argv(self, snapshot_fingerprint, is_platform_specific):
        """Create a command line to generate a wheel via `setup.py`.

        Note that distutils will convert `snapshot_fingerprint` into a string suitable for a version
        tag. Currently for versioned target fingerprints, this seems to convert all punctuation into
        '.' and downcase all ASCII chars. See https://www.python.org/dev/peps/pep-0440/ for further
        information on allowed version names.

        NB: adds a '+' before the fingerprint to the build tag!
        """
        egg_info_snapshot_tag_args = ["egg_info", f"--tag-build=+{snapshot_fingerprint}"]
        bdist_whl_args = ["bdist_wheel"]
        if is_platform_specific:
            platform_args = ["--plat-name", pep425tags.get_platform()]
        else:
            platform_args = []

        dist_dir_args = ["--dist-dir", self._DIST_OUTPUT_DIR]

        return egg_info_snapshot_tag_args + bdist_whl_args + platform_args + dist_dir_args
Exemple #18
0
    def FromCurrentSystem(cls):
        """Fill a Uname from the currently running platform."""
        uname = platform.uname()
        fqdn = socket.getfqdn()
        system = uname[0]
        architecture, _ = platform.architecture()
        if system == "Windows":
            service_pack = platform.win32_ver()[2]
            kernel = uname[3]  # 5.1.2600
            release = uname[2]  # XP, 2000, 7
            version = uname[3] + service_pack  # 5.1.2600 SP3, 6.1.7601 SP1
        elif system == "Darwin":
            kernel = uname[2]  # 12.2.0
            release = "OSX"  # OSX
            version = platform.mac_ver()[0]  # 10.8.2
        elif system == "Linux":
            kernel = uname[2]  # 3.2.5
            release = platform.linux_distribution()[0]  # Ubuntu
            version = platform.linux_distribution()[1]  # 12.04

        # Emulate PEP 425 naming conventions - e.g. cp27-cp27mu-linux_x86_64.
        if pep425tags:
            pep425tag = "%s%s-%s-%s" % (pep425tags.get_abbr_impl(),
                                        pep425tags.get_impl_ver(),
                                        str(pep425tags.get_abi_tag()).lower(),
                                        pep425tags.get_platform())
        else:
            # For example: windows_7_amd64
            pep425tag = "%s_%s_%s" % (system, release, architecture)

        return cls(
            system=system,
            architecture=architecture,
            node=uname[1],
            release=release,
            version=version,
            machine=uname[4],  # x86, x86_64
            kernel=kernel,
            fqdn=fqdn,
            pep425tag=pep425tag,
        )
Exemple #19
0
    def from_current_system(cls, session=None):
        """Gets a Uname object populated from the current system"""
        uname = platform.uname()
        fqdn = socket.getfqdn()
        system = uname[0]
        architecture, _ = platform.architecture()
        if system == "Windows":
            service_pack = platform.win32_ver()[2]
            kernel = uname[3]  # 5.1.2600
            release = uname[2]  # XP, 2000, 7
            version = uname[3] + service_pack  # 5.1.2600 SP3, 6.1.7601 SP1
        elif system == "Darwin":
            kernel = uname[2]  # 12.2.0
            release = "OSX"  # OSX
            version = platform.mac_ver()[0]  # 10.8.2
        elif system == "Linux":
            kernel = uname[2]  # 3.2.5
            release = platform.linux_distribution()[0]  # Ubuntu
            version = platform.linux_distribution()[1]  # 12.04

        # Emulate PEP 425 naming conventions - e.g. cp27-cp27mu-linux_x86_64.
        pep425tag = "%s%s-%s-%s" % (pep425tags.get_abbr_impl(),
                                    pep425tags.get_impl_ver(),
                                    str(pep425tags.get_abi_tag()).lower(),
                                    pep425tags.get_platform())

        return cls.from_keywords(
            session=session,
            system=system,
            architecture=architecture,
            node=uname[1],
            release=release,
            version=version,
            machine=uname[4],              # x86, x86_64
            kernel=kernel,
            fqdn=fqdn,
            pep425tag=pep425tag,
        )
Exemple #20
0
    def from_current_system(cls, session=None):
        """Gets a Uname object populated from the current system"""
        uname = platform.uname()
        fqdn = socket.getfqdn()
        system = uname[0]
        architecture, _ = platform.architecture()
        if system == "Windows":
            service_pack = platform.win32_ver()[2]
            kernel = uname[3]  # 5.1.2600
            release = uname[2]  # XP, 2000, 7
            version = uname[3] + service_pack  # 5.1.2600 SP3, 6.1.7601 SP1
        elif system == "Darwin":
            kernel = uname[2]  # 12.2.0
            release = "OSX"  # OSX
            version = platform.mac_ver()[0]  # 10.8.2
        elif system == "Linux":
            kernel = uname[2]  # 3.2.5
            release = platform.linux_distribution()[0]  # Ubuntu
            version = platform.linux_distribution()[1]  # 12.04

        # Emulate PEP 425 naming conventions - e.g. cp27-cp27mu-linux_x86_64.
        pep425tag = "%s%s-%s-%s" % (pep425tags.get_abbr_impl(),
                                    pep425tags.get_impl_ver(),
                                    str(pep425tags.get_abi_tag()).lower(),
                                    pep425tags.get_platform())

        return cls.from_keywords(
            session=session,
            system=system,
            architecture=architecture,
            node=uname[1],
            release=release,
            version=version,
            machine=uname[4],              # x86, x86_64
            kernel=kernel,
            fqdn=fqdn,
            pep425tag=pep425tag,
        )
Exemple #21
0
import shutil

from wheel.pep425tags import get_abi_tag, get_platform

os.environ["PYTHONDONTWRITEBYTECODE"] = "1"


def run(cmd):
    print(cmd)
    try:
        subprocess.check_call(cmd)
    except subprocess.CalledProcessError as e:
        sys.exit(e.returncode)


venv = "test-venv-{}-{}".format(get_abi_tag(), get_platform())

if not exists(venv):
    print("-- Creating venv in {} --".format(venv))
    run([sys.executable, "-m", "virtualenv", "-p", sys.executable, venv])

python_candidates = [
    join(venv, "bin", "python"),
    join(venv, "Scripts", "python.exe"),
]
for python_candidate in python_candidates:
    if exists(python_candidate):
        python_exe = python_candidate
        break
else:
    raise RuntimeError("I don't understand this platform's virtualenv layout")
Exemple #22
0
 def initialize_options(self):
     super(PlatformBDistWheel, self).initialize_options()
     if self.plat_name is None:
         self.plat_name = get_platform()
Exemple #23
0
 def get_tag(self):
     return ('py3', 'none',
             self.plat_name if self.plat_name_supplied \
                            else get_platform(self.bdist_dir))
Exemple #24
0
 def finalize_options(self):
     self.plat_name = get_platform()
     if not sys.platform.startswith('win'):
         self.python_tag = "py2.py3"
     bdist_wheel.finalize_options(self)
Exemple #25
0
def get_platform():
    return wheel_tags.get_platform()
Exemple #26
0
def normalized_current_platform() -> str:
    return _normalize_platform_tag(pep425tags.get_platform())
Exemple #27
0
def get_platform():
    return wheel_tags.get_platform()
class bdist_wheel(Command):

    description = 'create a wheel distribution'

    user_options = [
        ('bdist-dir=', 'b',
         "temporary directory for creating the distribution"),
        ('plat-name=', 'p', "platform name to embed in generated filenames "
         "(default: %s)" % get_platform()),
        ('keep-temp', 'k', "keep the pseudo-installation tree around after " +
         "creating the distribution archive"),
        ('dist-dir=', 'd', "directory to put final built distributions in"),
        ('skip-build', None,
         "skip rebuilding everything (for testing/debugging)"),
        ('relative', None, "build the archive using relative paths"
         "(default: false)"),
        ('owner=', 'u', "Owner name used when creating a tar file"
         " [default: current user]"),
        ('group=', 'g', "Group name used when creating a tar file"
         " [default: current group]"),
        ('universal', None, "make a universal wheel"
         " (default: false)"),
        ('python-tag=', None, "Python implementation compatibility tag"
         " (default: py%s)" % get_impl_ver()[0]),
    ]

    boolean_options = ['keep-temp', 'skip-build', 'relative', 'universal']

    def initialize_options(self):
        self.bdist_dir = None
        self.data_dir = None
        self.plat_name = None
        self.plat_tag = None
        self.format = 'zip'
        self.keep_temp = False
        self.dist_dir = None
        self.distinfo_dir = None
        self.egginfo_dir = None
        self.root_is_pure = None
        self.skip_build = None
        self.relative = False
        self.owner = None
        self.group = None
        self.universal = False
        self.python_tag = 'py' + get_impl_ver()[0]
        self.plat_name_supplied = False

    def finalize_options(self):
        if self.bdist_dir is None:
            bdist_base = self.get_finalized_command('bdist').bdist_base
            self.bdist_dir = os.path.join(bdist_base, 'wheel')

        self.data_dir = self.wheel_dist_name + '.data'
        self.plat_name_supplied = self.plat_name is not None

        need_options = ('dist_dir', 'plat_name', 'skip_build')

        self.set_undefined_options('bdist', *zip(need_options, need_options))

        self.root_is_pure = not (self.distribution.has_ext_modules()
                                 or self.distribution.has_c_libraries())

        # Support legacy [wheel] section for setting universal
        wheel = self.distribution.get_option_dict('wheel')
        if 'universal' in wheel:
            # please don't define this in your global configs
            val = wheel['universal'][1].strip()
            if val.lower() in ('1', 'true', 'yes'):
                self.universal = True

    @property
    def wheel_dist_name(self):
        """Return distribution full name with - replaced with _"""
        return '-'.join((safer_name(self.distribution.get_name()),
                         safer_version(self.distribution.get_version())))

    def get_tag(self):
        # bdist sets self.plat_name if unset, we should only use it for purepy
        # wheels if the user supplied it.
        if self.plat_name_supplied:
            plat_name = self.plat_name
        elif self.root_is_pure:
            plat_name = 'any'
        else:
            plat_name = self.plat_name or get_platform()
            if plat_name in ('linux-x86_64',
                             'linux_x86_64') and sys.maxsize == 2147483647:
                plat_name = 'linux_i686'
        plat_name = plat_name.replace('-', '_').replace('.', '_')

        if self.root_is_pure:
            if self.universal:
                impl = 'py2.py3'
            else:
                impl = self.python_tag
            tag = (impl, 'none', plat_name)
        else:
            impl_name = get_abbr_impl()
            impl_ver = get_impl_ver()
            # PEP 3149
            abi_tag = str(get_abi_tag()).lower()
            tag = (impl_name + impl_ver, abi_tag, plat_name)
            supported_tags = pep425tags.get_supported(
                supplied_platform=plat_name if self.
                plat_name_supplied else None)
            # XXX switch to this alternate implementation for non-pure:
            assert tag == supported_tags[0], "%s != %s" % (tag,
                                                           supported_tags[0])
        return tag

    def get_archive_basename(self):
        """Return archive name without extension"""

        impl_tag, abi_tag, plat_tag = self.get_tag()

        archive_basename = "%s-%s-%s-%s" % (self.wheel_dist_name, impl_tag,
                                            abi_tag, plat_tag)
        return archive_basename

    def run(self):
        build_scripts = self.reinitialize_command('build_scripts')
        build_scripts.executable = 'python'

        if not self.skip_build:
            self.run_command('build')

        install = self.reinitialize_command('install', reinit_subcommands=True)
        install.root = self.bdist_dir
        install.compile = False
        install.skip_build = self.skip_build
        install.warn_dir = False

        # A wheel without setuptools scripts is more cross-platform.
        # Use the (undocumented) `no_ep` option to setuptools'
        # install_scripts command to avoid creating entry point scripts.
        install_scripts = self.reinitialize_command('install_scripts')
        install_scripts.no_ep = True

        # Use a custom scheme for the archive, because we have to decide
        # at installation time which scheme to use.
        for key in ('headers', 'scripts', 'data', 'purelib', 'platlib'):
            setattr(install, 'install_' + key,
                    os.path.join(self.data_dir, key))

        basedir_observed = ''

        if os.name == 'nt':
            # win32 barfs if any of these are ''; could be '.'?
            # (distutils.command.install:change_roots bug)
            basedir_observed = os.path.normpath(
                os.path.join(self.data_dir, '..'))
            self.install_libbase = self.install_lib = basedir_observed

        setattr(install,
                'install_purelib' if self.root_is_pure else 'install_platlib',
                basedir_observed)

        logger.info("installing to %s", self.bdist_dir)

        self.run_command('install')

        archive_basename = self.get_archive_basename()

        pseudoinstall_root = os.path.join(self.dist_dir, archive_basename)
        if not self.relative:
            archive_root = self.bdist_dir
        else:
            archive_root = os.path.join(
                self.bdist_dir, self._ensure_relative(install.install_base))

        self.set_undefined_options('install_egg_info',
                                   ('target', 'egginfo_dir'))
        self.distinfo_dir = os.path.join(self.bdist_dir,
                                         '%s.dist-info' % self.wheel_dist_name)
        self.egg2dist(self.egginfo_dir, self.distinfo_dir)

        self.write_wheelfile(self.distinfo_dir)

        self.write_record(self.bdist_dir, self.distinfo_dir)

        # Make the archive
        if not os.path.exists(self.dist_dir):
            os.makedirs(self.dist_dir)
        wheel_name = archive_wheelfile(pseudoinstall_root, archive_root)

        # Sign the archive
        if 'WHEEL_TOOL' in os.environ:
            subprocess.call([os.environ['WHEEL_TOOL'], 'sign', wheel_name])

        # Add to 'Distribution.dist_files' so that the "upload" command works
        getattr(self.distribution, 'dist_files', []).append(
            ('bdist_wheel', get_python_version(), wheel_name))

        if not self.keep_temp:
            if self.dry_run:
                logger.info('removing %s', self.bdist_dir)
            else:
                rmtree(self.bdist_dir)

    def write_wheelfile(self,
                        wheelfile_base,
                        generator='bdist_wheel (' + wheel_version + ')'):
        from email.message import Message
        msg = Message()
        msg['Wheel-Version'] = '1.0'  # of the spec
        msg['Generator'] = generator
        msg['Root-Is-Purelib'] = str(self.root_is_pure).lower()

        # Doesn't work for bdist_wininst
        impl_tag, abi_tag, plat_tag = self.get_tag()
        for impl in impl_tag.split('.'):
            for abi in abi_tag.split('.'):
                for plat in plat_tag.split('.'):
                    msg['Tag'] = '-'.join((impl, abi, plat))

        wheelfile_path = os.path.join(wheelfile_base, 'WHEEL')
        logger.info('creating %s', wheelfile_path)
        with open(wheelfile_path, 'w') as f:
            Generator(f, maxheaderlen=0).flatten(msg)

    def _ensure_relative(self, path):
        # copied from dir_util, deleted
        drive, path = os.path.splitdrive(path)
        if path[0:1] == os.sep:
            path = drive + path[1:]
        return path

    def _pkginfo_to_metadata(self, egg_info_path, pkginfo_path):
        return metadata.pkginfo_to_metadata(egg_info_path, pkginfo_path)

    def license_file(self):
        """Return license filename from a license-file key in setup.cfg, or None."""
        metadata = self.distribution.get_option_dict('metadata')
        if not 'license_file' in metadata:
            return None
        return metadata['license_file'][1]

    def setupcfg_requirements(self):
        """Generate requirements from setup.cfg as
        ('Requires-Dist', 'requirement; qualifier') tuples. From a metadata
        section in setup.cfg:

        [metadata]
        provides-extra = extra1
            extra2
        requires-dist = requirement; qualifier
            another; qualifier2
            unqualified

        Yields

        ('Provides-Extra', 'extra1'),
        ('Provides-Extra', 'extra2'),
        ('Requires-Dist', 'requirement; qualifier'),
        ('Requires-Dist', 'another; qualifier2'),
        ('Requires-Dist', 'unqualified')
        """
        metadata = self.distribution.get_option_dict('metadata')

        # our .ini parser folds - to _ in key names:
        for key, title in (('provides_extra', 'Provides-Extra'),
                           ('requires_dist', 'Requires-Dist')):
            if not key in metadata:
                continue
            field = metadata[key]
            for line in field[1].splitlines():
                line = line.strip()
                if not line:
                    continue
                yield (title, line)

    def add_requirements(self, metadata_path):
        """Add additional requirements from setup.cfg to file metadata_path"""
        additional = list(self.setupcfg_requirements())
        if not additional: return
        pkg_info = read_pkg_info(metadata_path)
        if 'Provides-Extra' in pkg_info or 'Requires-Dist' in pkg_info:
            warnings.warn(
                'setup.cfg requirements overwrite values from setup.py')
            del pkg_info['Provides-Extra']
            del pkg_info['Requires-Dist']
        for k, v in additional:
            pkg_info[k] = v
        write_pkg_info(metadata_path, pkg_info)

    def egg2dist(self, egginfo_path, distinfo_path):
        """Convert an .egg-info directory into a .dist-info directory"""
        def adios(p):
            """Appropriately delete directory, file or link."""
            if os.path.exists(p) and not os.path.islink(p) and os.path.isdir(
                    p):
                shutil.rmtree(p)
            elif os.path.exists(p):
                os.unlink(p)

        adios(distinfo_path)

        if not os.path.exists(egginfo_path):
            # There is no egg-info. This is probably because the egg-info
            # file/directory is not named matching the distribution name used
            # to name the archive file. Check for this case and report
            # accordingly.
            import glob
            pat = os.path.join(os.path.dirname(egginfo_path), '*.egg-info')
            possible = glob.glob(pat)
            err = "Egg metadata expected at %s but not found" % (
                egginfo_path, )
            if possible:
                alt = os.path.basename(possible[0])
                err += " (%s found - possible misnamed archive file?)" % (
                    alt, )

            raise ValueError(err)

        if os.path.isfile(egginfo_path):
            # .egg-info is a single file
            pkginfo_path = egginfo_path
            pkg_info = self._pkginfo_to_metadata(egginfo_path, egginfo_path)
            os.mkdir(distinfo_path)
        else:
            # .egg-info is a directory
            pkginfo_path = os.path.join(egginfo_path, 'PKG-INFO')
            pkg_info = self._pkginfo_to_metadata(egginfo_path, pkginfo_path)

            # ignore common egg metadata that is useless to wheel
            shutil.copytree(egginfo_path,
                            distinfo_path,
                            ignore=lambda x, y: set((
                                'PKG-INFO',
                                'requires.txt',
                                'SOURCES.txt',
                                'not-zip-safe',
                            )))

            # delete dependency_links if it is only whitespace
            dependency_links_path = os.path.join(distinfo_path,
                                                 'dependency_links.txt')
            with open(dependency_links_path, 'r') as dependency_links_file:
                dependency_links = dependency_links_file.read().strip()
            if not dependency_links:
                adios(dependency_links_path)

        write_pkg_info(os.path.join(distinfo_path, 'METADATA'), pkg_info)

        # XXX deprecated. Still useful for current distribute/setuptools.
        metadata_path = os.path.join(distinfo_path, 'METADATA')
        self.add_requirements(metadata_path)

        # XXX intentionally a different path than the PEP.
        metadata_json_path = os.path.join(distinfo_path, 'metadata.json')
        pymeta = pkginfo_to_dict(metadata_path, distribution=self.distribution)

        if 'description' in pymeta:
            description_filename = 'DESCRIPTION.rst'
            description_text = pymeta.pop('description')
            description_path = os.path.join(distinfo_path,
                                            description_filename)
            with open(description_path, "wb") as description_file:
                description_file.write(description_text.encode('utf-8'))
            pymeta['extensions']['python.details']['document_names'][
                'description'] = description_filename

        # XXX heuristically copy any LICENSE/LICENSE.txt?
        license = self.license_file()
        if license:
            license_filename = 'LICENSE.txt'
            shutil.copy(license,
                        os.path.join(self.distinfo_dir, license_filename))
            pymeta['extensions']['python.details']['document_names'][
                'license'] = license_filename

        with open(metadata_json_path, "w") as metadata_json:
            json.dump(pymeta, metadata_json, sort_keys=True)

        adios(egginfo_path)

    def write_record(self, bdist_dir, distinfo_dir):
        from wheel.util import urlsafe_b64encode

        record_path = os.path.join(distinfo_dir, 'RECORD')
        record_relpath = os.path.relpath(record_path, bdist_dir)

        def walk():
            for dir, dirs, files in os.walk(bdist_dir):
                dirs.sort()
                for f in sorted(files):
                    yield os.path.join(dir, f)

        def skip(path):
            """Wheel hashes every possible file."""
            return (path == record_relpath)

        with open_for_csv(record_path, 'w+') as record_file:
            writer = csv.writer(record_file)
            for path in walk():
                relpath = os.path.relpath(path, bdist_dir)
                if skip(relpath):
                    hash = ''
                    size = ''
                else:
                    with open(path, 'rb') as f:
                        data = f.read()
                    digest = hashlib.sha256(data).digest()
                    hash = 'sha256=' + native(urlsafe_b64encode(digest))
                    size = len(data)
                record_path = os.path.relpath(path, bdist_dir).replace(
                    os.path.sep, '/')
                writer.writerow((record_path, hash, size))
Exemple #29
0
def get_platform():
    return pep425tags.get_platform()
Exemple #30
0
def test_get_platform_linux(monkeypatch):
    monkeypatch.setattr(distutils.util, "get_platform",
                        return_factory("linux_x86_64"))
    monkeypatch.setattr(sys, "maxsize", 2147483647)
    assert get_platform(None) == "linux_i686"
from sys import argv
from wheel import pep425tags as w

assert len(argv) == 3

print("cuda%s-pygenn-%s-%s%s-%s-%s.whl" %
      (argv[1], argv[2], w.get_abbr_impl(), w.get_impl_ver(),
       w.get_abi_tag(), w.get_platform()))