comparison planemo/lib/python3.7/site-packages/setuptools/__init__.py @ 1:56ad4e20f292 draft

"planemo upload commit 6eee67778febed82ddd413c3ca40b3183a3898f1"
author guerler
date Fri, 31 Jul 2020 00:32:28 -0400
parents
children
comparison
equal deleted inserted replaced
0:d30785e31577 1:56ad4e20f292
1 """Extensions to the 'distutils' for large or complex distributions"""
2
3 import os
4 import sys
5 import functools
6 import distutils.core
7 import distutils.filelist
8 import re
9 from distutils.errors import DistutilsOptionError
10 from distutils.util import convert_path
11 from fnmatch import fnmatchcase
12
13 from ._deprecation_warning import SetuptoolsDeprecationWarning
14
15 from setuptools.extern.six import PY3, string_types
16 from setuptools.extern.six.moves import filter, map
17
18 import setuptools.version
19 from setuptools.extension import Extension
20 from setuptools.dist import Distribution, Feature
21 from setuptools.depends import Require
22 from . import monkey
23
24 __metaclass__ = type
25
26
27 __all__ = [
28 'setup', 'Distribution', 'Feature', 'Command', 'Extension', 'Require',
29 'SetuptoolsDeprecationWarning',
30 'find_packages'
31 ]
32
33 if PY3:
34 __all__.append('find_namespace_packages')
35
36 __version__ = setuptools.version.__version__
37
38 bootstrap_install_from = None
39
40 # If we run 2to3 on .py files, should we also convert docstrings?
41 # Default: yes; assume that we can detect doctests reliably
42 run_2to3_on_doctests = True
43 # Standard package names for fixer packages
44 lib2to3_fixer_packages = ['lib2to3.fixes']
45
46
47 class PackageFinder:
48 """
49 Generate a list of all Python packages found within a directory
50 """
51
52 @classmethod
53 def find(cls, where='.', exclude=(), include=('*',)):
54 """Return a list all Python packages found within directory 'where'
55
56 'where' is the root directory which will be searched for packages. It
57 should be supplied as a "cross-platform" (i.e. URL-style) path; it will
58 be converted to the appropriate local path syntax.
59
60 'exclude' is a sequence of package names to exclude; '*' can be used
61 as a wildcard in the names, such that 'foo.*' will exclude all
62 subpackages of 'foo' (but not 'foo' itself).
63
64 'include' is a sequence of package names to include. If it's
65 specified, only the named packages will be included. If it's not
66 specified, all found packages will be included. 'include' can contain
67 shell style wildcard patterns just like 'exclude'.
68 """
69
70 return list(cls._find_packages_iter(
71 convert_path(where),
72 cls._build_filter('ez_setup', '*__pycache__', *exclude),
73 cls._build_filter(*include)))
74
75 @classmethod
76 def _find_packages_iter(cls, where, exclude, include):
77 """
78 All the packages found in 'where' that pass the 'include' filter, but
79 not the 'exclude' filter.
80 """
81 for root, dirs, files in os.walk(where, followlinks=True):
82 # Copy dirs to iterate over it, then empty dirs.
83 all_dirs = dirs[:]
84 dirs[:] = []
85
86 for dir in all_dirs:
87 full_path = os.path.join(root, dir)
88 rel_path = os.path.relpath(full_path, where)
89 package = rel_path.replace(os.path.sep, '.')
90
91 # Skip directory trees that are not valid packages
92 if ('.' in dir or not cls._looks_like_package(full_path)):
93 continue
94
95 # Should this package be included?
96 if include(package) and not exclude(package):
97 yield package
98
99 # Keep searching subdirectories, as there may be more packages
100 # down there, even if the parent was excluded.
101 dirs.append(dir)
102
103 @staticmethod
104 def _looks_like_package(path):
105 """Does a directory look like a package?"""
106 return os.path.isfile(os.path.join(path, '__init__.py'))
107
108 @staticmethod
109 def _build_filter(*patterns):
110 """
111 Given a list of patterns, return a callable that will be true only if
112 the input matches at least one of the patterns.
113 """
114 return lambda name: any(fnmatchcase(name, pat=pat) for pat in patterns)
115
116
117 class PEP420PackageFinder(PackageFinder):
118 @staticmethod
119 def _looks_like_package(path):
120 return True
121
122
123 find_packages = PackageFinder.find
124
125 if PY3:
126 find_namespace_packages = PEP420PackageFinder.find
127
128
129 def _install_setup_requires(attrs):
130 # Note: do not use `setuptools.Distribution` directly, as
131 # our PEP 517 backend patch `distutils.core.Distribution`.
132 dist = distutils.core.Distribution(dict(
133 (k, v) for k, v in attrs.items()
134 if k in ('dependency_links', 'setup_requires')
135 ))
136 # Honor setup.cfg's options.
137 dist.parse_config_files(ignore_option_errors=True)
138 if dist.setup_requires:
139 dist.fetch_build_eggs(dist.setup_requires)
140
141
142 def setup(**attrs):
143 # Make sure we have any requirements needed to interpret 'attrs'.
144 _install_setup_requires(attrs)
145 return distutils.core.setup(**attrs)
146
147 setup.__doc__ = distutils.core.setup.__doc__
148
149
150 _Command = monkey.get_unpatched(distutils.core.Command)
151
152
153 class Command(_Command):
154 __doc__ = _Command.__doc__
155
156 command_consumes_arguments = False
157
158 def __init__(self, dist, **kw):
159 """
160 Construct the command for dist, updating
161 vars(self) with any keyword parameters.
162 """
163 _Command.__init__(self, dist)
164 vars(self).update(kw)
165
166 def _ensure_stringlike(self, option, what, default=None):
167 val = getattr(self, option)
168 if val is None:
169 setattr(self, option, default)
170 return default
171 elif not isinstance(val, string_types):
172 raise DistutilsOptionError("'%s' must be a %s (got `%s`)"
173 % (option, what, val))
174 return val
175
176 def ensure_string_list(self, option):
177 r"""Ensure that 'option' is a list of strings. If 'option' is
178 currently a string, we split it either on /,\s*/ or /\s+/, so
179 "foo bar baz", "foo,bar,baz", and "foo, bar baz" all become
180 ["foo", "bar", "baz"].
181 """
182 val = getattr(self, option)
183 if val is None:
184 return
185 elif isinstance(val, string_types):
186 setattr(self, option, re.split(r',\s*|\s+', val))
187 else:
188 if isinstance(val, list):
189 ok = all(isinstance(v, string_types) for v in val)
190 else:
191 ok = False
192 if not ok:
193 raise DistutilsOptionError(
194 "'%s' must be a list of strings (got %r)"
195 % (option, val))
196
197 def reinitialize_command(self, command, reinit_subcommands=0, **kw):
198 cmd = _Command.reinitialize_command(self, command, reinit_subcommands)
199 vars(cmd).update(kw)
200 return cmd
201
202
203 def _find_all_simple(path):
204 """
205 Find all files under 'path'
206 """
207 results = (
208 os.path.join(base, file)
209 for base, dirs, files in os.walk(path, followlinks=True)
210 for file in files
211 )
212 return filter(os.path.isfile, results)
213
214
215 def findall(dir=os.curdir):
216 """
217 Find all files under 'dir' and return the list of full filenames.
218 Unless dir is '.', return full filenames with dir prepended.
219 """
220 files = _find_all_simple(dir)
221 if dir == os.curdir:
222 make_rel = functools.partial(os.path.relpath, start=dir)
223 files = map(make_rel, files)
224 return list(files)
225
226
227 # Apply monkey patches
228 monkey.patch_all()