[3.6] bpo-29854: Fix segfault in call_readline() (GH-728) · python/cpython@04f77d4 (original) (raw)

`@@ -9,7 +9,7 @@

`

9

9

`import sys

`

10

10

`import tempfile

`

11

11

`import unittest

`

12

``

`-

from test.support import import_module, unlink, TESTFN

`

``

12

`+

from test.support import import_module, unlink, temp_dir, TESTFN

`

13

13

`from test.support.script_helper import assert_python_ok

`

14

14

``

15

15

`# Skip tests if there is no readline module

`

`@@ -210,13 +210,57 @@ def display(substitution, matches, longest_match_length):

`

210

210

`self.assertIn(b"result " + expected + b"\r\n", output)

`

211

211

`self.assertIn(b"history " + expected + b"\r\n", output)

`

212

212

``

``

213

`+

We have 2 reasons to skip this test:

`

``

214

`+

- readline: history size was added in 6.0

`

``

215

`+

See https://cnswww.cns.cwru.edu/php/chet/readline/CHANGES

`

``

216

`+

- editline: history size is broken on OS X 10.11.6.

`

``

217

`+

Newer versions were not tested yet.

`

``

218

`+

@unittest.skipIf(readline._READLINE_VERSION < 0x600,

`

``

219

`+

"this readline version does not support history-size")

`

``

220

`+

@unittest.skipIf(is_editline,

`

``

221

`+

"editline history size configuration is broken")

`

``

222

`+

def test_history_size(self):

`

``

223

`+

history_size = 10

`

``

224

`+

with temp_dir() as test_dir:

`

``

225

`+

inputrc = os.path.join(test_dir, "inputrc")

`

``

226

`+

with open(inputrc, "wb") as f:

`

``

227

`+

f.write(b"set history-size %d\n" % history_size)

`

``

228

+

``

229

`+

history_file = os.path.join(test_dir, "history")

`

``

230

`+

with open(history_file, "wb") as f:

`

``

231

`+

history_size * 2 items crashes readline

`

``

232

`+

data = b"".join(b"item %d\n" % i

`

``

233

`+

for i in range(history_size * 2))

`

``

234

`+

f.write(data)

`

``

235

+

``

236

`+

script = """

`

``

237

`+

import os

`

``

238

`+

import readline

`

``

239

+

``

240

`+

history_file = os.environ["HISTORY_FILE"]

`

``

241

`+

readline.read_history_file(history_file)

`

``

242

`+

input()

`

``

243

`+

readline.write_history_file(history_file)

`

``

244

`+

"""

`

``

245

+

``

246

`+

env = dict(os.environ)

`

``

247

`+

env["INPUTRC"] = inputrc

`

``

248

`+

env["HISTORY_FILE"] = history_file

`

``

249

+

``

250

`+

run_pty(script, input=b"last input\r", env=env)

`

``

251

+

``

252

`+

with open(history_file, "rb") as f:

`

``

253

`+

lines = f.readlines()

`

``

254

`+

self.assertEqual(len(lines), history_size)

`

``

255

`+

self.assertEqual(lines[-1].strip(), b"last input")

`

``

256

+

213

257

``

214

``

`-

def run_pty(script, input=b"dummy input\r"):

`

``

258

`+

def run_pty(script, input=b"dummy input\r", env=None):

`

215

259

`pty = import_module('pty')

`

216

260

`output = bytearray()

`

217

261

` [master, slave] = pty.openpty()

`

218

262

`args = (sys.executable, '-c', script)

`

219

``

`-

proc = subprocess.Popen(args, stdin=slave, stdout=slave, stderr=slave)

`

``

263

`+

proc = subprocess.Popen(args, stdin=slave, stdout=slave, stderr=slave, env=env)

`

220

264

`os.close(slave)

`

221

265

`with ExitStack() as cleanup:

`

222

266

`cleanup.enter_context(proc)

`