Discussion:
Mystery: wx.grid, a filter function, and Unicode
Bob Klahn
2008-01-03 05:52:31 UTC
Permalink
Here's a character-filter-generating function (a minor variation
of a recipe in "Python Cookbook" section 1.10) that I'm using in one
of my applications:

def makefilter( chars, delete=True ):
"""
Given a string of plain characters to (a) keep or (b) delete,
build a filtering function that, applied to any string s,
returns a copy of s containing
(a) only the characters to be kept, or
(b) all but the characters to be deleted.
"""
import string
allchars = string.maketrans('','')
if delete: delchars = chars
else: delchars = allchars.translate(allchars, chars)
def thefilter(s):
return s.translate(allchars, delchars)
return thefilter

I'm using the above function inside a wx.grid cell renderer:

class CellRenderer(gridlib.PyGridCellRenderer):
def __init__(self):
gridlib.PyGridCellRenderer.__init__(self)
self.filter = utils.makefilter('{}\x08\x0C',delete=True)

The problem: When the cell renderer executes and the filter is
invoked (e.g., as self.filter(word) ), it fails on the
return s.translate(allchars, delchars)
line in makefilter:
TypeError: translate() takes exactly one argument (2 given)

I.e, Python thinks that string s is a Unicode string. But I'm not
using Unicode strings anywhere! Any ideas where wxPython might be
changing my plain strings into Unicode strings? I'm not able to
provide a simple code example.

Filters generated by makefilter work perfectly outside of my wxPython
application.

Bob
Bob Klahn
2008-01-03 06:11:23 UTC
Permalink
(This is the same note I sent a few minutes ago, but with a P.S.
identifying my wxPython/Python/OS versions.)

Here's a character-filter-generating function (a minor variation
of a recipe in "Python Cookbook" section 1.10) that I'm using in one
of my applications:

def makefilter( chars, delete=True ):
"""
Given a string of plain characters to (a) keep or (b) delete,
build a filtering function that, applied to any string s,
returns a copy of s containing
(a) only the characters to be kept, or
(b) all but the characters to be deleted.
"""
import string
allchars = string.maketrans('','')
if delete: delchars = chars
else: delchars = allchars.translate(allchars, chars)
def thefilter(s):
return s.translate(allchars, delchars)
return thefilter

I'm using the above function inside a wx.grid cell renderer:

class CellRenderer(gridlib.PyGridCellRenderer):
def __init__(self):
gridlib.PyGridCellRenderer.__init__(self)
self.filter = utils.makefilter('{}\x08\x0C',delete=True)

The problem: When the cell renderer executes and the filter is
invoked (e.g., as self.filter(word) ), it fails on the
return s.translate(allchars, delchars)
line in makefilter:
TypeError: translate() takes exactly one argument (2 given)

I.e, Python thinks that string s is a Unicode string. But I'm not
using Unicode strings anywhere! Any ideas where wxPython might be
changing my plain strings into Unicode strings? I'm not able to
provide a simple code example.

Filters generated by makefilter work perfectly outside of my wxPython
application.

Bob

P.S. I'm using wxPython 2.8.4.0 with Python 2.5.1 under Windows XP SP2.
Marc Tompkins
2008-01-03 06:52:27 UTC
Permalink
I may be naive here, but isn't it possible that the error means exactly what
it says: translate() takes one argument, and you're calling it with two :
s.translate(allchars, delchars)

I agree that the exception's being called a "TypeError" is a bit misleading
- I would have called it a ParameterError or ArgumentError, maybe.

On Jan 2, 2008 10:11 PM, Bob Klahn <***@comcast.net> wrote:

> (This is the same note I sent a few minutes ago, but with a P.S.
> identifying my wxPython/Python/OS versions.)
>
>
> Here's a character-filter-generating function (a minor variation of a
> recipe in "Python Cookbook" section 1.10) that I'm using in one of my
> applications:
>
> def makefilter( chars, delete=True ):
> """
> Given a string of plain characters to (a) keep or (b) delete,
> build a filtering function that, applied to any string s,
> returns a copy of s containing
> (a) only the characters to be kept, or
> (b) all but the characters to be deleted.
> """
> import string
> allchars = string.maketrans('','')
> if delete: delchars = chars
> else: delchars = allchars.translate(allchars, chars)
> def thefilter(s):
> return s.translate(allchars, delchars)
> return thefilter
>
> I'm using the above function inside a wx.grid cell renderer:
>
> class CellRenderer(gridlib.PyGridCellRenderer):
> def __init__(self):
> gridlib.PyGridCellRenderer.__init__(self)
> self.filter = utils.makefilter('{}\x08\x0C',delete=True)
>
> The problem: When the cell renderer executes and the filter is invoked (
> e.g., as self.filter(word) ), it fails on the
> return s.translate(allchars, delchars)
> line in makefilter:
> TypeError: translate() takes exactly one argument (2 given)
>
> I.e, Python thinks that string s is a Unicode string. But I'm not using
> Unicode strings anywhere! Any ideas where wxPython might be changing my
> plain strings into Unicode strings? I'm not able to provide a simple code
> example.
>
> Filters generated by makefilter work perfectly outside of my wxPython
> application.
>
> Bob
>
> P.S. I'm using wxPython 2.8.4.0 with Python 2.5.1 under Windows XP SP2.
>
>
>


--
www.fsrtechnologies.com
Bob Klahn
2008-01-03 13:53:07 UTC
Permalink
No, Marc, it's not possible. translate takes two arguments when used
with plain strings, and one argument when used with Unicode strings.

As I said, filters generated by makefilter work perfectly outside of
my wxPython application.

Bob

At 01:52 AM 1/3/2008, Marc wrote:
>I may be naive here, but isn't it possible that the error means
>exactly what it says: translate() takes one argument, and you're
>calling it with two : s.translate(allchars, delchars)
>
>I agree that the exception's being called a "TypeError" is a bit
>misleading - I would have called it a ParameterError or ArgumentError, maybe.
>
>On Jan 2, 2008 10:11 PM, Bob Klahn
><<mailto:***@comcast.net>***@comcast.net> wrote:
>(This is the same note I sent a few minutes ago, but with a P.S.
>identifying my wxPython/Python/OS versions.)
>
>
>Here's a character-filter-generating function (a minor variation
>of a recipe in "Python Cookbook" section 1.10) that I'm using in
>one of my applications:
>
> def makefilter( chars, delete=True ):
> """
> Given a string of plain characters to (a) keep or (b) delete,
> build a filtering function that, applied to any string s,
> returns a copy of s containing
> (a) only the characters to be kept, or
> (b) all but the characters to be deleted.
> """
> import string
> allchars = string.maketrans('','')
> if delete: delchars = chars
> else: delchars = allchars.translate(allchars, chars)
> def thefilter(s):
> return s.translate(allchars, delchars)
> return thefilter
>
>I'm using the above function inside a wx.grid cell renderer:
>
> class CellRenderer(gridlib.PyGridCellRenderer):
> def __init__(self):
> gridlib.PyGridCellRenderer.__init__(self)
> self.filter = utils.makefilter('{}\x08\x0C',delete=True)
>
>The problem: When the cell renderer executes and the filter is
>invoked (e.g., as self.filter(word) ), it fails on the
> return s.translate(allchars, delchars)
>line in makefilter:
> TypeError: translate() takes exactly one argument (2 given)
>
>I.e, Python thinks that string s is a Unicode string. But I'm not
>using Unicode strings anywhere! Any ideas where wxPython might be
>changing my plain strings into Unicode strings? I'm not able to
>provide a simple code example.
>
>Filters generated by makefilter work perfectly outside of my
>wxPython application.
>
>Bob
>
>P.S. I'm using wxPython <http://2.8.4.0>2.8.4.0 with Python 2.5.1
>under Windows XP SP2.
>
>
>
>
>
>--
><http://www.fsrtechnologies.com>www.fsrtechnologies.com
>No virus found in this incoming message.
>Checked by AVG Free Edition.
>Version: 7.5.516 / Virus Database: 269.17.13/1207 - Release Date:
>1/2/2008 11:29 AM
Christian K.
2008-01-03 15:04:11 UTC
Permalink
Bob Klahn wrote:
> No, Marc, it's not possible. translate takes two arguments when used
> with plain strings, and one argument when used with Unicode strings.
>
> As I said, filters generated by makefilter work perfectly outside of my
> wxPython application.

wxPython unicode handles all strings as unicode internally. I can't tell
you exactly where the conversion takes place as you didn't show the
complete grid code. I guess that even if you handle all the underlying
data in your own TableBase class, you cannot avoid to receive unicode
strings from the gui when a value has been entered in a grid cell. You
could try to convert them to string in your own SetCellValue method.
Then the GridCellRenderer should pick up the string values.

Christian
Robin Dunn
2008-01-03 17:50:19 UTC
Permalink
Bob Klahn wrote:

> I'm using the above function inside a wx.grid cell renderer:
>
> class CellRenderer(gridlib.PyGridCellRenderer):
> def __init__(self):
> gridlib.PyGridCellRenderer.__init__(self)
> self.filter = utils.makefilter('{}\x08\x0C',delete=True)
>
> The problem: When the cell renderer executes and the filter is invoked
> (e.g., as self.filter(word) ), it fails on the
> return s.translate(allchars, delchars)
> line in makefilter:
> TypeError: translate() takes exactly one argument (2 given)
>
> I.e, Python thinks that string s is a Unicode string. But I'm not using
> Unicode strings anywhere! Any ideas where wxPython might be changing my
> plain strings into Unicode strings? I'm not able to provide a simple
> code example.
>
> Filters generated by makefilter work perfectly outside of my wxPython
> application.

Where does word come from? Have you checked it's type?
http://wiki.wxpython.org/UnicodeBuild


--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!
Bob Klahn
2008-01-03 19:43:25 UTC
Permalink
At 12:50 PM 1/3/2008, Robin wrote:
>Bob Klahn wrote:
>
>>I'm using the above function inside a wx.grid cell renderer:
>> class CellRenderer(gridlib.PyGridCellRenderer):
>> def __init__(self):
>> gridlib.PyGridCellRenderer.__init__(self)
>> self.filter = utils.makefilter('{}\x08\x0C',delete=True)
>>
>>The problem: When the cell renderer executes
>>and the filter is invoked (e.g., as self.filter(word) ), it fails on the
>> return s.translate(allchars, delchars)
>>line in makefilter:
>> TypeError: translate() takes exactly one argument (2 given)
>>I.e, Python thinks that string s is a Unicode
>>string. But I'm not using Unicode strings
>>anywhere! Any ideas where wxPython might be
>>changing my plain strings into Unicode
>>strings? I'm not able to provide a simple code example.
>>Filters generated by makefilter work perfectly
>>outside of my wxPython application.
>
>Where does word come from? Have you checked
>it's type? http://wiki.wxpython.org/UnicodeBuild

The overall problem: The external data I need to
read in and write out is the "extended ASCII" seen here:
http://www.cdrummond.qc.ca/cegep/informat/Professeurs/Alain/files/ascii.htm

Included in this external data are a number of
accented characters, vertical lines
(extended-ASCII B3), and broken bars (extended-ASCII 7C).

How should I be dealing with this data? E.g.,
none of the codecs I've tried can handle the
vertical-line data. When I try to do so, e.g.,
using utf-8, the error message
"UnicodeDecodeError: 'utf8' codec can't decode
byte 0xb3 in position 18: unexpected code byte" is returned.

How should I handle phrases such as "Déjà
vu"? Externally, the é and à are recorded as hex
82 and hex 85 respectively; internally, they
should presumably be hex E9 and hex E0
respectively. How do I get "Déjà vu" back from
Unicode to extended ASCII? All of the encode
methods I've applied to Unicode string "Déjà vu"
(e.g., latin1, ISO-8859-1, utf-8, utf-16) fail.

Clearly I'm Unicode-challenged. Spoon-feeding
needed! To whomever: If you give this a shot,
please make sure your code can handle both the
accented characters and the vertical lines and broken bars.

Bob
Loading...