bpo-28180: Fix the implementation of PEP 538 on Android (GH-4334) · python/cpython@1588be6 (original) (raw)

`@@ -459,7 +459,7 @@ _coerce_default_locale_settings(const _LocaleCoercionTarget *target)

`

459

459

`const char *newloc = target->locale_name;

`

460

460

``

461

461

`/* Reset locale back to currently configured defaults */

`

462

``

`-

setlocale(LC_ALL, "");

`

``

462

`+

_Py_SetLocaleFromEnv(LC_ALL);

`

463

463

``

464

464

`/* Set the relevant locale environment variable */

`

465

465

`if (setenv("LC_CTYPE", newloc, 1)) {

`

`@@ -472,7 +472,7 @@ _coerce_default_locale_settings(const _LocaleCoercionTarget *target)

`

472

472

` }

`

473

473

``

474

474

`/* Reconfigure with the overridden environment variables */

`

475

``

`-

setlocale(LC_ALL, "");

`

``

475

`+

_Py_SetLocaleFromEnv(LC_ALL);

`

476

476

`}

`

477

477

`#endif

`

478

478

``

`@@ -503,13 +503,14 @@ _Py_CoerceLegacyLocale(void)

`

503

503

`const char *new_locale = setlocale(LC_CTYPE,

`

504

504

`target->locale_name);

`

505

505

`if (new_locale != NULL) {

`

506

``

`-

#if !defined(APPLE) && defined(HAVE_LANGINFO_H) && defined(CODESET)

`

``

506

`+

#if !defined(APPLE) && !defined(ANDROID) && \

`

``

507

`+

defined(HAVE_LANGINFO_H) && defined(CODESET)

`

507

508

`/* Also ensure that nl_langinfo works in this locale */

`

508

509

`char *codeset = nl_langinfo(CODESET);

`

509

510

`if (!codeset || *codeset == '\0') {

`

510

511

`/* CODESET is not set or empty, so skip coercion */

`

511

512

`new_locale = NULL;

`

512

``

`-

setlocale(LC_CTYPE, "");

`

``

513

`+

_Py_SetLocaleFromEnv(LC_CTYPE);

`

513

514

`continue;

`

514

515

` }

`

515

516

`#endif

`

`@@ -524,6 +525,65 @@ _Py_CoerceLegacyLocale(void)

`

524

525

`#endif

`

525

526

`}

`

526

527

``

``

528

`+

/* _Py_SetLocaleFromEnv() is a wrapper around setlocale(category, "") to

`

``

529

`+

`

``

530

`+

`

``

531

`+

`

``

532

`+

char *

`

``

533

`+

_Py_SetLocaleFromEnv(int category)

`

``

534

`+

{

`

``

535

`+

#ifdef ANDROID

`

``

536

`+

const char *locale;

`

``

537

`+

const char **pvar;

`

``

538

`+

#ifdef PY_COERCE_C_LOCALE

`

``

539

`+

const char *coerce_c_locale;

`

``

540

`+

#endif

`

``

541

`+

const char *utf8_locale = "C.UTF-8";

`

``

542

`+

const char *env_var_set[] = {

`

``

543

`+

"LC_ALL",

`

``

544

`+

"LC_CTYPE",

`

``

545

`+

"LANG",

`

``

546

`+

NULL,

`

``

547

`+

};

`

``

548

+

``

549

`+

/* Android setlocale(category, "") doesn't check the environment variables

`

``

550

`+

`

``

551

`+

`

``

552

`+

for (pvar=env_var_set; *pvar; pvar++) {

`

``

553

`+

locale = getenv(*pvar);

`

``

554

`+

if (locale != NULL && *locale != '\0') {

`

``

555

`+

if (strcmp(locale, utf8_locale) == 0 ||

`

``

556

`+

strcmp(locale, "en_US.UTF-8") == 0) {

`

``

557

`+

return setlocale(category, utf8_locale);

`

``

558

`+

}

`

``

559

`+

return setlocale(category, "C");

`

``

560

`+

}

`

``

561

`+

}

`

``

562

+

``

563

`+

/* Android uses UTF-8, so explicitly set the locale to C.UTF-8 if none of

`

``

564

`+

`

``

565

`+

`

``

566

`+

`

``

567

`+

`

``

568

+

``

569

`+

#ifdef PY_COERCE_C_LOCALE

`

``

570

`+

coerce_c_locale = getenv("PYTHONCOERCECLOCALE");

`

``

571

`+

if (coerce_c_locale == NULL || strcmp(coerce_c_locale, "0") != 0) {

`

``

572

`+

/* Some other ported code may check the environment variables (e.g. in

`

``

573

`+

`

``

574

`+

`

``

575

`+

if (setenv("LC_CTYPE", utf8_locale, 1)) {

`

``

576

`+

fprintf(stderr, "Warning: failed setting the LC_CTYPE "

`

``

577

`+

"environment variable to %s\n", utf8_locale);

`

``

578

`+

}

`

``

579

`+

}

`

``

580

`+

#endif

`

``

581

`+

return setlocale(category, utf8_locale);

`

``

582

`+

#else /* ANDROID */

`

``

583

`+

return setlocale(category, "");

`

``

584

`+

#endif /* ANDROID */

`

``

585

`+

}

`

``

586

+

527

587

``

528

588

`/* Global initializations. Can be undone by Py_Finalize(). Don't

`

529

589

` call this twice without an intervening Py_Finalize() call.

`

`@@ -599,19 +659,12 @@ void _Py_InitializeCore(const _PyCoreConfig *config)

`

599

659

`exit(1);

`

600

660

` }

`

601

661

``

602

``

`-

#ifdef ANDROID

`

603

``

`-

/* Passing "" to setlocale() on Android requests the C locale rather

`

604

``

`-

`

605

``

`-

*/

`

606

``

`-

setlocale(LC_CTYPE, "C.UTF-8");

`

607

``

`-

#else

`

608

662

`#ifndef MS_WINDOWS

`

609

663

`/* Set up the LC_CTYPE locale, so we can obtain

`

610

664

` the locale's charset without having to switch

`

611

665

` locales. */

`

612

``

`-

setlocale(LC_CTYPE, "");

`

``

666

`+

_Py_SetLocaleFromEnv(LC_CTYPE);

`

613

667

`_emit_stderr_warning_for_legacy_locale();

`

614

``

`-

#endif

`

615

668

`#endif

`

616

669

``

617

670

`if ((p = Py_GETENV("PYTHONDEBUG")) && *p != '\0')

`