qutebrowser HACKING =================== Run checks! ----------- In the _scripts/_ subfolder, there are a `run_checks.py`. `run_checks.py` runs a bunch of static checks on all source files. It uses the following checkers to do so: * unittests using the Python https://docs.python.org/3.4/library/unittest.html[unittest] framework * https://pypi.python.org/pypi/flake8/1.3.1[flake8] * https://github.com/GreenSteam/pep257/[pep257] * http://pylint.org/[pylint] * Custom checkers for untracked git files, whitespace/CRLF problems, * `set_trace` invocations and VCS conflict markers. If you changed `setup.py`/`MANIFEST.in` and add the `--setup` argument, the following additional checkers are run: * https://pypi.python.org/pypi/pyroma/0.9.3[pyroma] * https://github.com/mgedmin/check-manifest[check-manifest] Please make sure this script runs without any warnings on your new contributions. There's of course the possibility of false-positives, and the following techniques are useful to handle these: * Use `_foo` for unused parameters, with `foo` being a descriptive name. Using `_` is discouraged. * If you think you have a good reason to suppress a message, add the following comment: + ---- # pylint: disable=message-name ---- + Note you can add this per line, per function/class, or per file. Please use the smallest scope which makes sense. Most of the time, this will be line scope. + * If you really think a check shouldn't be done globally as it yields a lot of false-positives, let me know! I'm still tweaking the parameters. Profiling --------- In the _scripts/_ subfolder there's a `run_profile.py` which profiles the code and shows a graphical representation of what takes how much time. It needs https://pypi.python.org/pypi/pyprof2calltree/[pyprof2calltree] and http://kcachegrind.sourceforge.net/html/Home.html[KCacheGrind]. It uses the built-in Python https://docs.python.org/3.4/library/profile.html[cProfile] module. Useful utilities ---------------- In the `qutebrowser.utils.debug` and `qutebrowser.utils.signal` modules there are some useful functions for debugging. In particular you should use `set_trace` from `qutebrowser.utils.debug` instead of `pdb` to set breakpoints or you'll get annoying Qt error messages. When starting qutebrowser with the `--debug` flag you also get useful debug logs. You can add `--logfilter category[,category,...]` to restrict logging to the given categories. With `--debug` there are also some additional `debug-*` commands available, for example `debug-all-objects` and `debug-all-widgets` which prints a list of all Qt objects or widgets to the debug log -- this is very useful for finding memory leaks. Style conventions ----------------- As you might have noticed, I *really* like clean and consistent code. While I won't reject your contribution when you don't follow the guidelines, I'd be really glad if you'd do so. qutebrowser's coding conventions are based on http://legacy.python.org/dev/peps/pep-0008/[PEP8] and the https://google-styleguide.googlecode.com/svn/trunk/pyguide.html[Google Python style guidelines] with some additions: * Methods overriding Qt methods (obviously!) don't follow the naming schemes. * Everything else does though, even slots. * Docstring are like described in http://legacy.python.org/dev/peps/pep-0257/[PEP257] and the google guidelines. * Class docstrings have additional `Attributes:`, `Class attributes:` and `Signals:` sections, method/function docstrings have an `Emit:` section. + Example for a class docstring: + [source,python] ---- """Some object. Attributes: blub: The current thing to handle. Signals: valueChanged: When a value changed. arg: The new value """ ---- + Example for a method/function docstring: + [source,python] ---- """Do something special. Args: foo: ... Return: True if something, False if something else. Raise: ValueError if foo is None Emit: value_changed """ ---- + * The layout of a module should be roughly like this: - Shebang (`#!/usr/bin/python`, if needed) - vim-modeline (`# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et`) - Copyright - GPL boilerplate - Module docstring - Python standard library imports - PyQt imports - qutebrowser imports - functions - classes * The layout of a class should be like this: - docstring - `__magic__` methods - properties - _private methods - public methods - `on_*` methods - overrides of Qt methods