Skip to content

Commit 85db7a4

Browse files
authored
Merge pull request #71 from abravalheri/use-tokenize
Update `distutils.core.setup/run_setup` to better match `setuptools.build_meta`.
2 parents 514e9d0 + 405c150 commit 85db7a4

File tree

2 files changed

+60
-20
lines changed

2 files changed

+60
-20
lines changed

distutils/core.py

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import os
1010
import sys
11+
import tokenize
1112

1213
from distutils.debug import DEBUG
1314
from distutils.errors import *
@@ -144,29 +145,41 @@ class found in 'cmdclass' is used in place of the default, which is
144145

145146
# And finally, run all the commands found on the command line.
146147
if ok:
147-
try:
148-
dist.run_commands()
149-
except KeyboardInterrupt:
150-
raise SystemExit("interrupted")
151-
except OSError as exc:
152-
if DEBUG:
153-
sys.stderr.write("error: %s\n" % (exc,))
154-
raise
155-
else:
156-
raise SystemExit("error: %s" % (exc,))
157-
158-
except (DistutilsError,
159-
CCompilerError) as msg:
160-
if DEBUG:
161-
raise
162-
else:
163-
raise SystemExit("error: " + str(msg))
148+
return run_commands(dist)
164149

165150
return dist
166151

167152
# setup ()
168153

169154

155+
def run_commands (dist):
156+
"""Given a Distribution object run all the commands,
157+
raising ``SystemExit`` errors in the case of failure.
158+
159+
This function assumes that either ``sys.argv`` or ``dist.script_args``
160+
is already set accordingly.
161+
"""
162+
try:
163+
dist.run_commands()
164+
except KeyboardInterrupt:
165+
raise SystemExit("interrupted")
166+
except OSError as exc:
167+
if DEBUG:
168+
sys.stderr.write("error: %s\n" % (exc,))
169+
raise
170+
else:
171+
raise SystemExit("error: %s" % (exc,))
172+
173+
except (DistutilsError,
174+
CCompilerError) as msg:
175+
if DEBUG:
176+
raise
177+
else:
178+
raise SystemExit("error: " + str(msg))
179+
180+
return dist
181+
182+
170183
def run_setup (script_name, script_args=None, stop_after="run"):
171184
"""Run a setup script in a somewhat controlled environment, and
172185
return the Distribution instance that drives things. This is useful
@@ -205,14 +218,16 @@ def run_setup (script_name, script_args=None, stop_after="run"):
205218
_setup_stop_after = stop_after
206219

207220
save_argv = sys.argv.copy()
208-
g = {'__file__': script_name}
221+
g = {'__file__': script_name, '__name__': '__main__'}
209222
try:
210223
try:
211224
sys.argv[0] = script_name
212225
if script_args is not None:
213226
sys.argv[1:] = script_args
214-
with open(script_name, 'rb') as f:
215-
exec(f.read(), g)
227+
# tokenize.open supports automatic encoding detection
228+
with tokenize.open(script_name) as f:
229+
code = f.read().replace(r'\r\n', r'\n')
230+
exec(code, g)
216231
finally:
217232
sys.argv = save_argv
218233
_setup_stop_after = None

distutils/tests/test_core.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import unittest
1111
from distutils.tests import support
1212
from distutils import log
13+
from distutils.dist import Distribution
1314

1415
# setup script that uses __file__
1516
setup_using___file__ = """\
@@ -45,6 +46,16 @@ class install(_install):
4546
setup(cmdclass={'install': install})
4647
"""
4748

49+
setup_within_if_main = """\
50+
from distutils.core import setup
51+
52+
def main():
53+
return setup(name="setup_within_if_main")
54+
55+
if __name__ == "__main__":
56+
main()
57+
"""
58+
4859
class CoreTestCase(support.EnvironGuard, unittest.TestCase):
4960

5061
def setUp(self):
@@ -115,6 +126,20 @@ def test_run_setup_uses_current_dir(self):
115126
output = output[:-1]
116127
self.assertEqual(cwd, output)
117128

129+
def test_run_setup_within_if_main(self):
130+
dist = distutils.core.run_setup(
131+
self.write_setup(setup_within_if_main), stop_after="config")
132+
self.assertIsInstance(dist, Distribution)
133+
self.assertEqual(dist.get_name(), "setup_within_if_main")
134+
135+
def test_run_commands(self):
136+
sys.argv = ['setup.py', 'build']
137+
dist = distutils.core.run_setup(
138+
self.write_setup(setup_within_if_main), stop_after="commandline")
139+
self.assertNotIn('build', dist.have_run)
140+
distutils.core.run_commands(dist)
141+
self.assertIn('build', dist.have_run)
142+
118143
def test_debug_mode(self):
119144
# this covers the code called when DEBUG is set
120145
sys.argv = ['setup.py', '--name']

0 commit comments

Comments
 (0)