bpo-2504: Add pgettext() and variants to gettext. (GH-7253) · python/cpython@637a33b

@@ -57,6 +57,7 @@

5757

'bind_textdomain_codeset',

5858

'dgettext', 'dngettext', 'gettext', 'lgettext', 'ldgettext',

5959

'ldngettext', 'lngettext', 'ngettext',

60+

'pgettext', 'dpgettext', 'npgettext', 'dnpgettext',

6061

]

61626263

_default_localedir = os.path.join(sys.base_prefix, 'share', 'locale')

@@ -311,6 +312,19 @@ def lngettext(self, msgid1, msgid2, n):

311312

return tmsg.encode(self._output_charset)

312313

return tmsg.encode(locale.getpreferredencoding())

313314315+

def pgettext(self, context, message):

316+

if self._fallback:

317+

return self._fallback.pgettext(context, message)

318+

return message

319+320+

def npgettext(self, context, msgid1, msgid2, n):

321+

if self._fallback:

322+

return self._fallback.npgettext(context, msgid1, msgid2, n)

323+

if n == 1:

324+

return msgid1

325+

else:

326+

return msgid2

327+314328

def info(self):

315329

return self._info

316330

@@ -332,22 +346,22 @@ def set_output_charset(self, charset):

332346

def install(self, names=None):

333347

import builtins

334348

builtins.__dict__['_'] = self.gettext

335-

if hasattr(names, "__contains__"):

336-

if "gettext" in names:

337-

builtins.__dict__['gettext'] = builtins.__dict__['_']

338-

if "ngettext" in names:

339-

builtins.__dict__['ngettext'] = self.ngettext

340-

if "lgettext" in names:

341-

builtins.__dict__['lgettext'] = self.lgettext

342-

if "lngettext" in names:

343-

builtins.__dict__['lngettext'] = self.lngettext

349+

if names is not None:

350+

allowed = {'gettext', 'lgettext', 'lngettext',

351+

'ngettext', 'npgettext', 'pgettext'}

352+

for name in allowed & set(names):

353+

builtins.__dict__[name] = getattr(self, name)

344354345355346356

class GNUTranslations(NullTranslations):

347357

# Magic number of .mo files

348358

LE_MAGIC = 0x950412de

349359

BE_MAGIC = 0xde120495

350360361+

# The encoding of a msgctxt and a msgid in a .mo file is

362+

# msgctxt + "\x04" + msgid (gettext version >= 0.15)

363+

CONTEXT = "%s\x04%s"

364+351365

# Acceptable .mo versions

352366

VERSIONS = (0, 1)

353367

@@ -493,6 +507,29 @@ def ngettext(self, msgid1, msgid2, n):

493507

tmsg = msgid2

494508

return tmsg

495509510+

def pgettext(self, context, message):

511+

ctxt_msg_id = self.CONTEXT % (context, message)

512+

missing = object()

513+

tmsg = self._catalog.get(ctxt_msg_id, missing)

514+

if tmsg is missing:

515+

if self._fallback:

516+

return self._fallback.pgettext(context, message)

517+

return message

518+

return tmsg

519+520+

def npgettext(self, context, msgid1, msgid2, n):

521+

ctxt_msg_id = self.CONTEXT % (context, msgid1)

522+

try:

523+

tmsg = self._catalog[ctxt_msg_id, self.plural(n)]

524+

except KeyError:

525+

if self._fallback:

526+

return self._fallback.npgettext(context, msgid1, msgid2, n)

527+

if n == 1:

528+

tmsg = msgid1

529+

else:

530+

tmsg = msgid2

531+

return tmsg

532+496533497534

# Locate a .mo file using the gettext strategy

498535

def find(domain, localedir=None, languages=None, all=False):

@@ -672,6 +709,26 @@ def ldngettext(domain, msgid1, msgid2, n):

672709

DeprecationWarning)

673710

return t.lngettext(msgid1, msgid2, n)

674711712+713+

def dpgettext(domain, context, message):

714+

try:

715+

t = translation(domain, _localedirs.get(domain, None))

716+

except OSError:

717+

return message

718+

return t.pgettext(context, message)

719+720+721+

def dnpgettext(domain, context, msgid1, msgid2, n):

722+

try:

723+

t = translation(domain, _localedirs.get(domain, None))

724+

except OSError:

725+

if n == 1:

726+

return msgid1

727+

else:

728+

return msgid2

729+

return t.npgettext(context, msgid1, msgid2, n)

730+731+675732

def gettext(message):

676733

return dgettext(_current_domain, message)

677734

@@ -696,6 +753,15 @@ def lngettext(msgid1, msgid2, n):

696753

DeprecationWarning)

697754

return ldngettext(_current_domain, msgid1, msgid2, n)

698755756+757+

def pgettext(context, message):

758+

return dpgettext(_current_domain, context, message)

759+760+761+

def npgettext(context, msgid1, msgid2, n):

762+

return dnpgettext(_current_domain, context, msgid1, msgid2, n)

763+764+699765

# dcgettext() has been deemed unnecessary and is not implemented.

700766701767

# James Henstridge's Catalog constructor from GNOME gettext. Documented usage