Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/chardet/registry.py: 71%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

77 statements  

1"""Encoding registry with metadata for all supported encodings.""" 

2 

3from __future__ import annotations 

4 

5import codecs 

6import dataclasses 

7import encodings 

8import functools 

9import warnings 

10from collections.abc import Iterable 

11from encodings.aliases import aliases as _stdlib_aliases 

12from types import MappingProxyType 

13from typing import Literal 

14 

15from chardet.enums import EncodingEra 

16 

17EncodingName = Literal[ 

18 "ascii", 

19 "big5hkscs", 

20 "cp1006", 

21 "cp1026", 

22 "cp1125", 

23 "cp1140", 

24 "cp1250", 

25 "cp1251", 

26 "cp1252", 

27 "cp1253", 

28 "cp1254", 

29 "cp1255", 

30 "cp1256", 

31 "cp1257", 

32 "cp1258", 

33 "cp273", 

34 "cp424", 

35 "cp437", 

36 "cp500", 

37 "cp720", 

38 "cp737", 

39 "cp775", 

40 "cp850", 

41 "cp852", 

42 "cp855", 

43 "cp856", 

44 "cp857", 

45 "cp858", 

46 "cp860", 

47 "cp861", 

48 "cp862", 

49 "cp863", 

50 "cp864", 

51 "cp865", 

52 "cp866", 

53 "cp869", 

54 "cp874", 

55 "cp875", 

56 "cp932", 

57 "cp949", 

58 "euc_jis_2004", 

59 "euc_kr", 

60 "gb18030", 

61 "hp-roman8", 

62 "hz", 

63 "iso2022_jp_2", 

64 "iso2022_jp_2004", 

65 "iso2022_jp_ext", 

66 "iso2022_kr", 

67 "iso8859-1", 

68 "iso8859-10", 

69 "iso8859-13", 

70 "iso8859-14", 

71 "iso8859-15", 

72 "iso8859-16", 

73 "iso8859-2", 

74 "iso8859-3", 

75 "iso8859-4", 

76 "iso8859-5", 

77 "iso8859-6", 

78 "iso8859-7", 

79 "iso8859-8", 

80 "iso8859-9", 

81 "johab", 

82 "koi8-r", 

83 "koi8-t", 

84 "koi8-u", 

85 "kz1048", 

86 "mac-cyrillic", 

87 "mac-greek", 

88 "mac-iceland", 

89 "mac-latin2", 

90 "mac-roman", 

91 "mac-turkish", 

92 "ptcp154", 

93 "shift_jis_2004", 

94 "tis-620", 

95 "utf-16", 

96 "utf-16-be", 

97 "utf-16-le", 

98 "utf-32", 

99 "utf-32-be", 

100 "utf-32-le", 

101 "utf-7", 

102 "utf-8", 

103 "utf-8-sig", 

104] 

105 

106# Shared language tuples — used by multiple EncodingInfo entries below. 

107_WESTERN = ( 

108 "br", 

109 "cy", 

110 "da", 

111 "de", 

112 "en", 

113 "es", 

114 "fi", 

115 "fr", 

116 "ga", 

117 "id", 

118 "is", 

119 "it", 

120 "ms", 

121 "nl", 

122 "no", 

123 "pt", 

124 "sv", 

125) 

126_WESTERN_TR = (*_WESTERN, "tr") 

127_CYRILLIC = ("ru", "bg", "uk", "sr", "mk", "be") 

128_CENTRAL_EU = ("pl", "cs", "hu", "hr", "ro", "sk", "sl") 

129_CENTRAL_EU_NO_RO = ("pl", "cs", "hu", "hr", "sk", "sl") 

130_BALTIC = ("et", "lt", "lv") 

131_ARABIC = ("ar", "fa") 

132 

133 

134@dataclasses.dataclass(frozen=True, slots=True) 

135class EncodingInfo: 

136 """Metadata for a single encoding.""" 

137 

138 name: EncodingName 

139 aliases: tuple[str, ...] 

140 era: EncodingEra 

141 #: Whether the encoding has the CJK byte structure that the structural 

142 #: stage probes and the CJK gate requires. Off for UTF-8, UTF-16 and 

143 #: UTF-32, which spend more than one byte per character but are handled 

144 #: by their own stages. 

145 is_multibyte_cjk: bool 

146 languages: tuple[str, ...] 

147 #: The Windows/CP code page that stands in for this encoding in 

148 #: practice (``iso8859-1`` -> ``cp1252``, ``euc_kr`` -> ``cp949``), as a 

149 #: canonical registry name, or ``None`` when there is none. It decodes 

150 #: nearly everything this encoding does, though not always byte for 

151 #: byte: the Windows code pages leave a few positions undefined that 

152 #: the ISO standards map, and cp932 is a superset of plain Shift_JIS 

153 #: rather than of JIS X 0213, so code that swaps one name for the other 

154 #: checks the data first. A codec fact only: which pairs the 

155 #: ``prefer_superset`` option applies is 

156 #: :data:`chardet.output_names.PREFERRED_SUPERSET`'s call (ADR-0007). 

157 superset: str | None = None 

158 

159 @property 

160 def is_multibyte(self) -> bool: 

161 """Deprecated name for :attr:`is_multibyte_cjk`. 

162 

163 The old name read as "more than one byte per character", which the 

164 flag never meant. Will be removed in chardet 8.0. 

165 """ 

166 warnings.warn( 

167 "EncodingInfo.is_multibyte is deprecated; use is_multibyte_cjk " 

168 "instead. Will be removed in chardet 8.0.", 

169 DeprecationWarning, 

170 stacklevel=2, 

171 ) 

172 return self.is_multibyte_cjk 

173 

174 

175@functools.lru_cache(maxsize=256) 

176def get_candidates( 

177 era: EncodingEra, 

178 include_encodings: frozenset[str] | None = None, 

179 exclude_encodings: frozenset[str] | None = None, 

180) -> tuple[EncodingInfo, ...]: 

181 """Return registry entries matching the given filters. 

182 

183 Filters are applied in order: era, include, exclude. 

184 

185 :param era: Bit flags specifying which encoding eras to include. 

186 :param include_encodings: If not ``None``, only return encodings in this set. 

187 :param exclude_encodings: If not ``None``, exclude encodings in this set. 

188 :returns: A tuple of matching :class:`EncodingInfo` entries. 

189 """ 

190 candidates = (enc for enc in REGISTRY.values() if enc.era & era) 

191 if include_encodings is not None: 

192 candidates = (enc for enc in candidates if enc.name in include_encodings) 

193 if exclude_encodings is not None: 

194 candidates = (enc for enc in candidates if enc.name not in exclude_encodings) 

195 return tuple(candidates) 

196 

197 

198# Era assignments match chardet 6.0.0's chardet/metadata/charsets.py 

199 

200_REGISTRY_ENTRIES = ( 

201 # === MODERN_WEB === 

202 EncodingInfo( 

203 name="ascii", 

204 aliases=("us-ascii",), 

205 era=EncodingEra.MODERN_WEB, 

206 is_multibyte_cjk=False, 

207 languages=(), 

208 superset="cp1252", 

209 ), 

210 EncodingInfo( 

211 name="utf-8", 

212 aliases=( 

213 "utf-8", 

214 "utf8", 

215 "csutf8", 

216 "unicode-1-1-utf-8", 

217 "unicode11utf8", 

218 "unicode20utf8", 

219 "x-unicode20utf8", 

220 ), 

221 era=EncodingEra.MODERN_WEB, 

222 is_multibyte_cjk=False, 

223 languages=(), 

224 ), 

225 EncodingInfo( 

226 name="utf-8-sig", 

227 aliases=("UTF-8-SIG", "utf-8-bom"), 

228 era=EncodingEra.MODERN_WEB, 

229 is_multibyte_cjk=False, 

230 languages=(), 

231 ), 

232 EncodingInfo( 

233 name="utf-16", 

234 aliases=("UTF-16", "utf16", "csutf16"), 

235 era=EncodingEra.MODERN_WEB, 

236 is_multibyte_cjk=False, 

237 languages=(), 

238 ), 

239 EncodingInfo( 

240 name="utf-16-be", 

241 aliases=("UTF-16-BE", "utf-16be", "csutf16be"), 

242 era=EncodingEra.MODERN_WEB, 

243 is_multibyte_cjk=False, 

244 languages=(), 

245 ), 

246 EncodingInfo( 

247 name="utf-16-le", 

248 aliases=("UTF-16-LE", "utf-16le", "csutf16le"), 

249 era=EncodingEra.MODERN_WEB, 

250 is_multibyte_cjk=False, 

251 languages=(), 

252 ), 

253 EncodingInfo( 

254 name="utf-32", 

255 aliases=("UTF-32", "utf32", "csutf32"), 

256 era=EncodingEra.MODERN_WEB, 

257 is_multibyte_cjk=False, 

258 languages=(), 

259 ), 

260 EncodingInfo( 

261 name="utf-32-be", 

262 aliases=("UTF-32-BE", "utf-32be", "csutf32be"), 

263 era=EncodingEra.MODERN_WEB, 

264 is_multibyte_cjk=False, 

265 languages=(), 

266 ), 

267 EncodingInfo( 

268 name="utf-32-le", 

269 aliases=("UTF-32-LE", "utf-32le", "csutf32le"), 

270 era=EncodingEra.MODERN_WEB, 

271 is_multibyte_cjk=False, 

272 languages=(), 

273 ), 

274 EncodingInfo( 

275 name="utf-7", 

276 aliases=("UTF-7", "utf7", "csutf7"), 

277 era=EncodingEra.LEGACY_REGIONAL, 

278 is_multibyte_cjk=False, 

279 languages=(), 

280 ), 

281 # CJK - Modern Web 

282 EncodingInfo( 

283 name="big5hkscs", 

284 aliases=( 

285 "Big5-HKSCS", 

286 "Big5HKSCS", 

287 "big5", 

288 "big5-tw", 

289 "csbig5", 

290 "cp950", 

291 "cn-big5", 

292 "x-x-big5", 

293 "csbig5hkscs", 

294 ), 

295 era=EncodingEra.MODERN_WEB, 

296 is_multibyte_cjk=True, 

297 languages=("zh",), 

298 ), 

299 EncodingInfo( 

300 name="cp932", 

301 aliases=( 

302 "CP932", 

303 "ms932", 

304 "mskanji", 

305 "ms-kanji", 

306 "cswindows31j", 

307 "windows-31j", 

308 ), 

309 era=EncodingEra.MODERN_WEB, 

310 is_multibyte_cjk=True, 

311 languages=("ja",), 

312 ), 

313 EncodingInfo( 

314 # Note: "korean" is NOT an alias here. Python's codec table 

315 # already resolves "korean" to ``euc_kr``, and WHATWG's primary 

316 # name for the group is EUC-KR, so letting the default fall 

317 # through is more spec-aligned than routing to cp949. 

318 name="cp949", 

319 aliases=( 

320 "CP949", 

321 "ms949", 

322 "uhc", 

323 "windows-949", 

324 "csksc56011987", 

325 "iso-ir-149", 

326 "ks_c_5601-1987", 

327 "ks_c_5601-1989", 

328 "ksc5601", 

329 "ksc_5601", 

330 ), 

331 era=EncodingEra.MODERN_WEB, 

332 is_multibyte_cjk=True, 

333 languages=("ko",), 

334 ), 

335 EncodingInfo( 

336 name="euc_jis_2004", 

337 aliases=( 

338 "EUC-JIS-2004", 

339 "euc-jp", 

340 "eucjp", 

341 "ujis", 

342 "u-jis", 

343 "euc-jisx0213", 

344 "cseucpkdfmtjapanese", 

345 "x-euc-jp", 

346 ), 

347 era=EncodingEra.MODERN_WEB, 

348 is_multibyte_cjk=True, 

349 languages=("ja",), 

350 ), 

351 EncodingInfo( 

352 name="euc_kr", 

353 aliases=("EUC-KR", "euckr", "cseuckr"), 

354 era=EncodingEra.MODERN_WEB, 

355 is_multibyte_cjk=True, 

356 languages=("ko",), 

357 superset="cp949", 

358 ), 

359 EncodingInfo( 

360 # Note: "chinese" is NOT listed here because the label is 

361 # semantically ambiguous between Traditional (Big5) and Simplified 

362 # (GB18030) Chinese. Python's codec table still resolves 

363 # "chinese" -> "gb2312" -> (via the gb2312 alias below) gb18030, 

364 # so the label continues to work for Simplified content via the 

365 # codec fallback in lookup_encoding(). We simply decline to 

366 # bless the ambiguity in our own table. 

367 name="gb18030", 

368 aliases=( 

369 "GB18030", 

370 "gb-18030", 

371 "gb2312", 

372 "gbk", 

373 "csgb2312", 

374 "gb_2312", 

375 "gb_2312-80", 

376 "x-gbk", 

377 "csiso58gb231280", 

378 "iso-ir-58", 

379 "csgb18030", 

380 "csgbk", 

381 "cp936", 

382 "ms936", 

383 "windows-936", 

384 ), 

385 era=EncodingEra.MODERN_WEB, 

386 is_multibyte_cjk=True, 

387 languages=("zh",), 

388 ), 

389 EncodingInfo( 

390 name="hz", 

391 aliases=("HZ-GB-2312", "hz"), 

392 era=EncodingEra.LEGACY_REGIONAL, 

393 is_multibyte_cjk=True, 

394 languages=("zh",), 

395 ), 

396 EncodingInfo( 

397 name="iso2022_jp_2", 

398 aliases=( 

399 "ISO-2022-JP-2", 

400 "iso-2022-jp", 

401 "csiso2022jp", 

402 "iso2022-jp-1", 

403 "csiso2022jp2", 

404 ), 

405 era=EncodingEra.MODERN_WEB, 

406 is_multibyte_cjk=True, 

407 languages=("ja",), 

408 ), 

409 EncodingInfo( 

410 name="iso2022_jp_2004", 

411 aliases=("ISO-2022-JP-2004", "iso2022-jp-3"), 

412 era=EncodingEra.MODERN_WEB, 

413 is_multibyte_cjk=True, 

414 languages=("ja",), 

415 ), 

416 EncodingInfo( 

417 name="iso2022_jp_ext", 

418 aliases=("ISO-2022-JP-EXT",), 

419 era=EncodingEra.MODERN_WEB, 

420 is_multibyte_cjk=True, 

421 languages=("ja",), 

422 ), 

423 EncodingInfo( 

424 name="iso2022_kr", 

425 aliases=("ISO-2022-KR", "csiso2022kr"), 

426 era=EncodingEra.LEGACY_REGIONAL, 

427 is_multibyte_cjk=True, 

428 languages=("ko",), 

429 ), 

430 EncodingInfo( 

431 name="shift_jis_2004", 

432 aliases=( 

433 "Shift-JIS-2004", 

434 "Shift_JIS_2004", 

435 "shift_jis", 

436 "sjis", 

437 "shiftjis", 

438 "s_jis", 

439 "shift-jisx0213", 

440 "x-sjis", 

441 "csshiftjis", 

442 "ms_kanji", 

443 ), 

444 era=EncodingEra.MODERN_WEB, 

445 is_multibyte_cjk=True, 

446 languages=("ja",), 

447 superset="cp932", 

448 ), 

449 # Windows code pages - Modern Web 

450 EncodingInfo( 

451 name="cp874", 

452 aliases=("CP874", "windows-874", "dos-874"), 

453 era=EncodingEra.MODERN_WEB, 

454 is_multibyte_cjk=False, 

455 languages=("th",), 

456 ), 

457 EncodingInfo( 

458 name="cp1250", 

459 aliases=("Windows-1250", "cp1250", "x-cp1250", "cswindows1250"), 

460 era=EncodingEra.MODERN_WEB, 

461 is_multibyte_cjk=False, 

462 languages=(*_CENTRAL_EU, "sr"), 

463 ), 

464 EncodingInfo( 

465 name="cp1251", 

466 aliases=("Windows-1251", "cp1251", "x-cp1251", "cswindows1251"), 

467 era=EncodingEra.MODERN_WEB, 

468 is_multibyte_cjk=False, 

469 languages=_CYRILLIC, 

470 ), 

471 EncodingInfo( 

472 name="cp1252", 

473 aliases=("Windows-1252", "cp1252", "x-cp1252", "cswindows1252"), 

474 era=EncodingEra.MODERN_WEB, 

475 is_multibyte_cjk=False, 

476 languages=_WESTERN, 

477 ), 

478 EncodingInfo( 

479 name="cp1253", 

480 aliases=("Windows-1253", "cp1253", "x-cp1253", "cswindows1253"), 

481 era=EncodingEra.MODERN_WEB, 

482 is_multibyte_cjk=False, 

483 languages=("el",), 

484 ), 

485 EncodingInfo( 

486 name="cp1254", 

487 aliases=("Windows-1254", "cp1254", "x-cp1254", "cswindows1254"), 

488 era=EncodingEra.MODERN_WEB, 

489 is_multibyte_cjk=False, 

490 languages=("tr",), 

491 ), 

492 EncodingInfo( 

493 name="cp1255", 

494 aliases=("Windows-1255", "cp1255", "x-cp1255", "cswindows1255"), 

495 era=EncodingEra.MODERN_WEB, 

496 is_multibyte_cjk=False, 

497 languages=("he",), 

498 ), 

499 EncodingInfo( 

500 name="cp1256", 

501 aliases=("Windows-1256", "cp1256", "x-cp1256", "cswindows1256"), 

502 era=EncodingEra.MODERN_WEB, 

503 is_multibyte_cjk=False, 

504 languages=_ARABIC, 

505 ), 

506 EncodingInfo( 

507 name="cp1257", 

508 aliases=("Windows-1257", "cp1257", "x-cp1257", "cswindows1257"), 

509 era=EncodingEra.MODERN_WEB, 

510 is_multibyte_cjk=False, 

511 languages=_BALTIC, 

512 ), 

513 EncodingInfo( 

514 name="cp1258", 

515 aliases=("Windows-1258", "cp1258", "x-cp1258", "cswindows1258"), 

516 era=EncodingEra.MODERN_WEB, 

517 is_multibyte_cjk=False, 

518 languages=("vi",), 

519 ), 

520 # KOI8 - Modern Web 

521 EncodingInfo( 

522 name="koi8-r", 

523 aliases=("KOI8-R", "koi8r", "koi", "koi8", "cskoi8r"), 

524 era=EncodingEra.MODERN_WEB, 

525 is_multibyte_cjk=False, 

526 languages=("ru",), 

527 ), 

528 EncodingInfo( 

529 name="koi8-u", 

530 aliases=("KOI8-U", "koi8u", "koi8-ru", "cskoi8u"), 

531 era=EncodingEra.MODERN_WEB, 

532 is_multibyte_cjk=False, 

533 languages=("uk",), 

534 ), 

535 # TIS-620 - Modern Web 

536 EncodingInfo( 

537 name="tis-620", 

538 aliases=( 

539 "TIS-620", 

540 "tis620", 

541 "iso-8859-11", 

542 "iso8859-11", 

543 "iso885911", 

544 "cstis620", 

545 ), 

546 era=EncodingEra.MODERN_WEB, 

547 is_multibyte_cjk=False, 

548 languages=("th",), 

549 superset="cp874", 

550 ), 

551 # === LEGACY_ISO === 

552 EncodingInfo( 

553 name="iso8859-1", 

554 aliases=("ISO-8859-1", "latin-1", "latin1", "iso8859-1", "iso88591"), 

555 era=EncodingEra.LEGACY_ISO, 

556 is_multibyte_cjk=False, 

557 languages=_WESTERN, 

558 superset="cp1252", 

559 ), 

560 EncodingInfo( 

561 name="iso8859-2", 

562 aliases=("ISO-8859-2", "latin-2", "latin2", "iso8859-2", "iso88592"), 

563 era=EncodingEra.LEGACY_ISO, 

564 is_multibyte_cjk=False, 

565 languages=_CENTRAL_EU, 

566 superset="cp1250", 

567 ), 

568 EncodingInfo( 

569 name="iso8859-3", 

570 aliases=("ISO-8859-3", "latin-3", "latin3", "iso8859-3", "iso88593"), 

571 era=EncodingEra.LEGACY_ISO, 

572 is_multibyte_cjk=False, 

573 languages=("eo", "mt", "tr"), 

574 ), 

575 EncodingInfo( 

576 name="iso8859-4", 

577 aliases=("ISO-8859-4", "latin-4", "latin4", "iso8859-4", "iso88594"), 

578 era=EncodingEra.LEGACY_ISO, 

579 is_multibyte_cjk=False, 

580 languages=_BALTIC, 

581 ), 

582 EncodingInfo( 

583 name="iso8859-5", 

584 aliases=("ISO-8859-5", "iso8859-5", "cyrillic", "iso88595"), 

585 era=EncodingEra.LEGACY_ISO, 

586 is_multibyte_cjk=False, 

587 languages=_CYRILLIC, 

588 superset="cp1251", 

589 ), 

590 EncodingInfo( 

591 # The -E ("explicit directionality") and -I ("implicit 

592 # directionality") variants listed by IANA and WHATWG are 

593 # higher-level bidi-ordering hints, not separate codecs -- Python 

594 # stdlib has no distinct decoder for them, so all four resolve to 

595 # the same ``iso8859-6`` canonical here. 

596 name="iso8859-6", 

597 aliases=( 

598 "ISO-8859-6", 

599 "iso8859-6", 

600 "arabic", 

601 "iso88596", 

602 "iso-8859-6-e", 

603 "iso-8859-6-i", 

604 "csiso88596e", 

605 "csiso88596i", 

606 ), 

607 era=EncodingEra.LEGACY_ISO, 

608 is_multibyte_cjk=False, 

609 languages=_ARABIC, 

610 superset="cp1256", 

611 ), 

612 EncodingInfo( 

613 name="iso8859-7", 

614 aliases=( 

615 "ISO-8859-7", 

616 "iso8859-7", 

617 "greek", 

618 "iso88597", 

619 "sun_eu_greek", 

620 ), 

621 era=EncodingEra.LEGACY_ISO, 

622 is_multibyte_cjk=False, 

623 languages=("el",), 

624 superset="cp1253", 

625 ), 

626 EncodingInfo( 

627 # WHATWG and IANA distinguish ISO-8859-8 ("visual", -E) from 

628 # ISO-8859-8-I ("logical", -I) to signal Hebrew bidi ordering, but 

629 # Python's stdlib has a single ``iso8859-8`` codec -- the bidi 

630 # distinction is a higher-layer concern. All variants collapse 

631 # onto this one canonical. 

632 name="iso8859-8", 

633 aliases=( 

634 "ISO-8859-8", 

635 "iso8859-8", 

636 "hebrew", 

637 "iso88598", 

638 "iso-8859-8-e", 

639 "iso-8859-8-i", 

640 "csiso88598e", 

641 "csiso88598i", 

642 "visual", 

643 "logical", 

644 ), 

645 era=EncodingEra.LEGACY_ISO, 

646 is_multibyte_cjk=False, 

647 languages=("he",), 

648 superset="cp1255", 

649 ), 

650 EncodingInfo( 

651 name="iso8859-9", 

652 aliases=("ISO-8859-9", "latin-5", "latin5", "iso8859-9", "iso88599"), 

653 era=EncodingEra.LEGACY_ISO, 

654 is_multibyte_cjk=False, 

655 languages=("tr",), 

656 superset="cp1254", 

657 ), 

658 EncodingInfo( 

659 name="iso8859-10", 

660 aliases=("ISO-8859-10", "latin-6", "latin6", "iso8859-10", "iso885910"), 

661 era=EncodingEra.LEGACY_ISO, 

662 is_multibyte_cjk=False, 

663 languages=("is", "fi"), 

664 ), 

665 EncodingInfo( 

666 name="iso8859-13", 

667 aliases=( 

668 "ISO-8859-13", 

669 "latin-7", 

670 "latin7", 

671 "iso8859-13", 

672 "iso885913", 

673 "csiso885913", 

674 ), 

675 era=EncodingEra.LEGACY_ISO, 

676 is_multibyte_cjk=False, 

677 languages=_BALTIC, 

678 superset="cp1257", 

679 ), 

680 EncodingInfo( 

681 # ``iso-celtic`` is a Python stdlib alias, not a WHATWG/IANA name. 

682 name="iso8859-14", 

683 aliases=( 

684 "ISO-8859-14", 

685 "latin-8", 

686 "latin8", 

687 "iso8859-14", 

688 "iso885914", 

689 "csiso885914", 

690 "iso-ir-199", 

691 "iso-celtic", 

692 "l8", 

693 ), 

694 era=EncodingEra.LEGACY_ISO, 

695 is_multibyte_cjk=False, 

696 languages=("cy", "ga", "br", "gd"), 

697 ), 

698 EncodingInfo( 

699 name="iso8859-15", 

700 aliases=( 

701 "ISO-8859-15", 

702 "latin-9", 

703 "latin9", 

704 "iso8859-15", 

705 "iso885915", 

706 "csisolatin9", 

707 "csiso885915", 

708 "l9", 

709 ), 

710 era=EncodingEra.LEGACY_ISO, 

711 is_multibyte_cjk=False, 

712 languages=_WESTERN, 

713 ), 

714 EncodingInfo( 

715 name="iso8859-16", 

716 aliases=( 

717 "ISO-8859-16", 

718 "latin-10", 

719 "latin10", 

720 "iso8859-16", 

721 "iso885916", 

722 "csiso885916", 

723 "iso-ir-226", 

724 "l10", 

725 ), 

726 era=EncodingEra.LEGACY_ISO, 

727 is_multibyte_cjk=False, 

728 languages=("ro", "pl", "hr", "hu", "sk", "sl"), 

729 ), 

730 # Johab - Legacy ISO per chardet 6.0.0 

731 EncodingInfo( 

732 name="johab", 

733 aliases=("Johab",), 

734 era=EncodingEra.LEGACY_ISO, 

735 is_multibyte_cjk=True, 

736 languages=("ko",), 

737 ), 

738 # === LEGACY_MAC === 

739 EncodingInfo( 

740 name="mac-cyrillic", 

741 aliases=( 

742 "Mac-Cyrillic", 

743 "MacCyrillic", 

744 "maccyrillic", 

745 "x-mac-cyrillic", 

746 "x-mac-ukrainian", 

747 ), 

748 era=EncodingEra.LEGACY_MAC, 

749 is_multibyte_cjk=False, 

750 languages=_CYRILLIC, 

751 ), 

752 EncodingInfo( 

753 name="mac-greek", 

754 aliases=("Mac-Greek", "MacGreek", "macgreek"), 

755 era=EncodingEra.LEGACY_MAC, 

756 is_multibyte_cjk=False, 

757 languages=("el",), 

758 ), 

759 EncodingInfo( 

760 name="mac-iceland", 

761 aliases=("Mac-Iceland", "MacIceland", "maciceland"), 

762 era=EncodingEra.LEGACY_MAC, 

763 is_multibyte_cjk=False, 

764 languages=("is",), 

765 ), 

766 EncodingInfo( 

767 name="mac-latin2", 

768 aliases=("Mac-Latin2", "MacLatin2", "maclatin2", "maccentraleurope"), 

769 era=EncodingEra.LEGACY_MAC, 

770 is_multibyte_cjk=False, 

771 languages=_CENTRAL_EU_NO_RO, 

772 ), 

773 EncodingInfo( 

774 name="mac-roman", 

775 aliases=( 

776 "Mac-Roman", 

777 "MacRoman", 

778 "macroman", 

779 "macintosh", 

780 "csmacintosh", 

781 "mac", 

782 "x-mac-roman", 

783 ), 

784 era=EncodingEra.LEGACY_MAC, 

785 is_multibyte_cjk=False, 

786 languages=_WESTERN, 

787 ), 

788 EncodingInfo( 

789 name="mac-turkish", 

790 aliases=("Mac-Turkish", "MacTurkish", "macturkish"), 

791 era=EncodingEra.LEGACY_MAC, 

792 is_multibyte_cjk=False, 

793 languages=("tr",), 

794 ), 

795 # === LEGACY_REGIONAL === 

796 EncodingInfo( 

797 name="cp720", 

798 aliases=("CP720",), 

799 era=EncodingEra.LEGACY_REGIONAL, 

800 is_multibyte_cjk=False, 

801 languages=_ARABIC, 

802 ), 

803 EncodingInfo( 

804 name="cp1006", 

805 aliases=("CP1006",), 

806 era=EncodingEra.LEGACY_REGIONAL, 

807 is_multibyte_cjk=False, 

808 languages=("ur",), 

809 ), 

810 EncodingInfo( 

811 name="cp1125", 

812 aliases=("CP1125",), 

813 era=EncodingEra.LEGACY_REGIONAL, 

814 is_multibyte_cjk=False, 

815 languages=("uk",), 

816 ), 

817 EncodingInfo( 

818 name="koi8-t", 

819 aliases=("KOI8-T",), 

820 era=EncodingEra.LEGACY_REGIONAL, 

821 is_multibyte_cjk=False, 

822 languages=("tg",), 

823 ), 

824 EncodingInfo( 

825 name="kz1048", 

826 aliases=("KZ-1048", "kz1048", "strk1048-2002", "rk1048"), 

827 era=EncodingEra.LEGACY_REGIONAL, 

828 is_multibyte_cjk=False, 

829 languages=("kk",), 

830 ), 

831 EncodingInfo( 

832 name="ptcp154", 

833 aliases=("PTCP154", "pt154", "cp154"), 

834 era=EncodingEra.LEGACY_REGIONAL, 

835 is_multibyte_cjk=False, 

836 languages=("kk",), 

837 ), 

838 EncodingInfo( 

839 name="hp-roman8", 

840 aliases=("HP-Roman8", "roman8", "r8", "csHPRoman8"), 

841 era=EncodingEra.LEGACY_REGIONAL, 

842 is_multibyte_cjk=False, 

843 languages=_WESTERN, 

844 ), 

845 # === DOS === 

846 EncodingInfo( 

847 name="cp437", 

848 aliases=("CP437",), 

849 era=EncodingEra.DOS, 

850 is_multibyte_cjk=False, 

851 languages=("en", "fr", "de", "es", "pt", "it", "nl", "da", "sv", "fi", "ga"), 

852 ), 

853 EncodingInfo( 

854 name="cp737", 

855 aliases=("CP737",), 

856 era=EncodingEra.DOS, 

857 is_multibyte_cjk=False, 

858 languages=("el",), 

859 ), 

860 EncodingInfo( 

861 name="cp775", 

862 aliases=("CP775",), 

863 era=EncodingEra.DOS, 

864 is_multibyte_cjk=False, 

865 languages=_BALTIC, 

866 ), 

867 EncodingInfo( 

868 name="cp850", 

869 aliases=("CP850",), 

870 era=EncodingEra.DOS, 

871 is_multibyte_cjk=False, 

872 languages=_WESTERN, 

873 ), 

874 EncodingInfo( 

875 name="cp852", 

876 aliases=("CP852",), 

877 era=EncodingEra.DOS, 

878 is_multibyte_cjk=False, 

879 languages=_CENTRAL_EU, 

880 ), 

881 EncodingInfo( 

882 name="cp855", 

883 aliases=("CP855",), 

884 era=EncodingEra.DOS, 

885 is_multibyte_cjk=False, 

886 languages=_CYRILLIC, 

887 ), 

888 EncodingInfo( 

889 name="cp856", 

890 aliases=("CP856",), 

891 era=EncodingEra.DOS, 

892 is_multibyte_cjk=False, 

893 languages=("he",), 

894 ), 

895 EncodingInfo( 

896 name="cp857", 

897 aliases=("CP857",), 

898 era=EncodingEra.DOS, 

899 is_multibyte_cjk=False, 

900 languages=("tr",), 

901 ), 

902 EncodingInfo( 

903 name="cp858", 

904 aliases=("CP858",), 

905 era=EncodingEra.DOS, 

906 is_multibyte_cjk=False, 

907 languages=_WESTERN, 

908 ), 

909 EncodingInfo( 

910 name="cp860", 

911 aliases=("CP860",), 

912 era=EncodingEra.DOS, 

913 is_multibyte_cjk=False, 

914 languages=("pt",), 

915 ), 

916 EncodingInfo( 

917 name="cp861", 

918 aliases=("CP861",), 

919 era=EncodingEra.DOS, 

920 is_multibyte_cjk=False, 

921 languages=("is",), 

922 ), 

923 EncodingInfo( 

924 name="cp862", 

925 aliases=("CP862",), 

926 era=EncodingEra.DOS, 

927 is_multibyte_cjk=False, 

928 languages=("he",), 

929 ), 

930 EncodingInfo( 

931 name="cp863", 

932 aliases=("CP863",), 

933 era=EncodingEra.DOS, 

934 is_multibyte_cjk=False, 

935 languages=("fr",), 

936 ), 

937 EncodingInfo( 

938 name="cp864", 

939 aliases=("CP864",), 

940 era=EncodingEra.DOS, 

941 is_multibyte_cjk=False, 

942 languages=("ar",), 

943 ), 

944 EncodingInfo( 

945 name="cp865", 

946 aliases=("CP865",), 

947 era=EncodingEra.DOS, 

948 is_multibyte_cjk=False, 

949 languages=("da", "no"), 

950 ), 

951 EncodingInfo( 

952 name="cp866", 

953 aliases=("CP866",), 

954 era=EncodingEra.DOS, 

955 is_multibyte_cjk=False, 

956 languages=_CYRILLIC, 

957 ), 

958 EncodingInfo( 

959 name="cp869", 

960 aliases=("CP869",), 

961 era=EncodingEra.DOS, 

962 is_multibyte_cjk=False, 

963 languages=("el",), 

964 ), 

965 # === MAINFRAME === 

966 EncodingInfo( 

967 name="cp1140", 

968 aliases=( 

969 "CP1140", 

970 "cp037", 

971 "cp01140", 

972 "ibm01140", 

973 "ibm1140", 

974 "csibm01140", 

975 ), 

976 era=EncodingEra.MAINFRAME, 

977 is_multibyte_cjk=False, 

978 languages=_WESTERN_TR, 

979 ), 

980 EncodingInfo( 

981 name="cp424", 

982 aliases=("CP424",), 

983 era=EncodingEra.MAINFRAME, 

984 is_multibyte_cjk=False, 

985 languages=("he",), 

986 ), 

987 EncodingInfo( 

988 name="cp500", 

989 aliases=("CP500",), 

990 era=EncodingEra.MAINFRAME, 

991 is_multibyte_cjk=False, 

992 languages=_WESTERN, 

993 ), 

994 EncodingInfo( 

995 name="cp875", 

996 aliases=("CP875",), 

997 era=EncodingEra.MAINFRAME, 

998 is_multibyte_cjk=False, 

999 languages=("el",), 

1000 ), 

1001 EncodingInfo( 

1002 name="cp1026", 

1003 aliases=("CP1026",), 

1004 era=EncodingEra.MAINFRAME, 

1005 is_multibyte_cjk=False, 

1006 languages=("tr",), 

1007 ), 

1008 EncodingInfo( 

1009 name="cp273", 

1010 aliases=("CP273",), 

1011 era=EncodingEra.MAINFRAME, 

1012 is_multibyte_cjk=False, 

1013 languages=("de",), 

1014 ), 

1015) 

1016 

1017REGISTRY: MappingProxyType[str, EncodingInfo] = MappingProxyType( 

1018 {e.name: e for e in _REGISTRY_ENTRIES} 

1019) 

1020 

1021#: The Windows superset of each multi-byte CJK encoding that has one 

1022#: (``shift_jis_2004`` -> ``cp932``, ``euc_kr`` -> ``cp949``). The one 

1023#: selection the markup promotion and the dead-heat promotion share; the 

1024#: ISO/Windows pairs stay out of both (ADR-0007). 

1025CJK_SUPERSETS: MappingProxyType[str, str] = MappingProxyType( 

1026 { 

1027 e.name: e.superset 

1028 for e in _REGISTRY_ENTRIES 

1029 if e.is_multibyte_cjk and e.superset is not None 

1030 } 

1031) 

1032 

1033# Names ``codecs.lookup`` may be asked about, normalized the way its search 

1034# function normalizes them: the stdlib alias table (aliases and module names) 

1035# plus the registry's own names. Anything else is a miss there, and 

1036# ``encodings.search_function`` keeps every miss in a module-level dict that 

1037# has no bound before Python 3.13.13 / 3.14.4 (python/cpython#146054), so an 

1038# untrusted name that reaches it is retained for the life of the process. 

1039_STDLIB_CODEC_NAMES: frozenset[str] = frozenset( 

1040 ( 

1041 *_stdlib_aliases, 

1042 *_stdlib_aliases.values(), 

1043 *( 

1044 encodings.normalize_encoding(n.lower()) 

1045 for e in _REGISTRY_ENTRIES 

1046 for n in (e.name, *e.aliases) 

1047 ), 

1048 ) 

1049) 

1050 

1051 

1052# Bounded because *name* comes from untrusted markup (``<meta charset>``, 

1053# ``<?xml encoding>``) and the set of distinct spellings is unbounded. 1024 

1054# is well above the registry's names and aliases, so real lookups never evict. 

1055@functools.lru_cache(maxsize=1024) 

1056def lookup_encoding(name: str) -> EncodingName | None: 

1057 """Convert an encoding name string to the canonical EncodingName. 

1058 

1059 Handles arbitrary casing, aliases, and Python codec names. 

1060 

1061 :param name: Any encoding name string. 

1062 :returns: The canonical :data:`EncodingName`, or ``None`` if unknown. 

1063 """ 

1064 lowered = name.lower() 

1065 for entry in REGISTRY.values(): 

1066 if entry.name == lowered: 

1067 return entry.name 

1068 for alias in entry.aliases: 

1069 if alias.lower() == lowered: 

1070 return entry.name 

1071 # Fallback: resolve through Python's codec registry, which is only asked 

1072 # about names it can answer (see _STDLIB_CODEC_NAMES). The search 

1073 # function tries a dotted name both as is and with the dots folded. 

1074 normalized = encodings.normalize_encoding(lowered) 

1075 if ( 

1076 normalized not in _STDLIB_CODEC_NAMES 

1077 and normalized.replace(".", "_") not in _STDLIB_CODEC_NAMES 

1078 ): 

1079 return None 

1080 try: 

1081 codec_name = codecs.lookup(name).name 

1082 except (LookupError, ValueError): 

1083 return None 

1084 if codec_name != lowered: 

1085 return lookup_encoding(codec_name) 

1086 return None 

1087 

1088 

1089def _validate_encoding(name: str, param_name: str) -> str: 

1090 """Validate and normalize a single encoding name. 

1091 

1092 :param name: The encoding name to validate. 

1093 :param param_name: Parameter name for error messages. 

1094 :returns: The canonical encoding name. 

1095 :raises ValueError: If the encoding name is unknown. 

1096 """ 

1097 canonical = lookup_encoding(name) 

1098 if canonical is None: 

1099 msg = f"Unknown encoding {name!r} in {param_name}" 

1100 raise ValueError(msg) 

1101 return canonical 

1102 

1103 

1104def normalize_encodings( 

1105 encodings: Iterable[str] | None, 

1106 param_name: str, 

1107) -> frozenset[str] | None: 

1108 """Normalize an iterable of encoding names to canonical forms. 

1109 

1110 :param encodings: Encoding names to normalize, or ``None``. 

1111 :param param_name: Parameter name for error messages. 

1112 :returns: A frozenset of canonical encoding names, or ``None``. 

1113 :raises ValueError: If any encoding name is unknown. 

1114 """ 

1115 if encodings is None: 

1116 return None 

1117 result = frozenset(_validate_encoding(name, param_name) for name in encodings) 

1118 if not result: 

1119 msg = f"{param_name} must not be empty; omit the argument or pass None to disable filtering" 

1120 raise ValueError(msg) 

1121 return result