1- #! /usr/bin/env python
1+ #! /usr/bin/env python2.5
2+ # -*- coding: iso-8859-1 -*-
23# Originally written by Barry Warsaw <[email protected] > 34#
4- # Minimally patched to make it even more xgettext compatible
5+ # Minimally patched to make it even more xgettext compatible
56# by Peter Funk <[email protected] > 67#
7- # 2001-12-18 Jürgen Hermann <[email protected] > 8+ # 2002-11-22 Jürgen Hermann <[email protected] > 89# Added checks that _() only contains string literals, and
910# command line args are resolved to module lists, i.e. you
1011# can now pass a filename, a module or package name, or a
2425Many systems (Solaris, Linux, Gnu) provide extensive tools that ease the
2526internationalization of C programs. Most of these tools are independent of
2627the programming language and can be used from within Python programs.
27- Martin von Loewis' work[1] helps considerably in this regard.
28+ Martin von Loewis' work[1] helps considerably in this regard.
2829
2930There's one problem though; xgettext is the program that scans source code
3031looking for message strings, but it groks only C (or C++). Python
3132introduces a few wrinkles, such as dual quoting characters, triple quoted
32- strings, and raw strings. xgettext understands none of this.
33+ strings, and raw strings. xgettext understands none of this.
3334
3435Enter pygettext, which uses Python's standard tokenize module to scan
3536Python source code, generating .pot files identical to what GNU xgettext[2]
3637generates for C and C++ code. From there, the standard GNU tools can be
37- used.
38+ used.
3839
3940A word about marking Python strings as candidates for translation. GNU
4041xgettext recognizes the following keywords: gettext, dgettext, dcgettext,
4142and gettext_noop. But those can be a lot of text to include all over your
4243code. C and C++ have a trick: they use the C preprocessor. Most
4344internationalized C source includes a #define for gettext() to _() so that
4445what has to be written in the source is much less. Thus these are both
45- translatable strings:
46+ translatable strings:
4647
4748 gettext("Translatable String")
4849 _("Translatable String")
5859xgettext where ever possible. However some options are still missing or are
5960not fully implemented. Also, xgettext's use of command line switches with
6061option arguments is broken, and in these cases, pygettext just defines
61- additional switches.
62+ additional switches.
6263
6364Usage: pygettext [options] inputfile ...
6465
155156""" )
156157
157158import os
159+ import imp
158160import sys
161+ import glob
159162import time
160163import getopt
161164import token
@@ -255,40 +258,36 @@ def normalize(s):
255258
256259
257260def containsAny (str , set ):
258- """ Check whether 'str' contains ANY of the chars in 'set'
259- """
261+ """Check whether 'str' contains ANY of the chars in 'set'"""
260262 return 1 in [c in str for c in set ]
261263
262264
263265def _visit_pyfiles (list , dirname , names ):
264- """ Helper for getFilesForName().
265- """
266+ """Helper for getFilesForName()."""
266267 # get extension for python source files
267268 if not globals ().has_key ('_py_ext' ):
268- import imp
269269 global _py_ext
270- _py_ext = [triple [0 ] for triple in imp .get_suffixes () if triple [2 ] == imp .PY_SOURCE ][0 ]
270+ _py_ext = [triple [0 ] for triple in imp .get_suffixes ()
271+ if triple [2 ] == imp .PY_SOURCE ][0 ]
271272
272273 # don't recurse into CVS directories
273274 if 'CVS' in names :
274275 names .remove ('CVS' )
275276
276277 # add all *.py files to list
277278 list .extend (
278- [os .path .join (dirname , file )
279- for file in names
280- if os . path . splitext ( file )[ 1 ] == _py_ext ] )
279+ [os .path .join (dirname , file ) for file in names
280+ if os . path . splitext ( file )[ 1 ] == _py_ext ]
281+ )
281282
282283
283284def _get_modpkg_path (dotted_name , pathlist = None ):
284- """ Get the filesystem path for a module or a package.
285+ """Get the filesystem path for a module or a package.
285286
286- Return the file system path to a file for a module,
287- and to a directory for a package. Return None if
288- the name is not found, or is a builtin or extension module.
287+ Return the file system path to a file for a module, and to a directory for
288+ a package. Return None if the name is not found, or is a builtin or
289+ extension module.
289290 """
290- import imp
291-
292291 # split off top-most name
293292 parts = dotted_name .split ('.' , 1 )
294293
@@ -309,8 +308,10 @@ def _get_modpkg_path(dotted_name, pathlist=None):
309308 else :
310309 # plain name
311310 try :
312- file , pathname , description = imp .find_module (dotted_name , pathlist )
313- if file : file .close ()
311+ file , pathname , description = imp .find_module (
312+ dotted_name , pathlist )
313+ if file :
314+ file .close ()
314315 if description [2 ] not in [imp .PY_SOURCE , imp .PKG_DIRECTORY ]:
315316 pathname = None
316317 except ImportError :
@@ -320,15 +321,12 @@ def _get_modpkg_path(dotted_name, pathlist=None):
320321
321322
322323def getFilesForName (name ):
323- """ Get a list of module files for a filename, a module or package name,
324- or a directory.
324+ """Get a list of module files for a filename, a module or package name,
325+ or a directory.
325326 """
326- import imp
327-
328327 if not os .path .exists (name ):
329328 # check for glob chars
330329 if containsAny (name , "*?[]" ):
331- import glob
332330 files = glob .glob (name )
333331 list = []
334332 for file in files :
@@ -414,7 +412,7 @@ def __keywordseen(self, ttype, tstring, lineno):
414412 def __openseen (self , ttype , tstring , lineno ):
415413 if ttype == tokenize .OP and tstring == ')' :
416414 # We've seen the last of the translatable strings. Record the
417- # line number of the first line of the strings and update the list
415+ # line number of the first line of the strings and update the list
418416 # of messages seen. Reset state for the next batch. If there
419417 # were no strings inside _(), then just ignore this entry.
420418 if self .__data :
@@ -425,8 +423,13 @@ def __openseen(self, ttype, tstring, lineno):
425423 elif ttype not in [tokenize .COMMENT , token .INDENT , token .DEDENT ,
426424 token .NEWLINE , tokenize .NL ]:
427425 # warn if we see anything else than STRING or whitespace
428- print >> sys .stderr , _ ('*** %(file)s:%(lineno)s: Seen unexpected token "%(token)s"' ) % {
429- 'token' : tstring , 'file' : self .__curfile , 'lineno' : self .__lineno }
426+ print >> sys .stderr , _ (
427+ '*** %(file)s:%(lineno)s: Seen unexpected token "%(token)s"'
428+ ) % {
429+ 'token' : tstring ,
430+ 'file' : self .__curfile ,
431+ 'lineno' : self .__lineno
432+ }
430433 self .__state = self .__waiting
431434
432435 def __addentry (self , msg , lineno = None , isdocstring = 0 ):
@@ -442,7 +445,7 @@ def set_filename(self, filename):
442445
443446 def write (self , fp ):
444447 options = self .__options
445- timestamp = time .ctime ( time . time () )
448+ timestamp = time .strftime ( '%Y-%m-%d %H:%M+%Z' )
446449 # The time stamp in the header doesn't have the same format as that
447450 # generated by xgettext...
448451 print >> fp , pot_header % {'time' : timestamp , 'version' : __version__ }
@@ -661,6 +664,6 @@ class Options:
661664 main ()
662665 # some more test strings
663666 _ (u'a unicode string' )
664- _ ('*** Seen unexpected token "%(token)s"' % {'token' : 'test' }) # this one creates a warning
667+ # this one creates a warning
668+ _ ('*** Seen unexpected token "%(token)s"' ) % {'token' : 'test' }
665669 _ ('more' 'than' 'one' 'string' )
666-
0 commit comments