Learn more  » Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Bower components Debian packages RPM packages NuGet packages

squarecapadmin / Pillow   python

Repository URL to install this package:

/ setup.py

#!/usr/bin/env python
# > pyroma .
# ------------------------------
# Checking .
# Found Pillow
# ------------------------------
# Final rating: 10/10
# Your cheese is so fresh most people think it's a cream: Mascarpone
# ------------------------------
from __future__ import print_function

import os
import platform as plat
import re
import struct
import subprocess
import sys
import warnings
from distutils import ccompiler, sysconfig
from distutils.command.build_ext import build_ext

from setuptools import Extension, setup

# monkey patch import hook. Even though flake8 says it's not used, it is.
# comment this out to disable multi threaded builds.
import mp_compile


if sys.platform == "win32" and sys.version_info >= (3, 8):
    warnings.warn(
        "Pillow does not yet support Python {}.{} and does not yet provide "
        "prebuilt Windows binaries. We do not recommend building from "
        "source on Windows.".format(sys.version_info.major,
                                    sys.version_info.minor),
        RuntimeWarning)


_IMAGING = ("decode", "encode", "map", "display", "outline", "path")

_LIB_IMAGING = (
    "Access", "AlphaComposite", "Resample", "Bands", "BcnDecode", "BitDecode",
    "Blend", "Chops", "ColorLUT", "Convert", "ConvertYCbCr", "Copy", "Crop",
    "Dib", "Draw", "Effects", "EpsEncode", "File", "Fill", "Filter",
    "FliDecode", "Geometry", "GetBBox", "GifDecode", "GifEncode", "HexDecode",
    "Histo", "JpegDecode", "JpegEncode", "Matrix", "ModeFilter",
    "Negative", "Offset", "Pack", "PackDecode", "Palette", "Paste", "Quant",
    "QuantOctree", "QuantHash", "QuantHeap", "PcdDecode", "PcxDecode",
    "PcxEncode", "Point", "RankFilter", "RawDecode", "RawEncode", "Storage",
    "SgiRleDecode", "SunRleDecode", "TgaRleDecode", "TgaRleEncode", "Unpack",
    "UnpackYCC", "UnsharpMask", "XbmDecode", "XbmEncode", "ZipDecode",
    "ZipEncode", "TiffDecode", "Jpeg2KDecode", "Jpeg2KEncode", "BoxBlur",
    "QuantPngQuant", "codec_fd")

DEBUG = False


class DependencyException(Exception):
    pass


class RequiredDependencyException(Exception):
    pass


PLATFORM_MINGW = 'mingw' in ccompiler.get_default_compiler()
PLATFORM_PYPY = hasattr(sys, 'pypy_version_info')


def _dbg(s, tp=None):
    if DEBUG:
        if tp:
            print(s % tp)
            return
        print(s)


def _add_directory(path, subdir, where=None):
    if subdir is None:
        return
    subdir = os.path.realpath(subdir)
    if os.path.isdir(subdir) and subdir not in path:
        if where is None:
            _dbg('Appending path %s', subdir)
            path.append(subdir)
        else:
            _dbg('Inserting path %s', subdir)
            path.insert(where, subdir)
    elif subdir in path and where is not None:
        path.remove(subdir)
        path.insert(where, subdir)


def _find_include_file(self, include):
    for directory in self.compiler.include_dirs:
        _dbg('Checking for include file %s in %s', (include, directory))
        if os.path.isfile(os.path.join(directory, include)):
            _dbg('Found %s', include)
            return 1
    return 0


def _find_library_file(self, library):
    ret = self.compiler.find_library_file(self.compiler.library_dirs, library)
    if ret:
        _dbg('Found library %s at %s', (library, ret))
    else:
        _dbg("Couldn't find library %s in %s",
             (library, self.compiler.library_dirs))
    return ret


def _cmd_exists(cmd):
    return any(
        os.access(os.path.join(path, cmd), os.X_OK)
        for path in os.environ["PATH"].split(os.pathsep)
    )


def _read(file):
    with open(file, 'rb') as fp:
        return fp.read()


def get_version():
    version_file = 'src/PIL/_version.py'
    with open(version_file, 'r') as f:
        exec(compile(f.read(), version_file, 'exec'))
    return locals()['__version__']


try:
    import _tkinter
except (ImportError, OSError):
    # pypy emits an oserror
    _tkinter = None

NAME = 'Pillow'
PILLOW_VERSION = get_version()
JPEG_ROOT = None
JPEG2K_ROOT = None
ZLIB_ROOT = None
IMAGEQUANT_ROOT = None
TIFF_ROOT = None
FREETYPE_ROOT = None
LCMS_ROOT = None


def _pkg_config(name):
    try:
        command = [
            'pkg-config',
            '--libs-only-L', name,
            '--cflags-only-I', name,
        ]
        if not DEBUG:
            command.append('--silence-errors')
        libs = subprocess.check_output(command).decode('utf8').split(' ')
        return libs[1][2:].strip(), libs[0][2:].strip()
    except Exception:
        pass


class pil_build_ext(build_ext):
    class feature:
        features = ['zlib', 'jpeg', 'tiff', 'freetype', 'lcms', 'webp',
                    'webpmux', 'jpeg2000', 'imagequant']

        required = {'jpeg', 'zlib'}

        def __init__(self):
            for f in self.features:
                setattr(self, f, None)

        def require(self, feat):
            return feat in self.required

        def want(self, feat):
            return getattr(self, feat) is None

        def __iter__(self):
            for x in self.features:
                yield x

    feature = feature()

    user_options = build_ext.user_options + [
        ('disable-%s' % x, None, 'Disable support for %s' % x) for x in feature
    ] + [
        ('enable-%s' % x, None, 'Enable support for %s' % x) for x in feature
    ] + [
        ('disable-platform-guessing', None,
         'Disable platform guessing on Linux'),
        ('debug', None, 'Debug logging')
    ]

    def initialize_options(self):
        self.disable_platform_guessing = None
        build_ext.initialize_options(self)
        for x in self.feature:
            setattr(self, 'disable_%s' % x, None)
            setattr(self, 'enable_%s' % x, None)

    def finalize_options(self):
        build_ext.finalize_options(self)
        if self.debug:
            global DEBUG
            DEBUG = True
        for x in self.feature:
            if getattr(self, 'disable_%s' % x):
                setattr(self.feature, x, False)
                self.feature.required.discard(x)
                _dbg('Disabling %s', x)
                if getattr(self, 'enable_%s' % x):
                    raise ValueError(
                        'Conflicting options: --enable-%s and --disable-%s' %
                        (x, x))
            if getattr(self, 'enable_%s' % x):
                _dbg('Requiring %s', x)
                self.feature.required.add(x)

    def build_extensions(self):

        library_dirs = []
        include_dirs = []

        _add_directory(include_dirs, "src/libImaging")

        pkg_config = None
        if _cmd_exists('pkg-config'):
            pkg_config = _pkg_config

        #
        # add configured kits
        for root_name, lib_name in dict(JPEG_ROOT="libjpeg",
                                        JPEG2K_ROOT="libopenjp2",
                                        TIFF_ROOT=("libtiff-5", "libtiff-4"),
                                        ZLIB_ROOT="zlib",
                                        FREETYPE_ROOT="freetype2",
                                        LCMS_ROOT="lcms2",
                                        IMAGEQUANT_ROOT="libimagequant"
                                        ).items():
            root = globals()[root_name]
            if root is None and pkg_config:
                if isinstance(lib_name, tuple):
                    for lib_name2 in lib_name:
                        _dbg('Looking for `%s` using pkg-config.' % lib_name2)
                        root = pkg_config(lib_name2)
                        if root:
                            break
                else:
                    _dbg('Looking for `%s` using pkg-config.' % lib_name)
                    root = pkg_config(lib_name)

            if isinstance(root, tuple):
                lib_root, include_root = root
            else:
                lib_root = include_root = root

            _add_directory(library_dirs, lib_root)
            _add_directory(include_dirs, include_root)

        # respect CFLAGS/LDFLAGS
        for k in ('CFLAGS', 'LDFLAGS'):
            if k in os.environ:
                for match in re.finditer(r'-I([^\s]+)', os.environ[k]):
                    _add_directory(include_dirs, match.group(1))
                for match in re.finditer(r'-L([^\s]+)', os.environ[k]):
                    _add_directory(library_dirs, match.group(1))

        # include, rpath, if set as environment variables:
        for k in ('C_INCLUDE_PATH', 'CPATH', 'INCLUDE'):
            if k in os.environ:
                for d in os.environ[k].split(os.path.pathsep):
                    _add_directory(include_dirs, d)

        for k in ('LD_RUN_PATH', 'LIBRARY_PATH', 'LIB'):
            if k in os.environ:
                for d in os.environ[k].split(os.path.pathsep):
                    _add_directory(library_dirs, d)

        prefix = sysconfig.get_config_var("prefix")
        if prefix:
            _add_directory(library_dirs, os.path.join(prefix, "lib"))
            _add_directory(include_dirs, os.path.join(prefix, "include"))

        #
        # add platform directories

        if self.disable_platform_guessing:
            pass

        elif sys.platform == "cygwin":
            # pythonX.Y.dll.a is in the /usr/lib/pythonX.Y/config directory
            _add_directory(library_dirs,
                           os.path.join("/usr/lib", "python%s" %
                                        sys.version[:3], "config"))

        elif sys.platform == "darwin":
            # attempt to make sure we pick freetype2 over other versions
            _add_directory(include_dirs, "/sw/include/freetype2")
            _add_directory(include_dirs, "/sw/lib/freetype2/include")
            # fink installation directories
            _add_directory(library_dirs, "/sw/lib")
            _add_directory(include_dirs, "/sw/include")
            # darwin ports installation directories
            _add_directory(library_dirs, "/opt/local/lib")
            _add_directory(include_dirs, "/opt/local/include")

            # if Homebrew is installed, use its lib and include directories
            try:
                prefix = subprocess.check_output(['brew', '--prefix']).strip(
                ).decode('latin1')
            except Exception:
                # Homebrew not installed
                prefix = None

            ft_prefix = None

            if prefix:
                # add Homebrew's include and lib directories
                _add_directory(library_dirs, os.path.join(prefix, 'lib'))
                _add_directory(include_dirs, os.path.join(prefix, 'include'))
                ft_prefix = os.path.join(prefix, 'opt', 'freetype')

            if ft_prefix and os.path.isdir(ft_prefix):
                # freetype might not be linked into Homebrew's prefix
                _add_directory(library_dirs, os.path.join(ft_prefix, 'lib'))
                _add_directory(include_dirs,
                               os.path.join(ft_prefix, 'include'))
            else:
                # fall back to freetype from XQuartz if
                # Homebrew's freetype is missing
                _add_directory(library_dirs, "/usr/X11/lib")
                _add_directory(include_dirs, "/usr/X11/include")

        elif sys.platform.startswith("linux"):
            arch_tp = (plat.processor(), plat.architecture()[0])
            # This should be correct on debian derivatives.
            if os.path.exists('/etc/debian_version'):
                # If this doesn't work, don't just silently patch
                # downstream because it's going to break when people
                # try to build pillow from source instead of
                # installing from the system packages.
                self.add_multiarch_paths()
Loading ...