Hacking

Not logged in - Log In / Register

Revision 5 as of 2009-08-03 15:27:29

Clear message

See also: PythonStyleGuide and HackingLazrLibraries.

Contents

  1. HTML, TAL, and CSS
  2. Python programming
    1. Which version of Python should I target?
    2. How should I format my docstrings?
    3. How should I use assertions in Launchpad code?
    4. What exceptions am I allowed to catch?
    5. What exception should I raise when something passed into an API isn't quite right?
    6. I have a self-posting form which doesn't display the updated values after it's submitted. What's wrong?
    7. I need to define a database class that includes a column of dbschema values. How do I do this?
    8. I have received a security proxied list from some API. I need to sort it, but the 'sort()' method is forbidden. What do I do?
    9. SQL Result Set Ordering
    10. How do I use a postgres stored-procedure/expression as the orderBy in SQLObject?
    11. How do I generate SQL commands safely?
    12. What date and time related types should I use?
    13. Python segfaulted. What should I do?
    14. I want an object to support __getitem__, what's the best style?
    15. Properties
  3. Storm
    1. How to retrieve a store ?
  4. Security, authentication
    1. How can I do get the current user in a database class?
    2. How can I protect a method based on one of its parameter?
  5. Email Notifications
    1. When I need to send a notification for a person/team, how do I know what email address(es) I have to send the notification to?
  6. Web UI
    1. When should I use SQLObjectEditView and SQLObjectAddView
    2. How do I use the General Form
    3. How do I perform an action after an autogenerated edit form has been successfully submitted?
    4. How do I perform an action after an autogenerated add form has been successfully submitted?
    5. How can I redirect a user to a new object just created from an autogenerated add form?
    6. How do I format dates and times in page templates?
    7. How should I generate notices like "Added Bug #1234" to the top of the page?
  7. Launchpad API
    1. How do I add a new celebrity?
  8. Global Configuration
    1. How do I add items to launchpad.conf?
    2. How are these default values changed for specific environments?
    3. How do I use the items listed in launchpad.conf?
    4. How can I temporarily override configuration variables in tests?
  9. Testing
    1. What kind of tests should we use?
    2. How do I run just one doctest file, e.g. `lib/canonical/launchpad/doc/mytest.txt`?
    3. What about running just one pagetest story, e.g. `lib/canonical/launchpad/pagetests/initial-bug-contacts`?
    4. What about running a standalone pagetest, e.g. `xx-bug-index.txt`
    5. And if I want to execute all test except one?
    6. How can I examine my test output with PDB?
    7. Where can I get help on running tests?
    8. How can I check test coverage?
    9. How can I run only the tests for the page test layer?
    10. Where should I put my tests: in a `test_foo.py` module, or a `foo.txt` doctest file?
    11. How to I setup my tests namespace so I can remove unwanted import statements and other noise?
    12. Why is my page test failing mysteriously?
    13. I'm writing a pagetest in the standalone directory that changes some objects. Will my changes be visible to other pagetests in this directory?
    14. Why is not my page test failing when adding extra whitespace chars inside a textarea?
    15. What does the number in square brackets after a doctest name mean?
    16. How do I find a backtrace?
    17. Should I rely on the order of os.listdir?
    18. How do I find the tests that cover the code I've changed?
  10. Sample Data
    1. Where can I find a list of the sample users?
    2. How to I make changes to the sample Launchpad database?
    3. I've only made minor changes to the sample data, but the diff is huge!
  11. Code Reviews
    1. How do I use Meld with Bazaar to do code reviews?
  12. Bazaar
    1. How do I revert some revisions from my archive?
    2. I merged from another branch and did a lot of changes without first committing the merge. How can I undo only the merge?
      1. If you are sure your changes don't touch the same code as the merge does, you can do this and it'll probably work:
      2. On the other hand, if your changes touch the same code as the merge, it's better to do the following
    3. How can I get error failures from PQM by email?
    4. How do I set up connection multiplexing for my SSH session?
  13. Rollouts
    1. When will my code changes end up on production?
    2. I have an urgent bug fix
    3. What is the staging server?
  14. How do I run scripts with the Python environment of Launchpad?
  15. Buildout
  16. Working with our open-source components (lazr.*)
  17. Where to go for other help
  18. Unanswered questions

HTML, TAL, and CSS

Python programming

Which version of Python should I target?

Currently, Launchpad and Bazaar require Python 2.4. You may use features that require Python 2.4, as long as you abide by the PythonStyleGuide.

How should I format my docstrings?

How should I use assertions in Launchpad code?

What exceptions am I allowed to catch?

What exception should I raise when something passed into an API isn't quite right?

I have a self-posting form which doesn't display the updated values after it's submitted. What's wrong?

I need to define a database class that includes a column of dbschema values. How do I do this?

I have received a security proxied list from some API. I need to sort it, but the 'sort()' method is forbidden. What do I do?

SQL Result Set Ordering

If the ordering of an SQL result set is not fully constrained, then your tests should not be dependent on the natural ordering of results in the sample data.

If Launchpad does not depend on the ordering of a particular result set, then that result set should be sorted within the test so that it will pass for any ordering.

As a general rule, the result sets whose order we want to test are the ones that are displayed to the user. These should use an ordering that makes sense to the user, and the tests should ensure that happens.

For code that uses SQLObject, result sets will be randomised while conforming to the specified ORDER BY clause. This makes it difficult to write tests that depend on the natural ordering.

In contrast, code that does raw SQL won't have a randomised result set, so the natural order gets exposed to the user. The same rules of thumb apply when testing such code, but extra care should be taken not to rely on natural ordering.

How do I use a postgres stored-procedure/expression as the orderBy in SQLObject?

How do I generate SQL commands safely?

Python segfaulted. What should I do?

I want an object to support __getitem__, what's the best style?

Properties

Properties should always be used instead of __call__() semantics in TALES expressions. The rule is that in view classes, we don't do this:

    def foo(self):
        ...

We always do this:

    @property
    def foo(self):
        ...

Storm

Questions about Storm usage.

StormMigrationGuide document is highly recommended.

How to retrieve a store ?

There are two ways of retrieving a storm 'store', before issuing a query using native syntax.

The first format retrieves the Store being used by another object. Use this method when you don't need to make changes, but want your objects to interact nicely with objects from an unknown Store (such as a methods parameters):

   1 from storm.store import Store
   2 
   3 store = Store.of(object)
   4 
   5 result = store.find(Person, Person.name == 'zeca')

You can also explicitly specify what Store you want to use. You get to choose the realm (Launchpad main, auth database) and the flavor (master or slave). If you are retrieving objects that will need to be updated, you need to use the master. If you are doing a search and we don't mind querying data a few seconds out of date, you should use the slave.

   1 from canonical.launchpad.webapp.interfaces import (
   2     IStoreSelector, MAIN_STORE, AUTH_STORE,
   3     MASTER_FLAVOR, SLAVE_FLAVOR)
   4 
   5 master_store = getUtility(IStoreSelector).get(MAIN_STORE, MASTER_FLAVOR)
   6 
   7 master_obj = store.find(Person, Person.name == 'zeca')
   8 
   9 slave_store = getUtility(IStoreSelector).get(MAIN_STORE, SLAVE_FLAVOR)
  10 
  11 slave_obj = store.find(Person, Person.name == 'zeca')

If you don't need to update, but require up-to-date data, you should use the default flavor. (eg. most views - the object you are viewing might just have been created). This will retrieve the master unless the load balancer is sure all changes made by the current client have propagated to the replica databases.

   1 from canonical.launchpad.webapp.interfaces import (
   2     IStoreSelector, MAIN_STORE, AUTH_STORE, DEFAULT_FLAVOR)
   3 
   4 store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
   5 
   6 result = store.find(Person, Person.name == 'zeca')

See more details about this in https://lists.ubuntu.com/mailman/private/launchpad/2008-August/031418.html

Security, authentication

How can I do get the current user in a database class?

How can I protect a method based on one of its parameter?

Email Notifications

When I need to send a notification for a person/team, how do I know what email address(es) I have to send the notification to?

Web UI

When should I use SQLObjectEditView and SQLObjectAddView

How do I use the General Form

How do I perform an action after an autogenerated edit form has been successfully submitted?

How do I perform an action after an autogenerated add form has been successfully submitted?

How can I redirect a user to a new object just created from an autogenerated add form?

How do I format dates and times in page templates?

How should I generate notices like "Added Bug #1234" to the top of the page?

Launchpad API

How do I add a new celebrity?

Global Configuration

How do I add items to launchpad.conf?

key_name must be a valid Python identifier.

section_name must be a valid Python identifier.

How are these default values changed for specific environments?

The default configuration values are overridden in /configs/<environment>/launchpad-lazr.conf. Notable environments include:

The syntax for overriding configuration values is the same as the syntax for defining them.

How do I use the items listed in launchpad.conf?

How can I temporarily override configuration variables in tests?

Since configuration is specified by a global object, canonical.config.config, tests for configuration-dependent will need to temporarily change configuration values.

Here's how to do it:

Note that config.push will alter the global configuration of the current environment. If you invoke it, you must call config.pop. You can make sure this happens by:

XXX: JonathanLange 2008-09-17: pushConfig in codeimport.tests.test_dispatcher should be moved into TestCase and this FAQ updated accordingly.

Testing

What kind of tests should we use?

How do I run just one doctest file, e.g. `lib/canonical/launchpad/doc/mytest.txt`?

What about running just one pagetest story, e.g. `lib/canonical/launchpad/pagetests/initial-bug-contacts`?

What about running a standalone pagetest, e.g. `xx-bug-index.txt`

And if I want to execute all test except one?

How can I examine my test output with PDB?

Where can I get help on running tests?

How can I check test coverage?

How can I run only the tests for the page test layer?

Where should I put my tests: in a `test_foo.py` module, or a `foo.txt` doctest file?

How to I setup my tests namespace so I can remove unwanted import statements and other noise?

Why is my page test failing mysteriously?

I'm writing a pagetest in the standalone directory that changes some objects. Will my changes be visible to other pagetests in this directory?

Why is not my page test failing when adding extra whitespace chars inside a textarea?

What does the number in square brackets after a doctest name mean?

How do I find a backtrace?

Should I rely on the order of os.listdir?

How do I find the tests that cover the code I've changed?

Although you've written the tests first before changing code, a lot of code is also exercised by many other tests and it's not immediately obvious which those might be without running the whole test suite. There is an experimental tool to help with this at TestsFromChanges.

Sample Data

Sampledata should be innocuous, such that if it is viewed by people outside Canonical, it will not be embarrassing or reveal company-confidential information.

Where can I find a list of the sample users?

How to I make changes to the sample Launchpad database?

I've only made minor changes to the sample data, but the diff is huge!

Code Reviews

How do I use Meld with Bazaar to do code reviews?

Bazaar

How do I revert some revisions from my archive?

I merged from another branch and did a lot of changes without first committing the merge. How can I undo only the merge?

If you are sure your changes don't touch the same code as the merge does, you can do this and it'll probably work:

On the other hand, if your changes touch the same code as the merge, it's better to do the following

How can I get error failures from PQM by email?

How do I set up connection multiplexing for my SSH session?

Rollouts

See ReleaseCycles for more information.

When will my code changes end up on production?

I have an urgent bug fix

What is the staging server?

How do I run scripts with the Python environment of Launchpad?

Use bin/py in your trunk, or whatever other branch you want to use. You might also want to use bin/ipy, if you like IPython.

Buildout

We use zc.buildout for our build system. You can read about how we set it up in doc/buildout.txt in your trunk.

Working with our open-source components (lazr.*)

See HackingLazrLibraries.

Where to go for other help

If you have encountered a problem, maybe someone else has and has already documented it on the SolutionsLog. Go have a look! If have a problem and you find a solution, document it there!

Unanswered questions