The supported Python framework
As of this moment there are currently two commonly used python frameworks for eclipse:
DLTK. The PyDev framework is a complete set of language specific bundles where DLTK is a general purpose framework for dynamic languages including python support.
Both do have it's pro's and con's whereas I personally prefer
PyDev since it has a higher level of maturity.
Nevertheless the Python ant tasks contains support for both of these frameworks so in theory you should be able to use them the same way whether you use the one or the other framework.
Parsing the project files
Since both frameworks are generally using a different way to store their information there are two parsers:
PyDevParser just parses the file .pydevproject where the
DLTKParser parses the local .buildpath file.
PyDev framework uses the general project dependencies mechanism from eclipse in order to declare relationships between python projects. Therefore these project dependencies are processed after the .pydevproject file has been parsed which means that referenced projects are always located at the end of the pythonpath affecting the path order. Nevertheless this should be rarely an issue for developers.
Resolving filesystem locations
The previously mentioned parsers only create records of type
RawPathEntry. It is just a simple datastructure providing a common representation of the records stored within the projects, thus we don't need to distinguish between
PythonResolver is responsible to transform these
RawPathEntry into corresponding
ResolvedPathEntry instances. Therefore it is following each record (f.e. a project record might cause the inclusion of the referred projects pythonpaths). It's also maintaining the
PathEntryRegistry so each resolving process is executed once.
The last step is established by the class
PathExpander which just calculates the filesystem locations depending on the type of record.
Supported python installations
As of these days there are different implementations of python available. Generally they should be capable to run the same code but there are obviously differences. The python ant task allow to manage multiple installations at the same time using the
pythonContainer declaration. F.e.:
<ant4eclipse:pythonContainer default="python-2.5"> <ant4eclipse:pyre id="python-2.5" location="/usr/lib/python/cpython/2.5"/> </ant4eclipse:pythonContainer>
The corresponding class
PythonContainer will register a runtime for each
pyre element. This registration process is provided by the service class
PythonRuntimeRegistryImpl which performs the following actions:
- Identify the interpreter
- Determine python version
- Determine the pythonpath of the runtime
Identifying the interpreter
PythonRuntimeRegistry supports different interpreter types using the class
PythonInterpreter. If you take a look into the file
python.properties you will see the following declarations:
interpreter.python=python,pythonw interpreter.ironpython=ipy,ipyw interpreter.jython=jython
Each declaration allows to setup a
PythonInterpreter which will be able to look for the corresponding executable file through the supplied values. The ironpython instance would look for the following executables: ipy, ipy.exe, ipy.bat, ipy.sh, ipyw, ipyw.exe, ipyw.bat, ipyw.sh. Just in case a declaration is missed a user can alter just that file with an additional entry to support his type of python installation (hopefully informing us about this).
Determine the python version and the pythonpath
When the executable is known we still should know the used language version and more important the pythonpath provided by this installation. It would be a pain if we would try to create an internal list of paths per python installation since it would be really hard to maintain such an internally used database (especially since there might be often changes due to versionings).
Therefore we wrote a simple python application you will find as part of the tasks:
import sys if __name__ == "__main__": print("ANT4ECLIPSE-BEGIN") print("_".join([".".join([repr(x) for x in sys.version_info[:-2]]),sys.version_info])) for i in sys.path: print("[" + i + "]") print("ANT4ECLIPSE-END")
Using the interpreter we're just executing this application and analysing it's output afterwards. The literals ANT4ECLIPSE-BEGIN and ANT4ECLIPSE-END are just helpful to make sure that the launched python interpreter did not dump some kind of strange error information. Whenever we can find these literals we can be sure that execution worked fine (the returncode is just not reliable enough). The first line will always contain the versioning information while the following line will contain the pathes as desired by our tasks.
Some interpreters like f.e.
Jython do list symbols rather than real pathes (f.e. __classpath__). If such a record determines a non-existing filesystem resource it will be ignored. If the user requested to ignore the site packages (can be set on the
pyre element) they're discared, too.