[med-svn] [Git][med-team/python-leidenalg][upstream] New upstream version 0.8.10
Étienne Mollier (@emollier)
gitlab at salsa.debian.org
Sun Jul 3 16:27:51 BST 2022
Étienne Mollier pushed to branch upstream at Debian Med / python-leidenalg
Commits:
ed8c8ccc by Étienne Mollier at 2022-07-03T17:20:58+02:00
New upstream version 0.8.10
- - - - -
5 changed files:
- .github/workflows/build.yml
- CHANGELOG
- MANIFEST.in
- + etc/arith_apple_m1.h
- setup.py
Changes:
=====================================
.github/workflows/build.yml
=====================================
@@ -13,7 +13,7 @@ on:
env:
CIBW_TEST_REQUIRES: ddt
CIBW_TEST_COMMAND: "cd {project} && python -m unittest -v"
- CIBW_SKIP: "cp27-* pp27-* cp35-*"
+ CIBW_SKIP: "pp* cp27-* cp35-* cp36-*"
jobs:
build_wheel_linux:
@@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-20.04
strategy:
matrix:
- wheel_arch: [x86_64, i686]
+ wheel_arch: [x86_64, i686, aarch64]
steps:
- uses: actions/checkout at v2
@@ -34,10 +34,15 @@ jobs:
with:
python-version: '3.8'
+ - name: Set up QEMU
+ if: runner.os == 'Linux'
+ uses: docker/setup-qemu-action at v1
+
- name: Build wheels
- uses: joerick/cibuildwheel at v1.10.0
+ uses: pypa/cibuildwheel at v2.4.0
env:
CIBW_BEFORE_BUILD: "yum install -y flex bison && pip install cmake && python setup.py build_c_core"
+ CIBW_ARCHS_LINUX: ${{ matrix.wheel_arch }}
CIBW_BUILD: "*-manylinux_${{ matrix.wheel_arch }}"
- uses: actions/upload-artifact at v2
@@ -47,6 +52,14 @@ jobs:
build_wheel_macos:
name: Build wheels on macOS
runs-on: macos-10.15
+ strategy:
+ matrix:
+ include:
+ - cmake_arch: x86_64
+ wheel_arch: x86_64
+ - cmake_arch: arm64
+ cmake_extra_args: -DF2C_EXTERNAL_ARITH_HEADER=../../../etc/arith_apple_m1.h
+ wheel_arch: arm64
steps:
- uses: actions/checkout at v2
@@ -72,7 +85,7 @@ jobs:
brew install autoconf automake libtool cmake
- name: Build wheels
- uses: joerick/cibuildwheel at v1.10.0
+ uses: pypa/cibuildwheel at v2.4.0
env:
CIBW_BEFORE_BUILD: "python setup.py build_c_core"
@@ -116,7 +129,7 @@ jobs:
run: choco install winflexbison3 cmake
- name: Build wheels
- uses: joerick/cibuildwheel at v1.10.0
+ uses: pypa/cibuildwheel at v2.4.0
env:
CIBW_BEFORE_BUILD: "python setup.py build_c_core"
CIBW_BUILD: "*-${{ matrix.wheel_arch }}"
=====================================
CHANGELOG
=====================================
@@ -1,3 +1,6 @@
+0.8.10
+- Fixed installation from source package (issue #101)
+
0.8.9
- Fixed bug with renaming of python-igraph to igraph (issue #93)
- Removed irrelevant node_sizes argument for RBConfigurationVertexPartition and ModularityVertexPartition
=====================================
MANIFEST.in
=====================================
@@ -12,8 +12,3 @@ exclude release*
prune .github
graft vendor/source/igraph
-prune vendor/source/igraph/etc/abstracts
-prune vendor/source/igraph/etc/papers
-prune vendor/source/igraph/etc/presentations
-prune vendor/source/igraph/interfaces
-prune vendor/source/igraph/vendor/simpleraytracer
=====================================
etc/arith_apple_m1.h
=====================================
@@ -0,0 +1,9 @@
+#define IEEE_8087
+#define Arith_Kind_ASL 1
+#define Long int
+#define Intcast (int)(long)
+#define Double_Align
+#define X64_bit_pointers
+#define NANCHECK
+#define QNaN0 0x0
+#define QNaN1 0x7ff80000
=====================================
setup.py
=====================================
@@ -11,12 +11,6 @@ if sys.version_info < (3, 6):
print("This module requires Python >= 3.6")
sys.exit(0)
-# Check whether we are compiling for PyPy. Headers will not be installed
-# for PyPy.
-SKIP_HEADER_INSTALL = (platform.python_implementation() == "PyPy") or (
- "SKIP_HEADER_INSTALL" in os.environ
-)
-
###########################################################################
from setuptools import setup, Command, Extension
@@ -25,32 +19,46 @@ import glob
import shlex
import shutil
import subprocess
-import sys
import sysconfig
+from contextlib import contextmanager
from pathlib import Path
from select import select
from shutil import which
from time import sleep
+from typing import List, Iterable, Iterator, Optional, Tuple, TypeVar, Union
+
+###########################################################################
+
+LIBIGRAPH_FALLBACK_INCLUDE_DIRS = ["/usr/include/igraph", "/usr/local/include/igraph"]
+LIBIGRAPH_FALLBACK_LIBRARIES = ["igraph"]
+LIBIGRAPH_FALLBACK_LIBRARY_DIRS = []
+
+# Check whether we are compiling for PyPy. Headers will not be installed
+# for PyPy.
+SKIP_HEADER_INSTALL = (platform.python_implementation() == "PyPy") or (
+ "SKIP_HEADER_INSTALL" in os.environ
+)
###########################################################################
-is_windows = platform.system() == "windows"
+
+T = TypeVar("T")
-def building_on_windows_msvc():
+def building_on_windows_msvc() -> bool:
"""Returns True when using the non-MinGW CPython interpreter on Windows"""
return platform.system() == "Windows" and sysconfig.get_platform() != "mingw"
-def exclude_from_list(items, items_to_exclude):
+def exclude_from_list(items: Iterable[T], items_to_exclude: Iterable[T]) -> List[T]:
"""Excludes certain items from a list, keeping the original order of
the remaining items."""
itemset = set(items_to_exclude)
return [item for item in items if item not in itemset]
-def find_static_library(library_name, library_path):
+def find_static_library(library_name: str, library_path: List[str]) -> Optional[str]:
"""Given the raw name of a library in `library_name`, tries to find a
static library with this name in the given `library_path`. `library_path`
is automatically extended with common library directories on Linux and Mac
@@ -59,6 +67,7 @@ def find_static_library(library_name, library_path):
variants = ["lib{0}.a", "{0}.a", "{0}.lib", "lib{0}.lib"]
if is_unix_like():
extra_libdirs = [
+ "/opt/homebrew/lib", # for newer Homebrew installations on macOS
"/usr/local/lib64",
"/usr/local/lib",
"/usr/lib/x86_64-linux-gnu",
@@ -81,15 +90,17 @@ def find_static_library(library_name, library_path):
return full_path
-def first(iterable):
+def first(iterable: Iterable[T]) -> T:
"""Returns the first element from the given iterable."""
for item in iterable:
return item
raise ValueError("iterable is empty")
-def get_output(args, encoding="utf-8"):
- """Returns the output of a command returning a single line of output."""
+def get_output(args, encoding: str = "utf-8") -> Tuple[str, int]:
+ """Returns the output of a command returning a single line of output, and
+ the exit code of the command.
+ """
PIPE = subprocess.PIPE
try:
p = subprocess.Popen(args, shell=False, stdin=PIPE, stdout=PIPE, stderr=PIPE)
@@ -98,25 +109,23 @@ def get_output(args, encoding="utf-8"):
except OSError:
stdout, stderr = None, None
returncode = 77
- if encoding and type(stdout).__name__ == "bytes":
+ if isinstance(stdout, bytes):
stdout = str(stdout, encoding=encoding)
- if encoding and type(stderr).__name__ == "bytes":
+ if isinstance(stderr, bytes):
stderr = str(stderr, encoding=encoding)
- return stdout, returncode
+ return (stdout or ""), returncode
-def get_output_single_line(args, encoding="utf-8"):
- """Returns the output of a command returning a single line of output,
- stripped from any trailing newlines."""
+def get_output_single_line(args, encoding: str = "utf-8") -> Tuple[str, int]:
+ """Returns the first line of the output of a command, stripped from any
+ trailing newlines, and the exit code of the command.
+ """
stdout, returncode = get_output(args, encoding=encoding)
- if stdout is not None:
- line, _, _ = stdout.partition("\n")
- else:
- line = None
+ line, _, _ = stdout.partition("\n")
return line, returncode
-def is_unix_like(platform=None):
+def is_unix_like(platform: str = sys.platform) -> bool:
"""Returns whether the given platform is a Unix-like platform with the usual
Unix filesystem. When the parameter is omitted, it defaults to ``sys.platform``
"""
@@ -129,12 +138,10 @@ def is_unix_like(platform=None):
)
-def wait_for_keypress(seconds):
+def wait_for_keypress(seconds: float) -> None:
"""Wait for a keypress or until the given number of seconds have passed,
whichever happens first.
"""
- global is_windows
-
while seconds > 0:
if seconds > 1:
plural = "s"
@@ -147,10 +154,10 @@ def wait_for_keypress(seconds):
)
sys.stdout.flush()
- if is_windows:
- from msvcrt import kbhit
+ if platform.system() == "Windows":
+ from msvcrt import kbhit # type: ignore
- for i in range(10):
+ for _ in range(10):
if kbhit():
seconds = 0
break
@@ -167,62 +174,48 @@ def wait_for_keypress(seconds):
sys.stdout.write("\r" + " " * 65 + "\r")
-###########################################################################
-
-
-class IgraphCCoreBuilder(object):
- """Superclass for classes responsible for downloading and building the
- C core of igraph if it is not installed yet.
- """
-
- def create_build_config_file(self, install_folder, libraries):
- with (install_folder / "build.cfg").open("w") as fp:
- fp.write(repr(libraries))
-
- def parse_pkgconfig_file(self, filename):
- building_on_windows = building_on_windows_msvc()
-
- if building_on_windows:
- libraries = ["igraph"]
- else:
- libraries = []
- with filename.open("r") as fp:
- for line in fp:
- if line.startswith("Libs: ") or line.startswith("Libs.private: "):
- words = line.strip().split()
- libraries.extend(
- word[2:] for word in words if word.startswith("-l")
- )
-
- if not libraries:
- # Educated guess
- libraries = ["igraph"]
-
- return libraries
+ at contextmanager
+def working_directory(dir: Union[str, Path]) -> Iterator[None]:
+ cwd = os.getcwd()
+ os.chdir(dir)
+ try:
+ yield
+ finally:
+ os.chdir(cwd)
###########################################################################
-class IgraphCCoreCMakeBuilder(IgraphCCoreBuilder):
+class IgraphCCoreCMakeBuilder:
"""Class responsible for downloading and building the C core of igraph
if it is not installed yet, assuming that the C core uses CMake as the
build tool. This is the case from igraph 0.9.
-
- Returns:
- False if the build failed or the list of libraries to link to when
- linking the Python interface to igraph
"""
- def compile_in(self, source_folder, build_folder, install_folder):
+ def compile_in(
+ self, source_folder: Path, build_folder: Path, install_folder: Path
+ ) -> Union[bool, List[str]]:
"""Compiles igraph from its source code in the given folder.
- source_folder is the name of the folder that contains igraph's source
- files. build_folder is the name of the folder where the build should
- be executed. Both must be absolute paths.
+ Parameters:
+ source_folder: absolute path to the folder that contains igraph's
+ source files
+ build_folder: absolute path to the folder where the build should be
+ executed
+ install_folder: absolute path to the folder where the built library
+ should be installed
+
+ Returns:
+ False if the build failed or the list of libraries to link to when
+ linking the Python interface to igraph
"""
- global is_windows
+ with working_directory(build_folder):
+ return self._compile_in(source_folder, build_folder, install_folder)
+ def _compile_in(
+ self, source_folder: Path, build_folder: Path, install_folder: Path
+ ) -> Union[bool, List[str]]:
cmake = which("cmake")
if not cmake:
print(
@@ -232,7 +225,6 @@ class IgraphCCoreCMakeBuilder(IgraphCCoreBuilder):
return False
build_to_source_folder = os.path.relpath(source_folder, build_folder)
- os.chdir(build_folder)
print("Configuring build...")
args = [cmake]
@@ -245,6 +237,13 @@ class IgraphCCoreCMakeBuilder(IgraphCCoreBuilder):
# Python shared library
args.append("-DCMAKE_POSITION_INDEPENDENT_CODE=ON")
+ # No need to build tests
+ args.append("-DBUILD_TESTING=OFF")
+
+ # Set install directory during config step instead of install step in order
+ # to avoid having the architecture name in the LIBPATH (e.g. lib/x86_64-linux-gnu)
+ args.append("-DCMAKE_INSTALL_PREFIX=" + str(install_folder))
+
# Add any extra CMake args from environment variables
if "IGRAPH_CMAKE_EXTRA_ARGS" in os.environ:
args.extend(shlex.split(os.environ["IGRAPH_CMAKE_EXTRA_ARGS"]))
@@ -257,32 +256,63 @@ class IgraphCCoreCMakeBuilder(IgraphCCoreBuilder):
return False
print("Running build...")
- retcode = subprocess.call(
- [cmake, "--build", ".", "--config", "Release"]
- )
+ # We are _not_ using a parallel build; this is intentional, see igraph/igraph#1755
+ retcode = subprocess.call([cmake, "--build", ".", "--config", "Release"])
if retcode:
return False
print("Installing build...")
- retcode = subprocess.call([cmake, "--install", ".", "--prefix", str(install_folder), "--config", "Release"])
+ retcode = subprocess.call(
+ [
+ cmake,
+ "--install",
+ ".",
+ "--config",
+ "Release",
+ ]
+ )
if retcode:
return False
- pkgconfig_candidates = [
- install_folder / "lib" / "pkgconfig" / "igraph.pc",
- install_folder / "lib64" / "pkgconfig" / "igraph.pc"
- ]
- for candidate in pkgconfig_candidates:
- if candidate.exists():
- return self.parse_pkgconfig_file(candidate)
+ for candidate in install_folder.rglob("igraph.pc"):
+ return self._parse_pkgconfig_file(candidate)
+
+ raise RuntimeError(
+ "no igraph.pc was found in the installation folder of igraph"
+ )
- raise RuntimeError("no igraph.pc was found in the installation folder of igraph")
+ def create_build_config_file(
+ self, install_folder: Path, libraries: List[str]
+ ) -> None:
+ with (install_folder / "build.cfg").open("w") as fp:
+ fp.write(repr(libraries))
+
+ def _parse_pkgconfig_file(self, filename: Path) -> List[str]:
+ building_on_windows = building_on_windows_msvc()
+
+ if building_on_windows:
+ libraries = ["igraph"]
+ else:
+ libraries = []
+ with filename.open("r") as fp:
+ for line in fp:
+ if line.startswith("Libs: ") or line.startswith("Libs.private: "):
+ words = line.strip().split()
+ libraries.extend(
+ word[2:] for word in words if word.startswith("-l")
+ )
+
+ if not libraries:
+ # Educated guess
+ libraries = ["igraph"]
+
+ return libraries
###########################################################################
-class BuildConfiguration(object):
+class BuildConfiguration:
def __init__(self):
self.include_dirs = []
self.library_dirs = []
@@ -295,25 +325,26 @@ class BuildConfiguration(object):
self.static_extension = False
self.external = False
self.use_pkgconfig = False
+ self.c_core_built = False
self._has_pkgconfig = None
self.excluded_include_dirs = []
self.excluded_library_dirs = []
self.wait = platform.system() != "Windows"
@property
- def has_pkgconfig(self):
+ def has_pkgconfig(self) -> bool:
"""Returns whether ``pkg-config`` is available on the current system
and it knows about igraph or not."""
if self._has_pkgconfig is None:
if self.use_pkgconfig:
- line, exit_code = get_output_single_line(["pkg-config", "igraph"])
+ _, exit_code = get_output_single_line(["pkg-config", "igraph"])
self._has_pkgconfig = exit_code == 0
else:
self._has_pkgconfig = False
return self._has_pkgconfig
@property
- def build_c_core(self):
+ def build_c_core(self) -> Command:
"""Returns a class representing a custom setup.py command that builds
the C core of igraph.
@@ -342,20 +373,19 @@ class BuildConfiguration(object):
return build_c_core
@property
- def build_ext(self):
+ def build_ext(self) -> Command:
"""Returns a class that can be used as a replacement for the
``build_ext`` command in ``setuptools`` and that will compile the C core
of igraph before compiling the Python extension.
"""
from setuptools.command.build_ext import build_ext
- from distutils.sysconfig import get_python_inc
buildcfg = self
class custom_build_ext(build_ext):
def run(self):
# Bail out if we don't have the Python include files
- include_dir = get_python_inc()
+ include_dir = sysconfig.get_path('include')
if not os.path.isfile(os.path.join(include_dir, "Python.h")):
print("You will need the Python headers to compile this extension.")
sys.exit(1)
@@ -363,7 +393,7 @@ class BuildConfiguration(object):
# Check whether the user asked us to discover a pre-built igraph
# with pkg-config
detected = False
- if buildcfg.external:
+ if buildcfg.external:
if buildcfg.use_pkgconfig:
detected = buildcfg.detect_from_pkgconfig()
if not detected:
@@ -372,7 +402,7 @@ class BuildConfiguration(object):
)
sys.exit(1)
else:
- buildcfg.use_educated_guess()
+ buildcfg.use_educated_guess()
else:
# Build the C core from the vendored igraph source
self.run_command("build_c_core")
@@ -399,12 +429,16 @@ class BuildConfiguration(object):
# Add extra libraries that may have been specified
if "IGRAPH_EXTRA_LIBRARIES" in os.environ:
- extra_libraries = os.environ["IGRAPH_EXTRA_LIBRARIES"].split(',')
+ extra_libraries = os.environ["IGRAPH_EXTRA_LIBRARIES"].split(",")
buildcfg.libraries.extend(extra_libraries)
# Override static specification based on environment variable
if "IGRAPH_STATIC_EXTENSION" in os.environ:
- if os.environ["IGRAPH_STATIC_EXTENSION"].lower() in ['true', '1', 'on']:
+ if os.environ["IGRAPH_STATIC_EXTENSION"].lower() in [
+ "true",
+ "1",
+ "on",
+ ]:
buildcfg.static_extension = True
else:
buildcfg.static_extension = False
@@ -421,9 +455,16 @@ class BuildConfiguration(object):
# Add extra libraries that may have been specified
if "IGRAPH_EXTRA_DYNAMIC_LIBRARIES" in os.environ:
- extra_libraries = os.environ["IGRAPH_EXTRA_DYNAMIC_LIBRARIES"].split(',')
+ extra_libraries = os.environ[
+ "IGRAPH_EXTRA_DYNAMIC_LIBRARIES"
+ ].split(",")
buildcfg.libraries.extend(extra_libraries)
+ # Remove C++ standard library as we will use the C++ linker
+ for lib in ("c++", "stdc++"):
+ if lib in buildcfg.libraries:
+ buildcfg.libraries.remove(lib)
+
# Prints basic build information
buildcfg.print_build_info()
@@ -434,7 +475,7 @@ class BuildConfiguration(object):
for extension in self.extensions
if extension.name == "leidenalg._c_leiden"
)
- ext.include_dirs += buildcfg.include_dirs
+ ext.include_dirs += buildcfg.include_dirs
buildcfg.configure(ext)
# Run the original build_ext command
@@ -451,77 +492,84 @@ class BuildConfiguration(object):
"""
from setuptools.command.sdist import sdist
- def is_git_repo(folder):
- return os.path.exists(os.path.join(folder, ".git"))
+ def is_git_repo(folder) -> bool:
+ return (Path(folder) / ".git").exists()
- def cleanup_git_repo(folder):
- folder = str(folder)
- cwd = os.getcwd()
- try:
- os.chdir(folder)
+ def cleanup_git_repo(folder) -> None:
+ with working_directory(folder):
if os.path.exists(".git"):
retcode = subprocess.call("git clean -dfx", shell=True)
if retcode:
raise RuntimeError(f"Failed to clean {folder} with git")
- finally:
- os.chdir(cwd)
class custom_sdist(sdist):
def run(self):
- igraph_source_repo = os.path.join("vendor", "source", "igraph")
- igraph_build_dir = os.path.join("vendor", "build", "igraph")
- version_file = os.path.join(igraph_source_repo, "IGRAPH_VERSION")
+ igraph_source_repo = Path("vendor", "source", "igraph")
+ igraph_build_dir = Path("vendor", "build", "igraph")
+ version_file = igraph_source_repo / "IGRAPH_VERSION"
version = None
# Check whether the source repo contains an IGRAPH_VERSION file,
# and extract the version number from that
- if os.path.exists(version_file):
- with open(version_file, "r") as fp:
- version = fp.read().strip().split("\n")[0]
+ if version_file.exists():
+ version = version_file.read_text().strip().split("\n")[0]
# If no IGRAPH_VERSION file exists, but we have a git repo, try
# git describe
if not version and is_git_repo(igraph_source_repo):
- cwd = os.getcwd()
- try:
- os.chdir(igraph_source_repo)
- version = subprocess.check_output("git describe", shell=True).decode("utf-8").strip()
- finally:
- os.chdir(cwd)
+ with working_directory(igraph_source_repo):
+ version = (
+ subprocess.check_output("git describe", shell=True)
+ .decode("utf-8")
+ .strip()
+ )
# If we still don't have a version number, try to parse it from
# include/igraph_version.h
if not version:
- version_header = os.path.join(igraph_build_dir, "include", "igraph_version.h")
- if not os.path.exists(version_header):
- raise RuntimeError("You need to build the C core of igraph first before generating a source tarball of python-igraph")
+ version_header = igraph_build_dir / "include" / "igraph_version.h"
+ if not version_header.exists():
+ raise RuntimeError(
+ "You need to build the C core of igraph first before generating a source tarball of the Python interface of igraph"
+ )
- with open(version_header, "r") as fp:
- lines = [line.strip() for line in fp if line.startswith("#define IGRAPH_VERSION ")]
+ with version_header.open("r") as fp:
+ lines = [
+ line.strip()
+ for line in fp
+ if line.startswith("#define IGRAPH_VERSION ")
+ ]
if len(lines) == 1:
version = lines[0].split('"')[1]
if not isinstance(version, str) or len(version) < 5:
- raise RuntimeError(f"Cannot determine the version number of the C core in {igraph_source_repo}")
+ raise RuntimeError(
+ f"Cannot determine the version number of the C core in {igraph_source_repo}"
+ )
if not is_git_repo(igraph_source_repo):
- # python-igraph was extracted from an official tarball so
- # there is no need to tweak anything
+ # The Python interface was extracted from an official
+ # tarball so there is no need to tweak anything
return sdist.run(self)
else:
# Clean up vendor/source/igraph with git
cleanup_git_repo(igraph_source_repo)
# Copy the generated parser sources from the build folder
- parser_dir = os.path.join(igraph_build_dir, "src", "io", "parsers")
- if os.path.isdir(parser_dir):
- shutil.copytree(parser_dir, os.path.join(igraph_source_repo, "src", "io", "parsers"))
+ parser_dir = igraph_build_dir / "src" / "io" / "parsers"
+ if parser_dir.is_dir():
+ shutil.copytree(
+ parser_dir,
+ igraph_source_repo / "src" / "io" / "parsers"
+ )
else:
- raise RuntimeError(f"You need to build the C core of igraph first before generating a source tarball of python-igraph")
+ raise RuntimeError(
+ "You need to build the C core of igraph first before "
+ "generating a source tarball of the Python interface"
+ )
# Add a version file to the tarball
- with open(version_file, "w") as fp:
- fp.write(version)
+ version_file.write_text(version)
# Run the original sdist command
retval = sdist.run(self)
@@ -533,7 +581,7 @@ class BuildConfiguration(object):
return custom_sdist
- def compile_igraph_from_vendor_source(self):
+ def compile_igraph_from_vendor_source(self) -> bool:
"""Compiles igraph from the vendored source code inside `vendor/source/igraph`.
This folder typically comes from a git submodule.
"""
@@ -566,28 +614,31 @@ class BuildConfiguration(object):
Path(build_folder).mkdir(parents=True, exist_ok=True)
- cwd = os.getcwd()
- try:
- libraries = igraph_builder.compile_in(
- source_folder=source_folder,
- build_folder=build_folder,
- install_folder=install_folder,
- )
- finally:
- os.chdir(cwd)
+ libraries = igraph_builder.compile_in(
+ source_folder=source_folder,
+ build_folder=build_folder,
+ install_folder=install_folder,
+ )
+
+ if libraries is False:
+ print("Build failed for the C core of igraph.")
+ print("")
+ sys.exit(1)
+
+ assert not isinstance(libraries, bool)
igraph_builder.create_build_config_file(install_folder, libraries)
self.use_vendored_igraph()
return True
- def configure(self, ext):
+ def configure(self, ext) -> None:
"""Configures the given Extension object using this build configuration."""
ext.include_dirs = exclude_from_list(
ext.include_dirs, self.excluded_include_dirs
)
ext.library_dirs = exclude_from_list(
- self.library_dirs, self.excluded_library_dirs
+ ext.library_dirs, self.excluded_library_dirs
)
ext.runtime_library_dirs = self.runtime_library_dirs
ext.libraries = self.libraries
@@ -596,7 +647,7 @@ class BuildConfiguration(object):
ext.extra_objects = self.extra_objects
ext.define_macros = self.define_macros
- def detect_from_pkgconfig(self):
+ def detect_from_pkgconfig(self) -> bool:
"""Detects the igraph include directory, library directory and the
list of libraries to link to using ``pkg-config``."""
if not buildcfg.has_pkgconfig:
@@ -615,7 +666,7 @@ class BuildConfiguration(object):
self.include_dirs = [opt[2:] for opt in opts if opt.startswith("-I")]
return True
- def print_build_info(self):
+ def print_build_info(self) -> None:
"""Prints the include and library path being used for debugging purposes."""
if self.static_extension == "only_igraph":
build_type = "dynamic extension with vendored igraph source"
@@ -656,7 +707,7 @@ class BuildConfiguration(object):
self.wait = False
elif option == "--external":
opts_to_remove.append(idx)
- self.external = True
+ self.external = True
elif option == "--use-pkg-config":
opts_to_remove.append(idx)
self.use_pkgconfig = True
@@ -667,11 +718,6 @@ class BuildConfiguration(object):
def replace_static_libraries(self, only=None, exclusions=None):
"""Replaces references to libraries with full paths to their static
versions if the static version is to be found on the library path."""
- building_on_windows = building_on_windows_msvc()
-
- if not building_on_windows and "stdc++" not in self.libraries:
- self.libraries.append("stdc++")
-
if exclusions is None:
exclusions = []
@@ -689,7 +735,7 @@ class BuildConfiguration(object):
else:
print(f"Warning: could not find static library of {library_name}.")
- def use_vendored_igraph(self):
+ def use_vendored_igraph(self) -> None:
"""Assumes that igraph is installed already in ``vendor/install/igraph`` and sets up
the include and library paths and the library names accordingly."""
building_on_windows = building_on_windows_msvc()
@@ -705,7 +751,9 @@ class BuildConfiguration(object):
buildcfg.library_dirs.append(str(candidate))
break
else:
- raise RuntimeError("cannot detect igraph library dir within " + str(vendor_dir))
+ raise RuntimeError(
+ "cannot detect igraph library dir within " + str(vendor_dir)
+ )
if not buildcfg.static_extension:
buildcfg.static_extension = "only_igraph"
@@ -716,26 +764,33 @@ class BuildConfiguration(object):
if buildcfg_file.exists():
buildcfg.libraries = eval(buildcfg_file.open("r").read())
- def use_educated_guess(self):
- """Tries to guess the proper library names, include and library paths."""
+ def use_educated_guess(self) -> None:
+ """Tries to guess the proper library names, include and library paths
+ if everything else failed."""
+
+ global LIBIGRAPH_FALLBACK_LIBRARIES
+ global LIBIGRAPH_FALLBACK_INCLUDE_DIRS
+ global LIBIGRAPH_FALLBACK_LIBRARY_DIRS
- print("""WARNING: You are trying to install with an external igraph library.
-No include dirs or library dirs are specified, so they need to be set externally.
-If compilation fails you may adjust the following environment variables to adjust
-the required paths.
-- IGRAPH_EXTRA_INCLUDE_PATH
-- IGRAPH_EXTRA_LIBRARY_PATH
-- IGRAPH_EXTRA_LIBRARIES
-- IGRAPH_EXTRA_DYNAMIC_LIBRARIES
+ print("WARNING: we were not able to detect where igraph is installed on")
+ print("your machine (if it is installed at all). We will use the fallback")
+ print("library and include paths hardcoded in setup.py and hope that the")
+ print("C core of igraph is installed there.")
+ print("")
+ print("If the compilation fails and you are sure that igraph is installed")
+ print("on your machine, adjust the following two variables in setup.py")
+ print("accordingly and try again:")
+ print("")
+ print("- LIBIGRAPH_FALLBACK_INCLUDE_DIRS")
+ print("- LIBIGRAPH_FALLBACK_LIBRARY_DIRS")
+ print("")
-If a static build extension is used, we try to statically link to igraph. The extra
-libraries that are specified are then also assumed to be statically linked. If, in
-addition, some libraries need to be explicitly dynamically linked, you can specify this.
- """)
- self.libraries = ['igraph']
- self.include_dirs = []
- self.library_dirs = []
+ self.libraries = LIBIGRAPH_FALLBACK_LIBRARIES[:]
+ if self.static_extension:
+ self.libraries.extend(["xml2", "z", "m", "stdc++"])
+ self.include_dirs = LIBIGRAPH_FALLBACK_INCLUDE_DIRS[:]
+ self.library_dirs = LIBIGRAPH_FALLBACK_LIBRARY_DIRS[:]
###########################################################################
@@ -811,4 +866,4 @@ options = dict(
},
)
-setup(**options)
\ No newline at end of file
+setup(**options)
View it on GitLab: https://salsa.debian.org/med-team/python-leidenalg/-/commit/ed8c8ccce229070ed259de480dd407d9895bc8b2
--
View it on GitLab: https://salsa.debian.org/med-team/python-leidenalg/-/commit/ed8c8ccce229070ed259de480dd407d9895bc8b2
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20220703/c474fa60/attachment-0001.htm>
More information about the debian-med-commit
mailing list