Templates¶
pymetacode heavily relies on templates (and uses Jinja as template engine) for performing most of its tasks. The major areas where templates are used are identical to those use cases you encounter in the daily use of the package:
creating a new module
adding a class to a module
adding a function to a module
In each case, not only code stubs are created, but stubs for unit tests as well.
Another line of organisation are subpackages. Hence another, though perhaps less likely usecase in the daily use of the package is:
creating a new subpackage
Below, the templates for these most important aspects are documented in the form currently contained in the pymetacode package itself. Although these templates contain some markup for the Jinja template engine, they should still be rather readable.
Templates for modules¶
When adding a module to your package, three files are created in their respective (sub)directories:
The module in the package source directory (same name as the package)
The corresponding test module in the tests directory
The reStructuredText file for the API documentation in the docs/api directory
For details, see the pymetacode.coding.ModuleCreator
class documentation. Note that the module does not yet have any further content.
The module template¶
"""
{{ module.name }} module of the {{ package.name }} package.
"""
{% if options.logging %}
import logging
logger = logging.getLogger(__name__)
{% endif %}
The test_module template¶
import unittest
from {{ package.name }} import {{ module.name }}
The module API documentation template¶
{{ package.name }}.{{ module.name }} module
======={{ header_extension }}
.. automodule:: {{ package.name }}.{{ module.name }}
:members:
:inherited-members:
:undoc-members:
:show-inheritance:
Templates for classes¶
When adding a class to a module, two files are modified and the respective code appended:
The class implementation to the module in the package source directory
The TestClass implementation in the corresponding test module in the tests directory
As the class template comes with a docstring, and the module API documentation is set such that each class will automatically be documented there (see above), building the documentation will automatically add the class documentation without further ado.
Classes (and corresponding test classes) are always appended to the end of the respective module.
For details, see the pymetacode.coding.ClassCreator
class documentation.
The class template¶
class {{ class.name }}:
"""
One sentence (on one line) describing the class.
More description comes here...
Attributes
----------
attr : :class:`None`
Short description
Raises
------
exception
Short description when and why raised
Examples
--------
It is always nice to give some examples how to use the class. Best to do
that with code examples:
.. code-block::
obj = {{ class.name }}()
...
{% if package.version != '0.1' %}
.. versionadded:: {{ package.version }}
{% endif %}
"""
pass
The test_class template¶
class Test{{ class.name }}(unittest.TestCase):
def setUp(self):
self.{{ class.instance }} = {{ module.name }}.{{ class.name }}()
def test_instantiate_class(self):
pass
Templates for functions¶
When adding a function to a module, two files are modified and the respective code appended:
The function implementation to the module in the package source directory
The TestClass implementation in the corresponding test module in the tests directory
As the function template comes with a docstring, and the module API documentation is set such that each function will automatically be documented there (see above), building the documentation will automatically add the function documentation without further ado.
Functions (and corresponding test classes) are always appended to the end of the respective module.
For details, see the pymetacode.coding.FunctionCreator
class documentation.
The function template¶
def {{ function.name }}():
"""
One sentence (on one line) describing the function.
More description comes here...
Parameters
----------
param : :class:`None`
Short description
Returns
-------
param : :class:`None`
Short description
{% if package.version != '0.1' %}
.. versionadded:: {{ package.version }}
{% endif %}
"""
pass
The test_function template¶
class Test{{ function.name_camelcase }}(unittest.TestCase):
def test_{{ function.name }}(self):
pass
Templates for subpackages¶
When adding a subpackage to your package, three directories are created in their respective (sub)directories:
The subpackage directory in the package source directory (same name as the package)
The corresponding test subpackage directory in the tests directory
The subpackage directory for the API documentation in the docs/api/ directory
Furthermore, in each of these directories, the respective files are created:
__init__.py
in the subpackage and tests subpackage (empty files each)index.rst
in the docs/api subdirectory
If there is no subpackages table of contents (TOC) block in the API docs index.rst file, such a TOC block will be created using a specific template.
For details, see the pymetacode.coding.SubpackageCreator
class documentation.
The subpackage API documentation template¶
{{ subpackage.name }} subpackage
==========={{ header_extension }}
.. automodule:: {{ subpackage.name }}
:members:
:undoc-members:
:show-inheritance:
.. toctree::
:maxdepth: 1
The subpackage API index TOC template¶
Subpackages
-----------
An alphabetic list of the subpackages available within the {{ package.name }} package. The actual documentation is split in pages for each module of each subpackage, respectively.
.. toctree::
:maxdepth: 2
Customising templates¶
While you as a user are free to customise these templates according to your needs, regarding the pattern search and replace options you are pretty much stuck with what is implemented in the respective classes and passed as “context” to the Jinja template engine. As a rule of thumb, the entire configuration is passed as context to each template.