Filed Under (Python) by Marcin Kuźmiński on February-8-2010

I’d created another simple application in pylons, final step was to translate it from English to Polish.

I used the babel extractor recommended by pylons and that went really smooth.

My application have a language selector available anytime from menu.
I saw that even this switch worked very well for mako templates and string inside controllers,
it did not work when displaying my custom messages that i over rid in validators
and also did not work in my own custom validators that inherit from FancyValidator.
So i started to investigate this.

The first problem of not translating custom error messages in the regular formencode validators was easily being fixed by using lazy_ugettex method.

def _(s):
    #fix for translation error messages
    return lazy_ugettext(s)

This method allowed me to use lazy_ugettext to translate.
So now when in the validators your translating a string using _(‘this string is for translate’) method it’s actually wrapper for lazy_ugettext function.
Lazy translation is when you translate a string when it is accessed, not when the _() or other functions are called.

The second problem of translating custom error messages in your own validator was a bigger problem

I was looking for a solution for some time, and found a nice trick. You have to use your own
state_obj with static _() function. As example below for custom validation function.

class ValidLoginNames(formencode.validators.FancyValidator):

    messages = {'invalid_name':_('you cannot use %(username)s as login')}

    def validate_python(self, value, state):
        banned_names = ['admin', 'administrator', 'root']
        if value in banned_names:
            raise formencode.Invalid(self.message('invalid_name', state = State_obj, username = value), value, state)

#this is needed to translate the messages using _()
class State_obj(object):
    _ = staticmethod(_)

Those two trick now let’s you translate custom validators without a problem.



Filed Under (Editors, Python) by Marcin Kuźmiński on November-20-2009

Few days ago there was again a major update on pydev eclipse plugin.
The version 1.5.1. Comes with new refactoring engine PEPTIC, it’s way better than any one before.
Complete list below: visit http://pydev.org for download.

Release 1.5.1

  • Improvements in the AST rewriter
  • Improvements on the refactoring engine:
    • No longer using BRM
    • Merged with the latest PEPTIC
    • Inline local available
    • Extract method bug-fixes
    • Extract local on multi-line
    • Generating properties using coding style defined in preferences
    • Add after current method option added to extract method
    • A bunch of other corner-case situations were fixed
  • Bug-fixes:
    • Minor editor improvements
    • Adding default forced builtins on all platforms (e.g.: time, math, etc) which wouldn’t be on sys.builtin_module_names on some python installations
    • Adding ‘numpy’ and ‘Image’ to the forced builtins always
    • Ctrl+1: Generate docstring minor fixes
    • Ctrl+1: Assign to local now follows coding style preferences properly
    • Exponential with uppercase E working on code-formatting
    • When a set/get method is found in code-completion for a java class an NPE is no longer thrown
    • Backspace properly treated in block mode
    • Setting IRONPYTHONPATH when dealing with Iron Python (projects could not be referenced)
    • No longer giving spurious ’statement has no effect’ inside of lambda and decorators
    • Fixed new exec in python 3k
    • Fixed NPE when breakpoint is related to a resource in a removed project
    • Fixed import problem on regexp that could lead to a recursion.
    • No longer giving NPE when debugging with the register view open
    • List access be treated as __getitem__() in the list — patch from Tassilo Barth
    • Fix for invalid auto-self added when typing


Filed Under (Editors, Python) by Marcin Kuźmiński on November-15-2009

I installed new eclipse on ubuntu 9.10, and noticed that manu of FINISH,
NEXT buttons are not working correctly ( you can’t click them).

So it found out it’s eclipse bug, but fortunately there is a simple
solution to this problem.

Write a startup script:

#!/bin/sh
export GDK_NATIVE_WINDOWS=1
/path_to_eclipse/eclipse

Save it as eclipse-run.sh make it +x, and the buttons will work now if you
run your eclipse via the run script.



Filed Under (Python) by Łukasz Balcerzak on October-21-2009

While I love many things about SQLAlchemy this was something I just missed sooooo much – defining model’s methods without having to pass session object.
While using Django ORM for such action it is extra easy as there is no session objects at all (well, there is connection object but it’s much simpler and less sophisticated).
Assume you have BlogEntry and BlogComment mappers and you want to define function at entry model which returns related comments – I know, it is as simple as it could be, but it’s only an example.

class BlogEntry(Base):
    __tablename__ = 'blog_entry'

    title = Column(String)
    content = Column(Text)
    created_at = Column(DateTime, default=datetime.datetime.now)

    def __repr__(self):
        return self.title

class BlogComment(Base):
    __tablename__ = 'blog_comment'

    content = Column(Text)
    created_at = Column(DateTime, default=datetime.datetime.now)
    entry_id = Column(Integer, ForeignKey('blog_entry.id'))
    entry = relation('BlogEntry',
        primaryjoin='BlogEntry.id==BlogComment.entry_id',
        backref='comment_set')

You now can of course get comments using comment_set attribute on blog entry. But sometimes we want start querying for other objects, for some reasons.
With Django ORM, no problem, just define method on the model and start querying – it just works. With SQLAlchemy on the other hand we need to create query
using Session object. But how does mapper use proper session if you call ‘comment_set’? Well, I’ve found the answer here: http://www.sqlalchemy.org/docs/05/reference/orm/sessions.html . There is ‘Session.object_session’ class method which returns session object binded to an model object.

So now we can simply define method for BlogComment:

    def get_related_comments(self):
        session = Session.object_session(self)
        comment_list = session.query(BlogComment)\
            .filter(BlogComment.entry_id==BlogEntry.id)\
            .all()
        return comment_list

Just remember that object which is passed to ‘Session.object_session’ method has to be binded with some session first.



Filed Under (Python, Threads) by Łukasz Balcerzak on July-1-2009

Recently I’ve run into some optimizations problem which I once hoped I wouldn’t had to face. After some research on the subject I decided to split some process using threads. I hadn’t have much experience in that area except some classes at PJIIT (Polish-Japanese Institute of Information Technology) so start was painful… but not for long (as with everything in Python).

So I decided to share my thoughts with everyone who would ever try to use threads in Python programming.

Let’s imagine simple case: you want to check some host if it has opened any port from range 1-1000. We create simple script (use whatever host you like)

import socket
import time

def is_port_open(host, port):
    """
    Takes host param as string and port param as int.
    Returns true if port is open and false otherwise.
    """
    #print "[DEBUG] Checking host %s:%s" % (host, port)
    s = socket.socket()
    is_open = True
    try:
        s.connect( (host, port) )
    except socket.error:
        is_open = False
    s.close()
    return is_open

def main():
    start = time.time()

    host = 'some.host'
    ports = range(1,1000) 

    print "[INFO] Will now check host %s for ports between %s and %s" % \
        (host, ports[0], ports[-1]) 

    for port in ports:
        if is_port_open(host, port):
            print "[INFO] Port %s on host %s is open." % (port, host)

    print "Elapsed Time: %s" % (time.time() - start)

if __name__ == '__main__':
    main()

How long was it? Well, try this then:

import threading
import socket
import time
import Queue

THREAD_NUMBER = 20

def is_port_open(host, port):
    """
    Takes host param as string and port param as int.
    Returns true if port is open and false otherwise.
    """
    #print "[DEBUG] Checking host %s:%s" % (host, port)
    s = socket.socket()
    is_open = True
    try:
        s.connect( (host, port) )
    except socket.error:
        is_open = False
    s.close()
    return is_open

class PortChecker(threading.Thread):
    def __init__(self, queue):
        threading.Thread.__init__(self)
        self.queue = queue

    def run(self):
        while True:
            host, port = self.queue.get()
            if is_port_open(host, port):
                print "[INFO] Port %s on host %s is open." % (port, host)
            self.queue.task_done()

def main():
    start = time.time()

    host = 'some.host'
    ports = range(1,1000)
    queue = Queue.Queue()

    for i in xrange(THREAD_NUMBER):
        pc = PortChecker(queue)
        pc.setDaemon(True)
        pc.start()

    print "[INFO] Will now check host %s for ports between %s and %s" % \
        (host, ports[0], ports[-1]) 

    for port in ports:
        queue.put( (host, port) )

    queue.join()
    print "Elapsed Time: %s" % (time.time() - start)

if __name__ == '__main__':
    main()

Try with different port range/thread number. Ok, this is just an example. But it should give you an idea how to handle with some process that is done inside a loop. You have to define your “handler” (thread that will process on some object(s)), create empy queue and fill it with objects. Try to use only 1 thread (set THREAD_NUMBER to 1) and look at the time it took to finish whole process.

I know that programmer’s time is much more expensive than processor’s time and I try not to break this rule. But sometimes (i.e. when your script runs for over 12 hours) it is very nice if you can cut the time you can generate results. Just remember to catch exceptions inside threads – it is very important as if exception is risen by thread, it will just die without any notification.

Well, thats it. I will proceed tomorrow with some example with SQLAlchemy. Good night folks.