Decisions ========= This is a temporary place to note decisions. The idea is to later integrate them into the Zope Toolkit documentation, but we need a quick way to note decisions first. * ZMI related code shall not be part of the Zope Toolkit, and we shall strive to remove it. * If zope.deferredimport is used in a package merely to avoid the use of ``from`` imports, then instead we will use ``from`` imports to get rid of this dependency. * Files used to support the old ZPKG system such as ``DEPENDENCIES.cfg`` can be safely removed from packages. * So-called "ZCML-slugs" which were intended to be symlinked into a special slugs directory in a Zope installation are not in use anymore. They should be removed. Typically they look like ``zope.foo-configure.zcml``. * we are going to work at getting rid of the zope.app.testing extra by distributing its facilities into individual zope.* packages. Hopefully we can get a clear consensus on this one from the people who object to the general policy. * if you think a new "extra" dependency is needed in a Zope Toolkit package, and you're not just moving stuff between packages but actually developing new code, bring it up on zope-dev so we can at least consider alternatives. Perhaps a better home can be found for this code. * We can consider removing extra dependencies for particular Zope Toolkit packages in order to make the dependency graph easier to reason about. We will do this on a case by case basis though. * In namespace package's ``__init__.py`` we have been using the following boilerplate code:: try: import pkg_resources pkg_resources.declare_namespace(__name__) except ImportError: import pkgutil __path__ = pkgutil.extend_path(__path__, __name__) Since ``setuptools`` is a dependency of our packages anyway, we can instead do the following:: __import__('pkg_resources').declare_namespace(__name__) Feel free to use that and also feel free to simplify existing ``__init__.py`` modules. Just make sure ``setuptools`` is a declared dependency of the package. * Moving code around as part of dependency refactoring is worth a feature release (x.y as opposed to x.y.z version number) for the affected packages. Changing an import to make use of a new package that came out of such refactoring is also worth a feature release. * If a package A starts to rely on new features in dependency B, that is worth a feature release of package A. * The version requirements in setup.py should specify only API compatibility. They should not specify a dependency on bug fixes; that's the domain of the KGS. Therefore in a ``setup.py`` you are allowed to write this in ``setup.py``:: bar >= x.y I.e. relying on a newer feature release of package ``bar``. but not this:: bar >= x.y.z I.e. you're not allowed to rely on a newer *bugfix* release of package ``bar``. Elaboration: Imagine package ``foo`` that depends on package ``bar``. If you make changes in ``foo`` so that it starts to rely on changes in ``bar`` that are only introduced in a feature release of ``bar`` (``bar`` version ``x.y`` or ``bar`` version ``x``), you should update the ``setup.py`` of ``foo`` to state this dependency with a requirement like this:: bar >= x.y This is only relevant to *feature* releases. If there is a bugfix release of ``bar`` you should not write a dependency like ``bar >= x.y.z``. This is a compromise in the interests of both flexibility and giving hints to people who use our packages. We'll see how it goes. * Some Zope Toolkit packages are quite reusable without having to buy into the rest of the Zope Toolkit. Others aren't reusable at all without pulling in a huge chunk of the Zope Toolkit; they depend on many assumptions. We should communicate this clearly to potential users. As a first step, we will make sure these notifications are available on the PyPI pages. We will do this by adding a message about reusability to the long_description (which gets displayed on PyPI). Typically this is done by modifying the package's README.txt or ``src/zope/../README.txt`` doctest. The following text should be used for reusable packages:: *This package is intended to be independently reusable in any Python project. It is maintained by the* `Zope Toolkit project `_. The following text should be used for packages that are *not* easily reusable:: *This package is at present not reusable without depending on a large chunk of the Zope Toolkit and its assumptions. It is maintained by the* `Zope Toolkit project `_. At the time of writing, most of our packages will be marked as *not* reusable. Only packages at the roots of our dependency tree that have a clear purpose and some documentation (such as ``zope.interface`` and ``zope.component``) should be marked as reusable. We will slowly start to build up from there. * When code moves to a new location to import it from (in the same or another package), use a ``from foo import bar`` statement, with a ``#BBB`` comment to indicate the import is only there to support backwards compatibility. In the CHANGES.txt of a package, state that an import location got deprecated and where the new location is (making this a feature release, not a bugfix release). Reasons: * it avoid a dependency on zope.deprecation, which is quite involved in its implementation, using proxies. * A ``from .. import ..`` is immediately comprehensible to any Python programmer as well as tools. * Deprecation warnings make it hard to write a library that supports multiple versions of another library; a change in an indirect dependency can create deprecation warnings that the original developer does not care about. * We are in the process of developing a testrunner extension that will report on indirect imports, and a ZODB upgrade procedure. * The open issues will be moved to the launchpad blueprints and launchpad answers. The blueprint specifications will be stored in the ZTK documentation and linked to (each blueprint will be a separate document). * As a general direction we'd like to separate out the XML-RPC related code and FTP-related code into seperate packages that aren't depended on by the rest of the toolkit. This makes it possible for developers to use the toolkit without worrying about XML-RPC or FTP. * To make it easy for developers to identify which packages are in the ZTK, as they are sometimes working in isolation, a package that is maintained by the Zope Toolkit project should have the following text in its ``setup.py`` file just under the copyright header:: ############################################################################## # This package is developed by the Zope Toolkit project, documented here: # http://docs.zope.org/zopetoolkit # When developing and releasing this package, please follow the documented # Zope Toolkit policies as described by this documentation. ############################################################################## When a package is *removed* from the ZTK this header should be removed from its ``setup.py`` as well. * There was a discussion about whether the version in ``setup.py`` should be set to ``0`` instead of the next expected version. There was a discussion and the majority of the steering group was against this change - the ZTK release policy remains the same for the ZTK. The mailing list threads discusses various pros and cons:: https://mail.zope.org/pipermail/zope-dev/2009-September/037725.html https://mail.zope.org/pipermail/zope-dev/2009-September/037735.html * We want to encourage narrative documentation for packages (doctested or not). Even though we do not require that this documentation is executable (doctested), we do prefer a project setup so that it easy to support executable documentation as well, in cooperation with tools like manuel. The bobo documentation is an example of such a setup. We should document this better.