setup.py 4.48 KB
Newer Older
1 2 3
from __future__ import print_function
import re
import os
4
import sys
5
import setuptools
6 7 8 9 10 11 12 13 14 15 16
from setuptools.command.test import test as TestCommand
from distutils.version import StrictVersion
from setuptools import __version__ as setuptools_version


if StrictVersion(setuptools_version) < StrictVersion('38.3.0'):
    raise SystemExit(
        'Your `setuptools` version is old. '
        'Please upgrade setuptools by running `pip install -U setuptools` '
        'and try again.'
    )
17

18

19 20 21 22 23 24 25
# To prevent importing about and thereby breaking the coverage info we use this
# exec hack
about = {}
with open('portalocker/__about__.py') as fp:
    exec(fp.read(), about)


26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
tests_require = [
    'flake8>=3.5.0',
    'pytest>=3.4.0',
    'pytest-cache>=1.0',
    'pytest-cov>=2.5.1',
    'pytest-flakes>=2.0.0',
    'pytest-pep8>=1.0.6',
    'sphinx>=1.7.1',
]


class PyTest(TestCommand):
    user_options = [('pytest-args=', 'a', "Arguments to pass to pytest")]

    def initialize_options(self):
        TestCommand.initialize_options(self)
        self.pytest_args = ''
43

44 45 46 47 48 49 50
    def run_tests(self):
        import shlex
        # import here, cause outside the eggs aren't loaded
        import pytest
        errno = pytest.main(shlex.split(self.pytest_args))
        sys.exit(errno)
    
51

52 53 54 55 56 57 58 59 60 61 62 63 64 65
class Combine(setuptools.Command):
    description = 'Build single combined portalocker file'
    relative_import_re = re.compile(r'^from \. import (?P<name>.+)$',
                                    re.MULTILINE)
    user_options = [
        ('output-file=', 'o', 'Path to the combined output file'),
    ]

    def initialize_options(self):
        self.output_file = os.path.join(
            'dist', '%(package_name)s_%(version)s.py' % dict(
                package_name=about['__package_name__'],
                version=about['__version__'].replace('.', '-'),
            ))
66

67
    def finalize_options(self):
68 69 70 71 72 73 74 75 76 77 78 79 80
        pass

    def run(self):
        dirname = os.path.dirname(self.output_file)
        if dirname and not os.path.isdir(dirname):
            os.makedirs(dirname)

        output = open(self.output_file, 'w')
        print("'''", file=output)
        with open('README.rst') as fh:
            output.write(fh.read().rstrip())
            print('', file=output)
            print('', file=output)
81

82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
        with open('LICENSE') as fh:
            output.write(fh.read().rstrip())

        print('', file=output)
        print("'''", file=output)

        names = set()
        lines = []
        for line in open('portalocker/__init__.py'):
            match = self.relative_import_re.match(line)
            if match:
                names.add(match.group('name'))
                with open('portalocker/%(name)s.py' % match.groupdict()) as fh:
                    line = fh.read()
                    line = self.relative_import_re.sub('', line)

            lines.append(line)

        import_attributes = re.compile(r'\b(%s)\.' % '|'.join(names))
        for line in lines[:]:
            line = import_attributes.sub('', line)
            output.write(line)

        print('Wrote combined file to %r' % self.output_file)
106

107

108 109
if __name__ == '__main__':
    setuptools.setup(
110 111 112
        name=about['__package_name__'],
        version=about['__version__'],
        description=about['__description__'],
113
        long_description=open('README.rst').read(),
114 115 116 117
        classifiers=[
            'Intended Audience :: Developers',
            'Programming Language :: Python',
            'Programming Language :: Python :: 2.7',
118 119 120
            'Programming Language :: Python :: 3.3',
            'Programming Language :: Python :: 3.4',
            'Programming Language :: Python :: 3.5',
121
            'Programming Language :: Python :: 3.6',
122 123
            'Programming Language :: Python :: Implementation :: CPython',
            'Programming Language :: Python :: Implementation :: PyPy',
124 125
        ],
        keywords='locking, locks, with statement, windows, linux, unix',
126 127 128
        author=about['__author__'],
        author_email=about['__email__'],
        url=about['__url__'],
129 130
        license='PSF',
        packages=setuptools.find_packages(exclude=['ez_setup', 'examples']),
131
        # zip_safe=False,
132
        platforms=['any'],
133 134
        cmdclass={
            'combine': Combine,
135
            'test': PyTest,
136
        },
137 138
        install_requires=[
            'pypiwin32; platform_system == "Windows"',
139 140
        ],
        tests_require=tests_require,
141 142 143 144 145 146
        extras_require=dict(
            docs=[
                'sphinx>=1.7.1',
            ],
            tests=tests_require,
        ),
147 148
    )