bpo-34589: Add -X coerce_c_locale command line option (GH-9378) · python/cpython@dbdee00 (original) (raw)

`@@ -139,7 +139,7 @@ def _handle_output_variations(data):

`

139

139

`return data

`

140

140

``

141

141

`@classmethod

`

142

``

`-

def get_child_details(cls, env_vars):

`

``

142

`+

def get_child_details(cls, env_vars, xoption=None):

`

143

143

`"""Retrieves fsencoding and standard stream details from a child process

`

144

144

``

145

145

` Returns (encoding_details, stderr_lines):

`

`@@ -150,10 +150,11 @@ def get_child_details(cls, env_vars):

`

150

150

` The child is run in isolated mode if the current interpreter supports

`

151

151

` that.

`

152

152

` """

`

153

``

`-

result, py_cmd = run_python_until_end(

`

154

``

`-

"-X", "utf8=0", "-c", cls.CHILD_PROCESS_SCRIPT,

`

155

``

`-

**env_vars

`

156

``

`-

)

`

``

153

`+

args = []

`

``

154

`+

if xoption:

`

``

155

`+

args.extend(("-X", f"coerce_c_locale={xoption}"))

`

``

156

`+

args.extend(("-X", "utf8=0", "-c", cls.CHILD_PROCESS_SCRIPT))

`

``

157

`+

result, py_cmd = run_python_until_end(*args, **env_vars)

`

157

158

`if not result.rc == 0:

`

158

159

`result.fail(py_cmd)

`

159

160

`# All subprocess outputs in this test case should be pure ASCII

`

`@@ -212,15 +213,16 @@ def _check_child_encoding_details(self,

`

212

213

`expected_fs_encoding,

`

213

214

`expected_stream_encoding,

`

214

215

`expected_warnings,

`

215

``

`-

coercion_expected):

`

``

216

`+

coercion_expected,

`

``

217

`+

xoption=None):

`

216

218

`"""Check the C locale handling for the given process environment

`

217

219

``

218

220

` Parameters:

`

219

221

` expected_fs_encoding: expected sys.getfilesystemencoding() result

`

220

222

` expected_stream_encoding: expected encoding for standard streams

`

221

223

` expected_warning: stderr output to expect (if any)

`

222

224

` """

`

223

``

`-

result = EncodingDetails.get_child_details(env_vars)

`

``

225

`+

result = EncodingDetails.get_child_details(env_vars, xoption)

`

224

226

`encoding_details, stderr_lines = result

`

225

227

`expected_details = EncodingDetails.get_expected_details(

`

226

228

`coercion_expected,

`

`@@ -290,6 +292,7 @@ def _check_c_locale_coercion(self,

`

290

292

`coerce_c_locale,

`

291

293

`expected_warnings=None,

`

292

294

`coercion_expected=True,

`

``

295

`+

use_xoption=False,

`

293

296

`**extra_vars):

`

294

297

`"""Check the C locale handling for various configurations

`

295

298

``

`@@ -319,8 +322,12 @@ def _check_c_locale_coercion(self,

`

319

322

`"PYTHONCOERCECLOCALE": "",

`

320

323

` }

`

321

324

`base_var_dict.update(extra_vars)

`

``

325

`+

xoption = None

`

322

326

`if coerce_c_locale is not None:

`

323

``

`-

base_var_dict["PYTHONCOERCECLOCALE"] = coerce_c_locale

`

``

327

`+

if use_xoption:

`

``

328

`+

xoption = coerce_c_locale

`

``

329

`+

else:

`

``

330

`+

base_var_dict["PYTHONCOERCECLOCALE"] = coerce_c_locale

`

324

331

``

325

332

`# Check behaviour for the default locale

`

326

333

`with self.subTest(default_locale=True,

`

`@@ -342,7 +349,8 @@ def _check_c_locale_coercion(self,

`

342

349

`fs_encoding,

`

343

350

`stream_encoding,

`

344

351

`_expected_warnings,

`

345

``

`-

_coercion_expected)

`

``

352

`+

_coercion_expected,

`

``

353

`+

xoption=xoption)

`

346

354

``

347

355

`# Check behaviour for explicitly configured locales

`

348

356

`for locale_to_set in EXPECTED_C_LOCALE_EQUIVALENTS:

`

`@@ -357,7 +365,8 @@ def _check_c_locale_coercion(self,

`

357

365

`fs_encoding,

`

358

366

`stream_encoding,

`

359

367

`expected_warnings,

`

360

``

`-

coercion_expected)

`

``

368

`+

coercion_expected,

`

``

369

`+

xoption=xoption)

`

361

370

``

362

371

`def test_PYTHONCOERCECLOCALE_not_set(self):

`

363

372

`# This should coerce to the first available target locale by default

`

`@@ -404,6 +413,32 @@ def test_LC_ALL_set_to_C(self):

`

404

413

`expected_warnings=[LEGACY_LOCALE_WARNING],

`

405

414

`coercion_expected=False)

`

406

415

``

``

416

`+

def test_xoption_set_to_1(self):

`

``

417

`+

self._check_c_locale_coercion("utf-8", "utf-8", coerce_c_locale="1",

`

``

418

`+

use_xoption=True)

`

``

419

+

``

420

`+

def test_xoption_set_to_zero(self):

`

``

421

`+

The setting "0" should result in the locale coercion being disabled

`

``

422

`+

self._check_c_locale_coercion(EXPECTED_C_LOCALE_FS_ENCODING,

`

``

423

`+

EXPECTED_C_LOCALE_STREAM_ENCODING,

`

``

424

`+

coerce_c_locale="0",

`

``

425

`+

coercion_expected=False,

`

``

426

`+

use_xoption=True)

`

``

427

`+

Setting LC_ALL=C shouldn't make any difference to the behaviour

`

``

428

`+

self._check_c_locale_coercion(EXPECTED_C_LOCALE_FS_ENCODING,

`

``

429

`+

EXPECTED_C_LOCALE_STREAM_ENCODING,

`

``

430

`+

coerce_c_locale="0",

`

``

431

`+

LC_ALL="C",

`

``

432

`+

coercion_expected=False,

`

``

433

`+

use_xoption=True)

`

``

434

+

``

435

`+

def test_xoption_set_to_warn(self):

`

``

436

`+

-X coerce_c_locale=warn enables runtime warnings for legacy locales

`

``

437

`+

self._check_c_locale_coercion("utf-8", "utf-8",

`

``

438

`+

coerce_c_locale="warn",

`

``

439

`+

expected_warnings=[CLI_COERCION_WARNING],

`

``

440

`+

use_xoption=True)

`

``

441

+

407

442

`def test_main():

`

408

443

`test.support.run_unittest(

`

409

444

`LocaleConfigurationTests,

`