rjdbcm/Aspidites

View on GitHub
setup.py

Summary

Maintainability
B
4 hrs
Test Coverage
#!/usr/bin/python3
import importlib.util
import os
import sys
from glob import glob
from pathlib import Path
import sysconfig
import importlib
import pkg_resources
from setuptools import setup, find_packages, Extension
from setuptools.dist import Distribution
from setuptools.command.install import install
from setuptools.command.build_ext import build_ext

module_paths = [str(Path('Aspidites/_vendor/contracts/metaclass.py')),
                str(Path('Aspidites/_vendor/contracts/interface.py')),
                str(Path('Aspidites/_vendor/contracts/contract_parser.py')),
                str(Path('Aspidites/_vendor/contracts/syntax.py')),
                str(Path('Aspidites/_vendor/contracts/inspection.py')),
                str(Path('Aspidites/_vendor/contracts/docstring_parsing.py')),
                str(Path('Aspidites/_vendor/contracts/main_actual.py')),
                str(Path('Aspidites/_vendor/contracts/library/arithmetic.py')),
                str(Path('Aspidites/_vendor/contracts/library/files.py')),
                str(Path('Aspidites/_vendor/contracts/library/array_ops.py')),
                str(Path('Aspidites/_vendor/contracts/library/tuple.py')),
                str(Path('Aspidites/_vendor/contracts/library/types_misc.py')),
                str(Path('Aspidites/_vendor/contracts/library/lists.py')),
                str(Path('Aspidites/_vendor/contracts/library/miscellaneous_aliases.py')),
                str(Path('Aspidites/_vendor/contracts/library/attributes.py')),
                str(Path('Aspidites/_vendor/contracts/library/suggester.py')),
                str(Path('Aspidites/_vendor/contracts/library/variables.py')),
                str(Path('Aspidites/_vendor/contracts/library/separate_context.py')),
                str(Path('Aspidites/_vendor/contracts/library/simple_values.py')),
                str(Path('Aspidites/_vendor/contracts/library/map.py')),
                str(Path('Aspidites/_vendor/contracts/library/comparison.py')),
                str(Path('Aspidites/_vendor/contracts/library/extensions.py')),
                str(Path('Aspidites/_vendor/contracts/library/collection.py')),
                str(Path('Aspidites/_vendor/contracts/library/datetime_tz.py')),
                str(Path('Aspidites/_vendor/contracts/library/scoped_variables.py')),
                str(Path('Aspidites/_vendor/contracts/library/array.py')),
                str(Path('Aspidites/_vendor/contracts/library/sets.py')),
                str(Path('Aspidites/_vendor/contracts/library/dummy.py')),
                str(Path('Aspidites/_vendor/contracts/library/dicts.py')),
                str(Path('Aspidites/_vendor/contracts/library/compositions.py')),
                str(Path('Aspidites/_vendor/contracts/library/strings.py')),
                str(Path('Aspidites/_vendor/contracts/library/isinstance_imp.py')),
                str(Path('Aspidites/_vendor/contracts/library/seq.py')),
                str(Path('Aspidites/_vendor/contracts/useful_contracts/numbers.py')),
                str(Path("Aspidites/_vendor/fn/func.py")),
                str(Path("Aspidites/_vendor/fn/iters.py")),
                str(Path("Aspidites/_vendor/fn/op.py")),
                str(Path("Aspidites/_vendor/fn/underscore.py")),
                str(Path('Aspidites/_vendor/decorator_extension.py')),
                str(Path('Aspidites/_vendor/pyparsing_extension.py')),
                str(Path('Aspidites/_vendor/RestrictedPython/Limits.py')),
                str(Path('Aspidites/__main__.py')),
                str(Path('Aspidites/woma/fileutils.py')),
                str(Path('Aspidites/woma/gcutils.py')),
                str(Path('Aspidites/woma/mathutils.py')),
                str(Path('Aspidites/_vendor/pyrsistent/typing.py')),
                # str(Path('Aspidites/_vendor/pyrsistent/_transformations.py')),
                str(Path('Aspidites/_vendor/pyrsistent/_checked_types.py')),
                # str(Path('Aspidites/_vendor/pyrsistent/_field_common.py')),
                str(Path('Aspidites/_vendor/pyrsistent/_helpers.py')),
                str(Path('Aspidites/_vendor/pyrsistent/_immutable.py')),
                str(Path('Aspidites/_vendor/pyrsistent/_pclass.py')),
                str(Path('Aspidites/_vendor/pyrsistent/_pbag.py')),
                str(Path('Aspidites/_vendor/pyrsistent/_pdeque.py')),
                str(Path('Aspidites/_vendor/pyrsistent/_plist.py')),
                str(Path('Aspidites/_vendor/pyrsistent/_pmap.py')),
                str(Path('Aspidites/_vendor/pyrsistent/_precord.py')),
                str(Path('Aspidites/_vendor/pyrsistent/_pset.py')),
                str(Path('Aspidites/_vendor/pyrsistent/_pvector.py')),
                str(Path('Aspidites/_vendor/pyrsistent/_toolz.py')),
                str(Path('Aspidites/_vendor/apm/error.py')),
                # str(Path('Aspidites/_vendor/apm/case_of.py')),
                str(Path('Aspidites/_vendor/apm/patterns.py')),
                str(Path('Aspidites/_vendor/apm/overload.py')),
                str(Path('Aspidites/_vendor/apm/try_match.py')),
                # str(Path('Aspidites/_vendor/apm/typefoo.py')),
                # str(Path('Aspidites/_vendor/apm/core.py')),
                str(Path('Aspidites/_vendor/apm/_util.py')),
                # str(Path('Aspidites/_vendor/apm/agg.py')),
                str(Path('Aspidites/_vendor/apm/generic.py')),
                str(Path('Aspidites/_vendor/apm/no_value.py')),
                str(Path('Aspidites/_vendor/apm/match.py')),
                ]
bootstrap_paths = [

                str(Path('Aspidites/api/compiler.py')),
                str(Path('Aspidites/api/convert.py')),
                str(Path('Aspidites/api/reserved.py')),
                str(Path('Aspidites/api/parser.py')),
                str(Path('Aspidites/api/templates.py')),
                str(Path('Aspidites/api/type_guard.py')),
                str(Path('Aspidites/api/final.py')),
                str(Path('Aspidites/api/monads.py')),
                str(Path('Aspidites/api/math.py')),
                str(Path('Aspidites/api/api.py')),
]
try:
    from numpy import get_include
    module_paths += [str(Path('Aspidites/_vendor/contracts/useful_contracts/numpy_specific.py'))]
except ModuleNotFoundError:
    def get_include():
        try:
            return sysconfig.get_config_vars()['CONFINCLUDEPY']
        except KeyError:
            return ''

# ~#~ # Build static libs # ~#~ #
from Cython.Build import cythonize
from Cython.Compiler import Options
from Cython.Build.Cythonize import cython_compile
vendored = ['contracts', 'decorator', 'fn', 'pyparsing', 'pyrsistent', 'RestrictedPython', 'semantic_version']
if sys.platform == 'darwin' or sys.platform == 'linux':
    sep = '/'
else:
    sep = '\\'
extensions = []

for i in module_paths:
    extensions.append(
        Extension(
            i.replace('.py', '').replace(sep, '.'),
            sources=[i],
            extra_compile_args=['-fno-wrapv', '-flto'],
            extra_link_args=['-flto']))

for i in bootstrap_paths:
    extensions.append(
        Extension(
            i.replace('.py', '').replace(sep, '.'),
            sources=[i],
            extra_compile_args=['-fno-wrapv', '-flto'],
            extra_link_args=['-flto']))

print('compiling vendored extensions')
#       '-----------------------------')
# for lib in vendored:
#     module = importlib.import_module('Aspidites._vendor.' + lib)
#     print(lib, getattr(module, '__version__'))
# print('-----------------------------')


ext_modules = cythonize(extensions, quiet=True)
ext_modules += [Extension('Aspidites._vendor.pyrsistent.pvectorc', sources=['Aspidites/_vendor/pyrsistent/pvectorcmodule.c'])]


def read(fname):
    return open(Path(fname).absolute()).read()


# Tested with wheel v0.29.0, 0.36.2
class BinaryDistribution(Distribution):
    """Distribution which always forces a binary package with platform name"""
    def has_ext_modules(foo):
        return True


class InstallWrapper(install):
    """Provides a install wrapper for native woma
    extensions. These don't really belong in the
    Python package."""

    def run(self):
        # Run this first so the install stops in case
        # these fail otherwise the Python package is
        # successfully installed
        print("running preinstall hooks")
        self.preinstall()
        install.run(self)  # pip install
        print("running postinstall hooks")
        self.postinstall()

    def preinstall(self):
        """preinstall hook"""
        for i in module_paths:
            os.remove(i.replace('.py', '.c'))

    def postinstall(self):
        """postinstall hook"""
        pass


class BuildExtWrapper(build_ext):
    """Provides a build_ext wrapper for native woma
    extensions. These don't really belong in the
    Python package."""

    def run(self):
        # Run this first so the install stops in case
        # these fail otherwise the Python package is
        # successfully installed
        print("running prebuild hooks")
        self.prebuild()
        build_ext.run(self)  # pip install
        print("running postbuild hooks")
        self.postbuild()

    def prebuild(self):
        """prebuild hook"""

    def postbuild(self):
        """postbuild hook"""


        print('bootstrapping standard library in Aspidites/woma')
        from Aspidites.__main__ import get_cy_kwargs
        from Aspidites.api import Compiler, CompilerArgs, parser
        cy_kwargs = get_cy_kwargs()
        code = open(Path('Aspidites/woma/library.wom'), 'r').read()
        cy_kwargs.update(
            code=parser.parse_module(code),
            force=True,
            fname='Aspidites/woma/library.pyx',
            bytecode=False,
            c=True,
            verbose=0,
            build_requires='',
            bootstrap=True
        )
        compile_args = CompilerArgs(**cy_kwargs)
        Compiler(compile_args)


from Aspidites import __version__, __license__, __title__, __author__

setup(
    name=__title__,
    version=__version__,
    author=__author__,
    author_email="rjdbcm@mail.umkc.edu",
    description="Aspidites is the reference implementation of the Woma Language",
    license=__license__,
    keywords="language",
    url="https://github.com/rjdbcm/Aspidites",
    install_requires=[
        'cython>0.28,<3',
        'pytest',
        'pytest-xdist',
        'pytest-mock',
        'hypothesis',
        'future'
        ],
    packages=find_packages(),
    include_dirs=[get_include()],
    ext_modules=ext_modules,
    test_suite='Aspidites/tests',
    distclass=Distribution if sys.platform != 'darwin' else BinaryDistribution,
    entry_points={'console_scripts': ['aspidites = Aspidites.__main__:main']},
    package_data={'': ["*.wom", "*.pyx", "*.pyi", "*.so", "*.c", "Aspidites/py.typed"]},  # add any native *.wom files
    long_description=read('README.md'),
    cmdclass={'install': InstallWrapper, 'build_ext': BuildExtWrapper},
    long_description_content_type='text/markdown',
    classifiers=[
        "Operating System :: POSIX :: Linux",
        "Operating System :: MacOS :: MacOS X",
        "Operating System :: Microsoft :: Windows",
        "Development Status :: 4 - Beta",
        "Environment :: Console",
        "Programming Language :: Other",
        # "Programming Language :: Python :: 3.6", EOL in December 2021 and don't want to vendor dataclasses
        "Programming Language :: Python :: 3.7",
        "Programming Language :: Python :: 3.8",
        "Programming Language :: Python :: 3.9",
        # "Programming Language :: Python :: Implementation :: PyPy", looks like a no go
        "Programming Language :: Python :: Implementation :: CPython",
        "Topic :: Software Development :: Compilers",
        "Topic :: Utilities",
        "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
        "License :: OSI Approved :: MIT License",
        "License :: OSI Approved :: BSD License",
        # "License :: OSI Approved :: Zope Public License (ZPL)", ??? Invalid
        "License :: OSI Approved :: Apache Software License",
    ],
)