473,387 Members | 1,517 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Problem with mixing doctest with gettext _()

I have a problem writing self-testable modules using doctest when these
modules have internationalized strings using gettext _('...').

- The main module of an application (say app.py) calls gettext.install()
to install the special _ function inside Python builtin. Other modules,
taken from a general purpose collection of Python modules, also support
internationalisation and doctest testing.

For example:

utstring.py would contain some code like this:

def onOffStr(isOn) :
"""Return the "ON" string for True, "OFF" for False.

**Example**
onOffStr(True) u'ON' onOffStr(False) u'OFF'

"""
if isOn:
return _(u"ON") # notice the underscore
else:
return _(u"OFF")

The utstring module does not call any of the gettext calls, because some
other module does it when the application runs. So the doctest fails:

************************************************** ***************
Failure in example: onOffStr(True)
from line #4 of utstring.onOffStr
Exception raised:
Traceback (most recent call last):
File "C:\Python23\Lib\doctest.py", line 442, in _run_examples_inner
compileflags, 1) in globs
File "<string>", line 1, in ?
File "C:\dev\python\utstring.py", line 513, in onOffStr
return _(u"ON")
TypeError: 'tuple' object is not callable
************************************************** ***************

I tried to define a _() function when testing with the code below but
the doctest still fails. The following code is at the end of my
utstring.py module

def _test():
"""_test() perform docstring test"""

import doctest, utstring
return doctest.testmod(utstring)

if __name__ == "__main__":
def _(aString):
# dummy _() attempting to get doctest to pass.
return aString

_test()
----------

Does anyone know why the doctest still fails when I define the dummy _()
function?
Thanks in advance.

Pierre
Jul 18 '05 #1
14 2587

Pierre> I tried to define a _() function when testing with the code
Pierre> below but the doctest still fails. The following code is at the
Pierre> end of my utstring.py module
...

I suspect it's because your dummy _ is not in builtins. Why not just call
gettext.install() where you are currently defining _?

Skip

Jul 18 '05 #2
Skip Montanaro wrote:
Pierre> I tried to define a _() function when testing with the code
Pierre> below but the doctest still fails. The following code is at the
Pierre> end of my utstring.py module
...

I suspect it's because your dummy _ is not in builtins. Why not just call
gettext.install() where you are currently defining _?


Skip, this looks like the way to go.

I was trying to avoid it because the translation files for these library
modules are constructed at the application level somewhere else. But I
was also considering creating a translation library for these module, so
I guess that is one more incentive to do so...

Thanks

Pierre

Jul 18 '05 #3
I suspect it's because your dummy _ is not in builtins. Why not just
call gettext.install() where you are currently defining _?
Pierre> Skip, this looks like the way to go.

Pierre> I was trying to avoid it because the translation files for these
Pierre> library modules are constructed at the application level
Pierre> somewhere else. But I was also considering creating a
Pierre> translation library for these module, so I guess that is one
Pierre> more incentive to do so...

If you really want a dummy _() you can also stuff your version into
builtins:
import __builtin__
def foo(s): return s ... __builtin__._ = foo
_ <function foo at 0x1d6670> _("hi")

'hi'

Skip

Jul 18 '05 #4
Skip Montanaro wrote:


If you really want a dummy _() you can also stuff your version into
builtins:
>>> import __builtin__
>>> def foo(s): return s ... >>> __builtin__._ = foo
>>> _ <function foo at 0x1d6670> >>> _("hi") 'hi'


I tried that, but it only works for the first call...

[Shell buffer started: python.exe]
Python 2.3.3 (#51, Dec 18 2003, 20:22:39) [MSC v.1200 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
import __builtin__
def foo(s): return s .... __builtin__._ = foo
_ <function foo at 0x008F98B0> _ <function foo at 0x008F98B0> _('hi') 'hi' _ 'hi' _('Hello') Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: 'str' object is not callable

Pierre

Jul 18 '05 #5
Pierre Rouleau wrote:
Skip Montanaro wrote:
If you really want a dummy _() you can also stuff your version into
builtins:
>>> import __builtin__
>>> def foo(s): return s

...
>>> __builtin__._ = foo
>>> _

<function foo at 0x1d6670>
>>> _("hi")

'hi'


I tried that, but it only works for the first call...


Setting __builtin__._ to the result of the last calculation is a side effect
of sys.displayhook. Therefore you need to change that too:

Python 2.3.3 (#1, Jan 3 2004, 13:57:08)
[GCC 3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
import sys
def mydisplayhook(a): .... if a is not None: sys.stdout.write("%r\n" % a)
.... def foo(s): return s .... sys.displayhook = mydisplayhook
import __builtin__
__builtin__._ = foo
_("hi") 'hi' _("hello") 'hello'


Peter
Jul 18 '05 #6
Pierre Rouleau wrote:
Skip Montanaro wrote:
Pierre> I tried to define a _() function when testing with the code
Pierre> below but the doctest still fails. The following code is
at the
Pierre> end of my utstring.py module
...

I suspect it's because your dummy _ is not in builtins. Why not just
call
gettext.install() where you are currently defining _?


Skip, this looks like the way to go.

I was trying to avoid it because the translation files for these library
modules are constructed at the application level somewhere else. But I
was also considering creating a translation library for these module, so
I guess that is one more incentive to do so...


I implemented the dictionary and use it in the code just fine, but the
doctest still fails :(

My teststr.py module is:

#--[---------------------------------------------------------------
if __name__ == "__main__":
# install gettext for testing this module because of the string
translation
# performed in the code.
import gettext
gettext.install('impathpl', './locale', unicode=False)
presLan_en = gettext.translation('impathpl', "./locale",
languages=['en'])
presLan_en.install()

def onOffStr(isOn) :
"""Return the "ON" string for True, "OFF" for False.

**Example**
onOffStr(True) 'ON' onOffStr(False) 'OFF' """
if isOn:
return _("ON")
else:
return _("OFF")
def _test():
"""_test() perform docstring test"""

import doctest, teststr
return doctest.testmod(teststr)

if __name__ == "__main__":
_test()

#--]-------------------------------------------------
Running the following script shows that the module runs OK:

[Shell buffer started: python.exe]
Python 2.3.3 (#51, Dec 18 2003, 20:22:39) [MSC v.1200 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information. import teststr
import gettext
gettext.install('impathpl', './locale', unicode=False)
presLan_en = gettext.translation('impathpl', "./locale", languages=['en']) presLan_en.install()
teststr.onOffStr(True) 'ON'

BUT, the doctest fails:

D:\dev\python>teststr
************************************************** ***************
Failure in example: onOffStr(False)
from line #6 of teststr.onOffStr
Exception raised:
Traceback (most recent call last):
File "c:\Python23\lib\doctest.py", line 442, in _run_examples_inner
compileflags, 1) in globs
File "<string>", line 1, in ?
File "teststr.py", line 23, in onOffStr
return _("OFF")
TypeError: 'str' object is not callable
************************************************** ***************
1 items had failures:
1 of 2 in teststr.onOffStr
***Test Failed*** 1 failures.
I'm still puzzled...

Pierre
Jul 18 '05 #7
Peter Otten wrote:
Pierre Rouleau wrote:

Skip Montanaro wrote:

If you really want a dummy _() you can also stuff your version into
builtins:

>>> import __builtin__
>>> def foo(s): return s
...
>>> __builtin__._ = foo
>>> _
<function foo at 0x1d6670>
>>> _("hi")
'hi'


I tried that, but it only works for the first call...

Setting __builtin__._ to the result of the last calculation is a side effect
of sys.displayhook. Therefore you need to change that too:

Python 2.3.3 (#1, Jan 3 2004, 13:57:08)
[GCC 3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
import sys
def mydisplayhook(a):
... if a is not None: sys.stdout.write("%r\n" % a)
...
def foo(s): return s
...
sys.displayhook = mydisplayhook
import __builtin__
__builtin__._ = foo
_("hi")
'hi'
_("hello")


'hello'


Thanks Peter, it does work!
Jul 18 '05 #8

Pierre> BUT, the doctest fails:
...

Looks like Peter Otten's sys.displayhook hack is required for doctest.

Skip

Jul 18 '05 #9

Pierre> I tried that, but it only works for the first call...

:-)

Pierre> [Shell buffer started: python.exe]
Pierre> Python 2.3.3 (#51, Dec 18 2003, 20:22:39) [MSC v.1200 32 bit (Intel)] on
Pierre> win32
Pierre> Type "help", "copyright", "credits" or "license" for more information.
import __builtin__
def foo(s): return s Pierre> ... __builtin__._ = foo
_ Pierre> <function foo at 0x008F98B0> _ Pierre> <function foo at 0x008F98B0> _('hi') Pierre> 'hi' _ Pierre> 'hi' _('Hello') Pierre> Traceback (most recent call last):
Pierre> File "<stdin>", line 1, in ?
Pierre> TypeError: 'str' object is not callable


That's true. In interactive mode _ is assigned the value of the last
expression evaluated. Try it from a script.

Skip

Jul 18 '05 #10
Pierre Rouleau wrote:
Peter Otten wrote:
Pierre Rouleau wrote:

Skip Montanaro wrote:
If you really want a dummy _() you can also stuff your version into
builtins:

>>> import __builtin__
>>> def foo(s): return s
...
>>> __builtin__._ = foo
>>> _
<function foo at 0x1d6670>
>>> _("hi")
'hi'
I tried that, but it only works for the first call...


Setting __builtin__._ to the result of the last calculation is a side
effect
of sys.displayhook. Therefore you need to change that too:

Python 2.3.3 (#1, Jan 3 2004, 13:57:08)
[GCC 3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
> import sys
> def mydisplayhook(a):

... if a is not None: sys.stdout.write("%r\n" % a)
...
> def foo(s): return s

...
> sys.displayhook = mydisplayhook
> import __builtin__
> __builtin__._ = foo
> _("hi")

'hi'
> _("hello")

'hello'


Thanks Peter, it does work!

It worked, BUT only for a simple function, it fails if I add a another
simple function:

My updated teststr.py script:

#--[--------------------------------------
def onOffStr(isOn) :
"""Return the "ON" string for True, "OFF" for False.

**Example**
onOffStr(True) u'ON' onOffStr(False) u'OFF' """
if isOn:
return _(u"ON")
else:
return _(u"OFF")
def inList(longString, stringList) :
"""Return True if one of the string in `stringList` is inside
`longString`.

Also return the list index.
**Example**
L = ["**", "/*"]
inList("aksdkajshd",L) (False, 0) inList("aksdkajsh**d",L)

(True, 0)

"""

theIndex = 0
for theStr in stringList:
if longString.find(theStr) >= 0:
return (True,theIndex)
theIndex +=1
return (False,0)
def _test():
"""_test() perform docstring test"""

import doctest, teststr
return doctest.testmod(teststr)

if __name__ == "__main__":
import sys

def test_displayhook(a):
if a is not None: sys.stdout.write("%r\n" % a)

def test_translator(aString):
return aString

sys.displayhook = test_displayhook

import __builtin__
__builtin__._ = test_translator
_test()

#--]--------------------------------------

Running the test fails:

D:\dev\python>teststr
************************************************** ***************
Failure in example: inList("aksdkajshd",L)
from line #6 of teststr.inList
Exception raised:
Traceback (most recent call last):
File "c:\Python23\lib\doctest.py", line 442, in _run_examples_inner
compileflags, 1) in globs
File "<string>", line 1, in ?
File "D:\dev\python\teststr.py", line 50, in test_displayhook
if a is not None: sys.stdout.write("%r\n" % a)
TypeError: not all arguments converted during string formatting
************************************************** ***************
Failure in example: inList("aksdkajsh**d",L)
from line #8 of teststr.inList
Exception raised:
Traceback (most recent call last):
File "c:\Python23\lib\doctest.py", line 442, in _run_examples_inner
compileflags, 1) in globs
File "<string>", line 1, in ?
File "D:\dev\python\teststr.py", line 50, in test_displayhook
if a is not None: sys.stdout.write("%r\n" % a)
TypeError: not all arguments converted during string formatting
************************************************** ***************
1 items had failures:
2 of 3 in teststr.inList
***Test Failed*** 2 failures.

#------------------------------------------

So far, I don't have a solution for writing internationalized Python
that support doctest. Surely, I am not the first one trying to do that...
Pierre

Jul 18 '05 #11
Pierre Rouleau wrote:
It worked, BUT only for a simple function, it fails if I add a another
simple function:


Haven't read your post completely, but judging from the error message, it's
just a minor glitch in mydisplayhook(). Try the following instead:

def mydisplayhook(a):

.... if a is not None:
.... sys.stdout.write("%r\n" % (a,))
....

That should be able to cope with tuples as commandline results.

Peter
Jul 18 '05 #12
Peter Otten wrote:
Pierre Rouleau wrote:

It worked, BUT only for a simple function, it fails if I add a another
simple function:

Haven't read your post completely, but judging from the error message, it's
just a minor glitch in mydisplayhook(). Try the following instead:
def mydisplayhook(a):


... if a is not None:
... sys.stdout.write("%r\n" % (a,))
...

That should be able to cope with tuples as commandline results.

Peter

You're right! It does work. I must admit, that I don't see why though.
(a,) makes a tuple out of the `a` argument. Does the %r conversion
require a tuple?
Jul 18 '05 #13
Pierre Rouleau wrote:
Peter Otten wrote:
Pierre Rouleau wrote:

It worked, BUT only for a simple function, it fails if I add a another
simple function:

Haven't read your post completely, but judging from the error message,
it's just a minor glitch in mydisplayhook(). Try the following instead:
>def mydisplayhook(a):


... if a is not None:
... sys.stdout.write("%r\n" % (a,))
...

That should be able to cope with tuples as commandline results.

Peter

You're right! It does work. I must admit, that I don't see why though.
(a,) makes a tuple out of the `a` argument. Does the %r conversion
require a tuple?


The formatting operator behaves differently depending on whether the
righthand argument is a tuple or something else.

formatstr % tuple

ensures that there is a corresponding format expression - e.g. "%s" or "%d"
- for every item in the tuple, whereas

formatstr % nontuple

expects exactly one format expression. Therefore

"%r\n" % a

raises an exception when a is a tuple with more or less than one item and
wrongly prints the item's representation instead of the tuple's for
one-tuples.
Wrapping it like so (a,) fixes the problem because now we have always a
tuple with one item - where this item is sometimes a tuple.

An alternative approach would be to ensure that the righthand side is always
a nontuple:

"%s\n" % repr(a)

Peter

Jul 18 '05 #14


You're right! It does work. I must admit, that I don't see why though.
(a,) makes a tuple out of the `a` argument. Does the %r conversion
require a tuple?

The formatting operator behaves differently depending on whether the
righthand argument is a tuple or something else.

formatstr % tuple

ensures that there is a corresponding format expression - e.g. "%s" or "%d"
- for every item in the tuple, whereas

formatstr % nontuple

expects exactly one format expression. Therefore

"%r\n" % a

raises an exception when a is a tuple with more or less than one item and
wrongly prints the item's representation instead of the tuple's for
one-tuples.
Wrapping it like so (a,) fixes the problem because now we have always a
tuple with one item - where this item is sometimes a tuple.

An alternative approach would be to ensure that the righthand side is always
a nontuple:

"%s\n" % repr(a)


Thanks for this clear explanation!

Pierre
Jul 18 '05 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Alan G Isaac | last post by:
> python doctest.py -v Running doctest.__doc__ Trying: .remove(42) Expecting: Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: list.remove(x): x not in list ok...
5
by: Michele Simionato | last post by:
I am getting a strange error with this script: $ cat doctest-threads.py """ >>> import time, threading >>> def example(): .... thread.out = .... while thread.running: .... ...
1
by: Runsun Pan | last post by:
I intend to use the doctect heavily. For this I am thinking of coding a class that comes with a built-in doctest functionality. I'd like to seek for input before I start. The idea is to have a...
2
by: p.lavarre | last post by:
From: http://docs.python.org/lib/doctest-soapbox.html ... Can I somehow tell doctest that it's time to quit? I ask because not all doctest examples are created equal. Some failures are...
1
by: Stuart D. Gathman | last post by:
I am trying to create a doctest test case for the following: def quote_value(s): """Quote the value for a key-value pair in Received-SPF header field if needed. No quoting needed for a dot-atom...
0
by: Eric Mahurin | last post by:
Noob here. Just got into python a little over a week ago... One of the (unique?) things I really like about python is the concept of doctesting. But, now I want more! Here's what I'd like to...
2
by: jiang.haiyun | last post by:
Hi, I am having some serious problems with PyQT4, when i run pyqt script, I always get 'Segmentation fault'. the script is simple: ====================== %less qttest.py from PyQt4 import...
6
by: =?iso-8859-1?B?QW5kcuk=?= | last post by:
I've encountered a problem using gettext with properties while using a Python interpreter. Here's a simple program that illustrate the problem. ============== # i18n_test.py: test of gettext &...
6
by: Bzyczek | last post by:
Hello, I have problems with running doctests if I use czech national characters in UTF-8 encoding. I have Python script, which begin with encoding definition: # -*- coding: utf-8 -*- I...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.