IT Consultant – Java, J2EE, IBM WebSphere Portal, Lotus Notes/Domino
RSS icon Home icon
  • Leveraging PyDev’s auto-completion for indirectly created objects

    (1 votes) 1 Star2 Stars3 Stars4 Stars5 Stars
    Loading...
    Posted on 20 February 2010 Sebastian Thomschke*/?> 5 comments

    This is just a quick tip how to enable auto completion in PyDev for indirectly created objects.

    By default, PyDev has no problems in presenting you the possible object attributes and methods on a variable if that variable gets a new object instance assigned directly in the code.

    For example, when you first type …

    mybook = Book()

    … and in the next line you enter …

    mybook.

    … PyDev will dutifully present you the statically declared features for the Book class in a popup.

    If you however get that Book instance as the result of another method, e.g. …

    mybook = bookstore.findBook("foobar")

    … PyDev currently seems to be helpless.

    Because of Python’s dynamic nature it is of course a bit harder for an IDE to figure out what kind of objects may a method. But PyDev could for example honor the @return / @rtype PyDoc annotations (which you can add to the findBook’s method declaration) but currently it just does not.

    To still have auto-completion you have two options:

    1. Temporarily instantiate a Book object in the code.
      mybook = Book()
      mybook = bookstore.findBook("foobar")
      mybook. #--> now you have auto completion
      

      This has the drawback, that if you forget to remove the first line before you finish coding an unneccessary Book instance will be created on every execution during runtime.

    2. Use an assertion to ensure that the mybook variable contains an object of type Book
      mybook = bookstore.findBook("foobar")
      assert isinstance(mybook, Book)
      mybook. #--> now you have auto completion
      
  • Comparing version numbers in Jython / Python

    1 Star2 Stars3 Stars4 Stars5 Stars
    Loading...
    Posted on 14 March 2009 Sebastian Thomschke*/?> No comments

    Here comes a function to compare version numbers of e.g. Maven artifacts in Jython / Python.

    import re
    
    def cmpver(vA, vB):
        """
        Compares two version number strings
        @param vA: first version string to compare
        @param vB: second version string to compare
        @author Sebastian Thomschke
        @return negative if vA < vB, zero if vA == vB, positive if vA > vB.
       
        Examples:
        >>> cmpver("0", "1")
        -1
        >>> cmpver("1", "0")
        1
        >>> cmpver("1", "1")
        0
        >>> cmpver("1.0", "1.0")
        0
        >>> cmpver("1.0", "1")
        0
        >>> cmpver("1", "1.0")
        0
        >>> cmpver("1.1.0", "1.0.1")
        1
        >>> cmpver("1.0.1", "1.1.1")
        -1
        >>> cmpver("0.3-SNAPSHOT", "0.3")
        -1
        >>> cmpver("0.3", "0.3-SNAPSHOT")
        1
        >>> cmpver("1.3b", "1.3c")
        -1
        >>> cmpver("1.14b", "1.3c")
        1
        """
        if vA == vB: return 0
    
        def num(s): 
            if s.isdigit(): return int(s)
            return s
    
        seqA = map(num, re.findall('\d+|\w+', vA.replace('-SNAPSHOT', '')))
        seqB = map(num, re.findall('\d+|\w+', vB.replace('-SNAPSHOT', '')))
    
        # this is to ensure that 1.0 == 1.0.0 in cmp(..)
        lenA, lenB = len(seqA), len(seqB)
        for i in range(lenA, lenB): seqA += (0,) 
        for i in range(lenB, lenA): seqB += (0,)
        
        rc = cmp(seqA, seqB)
        
        if rc == 0:
            if vA.endswith('-SNAPSHOT'): return -1
            if vB.endswith('-SNAPSHOT'): return 1
        return rc
    

    Theoretically lines 43 – 49 could be written in a more compact way but using the short circuit evaluations (as below) lead to wrong results – at least in Jython 2.1:

        seqa = map(lambda s: s.isdigit() and int(s) or s, re.findall('\d+|\w+', vA.replace('-SNAPSHOT', '')))
        seqb = map(lambda s: s.isdigit() and int(s) or s, re.findall('\d+|\w+', vB.replace('-SNAPSHOT', '')))
    
  • getpass for Jython

    1 Star2 Stars3 Stars4 Stars5 Stars
    Loading...
    Posted on 21 November 2008 Sebastian Thomschke*/?> 1 comment

    In my current project I am developing some Jython based command line tools and had the need for masking passwords entered in the command shell. Python provides the getpass module for this purpose. Unfortunately this module has not been made available for Jython.

    Here comes a module I wrote to provide this kind of functionality. It uses the mechanism described here http://java.sun.com/developer/technicalArticles/Security/pwordmask/ to mask characters entered at the command prompt. Additionally if Java 6 or higher is running Jython the module will instead use the new Console.readPassword() method. In case the module is running in an environment where the getpass module is available it will delegate to the corresponding methods of this module instead of using its own implementations.

    # ext_getpass.py
    # @author Sebastian Thomschke, http://sebthom.de/
    import thread, sys, time, os
    
    # exposed methods:
    __all__ = ["getpass","getuser"]
    
    def __doMasking(stream):
        __doMasking.stop = 0
        while not __doMasking.stop:
            stream.write("b*")
            stream.flush()
            time.sleep(0.01)
    
    def generic_getpass(prompt="Password: ", stream=None):
        if not stream:
            stream = sys.stderr
        prompt = str(prompt)
        if prompt:
            stream.write(prompt)
            stream.flush()
        thread.start_new_thread(__doMasking, (stream,))
        password = raw_input()
        __doMasking.stop = 1
        return password
    
    def generic_getuser():
        for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'):
            usr = os.environ.get(name)
            if usr: return usr
    
    def java6_getpass(prompt="Password: ", stream=None):
        if not stream:
            stream = sys.stderr
        prompt = str(prompt)
        if prompt:
            stream.write(prompt)
            stream.flush()
    
        from java.lang import System
        console = System.console()
        if console == None:
    	    return generic_getpass(prompt, stream)
        else:
            return "".join(console.readPassword())
    
    try:
        # trying to use Python's getpass implementation
        import getpass
        getpass = getpass.getpass
        getuser = getpass.getuser
    except:
        getuser = generic_getuser
    	
        # trying to use Java 6's Console.readPassword() implementation
        try:
            from java.io import Console
            getpass = java6_getpass
        except ImportError, e:
            # use the generic getpass implementation
            getpass = generic_getpass
    

    Here is an usage example:

    import ext_getpass as getpass
    
    pw = getpass.getpass("Please enter your password:")
    print "The entered password was: " + pw