PyDatagram Problem?

Hi all :blush:

In my online game
chat system

self.chatinput = DirectEntry(text="" , entryFont= ThaiFont,
def talk (self, textenters):
	pkg = PyDatagram()
        self.cWriter.send(pkg, self.Connection)

this code is work.
the problem is when I use another language(Thai language) on DirectEntry
PyDatagram can’t addString
and show output error like this

UnicodedEncodeError: ‘ascii’ codec can’t encode characters in position 0-4 ordinal not in range(128)

please help me
how to fix it? :cry:

might be due to a string in the pydatagramm not beeing able to hold unicode. but cant tell for sure.
i found some code on the net (i think it was from some coding cookingbook-solutions) similar to python’s pickle module which is able to pack entire lists with different content into a string. it’s just ways more secure and supports unicode. in your case you can simply throw in your unicode string and send the result.

from types import (
    IntType, TupleType, StringType,
    FloatType, LongType, ListType,
    DictType, NoneType, BooleanType, UnicodeType

from struct import pack, unpack
from cStringIO import StringIO
import zlib

class EncodeError(Exception): pass
class DecodeError(Exception): pass


protocol = {
    TupleType  :"T",
    ListType   :"L",
    DictType   :"D",
    LongType   :"B",
    IntType    :"I",
    FloatType  :"F",
    StringType :"S",
    NoneType   :"N",

encoder = {}
class register_encoder_for_type(object):
    """Registers an encoder function, for a type, in the global encoder dictionary."""
    def __init__(self, t):
        self.type = t
    def __call__(self, func):
        encoder[self.type] = func
        return func

#contains dictionary of decoding functions, where the dictionary key is the type prefix used.
decoder = {}
class register_decoder_for_type(object):
    """Registers a decoder function, for a prefix, in the global decoder dictionary."""
    def __init__(self, t):
        self.prefix = protocol[t]
    def __call__(self, func):
        decoder[self.prefix] = func
        return func

## <encoding functions> ##
def enc_dict_type(obj):
    data = "".join([encoder[type(i)](i) for i in obj.items()])
    return "%s%s%s" % ("D", pack("!L", len(data)), data)

def enc_list_type(obj):
    data = "".join([encoder[type(i)](i) for i in obj])
    return "%s%s%s" % (protocol[type(obj)], pack("!L", len(data)), data)

def enc_int_type(obj):
    return "%s%s" % (protocol[IntType], pack("!i", obj))

def enc_float_type(obj):
    return "%s%s" % (protocol[FloatType], pack("!d", obj))

def enc_long_type(obj):
    obj = hex(obj)[2:-1]
    return "%s%s%s" % (protocol[LongType], pack("!L", len(obj)), obj)

def enc_unicode_type(obj):
    obj = obj.encode('utf-8')
    return "%s%s%s" % (protocol[UnicodeType], pack("!L", len(obj)), obj)

def enc_string_type(obj):
    return "%s%s%s" % (protocol[StringType], pack("!L", len(obj)), obj)

def enc_none_type(obj):
    return protocol[NoneType]

def enc_bool_type(obj):
    return protocol[BooleanType] + str(int(obj))

def dumps(obj, compress=False):
    """Encode simple Python types into a binary string."""
    option = "N"
    if compress: option = "Z"
        data = encoder[type(obj)](obj)
        if compress: data = zlib.compress(data)
        return "%s%s%s" % (HEADER, option, data)
    except KeyError, e:
        raise EncodeError, "Type not supported. (%s)" % e
## </encoding functions> ##

## <decoding functions> ##
def build_sequence(data, cast=list):
    size = unpack('!L',[0]
    items = []
    data_tell = data.tell
    data_read =
    items_append = items.append
    start_position = data.tell()
    while (data_tell() - start_position) < size:
        T = data_read(1)
        value = decoder[T](data)
    return cast(items)

def dec_tuple_type(data):
    return build_sequence(data, cast=tuple)

def dec_list_type(data):
    return build_sequence(data, cast=list)

def dec_dict_type(data):
    return build_sequence(data, cast=dict)

def dec_long_type(data):
    size = unpack('!L',[0]
    value = long(,16)
    return value

def dec_string_type(data):
    size = unpack('!L',[0]
    value = str(
    return value

def dec_float_type(data):
    value = unpack('!d',[0]
    return value

def dec_int_type(data):
    value = unpack('!i',[0]
    return value

def dec_none_type(data):
    return None

def dec_bool_type(data):
    value = int(
    return bool(value)

def dec_unicode_type(data):
    size = unpack('!L',[0]
    value ='utf-8')
    return value

def loads(data):
    Decode a binary string into the original Python types.
    buffer = StringIO(data)
    header =
    assert header == HEADER
    option =
    decompress = False
    if option == "Z":
        buffer = StringIO(zlib.decompress(
        value = decoder[](buffer)
    except KeyError, e:
        raise DecodeError, "Type prefix not supported. (%s)" % e

    return value
## </decoding functions> ##

    import psyco
    dumps = psyco.proxy(dumps)
    loads = psyco.proxy(loads)
except ImportError:

if __name__ == "__main__":
    value = (u'\N{POUND SIGN} Testing unicode', {True:False},[1,2,3,4],["simon"],("python is","cool"),
"pi equals",3.14,("longs are ok",
    data = dumps(value)
    print data
    x = loads(data)
    print x

i also added compression via zlib for fewer traffic. just save this file as and import it.
to use it in your code this would be

self.chatinput = DirectEntry(text="" , entryFont= ThaiFont,
def talk (self, textenters):
   pkg = PyDatagram()
        self.cWriter.send(pkg, self.Connection) 

to restore the unicode string on the other pc/client just read the second second string from your datagramm with this code

 yourChatMessage =  rencode.loads(pkg.getString())

at least this way it worked out for my unicode chat system which was tested with russian stuff^^

:smiley: Thank you very much Thomas

now i can send chat package
but have a little problem when use loads()

it return error
[color=red]assert header == HEADER

what’s it mean? sir :confused:

and when i comment “#assert header == HEADER”

it show error in loads()

[color=red]raise DecodeError, “Type prefix not supported. (%s)” %e
rencode.DecodeError: Type prefix not supported. (’ ')

:smiley: sorry it’s my fault

i send “self.sender+data” in package

then header not in front of package
sorry to annoy u

but thank you very much Thomas
You save my life