zope.formlib has the ability to customize the used widget like this:
form_fields = zope.formlib.form.Fields(IKeywords)
form_fields['keywords'].custom_widget = KWSelectWidgetFactory
I do not like this approach for two reasons:
- the widget has to be set manually every time the specific field is used
- there is no easy way to get a display widget if the form or field is not editable for the user
Defining a new schema field and registering the widget for this field seems a bit heavy, so I came up with providing a marker interface on the field:
"""Marker interface to get a special keywords widget."""
keywords = zope.schema.List(
title = _("Edit Keywords"),
value_type = zope.schema.Choice(
I registered the edit widget and display widget for the
IHaveSelectableKeywords interface, so the custom widget does not have to be set in the form like this (edit widget):
The whole company spent three days in Kloster Drübeck sprinting on internal tools and topics.
We overhauled our workflow for generating invoices and identified steps that we could automate.
describe 'MyApp', ->
it 'has read Douglas Adams', ->
and include them into your Python test suite with a single command:
The third area of our efforts was documentation, we designed a Sphinx skeleton to make it easy to get started writing docs, and created a template for eggs that contains the necessary boilerplate and codifies our packaging and documentation conventions. While the concrete details are probably a bit specific to our tastes, some of the general mechanincs might be interesting to others, so we’ll release gocept.package once we’ve got the missing integration tests sorted out.
For integration tests it can be helpful to have a fake HTTP server whose behaviour the tests can control. All necessary building blocks are even included in Python standard library. However, the BaseHTTPServer is surprisingly hard to shut down properly, so that it gives up the socket and everything.
While working on gocept.selenium, we came up with some code that does the trick (together with Jan-Wijbrand Kolman and Jan-Jaap Driessen).
_continue = True
self._continue = False
# We fire a last request at the server in order to take it out of the
# while loop in `self.serve_until_shutdown`.
'http://%s:%s/' % (self.server_name, self.server_port))
# If the server is already shut down, we receive a socket error,
# which we ignore.
You might use this in a zope.testrunner layer like this:
def log_message(self, format, *args):
host = 'localhost'
self.server = None
self.port = random.randint(30000, 40000)
self.server = HTTPServer((self.host, self.port), SilentRequestHandler)
self.server_thread = threading.Thread(
self.server_thread.daemon = True
# Kludge: Wait a little as it sometimes takes a while to get the server
if self.server is None:
zc.sourcefactory is very handy to easily create a source (zope.schema.interfaces.IIterableSource to be precise) with corresponding titles and tokens for its contents. Every now and then a source requires an explicit interface. For zc.sourcefactory the following code snippet helps:
"""The source factory."""
"""This class is being instanciated by the factory.
It *must* be called source_class.
def getValues(self, context):
Of course it is also possible to declare the source_class separately from the source factory and reference it. But since its sole purpose is to hold an implements declaration, I’m fine with defining it inline.