2929
3030 _MessageID : TypeAlias = str | tuple [str , ...] | list [str ]
3131
32- __all__ = ['Message' , 'Catalog' , 'TranslationError' ]
32+ __all__ = [
33+ 'DEFAULT_HEADER' ,
34+ 'PYTHON_FORMAT' ,
35+ 'Catalog' ,
36+ 'Message' ,
37+ 'TranslationError' ,
38+ ]
39+
3340
3441def get_close_matches (word , possibilities , n = 3 , cutoff = 0.6 ):
3542 """A modified version of ``difflib.get_close_matches``.
@@ -42,7 +49,7 @@ def get_close_matches(word, possibilities, n=3, cutoff=0.6):
4249 if not 0.0 <= cutoff <= 1.0 : # pragma: no cover
4350 raise ValueError (f"cutoff must be in [0.0, 1.0]: { cutoff !r} " )
4451 result = []
45- s = SequenceMatcher (autojunk = False ) # only line changed from difflib.py
52+ s = SequenceMatcher (autojunk = False ) # only line changed from difflib.py
4653 s .set_seq2 (word )
4754 for x in possibilities :
4855 s .set_seq1 (x )
@@ -274,6 +281,14 @@ def parse_separated_header(value: str) -> dict[str, str]:
274281 return dict (m .get_params ())
275282
276283
284+ def _force_text (s : str | bytes , encoding : str = 'utf-8' , errors : str = 'strict' ) -> str :
285+ if isinstance (s , str ):
286+ return s
287+ if isinstance (s , bytes ):
288+ return s .decode (encoding , errors )
289+ return str (s )
290+
291+
277292class Catalog :
278293 """Representation of a message catalog."""
279294
@@ -428,46 +443,39 @@ def _set_header_comment(self, string: str | None) -> None:
428443 """ )
429444
430445 def _get_mime_headers (self ) -> list [tuple [str , str ]]:
431- headers : list [tuple [str , str ]] = []
432- headers .append (("Project-Id-Version" , f"{ self .project } { self .version } " ))
433- headers .append (('Report-Msgid-Bugs-To' , self .msgid_bugs_address ))
434- headers .append (('POT-Creation-Date' ,
435- format_datetime (self .creation_date , 'yyyy-MM-dd HH:mmZ' ,
436- locale = 'en' )))
437446 if isinstance (self .revision_date , (datetime .datetime , datetime .time , int , float )):
438- headers .append (('PO-Revision-Date' ,
439- format_datetime (self .revision_date ,
440- 'yyyy-MM-dd HH:mmZ' , locale = 'en' )))
447+ revision_date = format_datetime (self .revision_date , 'yyyy-MM-dd HH:mmZ' , locale = 'en' )
441448 else :
442- headers .append (('PO-Revision-Date' , self .revision_date ))
443- headers .append (('Last-Translator' , self .last_translator ))
449+ revision_date = self .revision_date
450+
451+ language_team = self .language_team
452+ if self .locale_identifier and 'LANGUAGE' in language_team :
453+ language_team = language_team .replace ('LANGUAGE' , str (self .locale_identifier ))
454+
455+ headers : list [tuple [str , str ]] = [
456+ ("Project-Id-Version" , f"{ self .project } { self .version } " ),
457+ ('Report-Msgid-Bugs-To' , self .msgid_bugs_address ),
458+ ('POT-Creation-Date' , format_datetime (self .creation_date , 'yyyy-MM-dd HH:mmZ' , locale = 'en' )),
459+ ('PO-Revision-Date' , revision_date ),
460+ ('Last-Translator' , self .last_translator ),
461+ ]
444462 if self .locale_identifier :
445463 headers .append (('Language' , str (self .locale_identifier )))
446- if self .locale_identifier and ('LANGUAGE' in self .language_team ):
447- headers .append (('Language-Team' ,
448- self .language_team .replace ('LANGUAGE' ,
449- str (self .locale_identifier ))))
450- else :
451- headers .append (('Language-Team' , self .language_team ))
464+ headers .append (('Language-Team' , language_team ))
452465 if self .locale is not None :
453466 headers .append (('Plural-Forms' , self .plural_forms ))
454- headers .append (('MIME-Version' , '1.0' ))
455- headers .append (("Content-Type" , f"text/plain; charset={ self .charset } " ))
456- headers .append (('Content-Transfer-Encoding' , '8bit' ))
457- headers .append (("Generated-By" , f"Babel { VERSION } \n " ))
467+ headers += [
468+ ('MIME-Version' , '1.0' ),
469+ ("Content-Type" , f"text/plain; charset={ self .charset } " ),
470+ ('Content-Transfer-Encoding' , '8bit' ),
471+ ("Generated-By" , f"Babel { VERSION } \n " ),
472+ ]
458473 return headers
459474
460- def _force_text (self , s : str | bytes , encoding : str = 'utf-8' , errors : str = 'strict' ) -> str :
461- if isinstance (s , str ):
462- return s
463- if isinstance (s , bytes ):
464- return s .decode (encoding , errors )
465- return str (s )
466-
467475 def _set_mime_headers (self , headers : Iterable [tuple [str , str ]]) -> None :
468476 for name , value in headers :
469- name = self . _force_text (name .lower (), encoding = self .charset )
470- value = self . _force_text (value , encoding = self .charset )
477+ name = _force_text (name .lower (), encoding = self .charset )
478+ value = _force_text (value , encoding = self .charset )
471479 if name == 'project-id-version' :
472480 parts = value .split (' ' )
473481 self .project = ' ' .join (parts [:- 1 ])
@@ -824,6 +832,9 @@ def update(
824832
825833 :param template: the reference catalog, usually read from a POT file
826834 :param no_fuzzy_matching: whether to use fuzzy matching of message IDs
835+ :param update_header_comment: whether to copy the header comment from the template
836+ :param keep_user_comments: whether to keep user comments from the old catalog
837+ :param update_creation_date: whether to copy the creation date from the template
827838 """
828839 messages = self ._messages
829840 remaining = messages .copy ()
0 commit comments