Diff of /setup.py [000000] .. [4e96d3]

Switch to unified view

a b/setup.py
1
# Copyright (c) OpenMMLab. All rights reserved.
2
import os
3
import os.path as osp
4
import platform
5
import shutil
6
import sys
7
import warnings
8
from setuptools import find_packages, setup
9
10
11
def readme():
12
    with open('README.md', encoding='utf-8') as f:
13
        content = f.read()
14
    return content
15
16
17
version_file = 'mmseg/version.py'
18
19
20
def get_version():
21
    with open(version_file, 'r') as f:
22
        exec(compile(f.read(), version_file, 'exec'))
23
    return locals()['__version__']
24
25
26
def parse_requirements(fname='requirements.txt', with_version=True):
27
    """Parse the package dependencies listed in a requirements file but strips
28
    specific versioning information.
29
30
    Args:
31
        fname (str): path to requirements file
32
        with_version (bool, default=False): if True include version specs
33
34
    Returns:
35
        List[str]: list of requirements items
36
37
    CommandLine:
38
        python -c "import setup; print(setup.parse_requirements())"
39
    """
40
    import re
41
    import sys
42
    from os.path import exists
43
    require_fpath = fname
44
45
    def parse_line(line):
46
        """Parse information from a line in a requirements text file."""
47
        if line.startswith('-r '):
48
            # Allow specifying requirements in other files
49
            target = line.split(' ')[1]
50
            for info in parse_require_file(target):
51
                yield info
52
        else:
53
            info = {'line': line}
54
            if line.startswith('-e '):
55
                info['package'] = line.split('#egg=')[1]
56
            else:
57
                # Remove versioning from the package
58
                pat = '(' + '|'.join(['>=', '==', '>']) + ')'
59
                parts = re.split(pat, line, maxsplit=1)
60
                parts = [p.strip() for p in parts]
61
62
                info['package'] = parts[0]
63
                if len(parts) > 1:
64
                    op, rest = parts[1:]
65
                    if ';' in rest:
66
                        # Handle platform specific dependencies
67
                        # http://setuptools.readthedocs.io/en/latest/setuptools.html#declaring-platform-specific-dependencies
68
                        version, platform_deps = map(str.strip,
69
                                                     rest.split(';'))
70
                        info['platform_deps'] = platform_deps
71
                    else:
72
                        version = rest  # NOQA
73
                    info['version'] = (op, version)
74
            yield info
75
76
    def parse_require_file(fpath):
77
        with open(fpath, 'r') as f:
78
            for line in f.readlines():
79
                line = line.strip()
80
                if line and not line.startswith('#'):
81
                    for info in parse_line(line):
82
                        yield info
83
84
    def gen_packages_items():
85
        if exists(require_fpath):
86
            for info in parse_require_file(require_fpath):
87
                parts = [info['package']]
88
                if with_version and 'version' in info:
89
                    parts.extend(info['version'])
90
                if not sys.version.startswith('3.4'):
91
                    # apparently package_deps are broken in 3.4
92
                    platform_deps = info.get('platform_deps')
93
                    if platform_deps is not None:
94
                        parts.append(';' + platform_deps)
95
                item = ''.join(parts)
96
                yield item
97
98
    packages = list(gen_packages_items())
99
    return packages
100
101
102
def add_mim_extension():
103
    """Add extra files that are required to support MIM into the package.
104
105
    These files will be added by creating a symlink to the originals if the
106
    package is installed in `editable` mode (e.g. pip install -e .), or by
107
    copying from the originals otherwise.
108
    """
109
110
    # parse installment mode
111
    if 'develop' in sys.argv:
112
        # installed by `pip install -e .`
113
        if platform.system() == 'Windows':
114
            # set `copy` mode here since symlink fails on Windows.
115
            mode = 'copy'
116
        else:
117
            mode = 'symlink'
118
    elif 'sdist' in sys.argv or 'bdist_wheel' in sys.argv or \
119
            platform.system() == 'Windows':
120
        # installed by `pip install .`
121
        # or create source distribution by `python setup.py sdist`
122
        # set `copy` mode here since symlink fails with WinError on Windows.
123
        mode = 'copy'
124
    else:
125
        return
126
127
    filenames = ['tools', 'configs', 'model-index.yml']
128
    repo_path = osp.dirname(__file__)
129
    mim_path = osp.join(repo_path, 'mmseg', '.mim')
130
    os.makedirs(mim_path, exist_ok=True)
131
132
    for filename in filenames:
133
        if osp.exists(filename):
134
            src_path = osp.join(repo_path, filename)
135
            tar_path = osp.join(mim_path, filename)
136
137
            if osp.isfile(tar_path) or osp.islink(tar_path):
138
                os.remove(tar_path)
139
            elif osp.isdir(tar_path):
140
                shutil.rmtree(tar_path)
141
142
            if mode == 'symlink':
143
                src_relpath = osp.relpath(src_path, osp.dirname(tar_path))
144
                try:
145
                    os.symlink(src_relpath, tar_path)
146
                except OSError:
147
                    # Creating a symbolic link on windows may raise an
148
                    # `OSError: [WinError 1314]` due to privilege. If
149
                    # the error happens, the src file will be copied
150
                    mode = 'copy'
151
                    warnings.warn(
152
                        f'Failed to create a symbolic link for {src_relpath}, '
153
                        f'and it will be copied to {tar_path}')
154
                else:
155
                    continue
156
157
            if mode == 'copy':
158
                if osp.isfile(src_path):
159
                    shutil.copyfile(src_path, tar_path)
160
                elif osp.isdir(src_path):
161
                    shutil.copytree(src_path, tar_path)
162
                else:
163
                    warnings.warn(f'Cannot copy file {src_path}.')
164
            else:
165
                raise ValueError(f'Invalid mode {mode}')
166
167
168
if __name__ == '__main__':
169
    add_mim_extension()
170
    setup(
171
        name='mmsegmentation',
172
        version=get_version(),
173
        description='Open MMLab Semantic Segmentation Toolbox and Benchmark',
174
        long_description=readme(),
175
        long_description_content_type='text/markdown',
176
        author='MMSegmentation Contributors',
177
        author_email='openmmlab@gmail.com',
178
        keywords='computer vision, semantic segmentation',
179
        url='http://github.com/open-mmlab/mmsegmentation',
180
        packages=find_packages(exclude=('configs', 'tools', 'demo')),
181
        include_package_data=True,
182
        classifiers=[
183
            'Development Status :: 4 - Beta',
184
            'License :: OSI Approved :: Apache Software License',
185
            'Operating System :: OS Independent',
186
            'Programming Language :: Python :: 3.6',
187
            'Programming Language :: Python :: 3.7',
188
            'Programming Language :: Python :: 3.8',
189
            'Programming Language :: Python :: 3.9',
190
        ],
191
        license='Apache License 2.0',
192
        setup_requires=parse_requirements('requirements/build.txt'),
193
        tests_require=parse_requirements('requirements/tests.txt'),
194
        install_requires=parse_requirements('requirements/runtime.txt'),
195
        extras_require={
196
            'all': parse_requirements('requirements.txt'),
197
            'tests': parse_requirements('requirements/tests.txt'),
198
            'build': parse_requirements('requirements/build.txt'),
199
            'optional': parse_requirements('requirements/optional.txt'),
200
        },
201
        ext_modules=[],
202
        zip_safe=False)