# HG changeset patch # User cmlenz # Date 1181498626 0 # Node ID 4ff9cc26c11b9be2e253dc5dadb2b670143a1814 # Parent 6b6aa2f9e93d14fbfb5535144c252d51b41e50fd Some cosmetic changes for the new translator comments support. diff --git a/babel/messages/catalog.py b/babel/messages/catalog.py --- a/babel/messages/catalog.py +++ b/babel/messages/catalog.py @@ -35,7 +35,7 @@ class Message(object): """Representation of a single message in a catalog.""" - def __init__(self, id, string='', locations=(), flags=(), comments=[]): + def __init__(self, id, string='', locations=(), flags=(), comments=()): """Create the message object. :param id: the message ID, or a ``(singular, plural)`` tuple for @@ -44,7 +44,7 @@ ``(singular, plural)`` tuple for pluralizable messages :param locations: a sequence of ``(filenname, lineno)`` tuples :param flags: a set or sequence of flags - :param comments: a list of comments for the msgid + :param comments: a sequence of translator comments for the message """ self.id = id if not string and self.pluralizable: @@ -56,7 +56,7 @@ self.flags.add('python-format') else: self.flags.discard('python-format') - self.comments = comments + self.comments = list(comments) def __repr__(self): return '<%s %r>' % (type(self).__name__, self.id) @@ -130,9 +130,9 @@ self._messages = odict() self.project = project or 'PROJECT' #: the project name - self.version = version or 'VERSION' #: the project version + self.version = version or 'VERSION' #: the project version self.msgid_bugs_address = msgid_bugs_address or 'EMAIL@ADDRESS' - + if creation_date is None: creation_date = time.localtime() elif isinstance(creation_date, datetime): @@ -166,12 +166,11 @@ time.strftime('%Y-%m-%d %H:%M%z', self.revision_date))) headers.append(('Last-Translator', self.last_translator)) headers.append(('Language-Team', '%s ' % self.locale)) + headers.append(('Plural-Forms', self.plural_forms)) headers.append(('MIME-Version', '1.0')) headers.append(('Content-Type', 'text/plain; charset=%s' % self.charset)) headers.append(('Content-Transfer-Encoding', '8bit')) - if self.locale is not None: - headers.append(('Plural-Forms', self.plural_forms)) headers.append(('Generated-By', 'Babel %s' % VERSION)) return headers headers = property(headers, doc="""\ @@ -212,10 +211,10 @@ PO-Revision-Date: 1990-08-03 12:00+0000 Last-Translator: John Doe Language-Team: de_DE + Plural-Forms: nplurals=2; plural=(n != 1) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit - Plural-Forms: nplurals=2; plural=(n != 1) Generated-By: Babel ... :type: `list` @@ -229,7 +228,9 @@ elif self.locale.language in PLURALS: num = PLURALS[self.locale.language][0] return num - num_plurals = property(num_plurals) + num_plurals = property(num_plurals, doc="""\ + The number of plurals used by the locale. + """) def plural_forms(self): num, expr = ('INTEGER', 'EXPRESSION') @@ -255,6 +256,10 @@ return self._key_for(id) in self._messages def __len__(self): + """The number of messages in the catalog. + + This does not include the special ``msgid ""`` entry. + """ return len(self._messages) def __iter__(self): @@ -330,7 +335,7 @@ assert isinstance(message.string, (list, tuple)) self._messages[key] = message - def add(self, id, string=None, locations=(), flags=(), comments=[]): + def add(self, id, string=None, locations=(), flags=(), comments=()): """Add or update the message with the specified ID. >>> catalog = Catalog() @@ -347,7 +352,7 @@ ``(singular, plural)`` tuple for pluralizable messages :param locations: a sequence of ``(filenname, lineno)`` tuples :param flags: a set or sequence of flags - :param comments: a list of comments for the msgid + :param comments: a list of translator comments """ self[id] = Message(id, string, list(locations), flags, comments) diff --git a/babel/messages/extract.py b/babel/messages/extract.py --- a/babel/messages/extract.py +++ b/babel/messages/extract.py @@ -50,7 +50,7 @@ def extract_from_dir(dirname=os.getcwd(), method_map=DEFAULT_MAPPING, options_map=None, keywords=DEFAULT_KEYWORDS, - comments_tags=[], callback=None): + comment_tags=(), callback=None): """Extract messages from any source files found in the given directory. This function generates tuples of the form: @@ -106,8 +106,8 @@ that should be recognized as translation functions) to tuples that specify which of their arguments contain localizable strings - :param comments_tags: a list of translator tags to search for and include - in output + :param comment_tags: a list of tags of translator comments to search for + and include in the results :param callback: a function that is called for every file that message are extracted from, just before the extraction itself is performed; the function is passed the filename, the name @@ -142,13 +142,13 @@ for lineno, message, comments in \ extract_from_file(method, filepath, keywords=keywords, - comments_tags=comments_tags, + comment_tags=comment_tags, options=options): yield filename, lineno, message, comments break def extract_from_file(method, filename, keywords=DEFAULT_KEYWORDS, - comments_tags=[], options=None): + comment_tags=(), options=None): """Extract messages from a specific file. This function returns a list of tuples of the form: @@ -161,20 +161,19 @@ that should be recognized as translation functions) to tuples that specify which of their arguments contain localizable strings - :param comments_tags: a list of translator tags to search for and include - in output + :param comment_tags: a list of translator tags to search for and include + in the results :param options: a dictionary of additional options (optional) :return: the list of extracted messages :rtype: `list` """ fileobj = open(filename, 'U') try: - return list(extract(method, fileobj, keywords, - comments_tags=comments_tags, options=options)) + return list(extract(method, fileobj, keywords, comment_tags, options)) finally: fileobj.close() -def extract(method, fileobj, keywords=DEFAULT_KEYWORDS, comments_tags=[], +def extract(method, fileobj, keywords=DEFAULT_KEYWORDS, comment_tags=(), options=None): """Extract messages from the given file-like object using the specified extraction method. @@ -202,8 +201,8 @@ that should be recognized as translation functions) to tuples that specify which of their arguments contain localizable strings - :param comments_tags: a list of translator tags to search for and include - in output + :param comment_tags: a list of translator tags to search for and include + in the results :param options: a dictionary of additional options (optional) :return: the list of extracted messages :rtype: `list` @@ -213,12 +212,9 @@ for entry_point in working_set.iter_entry_points(GROUP_NAME, method): func = entry_point.load(require=True) - m = [] - for lineno, funcname, messages, comments in \ - func(fileobj, - keywords.keys(), - comments_tags=comments_tags, - options=options or {}): + results = func(fileobj, keywords.keys(), comment_tags, + options=options or {}) + for lineno, funcname, messages, comments in results: if isinstance(messages, (list, tuple)): msgs = [] for index in keywords[funcname]: @@ -231,20 +227,20 @@ raise ValueError('Unknown extraction method %r' % method) -def extract_nothing(fileobj, keywords, comments_tags, options): +def extract_nothing(fileobj, keywords, comment_tags, options): """Pseudo extractor that does not actually extract anything, but simply returns an empty list. """ return [] -def extract_genshi(fileobj, keywords, comments_tags, options): +def extract_genshi(fileobj, keywords, comment_tags, options): """Extract messages from Genshi templates. :param fileobj: the file-like object the messages should be extracted from :param keywords: a list of keywords (i.e. function names) that should be recognized as translation functions - :param comments_tags: a list of translator tags to search for and include - in output + :param comment_tags: a list of translator tags to search for and include + in the results :param options: a dictionary of additional options (optional) :return: an iterator over ``(lineno, funcname, message, comments)`` tuples :rtype: ``iterator`` @@ -272,14 +268,14 @@ gettext_functions=keywords): yield lineno, func, message, [] -def extract_python(fileobj, keywords, comments_tags, options): +def extract_python(fileobj, keywords, comment_tags, options): """Extract messages from Python source code. :param fileobj: the file-like object the messages should be extracted from :param keywords: a list of keywords (i.e. function names) that should be recognized as translation functions - :param comments_tags: a list of translator tags to search for and include - in output + :param comment_tags: a list of translator tags to search for and include + in the results :param options: a dictionary of additional options (optional) :return: an iterator over ``(lineno, funcname, message, comments)`` tuples :rtype: ``iterator`` @@ -300,8 +296,8 @@ if in_translator_comments is True: translator_comments.append(value[1:].strip()) continue - for comments_tag in comments_tags: - if comments_tag in value: + for comment_tags in comment_tags: + if comment_tags in value: if in_translator_comments is not True: in_translator_comments = True translator_comments.append(value[1:].strip()) diff --git a/babel/messages/frontend.py b/babel/messages/frontend.py --- a/babel/messages/frontend.py +++ b/babel/messages/frontend.py @@ -165,7 +165,7 @@ extracted = extract_from_dir(dirname, method_map, options_map, keywords=self.keywords, - comments_tags=self._add_comments, + comment_tags=self._add_comments, callback=callback) for filename, lineno, message, comments in extracted: filepath = os.path.normpath(os.path.join(dirname, filename)) diff --git a/babel/messages/pofile.py b/babel/messages/pofile.py --- a/babel/messages/pofile.py +++ b/babel/messages/pofile.py @@ -69,6 +69,7 @@ translations = [] locations = [] flags = [] + comments = [] in_msgid = in_msgstr = False def _add_message(): @@ -81,8 +82,9 @@ string = tuple([t[1] for t in translations]) else: string = translations[0][1] - catalog.add(msgid, string, list(locations), set(flags)) - del messages[:]; del translations[:]; del locations[:]; del flags[:] + catalog.add(msgid, string, list(locations), set(flags), list(comments)) + del messages[:]; del translations[:]; del locations[:]; + del flags[:]; del comments[:] for line in fileobj.readlines(): line = line.strip() @@ -97,6 +99,8 @@ elif line[1:].startswith(','): for flag in line[2:].lstrip().split(','): flags.append(flag.strip()) + elif line[1:].startswith('.'): + comments.append(line[2:].strip) elif line: if line.startswith('msgid_plural'): in_msgid = True diff --git a/doc/catalogs.txt b/doc/catalogs.txt --- a/doc/catalogs.txt +++ b/doc/catalogs.txt @@ -170,15 +170,15 @@ .. code-block:: python - def extract_xxx(fileobj, keywords, comments_tags, options): + def extract_xxx(fileobj, keywords, comment_tags, options): """Extract messages from XXX files. :param fileobj: the file-like object the messages should be extracted from :param keywords: a list of keywords (i.e. function names) that should be recognized as translation functions - :param comments_tags: a list of translator tags to search for and - include in output + :param comment_tags: a list of translator tags to search for and + include in the results :param options: a dictionary of additional options (optional) :return: an iterator over ``(lineno, funcname, message, comments)`` tuples