]>
Commit | Line | Data |
---|---|---|
1 | from distutils.errors import DistutilsArgError | |
2 | import inspect | |
3 | import glob | |
4 | import warnings | |
5 | import platform | |
6 | import distutils.command.install as orig | |
7 | ||
8 | import setuptools | |
9 | ||
10 | # Prior to numpy 1.9, NumPy relies on the '_install' name, so provide it for | |
11 | # now. See https://github.com/pypa/setuptools/issues/199/ | |
12 | _install = orig.install | |
13 | ||
14 | ||
15 | class install(orig.install): | |
16 | """Use easy_install to install the package, w/dependencies""" | |
17 | ||
18 | user_options = orig.install.user_options + [ | |
19 | ('old-and-unmanageable', None, "Try not to use this!"), | |
20 | ('single-version-externally-managed', None, | |
21 | "used by system package builders to create 'flat' eggs"), | |
22 | ] | |
23 | boolean_options = orig.install.boolean_options + [ | |
24 | 'old-and-unmanageable', 'single-version-externally-managed', | |
25 | ] | |
26 | new_commands = [ | |
27 | ('install_egg_info', lambda self: True), | |
28 | ('install_scripts', lambda self: True), | |
29 | ] | |
30 | _nc = dict(new_commands) | |
31 | ||
32 | def initialize_options(self): | |
33 | ||
34 | warnings.warn( | |
35 | "setup.py install is deprecated. " | |
36 | "Use build and pip and other standards-based tools.", | |
37 | setuptools.SetuptoolsDeprecationWarning, | |
38 | ) | |
39 | ||
40 | orig.install.initialize_options(self) | |
41 | self.old_and_unmanageable = None | |
42 | self.single_version_externally_managed = None | |
43 | ||
44 | def finalize_options(self): | |
45 | orig.install.finalize_options(self) | |
46 | if self.root: | |
47 | self.single_version_externally_managed = True | |
48 | elif self.single_version_externally_managed: | |
49 | if not self.root and not self.record: | |
50 | raise DistutilsArgError( | |
51 | "You must specify --record or --root when building system" | |
52 | " packages" | |
53 | ) | |
54 | ||
55 | def handle_extra_path(self): | |
56 | if self.root or self.single_version_externally_managed: | |
57 | # explicit backward-compatibility mode, allow extra_path to work | |
58 | return orig.install.handle_extra_path(self) | |
59 | ||
60 | # Ignore extra_path when installing an egg (or being run by another | |
61 | # command without --root or --single-version-externally-managed | |
62 | self.path_file = None | |
63 | self.extra_dirs = '' | |
64 | ||
65 | def run(self): | |
66 | # Explicit request for old-style install? Just do it | |
67 | if self.old_and_unmanageable or self.single_version_externally_managed: | |
68 | return orig.install.run(self) | |
69 | ||
70 | if not self._called_from_setup(inspect.currentframe()): | |
71 | # Run in backward-compatibility mode to support bdist_* commands. | |
72 | orig.install.run(self) | |
73 | else: | |
74 | self.do_egg_install() | |
75 | ||
76 | @staticmethod | |
77 | def _called_from_setup(run_frame): | |
78 | """ | |
79 | Attempt to detect whether run() was called from setup() or by another | |
80 | command. If called by setup(), the parent caller will be the | |
81 | 'run_command' method in 'distutils.dist', and *its* caller will be | |
82 | the 'run_commands' method. If called any other way, the | |
83 | immediate caller *might* be 'run_command', but it won't have been | |
84 | called by 'run_commands'. Return True in that case or if a call stack | |
85 | is unavailable. Return False otherwise. | |
86 | """ | |
87 | if run_frame is None: | |
88 | msg = "Call stack not available. bdist_* commands may fail." | |
89 | warnings.warn(msg) | |
90 | if platform.python_implementation() == 'IronPython': | |
91 | msg = "For best results, pass -X:Frames to enable call stack." | |
92 | warnings.warn(msg) | |
93 | return True | |
94 | ||
95 | frames = inspect.getouterframes(run_frame) | |
96 | for frame in frames[2:4]: | |
97 | caller, = frame[:1] | |
98 | info = inspect.getframeinfo(caller) | |
99 | caller_module = caller.f_globals.get('__name__', '') | |
100 | ||
101 | if caller_module == "setuptools.dist" and info.function == "run_command": | |
102 | # Starting from v61.0.0 setuptools overwrites dist.run_command | |
103 | continue | |
104 | ||
105 | return ( | |
106 | caller_module == 'distutils.dist' | |
107 | and info.function == 'run_commands' | |
108 | ) | |
109 | ||
110 | def do_egg_install(self): | |
111 | ||
112 | easy_install = self.distribution.get_command_class('easy_install') | |
113 | ||
114 | cmd = easy_install( | |
115 | self.distribution, args="x", root=self.root, record=self.record, | |
116 | ) | |
117 | cmd.ensure_finalized() # finalize before bdist_egg munges install cmd | |
118 | cmd.always_copy_from = '.' # make sure local-dir eggs get installed | |
119 | ||
120 | # pick up setup-dir .egg files only: no .egg-info | |
121 | cmd.package_index.scan(glob.glob('*.egg')) | |
122 | ||
123 | self.run_command('bdist_egg') | |
124 | args = [self.distribution.get_command_obj('bdist_egg').egg_output] | |
125 | ||
126 | if setuptools.bootstrap_install_from: | |
127 | # Bootstrap self-installation of setuptools | |
128 | args.insert(0, setuptools.bootstrap_install_from) | |
129 | ||
130 | cmd.args = args | |
131 | cmd.run(show_deprecation=False) | |
132 | setuptools.bootstrap_install_from = None | |
133 | ||
134 | ||
135 | # XXX Python 3.1 doesn't see _nc if this is inside the class | |
136 | install.sub_commands = ( | |
137 | [cmd for cmd in orig.install.sub_commands if cmd[0] not in install._nc] + | |
138 | install.new_commands | |
139 | ) |