pdb, you can embed an IPython console in your code with:
from IPython import embed; embed()
TAB completion with full introspectionWhat I like the most in IPython is its TAB completion features, it’s not just like normal text matching while you type but it has full realtime introspection, you only see what you have access to, being it a method of an instance or a class or a property, a module, a submodule or whatever you might think of: it even works when you’re importing something or you are typing a path like in
open('/home/..... Its TAB completion is so powerful that you can even use shell commands from within the IPython interpreter!
Full documentation is just a question mark awayJust type “?” after a method of function to print its docstring or its signature in case of SIP bindings.
Lot of special functionsIPython special functions are available for history, paste, run, include and many more topics, they are prefixed with “%” and self-documented in the shell.
All that sounds great! But what has to do with QGIS?I personally find the QGIS python console lacks some important features, expecially with the autocompletion (autosuggest). What’s the purpose of having autocompletion when most of the times you just get a traceback because the method the autocompleter proposed you is that of another class? My brain is too small and too old to keep the whole API docs in my mind, autocompletion is useful when it’s intelligent enough to tell between methods and properties of the instance/class on which you’re operating. Another problem is that the API is very far from being “pythonic” (this isn’t anyone’s fault, it’s just how SIP works), here’s an example (suppose we want the SRID of the first layer):
core.QgsMapLayerRegistry.instance().mapLayers().value().crs().authid() # TAB completion stops working here^TAB completion stop working at the first parenthesis 🙁 What if all those getter would be properties?
registry = core.QgsMapLayerRegistry.instance() # With a couple of TABs without having to remember any method or function name! registry.p_mapLayers.values() [<qgis._core.QgsRasterLayer at 0x7f07dff8e2b0>, <qgis._core.QgsRasterLayer at 0x7f07dff8ef28>, <qgis._core.QgsVectorLayer at 0x7f07dff48c30>, <qgis._core.QgsVectorLayer at 0x7f07dff8e478>, <qgis._core.QgsVectorLayer at 0x7f07dff489d0>, <qgis._core.QgsVectorLayer at 0x7f07dff48770>] layer = registry.p_mapLayers.values() layer.p_c ---> TAB! layer.p_cacheImage layer.p_children layer.p_connect layer.p_capabilitiesString layer.p_commitChanges layer.p_crs layer.p_changeAttributeValue layer.p_commitErrors layer.p_customProperty layer.p_crs.p_ ---> TAB! layer.p_crs.p_authid layer.p_crs.p_postgisSrid layer.p_crs.p_axisInverted layer.p_crs.p_projectionAcronym layer.p_crs.p_description layer.p_crs.p_recentProjections layer.p_crs.p_ellipsoidAcronym layer.p_crs.p_srsid layer.p_crs.p_findMatchingProj layer.p_crs.p_syncDb layer.p_crs.p_geographicCRSAuthId layer.p_crs.p_toProj4 layer.p_crs.p_geographicFlag layer.p_crs.p_toWkt layer.p_crs.p_isValid layer.p_crs.p_validationHint layer.p_crs.p_mapUnits layer.p_crs.p_authid Out: u'EPSG:4326'This works with a quick and dirty hack: propertize that adds a
p_...property to all methods in a module or in a class that
- do return something
- do not take any argument (except self)
A few methods are still not working with propertize, so far singleton methods like
instance()are not passing unit tests.
IPyConsole: a QGIS IPython pluginIf you’ve been reading up to this point you probably can’t wait to start using IPython inside your beloved QGIS (if that’s not the case, please keep reading the previous paragraphs carefully until your appetite is grown!). An experimental plugin that brings the magic of IPython to QGIS is now available:
Download IPyConsole Please start exploring QGIS objects and classes and give me some feedback!