-
Leveraging PyDev’s auto completion for indirectly created objects
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 autocompletion you have two options:
- Temporarily instantiate a Book object in the code.
mybook = Book() mybook = bookstore.findBook("foobar") mybook. #--> now you have auto completionThis 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.
- 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
- Temporarily instantiate a Book object in the code.
-
Comparing version numbers in Jython / Python
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 rcTheoretically 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
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 ImportError, e: 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_getpassHere is an usage example:
import ext_getpass as getpass pw = getpass.getpass("Please enter your password:") print "The entered password was: " + pw


Looking for a high performer for your next IT project?
English
Deutsch
Recent Comments