[[PageOutline]] = Python in WebKit = Below is an overview of WebKit's use of Python. == Basics == * WebKit's Python scripts require Python 2.6 or higher to run. * [http://trac.webkit.org/browser/trunk/Tools/Scripts/test-webkitpy Scripts/test-webkitpy] unit tests the Python code. It also cleans orphan *.pyc files from webkitpy (i.e. .pyc files without a corresponding .py file). You can also do this manually (for all *.pyc files in webkitpy) using the following command: {{{ find Tools/Scripts -wholename '*.pyc' | xargs rm }}} == Code Structure == * Most of the Python code is in [http://trac.webkit.org/browser/trunk/Tools/Scripts/webkitpy Tools/Scripts/webkitpy]. * [http://trac.webkit.org/browser/trunk/Tools/Scripts Tools/Scripts] also contains end-user Python scripts (which usually import from webkitpy). * Code is written to assume that `.../Tools/Scripts` is in your `PYTHONPATH`. `test-webkitpy` handles this internally, but you may find it useful to add the setting to your environment. * Generally, we try to keep as much of the Python code in webkitpy as possible since this allows the code to be organized more nicely (for unit tests to be in companion files, etc). * Unit test files are in correspondence with modules. For example, if module.py is the name of a module, its unit test file would be module_unittest.py and would lie in the same directory. * The root-level folders in webkitpy/ generally correspond to end-user scripts in Tools/Scripts. For example-- * check-webkit-style -> webkitpy/style/ * new-run-webkit-tests -> webkitpy/layout_tests/ * webkit-patch -> webkit/tool/ * Exceptions to the rule above are-- * webkitpy/common/: code shared by multiple root folders * webkitpy/python24/: code that needs to work under Python 2.4 (currently just the version-checking code) * [http://trac.webkit.org/browser/trunk/Tools/Scripts/webkitpy webkitpy/thirdparty/]: all third-party code in webkitpy == Strings and Unicode == Code should take care to follow the Unicode strategy outlined in this [https://bugs.webkit.org/show_bug.cgi?id=37765 comment thread]. FIXME: Fill in this section with specific guidance from the comment thread above. == Style == Informally, we try to follow [http://www.python.org/dev/peps/pep-0008/ PEP8]. Eventually we may make this official. For the time being, we are not following the 79 character line length limit (or any line length limit for that matter). For discussion purposes, here are some additional guidelines to consider: * Prefer single quotes to double quotes. Use double quotes only if the string contains single quotes (or if you are using "triple double quotes"). This simplifies writing unit tests because Python behaves this way when rendering string objects to the console. For example-- {{{ >>> list = ["blah", 'blah', '\'blah\''] >>> print list ['blah', 'blah', "'blah'"] }}} This allows console output to be cut and pasted directly into the code when writing and updating unit tests. * Order `from` and `import` statements within a group by the name of the leading module instead of putting all `from` statements before `import` statements: {{{ # Correct: import logging from optparse import OptionParser import sys # Incorrect: from optparse import OptionParser import logging import sys }}} This keeps the ordering of lines the same when changing a `from` statement to an `import` statement, and vice versa. This also makes it easer to see if both `from` and `import` statements are used to import from the same package (since the lines will be adjacent). By "within a group," we mean in the PEP8 sense of grouping standard library imports separately from local application imports, etc. * When writing unit tests with the unittest module, unittest.TestCase classes should have names of the form ClassTest, where "Class" is the name of the class being tested. Similarly, test methods should have names of the form test_method!__description, where "method" is the name of the method in the class being tested. The double underscore after "method" is helpful because "method" may itself have underscores. This style is used, for example, in the unit tests for Python's unittest module itself (e.g. see [http://svn.python.org/view/python/trunk/Lib/unittest/test/test_loader.py?revision=79464&view=markup here]). == Upgrading from Python 2.3 or Python 2.4 == [Much of these instructions are Mac-specific.] If you are upgrading from Python 2.3 or 2.4, you should upgrade to Python 2.6 rather than 2.5. You can tell what version of Python you are currently using by typing-- {{{ python -V }}} Before trying to install a new version, check whether your machine already has other versions installed. From a Mac, you can try reading the man page-- {{{ man python }}} For example, Snow Leopard comes with Python 2.5, 2.6, and 3.0. The man page provides instructions on how to switch your system between these system-installed versions. If you need to install a new version not on your machine, you can use [http://guide.macports.org/ MacPorts] to do this. MacPorts allows you to install Python versions alongside your system versions without interfering with them. After installing MacPorts, simply type (for example)-- {{{ sudo port install python26 }}} You should probably also install python_select using MacPorts-- {{{ sudo port install python_select }}} The python_select command allows you to quickly go back and forth between Python versions, like so-- {{{ > python -V Python 2.6.4 > sudo python_select python24 Selecting version "python24" for python > python -V Python 2.4.6 }}} To find out what versions of Python you can switch to using python_select, type-- {{{ python_select -l }}} == Building the Efl/Gtk port in a distro which uses Python 3.x as default == If you use a distro which has Python 3 as the default python for the system - such as [http://www.archlinux.org ArchLinux] -, you will have problems during the step that uses JHBuild to manage the dependencies of Efl and Gtk ports, since it requires Python 2. A solution to enable you to work properly with these ports in such distros would be to install [http://www.virtualenv.org/ virtualenv], which allows you to create virtual environments that may use different versions of python. In ArchLinux, you would install virtualenv with the following command: {{{ # pacman -S python2-virtualenv }}} [The next instructions are not distro-specific.] After installing virtualenv, create the place where the virtual environment will live: {{{ $ mkdir -p ~/.virtualenvs/webkit }}} And create the actual virtual environment: {{{ $ virtualenv2 ~/.virtualenvs/webkit }}} Now that the virtual environment exists, you will basically activate it before working on WebKit and once you are done, you can deactivate it. To activate the virtual environment: {{{ $ source ~/.virtualenvs/webkit/bin/activate }}} Now your default python is Python 2, which allows you to use JHBuild and build WebKit without hassle. When you are done, simply deactivate the virtual environment: {{{ $ deactivate }}} And you are back to your distro's default python.