* Fixed copyright year in a couple of file headers.
* Some cleanup.
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2006 Edgewall Software
+# Copyright (C) 2007 Edgewall Software
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
from babel.core import *
__docformat__ = 'restructuredtext en'
-__version__ = __import__('pkg_resources').get_distribution('Babel').version
+try:
+ __version__ = __import__('pkg_resources').get_distribution('Babel').version
+except ImportError:
+ pass
"""
import os
-from pkg_resources import working_set
import sys
from tokenize import generate_tokens, NAME, OP, STRING
GROUP_NAME = 'babel.extractors'
-KEYWORDS = {
+DEFAULT_KEYWORDS = {
'_': None,
'gettext': None,
'ngettext': (1, 2),
}
-def extract_from_dir(dirname, mapping=DEFAULT_MAPPING, keywords=KEYWORDS,
- options=None):
+def extract_from_dir(dirname, mapping=DEFAULT_MAPPING,
+ keywords=DEFAULT_KEYWORDS, options=None):
"""Extract messages from any source files found in the given directory.
This function generates tuples of the form:
:param dirname: the path to the directory to extract messages from
:param mapping: a mapping of extraction method names to extended glob
patterns
- :param keywords: a list of keywords (i.e. function names) that should be
- recognized as translation functions
+ :param keywords: a dictionary mapping keywords (i.e. names of functions
+ that should be recognized as translation functions) to
+ tuples that specify which of their arguments contain
+ localizable strings
:param options: a dictionary of additional options (optional)
:return: an iterator over ``(filename, lineno, funcname, message)`` tuples
:rtype: ``iterator``
yield filename, line, func, key
extracted_files[filename] = True
-def extract_from_file(method, filename, keywords=KEYWORDS, options=None):
+def extract_from_file(method, filename, keywords=DEFAULT_KEYWORDS,
+ options=None):
"""Extract messages from a specific file.
This function returns a list of tuples of the form:
:param filename: the path to the file to extract messages from
:param method: a string specifying the extraction method (.e.g. "python")
- :param keywords: a list of keywords (i.e. function names) that should be
- recognized as translation functions
+ :param keywords: a dictionary mapping keywords (i.e. names of functions
+ that should be recognized as translation functions) to
+ tuples that specify which of their arguments contain
+ localizable strings
:param options: a dictionary of additional options (optional)
:return: the list of extracted messages
:rtype: `list`
finally:
fileobj.close()
-def extract(method, fileobj, keywords=KEYWORDS, options=None):
+def extract(method, fileobj, keywords=DEFAULT_KEYWORDS, options=None):
"""Extract messages from the given file-like object using the specified
extraction method.
:param method: a string specifying the extraction method (.e.g. "python")
: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 keywords: a dictionary mapping keywords (i.e. names of functions
+ that should be recognized as translation functions) to
+ tuples that specify which of their arguments contain
+ localizable strings
:param options: a dictionary of additional options (optional)
:return: the list of extracted messages
:rtype: `list`
:raise ValueError: if the extraction method is not registered
"""
+ from pkg_resources import working_set
+
for entry_point in working_set.iter_entry_points(GROUP_NAME, method):
func = entry_point.load(require=True)
m = []
for lineno, funcname, messages in func(fileobj, keywords.keys(),
options=options or {}):
if isinstance(messages, (list, tuple)):
- indices = keywords[funcname]
msgs = []
- for indice in indices:
- msgs.append(messages[indice-1])
+ for index in keywords[funcname]:
+ msgs.append(messages[index - 1])
messages = tuple(msgs)
if len(messages) == 1:
messages = messages[0]
yield lineno, funcname, messages
return
+
raise ValueError('Unknown extraction method %r' % method)
def extract_genshi(fileobj, keywords, options):
import sys
from babel import __version__ as VERSION
-from babel.catalog.extract import extract_from_dir, KEYWORDS
+from babel.catalog.extract import extract_from_dir, DEFAULT_KEYWORDS
from babel.catalog.pofile import write_po
__all__ = ['extract_messages', 'main']
'space-separated list of keywords to look for in addition to the '
'defaults'),
('no-default-keywords', None,
- 'do not include the default keywords defined by Babel'),
+ 'do not include the default keywords'),
('no-location', None,
'do not include location comments with filename and line number'),
('omit-header', None,
('output-file=', 'o',
'name of the output file'),
]
- boolean_options = ['no-location', 'omit-header', 'no-default-keywords']
+ boolean_options = ['no-default-keywords', 'no-location', 'omit-header']
def initialize_options(self):
self.charset = 'utf-8'
- self.keywords = KEYWORDS
+ self.keywords = DEFAULT_KEYWORDS.copy()
+ self.no_default_keywords = False
self.no_location = False
self.omit_header = False
self.output_file = None
self.input_dirs = None
- self.no_default_keywords = False
def finalize_options(self):
if not self.input_dirs:
self.input_dirs = dict.fromkeys([k.split('.',1)[0]
for k in self.distribution.packages
]).keys()
+ if self.no_default_keywords:
+ self.keywords = {}
if isinstance(self.keywords, basestring):
- new_keywords = [k.strip() for k in self.keywords.split()]
- self.keywords = build_gettext_functions(
- new_keywords,
- dont_include_default=self.no_default_keywords
- )
+ new_keywords = parse_keywords(self.keywords.split())
+ self.keywords.update(new_keywords)
def run(self):
outfile = open(self.output_file, 'w')
finally:
outfile.close()
-def build_gettext_functions(func_list=[], dont_include_default=False):
- """Build the gettext function to parse."""
- if dont_include_default:
- func_dict = {}
- else:
- func_dict = KEYWORDS
- for func in func_list:
- if func.find(':') != -1:
- func_name, func_args = func.split(':')
- else:
- func_name, func_args = func, None
- if not func_dict.has_key(func_name):
- if func_args:
- str_indexes = [(int(x) -1 ) for x in func_args.split(',')]
- else:
- str_indexes = None
- func_dict[func_name] = str_indexes
- return func_dict
-
def main(argv=sys.argv):
"""Command-line interface.
outfile = open(options.output, 'w')
else:
outfile = sys.stdout
-
- if options.no_default_keywords and not options.keywords:
- parser.error("you must pass keywords to disable the default ones")
- elif options.no_default_keywords and options.keywords:
- keywords = build_gettext_functions(options.keywords,
- dont_include_default=options.no_default_keywords)
- else:
- keywords = build_gettext_functions()
+
+ keywords = DEFAULT_KEYWORDS.copy()
+ if options.no_default_keywords:
+ if not options.keywords:
+ parser.error('you must specify new keywords if you disable the '
+ 'default ones')
+ keywords = {}
+ if options.keywords:
+ keywords.update(parse_keywords(options.keywords))
try:
messages = []
if options.output:
outfile.close()
+def parse_keywords(strings=[]):
+ """Parse keywords specifications from the given list of strings.
+
+ >>> kw = parse_keywords(['_', 'dgettext:2', 'dngettext:2,3'])
+ >>> for keyword, indices in sorted(kw.items()):
+ ... print (keyword, indices)
+ ('_', None)
+ ('dgettext', (2,))
+ ('dngettext', (2, 3))
+ """
+ keywords = {}
+ for string in strings:
+ if ':' in string:
+ funcname, indices = string.split(':')
+ else:
+ funcname, indices = string, None
+ if funcname not in keywords:
+ if indices:
+ indices = tuple([(int(x)) for x in indices.split(',')])
+ keywords[funcname] = indices
+ return keywords
+
if __name__ == '__main__':
main()
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2006 Edgewall Software
+# Copyright (C) 2007 Edgewall Software
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
import unittest
def suite():
- from babel.catalog.tests import extract, pofile
+ from babel.catalog.tests import extract, frontend, pofile
suite = unittest.TestSuite()
suite.addTest(extract.suite())
+ suite.addTest(frontend.suite())
suite.addTest(pofile.suite())
return suite
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2006 Edgewall Software
+# Copyright (C) 2007 Edgewall Software
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
--- /dev/null
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2007 Edgewall Software
+# All rights reserved.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at http://babel.edgewall.org/wiki/License.
+#
+# This software consists of voluntary contributions made by many
+# individuals. For the exact contribution history, see the revision
+# history and logs, available at http://babel.edgewall.org/log/.
+
+import doctest
+import unittest
+
+from babel.catalog import frontend
+
+def suite():
+ suite = unittest.TestSuite()
+ suite.addTest(doctest.DocTestSuite(frontend))
+ return suite
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2006 Edgewall Software
+# Copyright (C) 2007 Edgewall Software
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2006 Edgewall Software
+# Copyright (C) 2007 Edgewall Software
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
"""Core locale representation and locale data access gateway."""
+import os
import pickle
-from pkg_resources import resource_filename
try:
import threading
except ImportError:
def _data(self):
if self.__data is None:
- filename = resource_filename(__name__, 'localedata/%s.dat' % self)
+ filename = os.path.join(os.path.dirname(__file__),
+ 'localedata/%s.dat' % self)
fileobj = open(filename, 'rb')
try:
self.__data = pickle.load(fileobj)
:type: `dict`
""")
+ def decimal_formats(self):
+ return self._data['decimal_formats']
+ decimal_formats = property(decimal_formats, doc="""\
+ Locale patterns for decimal number formatting.
+
+ >>> Locale('en', 'US').decimal_formats[None]
+ <NumberPattern u'#,##0.###'>
+
+ :type: `dict`
+ """)
+
#{ Calendar Information and Date Formatting
def periods(self):
Locale patterns for date formatting.
>>> Locale('en', 'US').date_formats['short']
- <DateTimeFormatPattern u'M/d/yy'>
+ <DateTimePattern u'M/d/yy'>
>>> Locale('fr', 'FR').date_formats['long']
- <DateTimeFormatPattern u'd MMMM yyyy'>
+ <DateTimePattern u'd MMMM yyyy'>
:type: `dict`
""")
Locale patterns for time formatting.
>>> Locale('en', 'US').time_formats['short']
- <DateTimeFormatPattern u'h:mm a'>
+ <DateTimePattern u'h:mm a'>
>>> Locale('fr', 'FR').time_formats['long']
- <DateTimeFormatPattern u'HH:mm:ss z'>
-
- :type: `dict`
- """)
-
- def decimal_formats(self):
- return self._data['decimal_formats']
- decimal_formats = property(decimal_formats, doc="""\
- Locale patterns for decimal number formatting.
-
- > Locale('en', 'US').decimal_formats[None]
- <NumberFormatPattern u'#,##0.###'>
+ <DateTimePattern u'HH:mm:ss z'>
:type: `dict`
""")
format.
>>> get_date_format(locale='en_US')
- <DateTimeFormatPattern u'MMM d, yyyy'>
+ <DateTimePattern u'MMM d, yyyy'>
>>> get_date_format('full', locale='de_DE')
- <DateTimeFormatPattern u'EEEE, d. MMMM yyyy'>
+ <DateTimePattern u'EEEE, d. MMMM yyyy'>
:param format: the format to use, one of "full", "long", "medium", or
"short"
format.
>>> get_time_format(locale='en_US')
- <DateTimeFormatPattern u'h:mm:ss a'>
+ <DateTimePattern u'h:mm:ss a'>
>>> get_time_format('full', locale='de_DE')
- <DateTimeFormatPattern u"H:mm' Uhr 'z">
+ <DateTimePattern u"H:mm' Uhr 'z">
:param format: the format to use, one of "full", "long", "medium", or
"short"
raise NotImplementedError
-class DateTimeFormatPattern(object):
+class DateTimePattern(object):
def __init__(self, pattern, format):
self.pattern = pattern
:param pattern: the formatting pattern to parse
"""
- if type(pattern) is DateTimeFormatPattern:
+ if type(pattern) is DateTimePattern:
return pattern
result = []
elif charbuf:
append_chars()
- return DateTimeFormatPattern(pattern, u''.join(result))
+ return DateTimePattern(pattern, u''.join(result))
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2006 Edgewall Software
+# Copyright (C) 2007 Edgewall Software
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2006 Edgewall Software
+# Copyright (C) 2007 Edgewall Software
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2006 Edgewall Software
+# Copyright (C) 2007 Edgewall Software
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2006 Edgewall Software
+# Copyright (C) 2007 Edgewall Software
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2006 Edgewall Software
+# Copyright (C) 2007 Edgewall Software
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
table.summary { margin: .5em 0; }
table.summary tr.table-header { background: #f7f7f0; }
table.summary td.table-header { color: #666; font-weight: bold; }
+table.summary th.group-header { background: #f7f7f0; color: #666;
+ font-size: 90%; font-weight: bold; text-align: left;
+}
table.summary th, table.summary td { border: 1px solid #d7d7d7; }
table.summary th th, table.summary td td { border: none; }
table.summary td.summary table td { color: #666; font-size: 90%; }
# individuals. For the exact contribution history, see the revision
# history and logs, available at http://babel.edgewall.org/log/.
+from distutils.cmd import Command
import doctest
from glob import glob
import os
-from setuptools import find_packages, setup, Command
+try:
+ from setuptools import setup
+except ImportError:
+ from distutils.core import setup
import sys
'Programming Language :: Python',
'Topic :: Software Development :: Libraries :: Python Modules',
],
- packages = find_packages(exclude=['tests']),
+ packages = ['babel', 'babel.catalog'],
package_data = {'babel': ['localedata/*.dat']},
test_suite = 'babel.tests.suite',