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

Use GitHub Actions for x86_64 tests #282

Merged
merged 4 commits into from
Feb 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Lint

on:
push:
pull_request:

jobs:
lint:
name: Lint
runs-on: ubuntu-20.04

steps:
- name: Checkout
uses: actions/checkout@v2

- name: Install CPython 3.8
uses: actions/setup-python@v2
with:
python-version: 3.8
architecture: x64

- name: Install/fetch dependencies
run: |
set -exuo pipefail
pip install --upgrade pip setuptools
pip install tox

- name: Run linter
run: tox -e lint
36 changes: 36 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Test

on:
push:
pull_request:

jobs:
test:
name: CPython ${{ matrix.python }}
runs-on: ubuntu-20.04
strategy:
matrix:
include:
- python: "3.6"
- python: "3.7"
- python: "3.8"
- python: "3.9"

steps:
- name: Checkout
uses: actions/checkout@v2

- name: Install CPython ${{ matrix.python }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python }}
architecture: x64

- name: Install/fetch dependencies
run: |
set -exuo pipefail
pip install --upgrade pip setuptools
./tests/install.sh

- name: Run tests
run: ./tests/travis.sh
12 changes: 1 addition & 11 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ language: python

jobs:
include:
- python: "3.6"
- python: "3.7"
- python: "3.8"
- python: "3.9"
- python: "3.8"
arch: arm64-graviton2
virt: vm
Expand All @@ -16,8 +12,6 @@ jobs:
arch: ppc64le
- python: "3.8"
arch: s390x
- python: "3.8"
env: LINTER=1

services:
- docker
Expand All @@ -29,11 +23,7 @@ before_install:
- pip install --upgrade pip setuptools

install:
- pip install -r test-requirements.txt
- pip install tox codecov
- pip install -e .
# pull manylinux images that will be used, this helps passing tests which would otherwise timeout.
- python -c $'from tests.integration.test_manylinux import MANYLINUX_IMAGES\nfor image in MANYLINUX_IMAGES.values():\n print(image)' | xargs -L 1 docker pull
- ./tests/install.sh

script:
- tests/travis.sh
Expand Down
14 changes: 9 additions & 5 deletions auditwheel/condatools.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,36 @@
conda packages.
"""
import os
from typing import List, Optional

from .tmpdirs import InTemporaryDirectory
from .tools import tarbz2todir


class InCondaPkg(InTemporaryDirectory):
def __init__(self, in_conda_pkg):
def __init__(self, in_conda_pkg: str) -> None:
"""Initialize in-conda-package context manager"""
self.in_conda_pkg = os.path.abspath(in_conda_pkg)
super().__init__()

def __enter__(self):
def __enter__(self) -> str:
tarbz2todir(self.in_conda_pkg, self.name)
return super().__enter__()


class InCondaPkgCtx(InCondaPkg):
def __init__(self, in_conda_pkg):
def __init__(self, in_conda_pkg: str) -> None:
super().__init__(in_conda_pkg)
self.path = None
self.path: Optional[str] = None

def __enter__(self):
self.path = super().__enter__()
return self

def iter_files(self):
def iter_files(self) -> List[str]:
if self.path is None:
raise ValueError(
"This function should be called from context manager")
files = os.path.join(self.path, 'info', 'files')
with open(files) as f:
return [line.strip() for line in f.readlines()]
7 changes: 4 additions & 3 deletions auditwheel/elfutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
from os.path import basename, realpath, relpath
from .lddtree import parse_ld_paths

from elftools.elf.elffile import ELFFile # type: ignore
from elftools.common.exceptions import ELFError # type: ignore
from elftools.elf.elffile import ELFFile
from elftools.common.exceptions import ELFError
from typing import Iterator, Tuple, Optional, Dict, List


Expand Down Expand Up @@ -78,7 +78,8 @@ def elf_references_PyFPE_jbuf(elf: ELFFile) -> bool:
return False


def elf_is_python_extension(fn, elf) -> Tuple[bool, Optional[int]]:
def elf_is_python_extension(fn: str,
elf: ELFFile) -> Tuple[bool, Optional[int]]:
modname = basename(fn).split('.', 1)[0]
module_init_f = {
'init' + modname: 2,
Expand Down
5 changes: 4 additions & 1 deletion auditwheel/genericpkgctx.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from typing import Optional, Union
from .wheeltools import InWheelCtx
from .condatools import InCondaPkgCtx


def InGenericPkgCtx(in_path, out_path=None):
def InGenericPkgCtx(
in_path: str, out_path: Optional[str] = None
) -> Union[InWheelCtx, InCondaPkgCtx]:
"""Factory that returns a InWheelCtx or InCondaPkgCtx
context manager depending on the file extension
"""
Expand Down
3 changes: 2 additions & 1 deletion auditwheel/hashfile.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import hashlib
from typing import BinaryIO


def hashfile(afile, blocksize=65536):
def hashfile(afile: BinaryIO, blocksize: int = 65536) -> str:
"""Hash the contents of an open file handle with SHA256"""
hasher = hashlib.sha256()
buf = afile.read(blocksize)
Expand Down
21 changes: 11 additions & 10 deletions auditwheel/lddtree.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
import errno
import logging
import functools
from typing import List, Dict, Optional, Any
from typing import List, Dict, Optional, Any, Tuple

from elftools.elf.elffile import ELFFile # type: ignore
from elftools.elf.elffile import ELFFile

log = logging.getLogger(__name__)
__all__ = ['lddtree']
Expand Down Expand Up @@ -75,7 +75,7 @@ def dedupe(items: List[str]) -> List[str]:
return [seen.setdefault(x, x) for x in items if x not in seen]


def parse_ld_paths(str_ldpaths, root='', path=None) -> List[str]:
def parse_ld_paths(str_ldpaths: str, path: str, root: str = '') -> List[str]:
"""Parse the colon-delimited list of paths and apply ldso rules to each

Note the special handling as dictated by the ldso:
Expand Down Expand Up @@ -204,7 +204,7 @@ def load_ld_paths(root: str = '/', prefix: str = '') -> Dict[str, List[str]]:
return ldpaths


def compatible_elfs(elf1, elf2):
def compatible_elfs(elf1: ELFFile, elf2: ELFFile) -> bool:
"""See if two ELFs are compatible

This compares the aspects of the ELF to see if they're compatible:
Expand Down Expand Up @@ -232,7 +232,8 @@ def compatible_elfs(elf1, elf2):
elf1.header['e_machine'] == elf2.header['e_machine'])


def find_lib(elf, lib, ldpaths, root='/'):
def find_lib(elf: ELFFile, lib: str, ldpaths: List[str],
root: str = '/') -> Tuple[Optional[str], Optional[str]]:
"""Try to locate a ``lib`` that is compatible to ``elf`` in the given
``ldpaths``

Expand Down Expand Up @@ -370,13 +371,13 @@ def lddtree(path: str,
if t.entry.d_tag == 'DT_RPATH':
rpaths = parse_ld_paths(
t.rpath,
root=root,
path=path)
path=path,
root=root)
elif t.entry.d_tag == 'DT_RUNPATH':
runpaths = parse_ld_paths(
t.runpath,
root=root,
path=path)
path=path,
root=root)
elif t.entry.d_tag == 'DT_NEEDED':
libs.append(t.needed)
if runpaths:
Expand Down Expand Up @@ -412,7 +413,7 @@ def lddtree(path: str,
'path': fullpath,
'needed': [],
}
if fullpath:
if realpath and fullpath:
lret = lddtree(realpath,
root,
prefix,
Expand Down
7 changes: 4 additions & 3 deletions auditwheel/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
import sys
import logging
import argparse
import pkg_resources # type: ignore
import pkg_resources
from typing import Optional

from . import main_show
from . import main_addtag
from . import main_lddtree
from . import main_repair


def main():
def main() -> Optional[int]:
if sys.platform != 'linux':
print('Error: This tool only supports Linux')
return 1
Expand Down Expand Up @@ -45,7 +46,7 @@ def main():

if not hasattr(args, 'func'):
p.print_help()
return
return None

rval = args.func(args, p)

Expand Down
2 changes: 1 addition & 1 deletion auditwheel/main_addtag.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def configure_parser(sub_parsers):

def execute(args, p):
import os
from ._vendor.wheel.wheelfile import WHEEL_INFO_RE # type: ignore
from ._vendor.wheel.wheelfile import WHEEL_INFO_RE
from .wheeltools import InWheelCtx, add_platforms, WheelToolsError
from .wheel_abi import analyze_wheel_abi, NonPlatformWheel

Expand Down
1 change: 0 additions & 1 deletion auditwheel/main_lddtree.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import logging

logger = logging.getLogger(__name__)


Expand Down
2 changes: 1 addition & 1 deletion auditwheel/main_show.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def configure_parser(sub_parsers):
p.set_defaults(func=execute)


def printp(text):
def printp(text: str) -> None:
from textwrap import wrap
print()
print('\n'.join(wrap(text)))
Expand Down
2 changes: 1 addition & 1 deletion auditwheel/patcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def _verify_patchelf() -> None:


class Patchelf(ElfPatcher):
def __init__(self):
def __init__(self) -> None:
_verify_patchelf()

def replace_needed(self,
Expand Down
8 changes: 4 additions & 4 deletions auditwheel/policy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import sys
import json
import platform as _platform_module
from typing import Optional
from typing import Optional, List
from os.path import join, dirname, abspath
import logging

Expand All @@ -12,7 +12,7 @@
bits = 8 * (8 if sys.maxsize > 2 ** 32 else 4)


def get_arch_name():
def get_arch_name() -> str:
machine = _platform_module.machine()
if machine not in {'x86_64', 'i686'}:
return machine
Expand Down Expand Up @@ -56,7 +56,7 @@ def get_policy_name(priority: int) -> Optional[str]:
return matches[0]


def get_priority_by_name(name: str):
def get_priority_by_name(name: str) -> Optional[int]:
matches = [p['priority'] for p in _POLICIES if p['name'] == name]
if len(matches) == 0:
return None
Expand All @@ -65,7 +65,7 @@ def get_priority_by_name(name: str):
return matches[0]


def get_replace_platforms(name: str):
def get_replace_platforms(name: str) -> List[str]:
"""Extract platform tag replacement rules from policy

>>> get_replace_platforms('linux_x86_64')
Expand Down
11 changes: 6 additions & 5 deletions auditwheel/policy/external_references.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import re
import logging
from typing import Dict, List, Set, Any
from typing import Dict, Set, Any, Generator

from ..elfutils import is_subdir
from . import load_policies
Expand All @@ -9,12 +9,13 @@
LIBPYTHON_RE = re.compile(r'^libpython\d\.\dm?.so(.\d)*$')


def lddtree_external_references(lddtree: Dict, wheel_path: str):
def lddtree_external_references(lddtree: Dict, wheel_path: str) -> Dict:
# XXX: Document the lddtree structure, or put it in something
# more stable than a big nested dict
policies = load_policies()

def filter_libs(libs, whitelist):
def filter_libs(libs: Set[str],
whitelist: Set[str]) -> Generator[str, None, None]:
for lib in libs:
if 'ld-linux' in lib or lib in ['ld64.so.2', 'ld64.so.1']:
# always exclude ELF dynamic linker/loader
Expand All @@ -30,7 +31,7 @@ def filter_libs(libs, whitelist):
continue
yield lib

def get_req_external(libs: Set[str], whitelist: Set[str]):
def get_req_external(libs: Set[str], whitelist: Set[str]) -> Set[str]:
# get all the required external libraries
libs = libs.copy()
reqs = set()
Expand All @@ -44,7 +45,7 @@ def get_req_external(libs: Set[str], whitelist: Set[str]):

ret = {} # type: Dict[str, Dict[str, Any]]
for p in policies:
needed_external_libs = [] # type: List[str]
needed_external_libs = set() # type: Set[str]

if not (p['name'] == 'linux' and p['priority'] == 0):
# special-case the generic linux platform here, because it
Expand Down
Loading