bpo-20844: open script file with "rb" mode (GH-12616) · python/cpython@10654c1

File tree

4 files changed

lines changed

  • Misc/NEWS.d/next/Core and Builtins

4 files changed

lines changed

Original file line numberDiff line numberDiff line change

@@ -109,6 +109,10 @@ the same library that the Python runtime is using.

109109

(:func:`sys.getfilesystemencoding`). If *closeit* is true, the file is

110110

closed before PyRun_SimpleFileExFlags returns.

111111
112+

.. note::

113+

On Windows, *fp* should be opened as binary mode (e.g. ``fopen(filename, "rb")``.

114+

Otherwise, Python may not handle script file with LF line ending correctly.

115+
112116
113117

.. c:function:: int PyRun_InteractiveOne(FILE *fp, const char *filename)

114118
Original file line numberDiff line numberDiff line change

@@ -409,6 +409,23 @@ def test_issue8202_dash_m_file_ignored(self):

409409

script_name, script_name, script_dir, '',

410410

importlib.machinery.SourceFileLoader)

411411
412+

def test_issue20884(self):

413+

# On Windows, script with encoding cookie and LF line ending

414+

# will be failed.

415+

with support.temp_dir() as script_dir:

416+

script_name = os.path.join(script_dir, "issue20884.py")

417+

with open(script_name, "w", newline='\n') as f:

418+

f.write("#coding: iso-8859-1\n")

419+

f.write('"""\n')

420+

for _ in range(30):

421+

f.write('x'*80 + '\n')

422+

f.write('"""\n')

423+
424+

with support.change_cwd(path=script_dir):

425+

rc, out, err = assert_python_ok(script_name)

426+

self.assertEqual(b"", out)

427+

self.assertEqual(b"", err)

428+
412429

@contextlib.contextmanager

413430

def setup_test_pkg(self, *args):

414431

with support.temp_dir() as script_dir, \

Original file line numberDiff line numberDiff line change

@@ -0,0 +1,2 @@

1+

Fix running script with encoding cookie and LF line ending

2+

may fail on Windows.

Original file line numberDiff line numberDiff line change

@@ -283,7 +283,7 @@ static int

283283

pymain_run_file(_PyCoreConfig *config, PyCompilerFlags *cf)

284284

{

285285

const wchar_t *filename = config->run_filename;

286-

FILE *fp = _Py_wfopen(filename, L"r");

286+

FILE *fp = _Py_wfopen(filename, L"rb");

287287

if (fp == NULL) {

288288

char *cfilename_buffer;

289289

const char *cfilename;