Skip to content

Commit e2f47dc

Browse files
committed
In build_scripts, open scripts as text. Fixes pypa/distutils#124.
1 parent 3663538 commit e2f47dc

File tree

1 file changed

+19
-20
lines changed

1 file changed

+19
-20
lines changed

distutils/command/build_scripts.py

+19-20
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
from distutils import log
1313
import tokenize
1414

15-
# check if Python is called on the first line with this expression
16-
shebang_pattern = re.compile(b'^#!.*python[0-9.]*([ \t].*)?$')
15+
shebang_pattern = re.compile('^#!.*python[0-9.]*([ \t].*)?$')
16+
"""
17+
Pattern matching a Python interpreter indicated in first line of a script.
18+
"""
1719

1820
# for Setuptools compatibility
1921
first_line_re = shebang_pattern
@@ -84,14 +86,12 @@ def _copy_script(self, script, outfiles, updated_files):
8486
# Always open the file, but ignore failures in dry-run mode
8587
# in order to attempt to copy directly.
8688
try:
87-
f = open(script, "rb")
89+
f = tokenize.open(script)
8890
except OSError:
8991
if not self.dry_run:
9092
raise
9193
f = None
9294
else:
93-
encoding, lines = tokenize.detect_encoding(f.readline)
94-
f.seek(0)
9595
first_line = f.readline()
9696
if not first_line:
9797
self.warn("%s is an empty file (skipping)" % script)
@@ -112,11 +112,10 @@ def _copy_script(self, script, outfiles, updated_files):
112112
"python%s%s" % (
113113
sysconfig.get_config_var("VERSION"),
114114
sysconfig.get_config_var("EXE")))
115-
executable = os.fsencode(executable)
116-
post_interp = shebang_match.group(1) or b''
117-
shebang = b"#!" + executable + post_interp + b"\n"
118-
self._validate_shebang(shebang, encoding)
119-
with open(outfile, "wb") as outf:
115+
post_interp = shebang_match.group(1) or ''
116+
shebang = "#!" + executable + post_interp + "\n"
117+
self._validate_shebang(shebang, f.encoding)
118+
with open(outfile, "w", encoding=f.encoding) as outf:
120119
outf.write(shebang)
121120
outf.writelines(f.readlines())
122121
if f:
@@ -150,22 +149,22 @@ def _validate_shebang(shebang, encoding):
150149
# Python parser starts to read a script using UTF-8 until
151150
# it gets a #coding:xxx cookie. The shebang has to be the
152151
# first line of a file, the #coding:xxx cookie cannot be
153-
# written before. So the shebang has to be decodable from
152+
# written before. So the shebang has to be encodable to
154153
# UTF-8.
155154
try:
156-
shebang.decode('utf-8')
157-
except UnicodeDecodeError:
155+
shebang.encode('utf-8')
156+
except UnicodeEncodeError:
158157
raise ValueError(
159-
"The shebang ({!r}) is not decodable "
160-
"from utf-8".format(shebang))
158+
"The shebang ({!r}) is not encodable "
159+
"to utf-8".format(shebang))
161160

162161
# If the script is encoded to a custom encoding (use a
163-
# #coding:xxx cookie), the shebang has to be decodable from
162+
# #coding:xxx cookie), the shebang has to be encodable to
164163
# the script encoding too.
165164
try:
166-
shebang.decode(encoding)
167-
except UnicodeDecodeError:
165+
shebang.encode(encoding)
166+
except UnicodeEncodeError:
168167
raise ValueError(
169-
"The shebang ({!r}) is not decodable "
170-
"from the script encoding ({})"
168+
"The shebang ({!r}) is not encodable "
169+
"to the script encoding ({})"
171170
.format(shebang, encoding))

0 commit comments

Comments
 (0)