]> jfr.im git - dlqueue.git/blob - venv/lib/python3.11/site-packages/setuptools/command/sdist.py
init: venv aand flask
[dlqueue.git] / venv / lib / python3.11 / site-packages / setuptools / command / sdist.py
1 from distutils import log
2 import distutils.command.sdist as orig
3 import os
4 import sys
5 import io
6 import contextlib
7 from itertools import chain
8
9 from .._importlib import metadata
10 from .build import _ORIGINAL_SUBCOMMANDS
11
12 _default_revctrl = list
13
14
15 def walk_revctrl(dirname=''):
16 """Find all files under revision control"""
17 for ep in metadata.entry_points(group='setuptools.file_finders'):
18 for item in ep.load()(dirname):
19 yield item
20
21
22 class sdist(orig.sdist):
23 """Smart sdist that finds anything supported by revision control"""
24
25 user_options = [
26 ('formats=', None, "formats for source distribution (comma-separated list)"),
27 (
28 'keep-temp',
29 'k',
30 "keep the distribution tree around after creating " + "archive file(s)",
31 ),
32 (
33 'dist-dir=',
34 'd',
35 "directory to put the source distribution archive(s) in " "[default: dist]",
36 ),
37 (
38 'owner=',
39 'u',
40 "Owner name used when creating a tar file [default: current user]",
41 ),
42 (
43 'group=',
44 'g',
45 "Group name used when creating a tar file [default: current group]",
46 ),
47 ]
48
49 negative_opt = {}
50
51 README_EXTENSIONS = ['', '.rst', '.txt', '.md']
52 READMES = tuple('README{0}'.format(ext) for ext in README_EXTENSIONS)
53
54 def run(self):
55 self.run_command('egg_info')
56 ei_cmd = self.get_finalized_command('egg_info')
57 self.filelist = ei_cmd.filelist
58 self.filelist.append(os.path.join(ei_cmd.egg_info, 'SOURCES.txt'))
59 self.check_readme()
60
61 # Run sub commands
62 for cmd_name in self.get_sub_commands():
63 self.run_command(cmd_name)
64
65 self.make_distribution()
66
67 dist_files = getattr(self.distribution, 'dist_files', [])
68 for file in self.archive_files:
69 data = ('sdist', '', file)
70 if data not in dist_files:
71 dist_files.append(data)
72
73 def initialize_options(self):
74 orig.sdist.initialize_options(self)
75
76 self._default_to_gztar()
77
78 def _default_to_gztar(self):
79 # only needed on Python prior to 3.6.
80 if sys.version_info >= (3, 6, 0, 'beta', 1):
81 return
82 self.formats = ['gztar']
83
84 def make_distribution(self):
85 """
86 Workaround for #516
87 """
88 with self._remove_os_link():
89 orig.sdist.make_distribution(self)
90
91 @staticmethod
92 @contextlib.contextmanager
93 def _remove_os_link():
94 """
95 In a context, remove and restore os.link if it exists
96 """
97
98 class NoValue:
99 pass
100
101 orig_val = getattr(os, 'link', NoValue)
102 try:
103 del os.link
104 except Exception:
105 pass
106 try:
107 yield
108 finally:
109 if orig_val is not NoValue:
110 setattr(os, 'link', orig_val)
111
112 def add_defaults(self):
113 super().add_defaults()
114 self._add_defaults_build_sub_commands()
115
116 def _add_defaults_optional(self):
117 super()._add_defaults_optional()
118 if os.path.isfile('pyproject.toml'):
119 self.filelist.append('pyproject.toml')
120
121 def _add_defaults_python(self):
122 """getting python files"""
123 if self.distribution.has_pure_modules():
124 build_py = self.get_finalized_command('build_py')
125 self.filelist.extend(build_py.get_source_files())
126 self._add_data_files(self._safe_data_files(build_py))
127
128 def _add_defaults_build_sub_commands(self):
129 build = self.get_finalized_command("build")
130 missing_cmds = set(build.get_sub_commands()) - _ORIGINAL_SUBCOMMANDS
131 # ^-- the original built-in sub-commands are already handled by default.
132 cmds = (self.get_finalized_command(c) for c in missing_cmds)
133 files = (c.get_source_files() for c in cmds if hasattr(c, "get_source_files"))
134 self.filelist.extend(chain.from_iterable(files))
135
136 def _safe_data_files(self, build_py):
137 """
138 Since the ``sdist`` class is also used to compute the MANIFEST
139 (via :obj:`setuptools.command.egg_info.manifest_maker`),
140 there might be recursion problems when trying to obtain the list of
141 data_files and ``include_package_data=True`` (which in turn depends on
142 the files included in the MANIFEST).
143
144 To avoid that, ``manifest_maker`` should be able to overwrite this
145 method and avoid recursive attempts to build/analyze the MANIFEST.
146 """
147 return build_py.data_files
148
149 def _add_data_files(self, data_files):
150 """
151 Add data files as found in build_py.data_files.
152 """
153 self.filelist.extend(
154 os.path.join(src_dir, name)
155 for _, src_dir, _, filenames in data_files
156 for name in filenames
157 )
158
159 def _add_defaults_data_files(self):
160 try:
161 super()._add_defaults_data_files()
162 except TypeError:
163 log.warn("data_files contains unexpected objects")
164
165 def check_readme(self):
166 for f in self.READMES:
167 if os.path.exists(f):
168 return
169 else:
170 self.warn(
171 "standard file not found: should have one of " + ', '.join(self.READMES)
172 )
173
174 def make_release_tree(self, base_dir, files):
175 orig.sdist.make_release_tree(self, base_dir, files)
176
177 # Save any egg_info command line options used to create this sdist
178 dest = os.path.join(base_dir, 'setup.cfg')
179 if hasattr(os, 'link') and os.path.exists(dest):
180 # unlink and re-copy, since it might be hard-linked, and
181 # we don't want to change the source version
182 os.unlink(dest)
183 self.copy_file('setup.cfg', dest)
184
185 self.get_finalized_command('egg_info').save_version_info(dest)
186
187 def _manifest_is_not_generated(self):
188 # check for special comment used in 2.7.1 and higher
189 if not os.path.isfile(self.manifest):
190 return False
191
192 with io.open(self.manifest, 'rb') as fp:
193 first_line = fp.readline()
194 return first_line != '# file GENERATED by distutils, do NOT edit\n'.encode()
195
196 def read_manifest(self):
197 """Read the manifest file (named by 'self.manifest') and use it to
198 fill in 'self.filelist', the list of files to include in the source
199 distribution.
200 """
201 log.info("reading manifest file '%s'", self.manifest)
202 manifest = open(self.manifest, 'rb')
203 for line in manifest:
204 # The manifest must contain UTF-8. See #303.
205 try:
206 line = line.decode('UTF-8')
207 except UnicodeDecodeError:
208 log.warn("%r not UTF-8 decodable -- skipping" % line)
209 continue
210 # ignore comments and blank lines
211 line = line.strip()
212 if line.startswith('#') or not line:
213 continue
214 self.filelist.append(line)
215 manifest.close()