Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: third_party/twisted_8_1/twisted/python/dist.py

Issue 12261012: Remove third_party/twisted_8_1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 """
2 Distutils convenience functionality.
3
4 Don't use this outside of Twisted.
5
6 Maintainer: U{Christopher Armstrong<mailto:radix@twistedmatrix.com>}
7 """
8
9 import sys, os
10 from distutils.command import build_scripts, install_data, build_ext, build_py
11 from distutils.errors import CompileError
12 from distutils import core
13 from distutils.core import Extension
14
15 twisted_subprojects = ["conch", "flow", "lore", "mail", "names",
16 "news", "pair", "runner", "web", "web2",
17 "words", "vfs"]
18
19
20 class ConditionalExtension(Extension):
21 """
22 An extension module that will only be compiled if certain conditions are
23 met.
24
25 @param condition: A callable of one argument which returns True or False to
26 indicate whether the extension should be built. The argument is an
27 instance of L{build_ext_twisted}, which has useful methods for checking
28 things about the platform.
29 """
30 def __init__(self, *args, **kwargs):
31 self.condition = kwargs.pop("condition", lambda builder: True)
32 Extension.__init__(self, *args, **kwargs)
33
34
35
36 def setup(**kw):
37 """
38 An alternative to distutils' setup() which is specially designed
39 for Twisted subprojects.
40
41 Pass twisted_subproject=projname if you want package and data
42 files to automatically be found for you.
43
44 @param conditionalExtensions: Extensions to optionally build.
45 @type conditionalExtensions: C{list} of L{ConditionalExtension}
46 """
47 return core.setup(**get_setup_args(**kw))
48
49 def get_setup_args(**kw):
50 if 'twisted_subproject' in kw:
51 if 'twisted' not in os.listdir('.'):
52 raise RuntimeError("Sorry, you need to run setup.py from the "
53 "toplevel source directory.")
54 projname = kw['twisted_subproject']
55 projdir = os.path.join('twisted', projname)
56
57 kw['packages'] = getPackages(projdir, parent='twisted')
58 kw['version'] = getVersion(projname)
59
60 plugin = "twisted/plugins/twisted_" + projname + ".py"
61 if os.path.exists(plugin):
62 kw.setdefault('py_modules', []).append(
63 plugin.replace("/", ".")[:-3])
64
65 kw['data_files'] = getDataFiles(projdir, parent='twisted')
66
67 del kw['twisted_subproject']
68 else:
69 if 'plugins' in kw:
70 py_modules = []
71 for plg in kw['plugins']:
72 py_modules.append("twisted.plugins." + plg)
73 kw.setdefault('py_modules', []).extend(py_modules)
74 del kw['plugins']
75
76 if 'cmdclass' not in kw:
77 kw['cmdclass'] = {
78 'install_data': install_data_twisted,
79 'build_scripts': build_scripts_twisted}
80 if sys.version_info[:3] < (2, 3, 0):
81 kw['cmdclass']['build_py'] = build_py_twisted
82
83 if "conditionalExtensions" in kw:
84 extensions = kw["conditionalExtensions"]
85 del kw["conditionalExtensions"]
86
87 if 'ext_modules' not in kw:
88 # This is a workaround for distutils behavior; ext_modules isn't
89 # actually used by our custom builder. distutils deep-down checks
90 # to see if there are any ext_modules defined before invoking
91 # the build_ext command. We need to trigger build_ext regardless
92 # because it is the thing that does the conditional checks to see
93 # if it should build any extensions. The reason we have to delay
94 # the conditional checks until then is that the compiler objects
95 # are not yet set up when this code is executed.
96 kw["ext_modules"] = extensions
97
98 class my_build_ext(build_ext_twisted):
99 conditionalExtensions = extensions
100 kw.setdefault('cmdclass', {})['build_ext'] = my_build_ext
101 return kw
102
103 def getVersion(proj, base="twisted"):
104 """
105 Extract the version number for a given project.
106
107 @param proj: the name of the project. Examples are "core",
108 "conch", "words", "mail".
109
110 @rtype: str
111 @returns: The version number of the project, as a string like
112 "2.0.0".
113 """
114 if proj == 'core':
115 vfile = os.path.join(base, '_version.py')
116 else:
117 vfile = os.path.join(base, proj, '_version.py')
118 ns = {'__name__': 'Nothing to see here'}
119 execfile(vfile, ns)
120 return ns['version'].base()
121
122
123 # Names that are exluded from globbing results:
124 EXCLUDE_NAMES = ["{arch}", "CVS", ".cvsignore", "_darcs",
125 "RCS", "SCCS", ".svn"]
126 EXCLUDE_PATTERNS = ["*.py[cdo]", "*.s[ol]", ".#*", "*~", "*.py"]
127
128 import fnmatch
129
130 def _filterNames(names):
131 """Given a list of file names, return those names that should be copied.
132 """
133 names = [n for n in names
134 if n not in EXCLUDE_NAMES]
135 # This is needed when building a distro from a working
136 # copy (likely a checkout) rather than a pristine export:
137 for pattern in EXCLUDE_PATTERNS:
138 names = [n for n in names
139 if (not fnmatch.fnmatch(n, pattern))
140 and (not n.endswith('.py'))]
141 return names
142
143 def relativeTo(base, relativee):
144 """
145 Gets 'relativee' relative to 'basepath'.
146
147 i.e.,
148
149 >>> relativeTo('/home/', '/home/radix/')
150 'radix'
151 >>> relativeTo('.', '/home/radix/Projects/Twisted') # curdir is /home/radix
152 'Projects/Twisted'
153
154 The 'relativee' must be a child of 'basepath'.
155 """
156 basepath = os.path.abspath(base)
157 relativee = os.path.abspath(relativee)
158 if relativee.startswith(basepath):
159 relative = relativee[len(basepath):]
160 if relative.startswith(os.sep):
161 relative = relative[1:]
162 return os.path.join(base, relative)
163 raise ValueError("%s is not a subpath of %s" % (relativee, basepath))
164
165
166 def getDataFiles(dname, ignore=None, parent=None):
167 """
168 Get all the data files that should be included in this distutils Project.
169
170 'dname' should be the path to the package that you're distributing.
171
172 'ignore' is a list of sub-packages to ignore. This facilitates
173 disparate package hierarchies. That's a fancy way of saying that
174 the 'twisted' package doesn't want to include the 'twisted.conch'
175 package, so it will pass ['conch'] as the value.
176
177 'parent' is necessary if you're distributing a subpackage like
178 twisted.conch. 'dname' should point to 'twisted/conch' and 'parent'
179 should point to 'twisted'. This ensures that your data_files are
180 generated correctly, only using relative paths for the first element
181 of the tuple ('twisted/conch/*').
182 The default 'parent' is the current working directory.
183 """
184 parent = parent or "."
185 ignore = ignore or []
186 result = []
187 for directory, subdirectories, filenames in os.walk(dname):
188 resultfiles = []
189 for exname in EXCLUDE_NAMES:
190 if exname in subdirectories:
191 subdirectories.remove(exname)
192 for ig in ignore:
193 if ig in subdirectories:
194 subdirectories.remove(ig)
195 for filename in _filterNames(filenames):
196 resultfiles.append(filename)
197 if resultfiles:
198 result.append((relativeTo(parent, directory),
199 [relativeTo(parent,
200 os.path.join(directory, filename))
201 for filename in resultfiles]))
202 return result
203
204 def getPackages(dname, pkgname=None, results=None, ignore=None, parent=None):
205 """
206 Get all packages which are under dname. This is necessary for
207 Python 2.2's distutils. Pretty similar arguments to getDataFiles,
208 including 'parent'.
209 """
210 parent = parent or ""
211 prefix = []
212 if parent:
213 prefix = [parent]
214 bname = os.path.basename(dname)
215 ignore = ignore or []
216 if bname in ignore:
217 return []
218 if results is None:
219 results = []
220 if pkgname is None:
221 pkgname = []
222 subfiles = os.listdir(dname)
223 abssubfiles = [os.path.join(dname, x) for x in subfiles]
224 if '__init__.py' in subfiles:
225 results.append(prefix + pkgname + [bname])
226 for subdir in filter(os.path.isdir, abssubfiles):
227 getPackages(subdir, pkgname=pkgname + [bname],
228 results=results, ignore=ignore,
229 parent=parent)
230 res = ['.'.join(result) for result in results]
231 return res
232
233
234
235 def getScripts(projname, basedir=''):
236 """
237 Returns a list of scripts for a Twisted subproject; this works in
238 any of an SVN checkout, a project-specific tarball.
239 """
240 scriptdir = os.path.join(basedir, 'bin', projname)
241 if not os.path.isdir(scriptdir):
242 # Probably a project-specific tarball, in which case only this
243 # project's bins are included in 'bin'
244 scriptdir = os.path.join(basedir, 'bin')
245 if not os.path.isdir(scriptdir):
246 return []
247 thingies = os.listdir(scriptdir)
248 if '.svn' in thingies:
249 thingies.remove('.svn')
250 return filter(os.path.isfile,
251 [os.path.join(scriptdir, x) for x in thingies])
252
253
254 ## Helpers and distutil tweaks
255
256 class build_py_twisted(build_py.build_py):
257 """
258 Changes behavior in Python 2.2 to support simultaneous specification of
259 `packages' and `py_modules'.
260 """
261 def run(self):
262 if self.py_modules:
263 self.build_modules()
264 if self.packages:
265 self.build_packages()
266 self.byte_compile(self.get_outputs(include_bytecode=0))
267
268
269
270 class build_scripts_twisted(build_scripts.build_scripts):
271 """Renames scripts so they end with '.py' on Windows."""
272
273 def run(self):
274 build_scripts.build_scripts.run(self)
275 if not os.name == "nt":
276 return
277 for f in os.listdir(self.build_dir):
278 fpath=os.path.join(self.build_dir, f)
279 if not fpath.endswith(".py"):
280 try:
281 os.unlink(fpath + ".py")
282 except EnvironmentError, e:
283 if e.args[1]=='No such file or directory':
284 pass
285 os.rename(fpath, fpath + ".py")
286
287
288
289 class install_data_twisted(install_data.install_data):
290 """I make sure data files are installed in the package directory."""
291 def finalize_options(self):
292 self.set_undefined_options('install',
293 ('install_lib', 'install_dir')
294 )
295 install_data.install_data.finalize_options(self)
296
297
298
299 class build_ext_twisted(build_ext.build_ext):
300 """
301 Allow subclasses to easily detect and customize Extensions to
302 build at install-time.
303 """
304
305 def prepare_extensions(self):
306 """
307 Prepare the C{self.extensions} attribute (used by
308 L{build_ext.build_ext}) by checking which extensions in
309 L{conditionalExtensions} should be built. In addition, if we are
310 building on NT, define the WIN32 macro to 1.
311 """
312 # always define WIN32 under Windows
313 if os.name == 'nt':
314 self.define_macros = [("WIN32", 1)]
315 else:
316 self.define_macros = []
317 self.extensions = [x for x in self.conditionalExtensions
318 if x.condition(self)]
319 for ext in self.extensions:
320 ext.define_macros.extend(self.define_macros)
321
322
323 def build_extensions(self):
324 """
325 Check to see which extension modules to build and then build them.
326 """
327 self.prepare_extensions()
328 build_ext.build_ext.build_extensions(self)
329
330
331 def _remove_conftest(self):
332 for filename in ("conftest.c", "conftest.o", "conftest.obj"):
333 try:
334 os.unlink(filename)
335 except EnvironmentError:
336 pass
337
338
339 def _compile_helper(self, content):
340 conftest = open("conftest.c", "w")
341 try:
342 conftest.write(content)
343 conftest.close()
344
345 try:
346 self.compiler.compile(["conftest.c"], output_dir='')
347 except CompileError:
348 return False
349 return True
350 finally:
351 self._remove_conftest()
352
353
354 def _check_header(self, header_name):
355 """
356 Check if the given header can be included by trying to compile a file
357 that contains only an #include line.
358 """
359 self.compiler.announce("checking for %s ..." % header_name, 0)
360 return self._compile_helper("#include <%s>\n" % header_name)
361
OLDNEW
« no previous file with comments | « third_party/twisted_8_1/twisted/python/dispatch.py ('k') | third_party/twisted_8_1/twisted/python/dxprofile.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698