You're reading an old version of this documentation. For up-to-date information, please have a look at v0.6.
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. Below, the templates for these most important aspects are documented in the form currently contained in the pymetacode package otseöf. 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. Note that the module does not yet have any further content.
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. Note that the module does not yet have any further content.
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
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.