diff options
author | Chris Jerdonek <chris.jerdonek@gmail.com> | 2012-05-06 20:43:49 -0700 |
---|---|---|
committer | Chris Jerdonek <chris.jerdonek@gmail.com> | 2012-05-06 20:43:49 -0700 |
commit | 78f48d52b7192745669c165f26d69f1d59b5ab0a (patch) | |
tree | f92bc3e0797b5759112d0e3383b5133d94d9277d | |
parent | 783e07a8c5100b9956d5c2c77f5b70e6f7021cbc (diff) | |
parent | 6c45363575b715f6d335edc41f94f20bb6656053 (diff) | |
download | pystache-78f48d52b7192745669c165f26d69f1d59b5ab0a.tar.gz |
Merge branch 'convert-docs-to-markdown' into development:
Converted README and HISTORY to markdown to allow use of GitHub
pages feature.
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | HISTORY.md | 146 | ||||
-rw-r--r-- | HISTORY.rst | 129 | ||||
-rw-r--r-- | LICENSE | 1 | ||||
-rw-r--r-- | MANIFEST.in | 5 | ||||
-rw-r--r-- | README.md | 228 | ||||
-rw-r--r-- | README.rst | 246 | ||||
-rw-r--r-- | pystache/tests/common.py | 2 | ||||
-rw-r--r-- | setup.py | 147 | ||||
-rw-r--r-- | setup_description.rst | 440 |
10 files changed, 946 insertions, 400 deletions
@@ -5,6 +5,8 @@ # Our tox runs convert the doctests in *.rst files to Python 3 prior to # running tests. Ignore these temporary files. *.temp2to3.rst +# The setup.py "prep" command converts *.md to *.temp.rst. +*.temp.rst # TextMate project file *.tmproj # Distribution-related folders and files. diff --git a/HISTORY.md b/HISTORY.md new file mode 100644 index 0000000..333e68c --- /dev/null +++ b/HISTORY.md @@ -0,0 +1,146 @@ +History +======= + +0.5.3 (TBD) +----------- + +- Added option of raising errors on missing tags/partials: + `Renderer(missing_tags='strict')` (issue \#110). +- Added a `parse()` function that yields a printable, pre-compiled + parse tree. +- Added support for rendering pre-compiled templates. +- Bugfix: exceptions raised from a property are no longer swallowed + when getting a key from a context stack (issue \#110). +- Bugfix: lambda section values can now return non-ascii, non-unicode + strings (issue \#118). +- More robust handling of byte strings in Python 3. + +0.5.2 (2012-05-03) +------------------ + +- Added support for dot notation and version 1.1.2 of the spec (issue + \#99). [rbp] +- Missing partials now render as empty string per latest version of + spec (issue \#115). +- Bugfix: falsey values now coerced to strings using str(). +- Bugfix: lambda return values for sections no longer pushed onto + context stack (issue \#113). +- Bugfix: lists of lambdas for sections were not rendered (issue + \#114). + +0.5.1 (2012-04-24) +------------------ + +- Added support for Python 3.1 and 3.2. +- Added tox support to test multiple Python versions. +- Added test script entry point: pystache-test. +- Added \_\_version\_\_ package attribute. +- Test harness now supports both YAML and JSON forms of Mustache spec. +- Test harness no longer requires nose. + +0.5.0 (2012-04-03) +------------------ + +This version represents a major rewrite and refactoring of the code base +that also adds features and fixes many bugs. All functionality and +nearly all unit tests have been preserved. However, some backwards +incompatible changes to the API have been made. + +Below is a selection of some of the changes (not exhaustive). + +Highlights: + +- Pystache now passes all tests in version 1.0.3 of the [Mustache + spec](https://github.com/mustache/spec). [pvande] +- Removed View class: it is no longer necessary to subclass from View + or from any other class to create a view. +- Replaced Template with Renderer class: template rendering behavior + can be modified via the Renderer constructor or by setting + attributes on a Renderer instance. +- Added TemplateSpec class: template rendering can be specified on a + per-view basis by subclassing from TemplateSpec. +- Introduced separation of concerns and removed circular dependencies + (e.g. between Template and View classes, cf. [issue + \#13](https://github.com/defunkt/pystache/issues/13)). +- Unicode now used consistently throughout the rendering process. +- Expanded test coverage: nosetests now runs doctests and \~105 test + cases from the Mustache spec (increasing the number of tests from 56 + to \~315). +- Added a rudimentary benchmarking script to gauge performance while + refactoring. +- Extensive documentation added (e.g. docstrings). + +Other changes: + +- Added a command-line interface. [vrde] +- The main rendering class now accepts a custom partial loader (e.g. a + dictionary) and a custom escape function. +- Non-ascii characters in str strings are now supported while + rendering. +- Added string encoding, file encoding, and errors options for + decoding to unicode. +- Removed the output encoding option. +- Removed the use of markupsafe. + +Bug fixes: + +- Context values no longer processed as template strings. + [jakearchibald] +- Whitespace surrounding sections is no longer altered, per the spec. + [heliodor] +- Zeroes now render correctly when using PyPy. [alex] +- Multline comments now permitted. [fczuardi] +- Extensionless template files are now supported. +- Passing `**kwargs` to `Template()` no longer modifies the context. +- Passing `**kwargs` to `Template()` with no context no longer raises + an exception. + +0.4.1 (2012-03-25) +------------------ + +- Added support for Python 2.4. [wangtz, jvantuyl] + +0.4.0 (2011-01-12) +------------------ + +- Add support for nested contexts (within template and view) +- Add support for inverted lists +- Decoupled template loading + +0.3.1 (2010-05-07) +------------------ + +- Fix package + +0.3.0 (2010-05-03) +------------------ + +- View.template\_path can now hold a list of path +- Add {{& blah}} as an alias for {{{ blah }}} +- Higher Order Sections +- Inverted sections + +0.2.0 (2010-02-15) +------------------ + +- Bugfix: Methods returning False or None are not rendered +- Bugfix: Don't render an empty string when a tag's value is 0. + [enaeseth] +- Add support for using non-callables as View attributes. + [joshthecoder] +- Allow using View instances as attributes. [joshthecoder] +- Support for Unicode and non-ASCII-encoded bytestring output. + [enaeseth] +- Template file encoding awareness. [enaeseth] + +0.1.1 (2009-11-13) +------------------ + +- Ensure we're dealing with strings, always +- Tests can be run by executing the test file directly + +0.1.0 (2009-11-12) +------------------ + +- First release + diff --git a/HISTORY.rst b/HISTORY.rst deleted file mode 100644 index 6ec24dd..0000000 --- a/HISTORY.rst +++ /dev/null @@ -1,129 +0,0 @@ -History -======= - -0.5.3 (TBD) ------------ - -* Added option of raising errors on missing tags/partials: - ``Renderer(missing_tags='strict')`` (issue #110). -* Added a ``parse()`` function that yields a printable, pre-compiled parse tree. -* Added support for rendering pre-compiled templates. -* Bugfix: exceptions raised from a property are no longer swallowed when - getting a key from a context stack (issue #110). -* Bugfix: lambda section values can now return non-ascii, non-unicode strings (issue #118). -* More robust handling of byte strings in Python 3. - -0.5.2 (2012-05-03) ------------------- - -* Added support for dot notation and version 1.1.2 of the spec (issue #99). [rbp] -* Missing partials now render as empty string per latest version of spec (issue #115). -* Bugfix: falsey values now coerced to strings using str(). -* Bugfix: lambda return values for sections no longer pushed onto context stack (issue #113). -* Bugfix: lists of lambdas for sections were not rendered (issue #114). - -0.5.1 (2012-04-24) ------------------- - -* Added support for Python 3.1 and 3.2. -* Added tox support to test multiple Python versions. -* Added test script entry point: pystache-test. -* Added __version__ package attribute. -* Test harness now supports both YAML and JSON forms of Mustache spec. -* Test harness no longer requires nose. - -0.5.0 (2012-04-03) ------------------- - -This version represents a major rewrite and refactoring of the code base -that also adds features and fixes many bugs. All functionality and nearly -all unit tests have been preserved. However, some backwards incompatible -changes to the API have been made. - -Below is a selection of some of the changes (not exhaustive). - -Highlights: - -* Pystache now passes all tests in version 1.0.3 of the `Mustache spec`_. [pvande] -* Removed View class: it is no longer necessary to subclass from View or - from any other class to create a view. -* Replaced Template with Renderer class: template rendering behavior can be - modified via the Renderer constructor or by setting attributes on a Renderer instance. -* Added TemplateSpec class: template rendering can be specified on a per-view - basis by subclassing from TemplateSpec. -* Introduced separation of concerns and removed circular dependencies (e.g. - between Template and View classes, cf. `issue #13`_). -* Unicode now used consistently throughout the rendering process. -* Expanded test coverage: nosetests now runs doctests and ~105 test cases - from the Mustache spec (increasing the number of tests from 56 to ~315). -* Added a rudimentary benchmarking script to gauge performance while refactoring. -* Extensive documentation added (e.g. docstrings). - -Other changes: - -* Added a command-line interface. [vrde] -* The main rendering class now accepts a custom partial loader (e.g. a dictionary) - and a custom escape function. -* Non-ascii characters in str strings are now supported while rendering. -* Added string encoding, file encoding, and errors options for decoding to unicode. -* Removed the output encoding option. -* Removed the use of markupsafe. - -Bug fixes: - -* Context values no longer processed as template strings. [jakearchibald] -* Whitespace surrounding sections is no longer altered, per the spec. [heliodor] -* Zeroes now render correctly when using PyPy. [alex] -* Multline comments now permitted. [fczuardi] -* Extensionless template files are now supported. -* Passing ``**kwargs`` to ``Template()`` no longer modifies the context. -* Passing ``**kwargs`` to ``Template()`` with no context no longer raises an exception. - -0.4.1 (2012-03-25) ------------------- -* Added support for Python 2.4. [wangtz, jvantuyl] - -0.4.0 (2011-01-12) ------------------- -* Add support for nested contexts (within template and view) -* Add support for inverted lists -* Decoupled template loading - -0.3.1 (2010-05-07) ------------------- - -* Fix package - -0.3.0 (2010-05-03) ------------------- - -* View.template_path can now hold a list of path -* Add {{& blah}} as an alias for {{{ blah }}} -* Higher Order Sections -* Inverted sections - -0.2.0 (2010-02-15) ------------------- - -* Bugfix: Methods returning False or None are not rendered -* Bugfix: Don't render an empty string when a tag's value is 0. [enaeseth] -* Add support for using non-callables as View attributes. [joshthecoder] -* Allow using View instances as attributes. [joshthecoder] -* Support for Unicode and non-ASCII-encoded bytestring output. [enaeseth] -* Template file encoding awareness. [enaeseth] - -0.1.1 (2009-11-13) ------------------- - -* Ensure we're dealing with strings, always -* Tests can be run by executing the test file directly - -0.1.0 (2009-11-12) ------------------- - -* First release - - -.. _2to3: http://docs.python.org/library/2to3.html -.. _issue #13: https://github.com/defunkt/pystache/issues/13 -.. _Mustache spec: https://github.com/mustache/spec @@ -1,4 +1,5 @@ Copyright (C) 2012 Chris Jerdonek. All rights reserved. + Copyright (c) 2009 Chris Wanstrath Permission is hereby granted, free of charge, to any person obtaining diff --git a/MANIFEST.in b/MANIFEST.in index 56a1d52..d7b83ca 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,7 @@ +include README.md +include HISTORY.md include LICENSE -include HISTORY.rst -include README.rst +include DESCRIPTION.rst include tox.ini include test_pystache.py # You cannot use package_data, for example, to include data files in a diff --git a/README.md b/README.md new file mode 100644 index 0000000..17f708c --- /dev/null +++ b/README.md @@ -0,0 +1,228 @@ +Pystache +======== + +![](https://s3.amazonaws.com/webdev_bucket/pystache.png "mustachioed, monocled snake by David Phillips") + +[Pystache](https://github.com/defunkt/pystache) is a Python +implementation of [Mustache](http://mustache.github.com/). Mustache is a +framework-agnostic, logic-free templating system inspired by +[ctemplate](http://code.google.com/p/google-ctemplate/) and +[et](http://www.ivan.fomichev.name/2008/05/erlang-template-engine-prototype.html). +Like ctemplate, Mustache "emphasizes separating logic from presentation: +it is impossible to embed application logic in this template language." + +The [mustache(5)](http://mustache.github.com/mustache.5.html) man page +provides a good introduction to Mustache's syntax. For a more complete +(and more current) description of Mustache's behavior, see the official +[Mustache spec](https://github.com/mustache/spec). + +Pystache is [semantically versioned](http://semver.org) and can be found +on [PyPI](http://pypi.python.org/pypi/pystache). This version of +Pystache passes all tests in [version +1.1.2](https://github.com/mustache/spec/tree/v1.1.2) of the spec. + +Logo: [David Phillips](http://davidphillips.us/) + +Requirements +------------ + +Pystache is tested with-- + +- Python 2.4 (requires simplejson [version + 2.0.9](http://pypi.python.org/pypi/simplejson/2.0.9) or earlier) +- Python 2.5 (requires + [simplejson](http://pypi.python.org/pypi/simplejson/)) +- Python 2.6 +- Python 2.7 +- Python 3.1 +- Python 3.2 + +JSON support is needed only for the command-line interface and to run +the spec tests. We require simplejson for earlier versions of Python +since Python's [json](http://docs.python.org/library/json.html) module +was added in Python 2.6. + +For Python 2.4 we require an earlier version of simplejson since +simplejson stopped officially supporting Python 2.4 in simplejson +version 2.1.0. Earlier versions of simplejson can be installed manually, +as follows: + + pip install 'simplejson<2.1.0' + +Install It +---------- + + pip install pystache + pystache-test + +To install and test from source (e.g. from GitHub), see the Develop +section. + +Use It +------ + + >>> import pystache + >>> print pystache.render('Hi {{person}}!', {'person': 'Mom'}) + Hi Mom! + +You can also create dedicated view classes to hold your view logic. + +Here's your view class (in .../examples/readme.py): + + class SayHello(object): + def to(self): + return "Pizza" + +Instantiating like so: + + >>> from pystache.tests.examples.readme import SayHello + >>> hello = SayHello() + +Then your template, say\_hello.mustache (by default in the same +directory as your class definition): + + Hello, {{to}}! + +Pull it together: + + >>> renderer = pystache.Renderer() + >>> print renderer.render(hello) + Hello, Pizza! + +For greater control over rendering (e.g. to specify a custom template +directory), use the `Renderer` class like above. One can pass attributes +to the Renderer class constructor or set them on a Renderer instance. To +customize template loading on a per-view basis, subclass `TemplateSpec`. +See the docstrings of the +[Renderer](https://github.com/defunkt/pystache/blob/master/pystache/renderer.py) +class and +[TemplateSpec](https://github.com/defunkt/pystache/blob/master/pystache/template_spec.py) +class for more information. + +You can also pre-parse a template: + + >>> parsed = pystache.parse(u"Hey {{#who}}{{.}}!{{/who}}") + >>> print parsed + [u'Hey ', _SectionNode(key=u'who', index_begin=12, index_end=18, parsed=[_EscapeNode(key=u'.'), u'!'])] + +And then: + + >>> print renderer.render(parsed, {'who': 'Pops'}) + Hey Pops! + >>> print renderer.render(parsed, {'who': 'you'}) + Hey you! + +Python 3 +-------- + +Pystache has supported Python 3 since version 0.5.1. Pystache behaves +slightly differently between Python 2 and 3, as follows: + +- In Python 2, the default html-escape function `cgi.escape()` does + not escape single quotes; whereas in Python 3, the default escape + function `html.escape()` does escape single quotes. +- In both Python 2 and 3, the string and file encodings default to + `sys.getdefaultencoding()`. However, this function can return + different values under Python 2 and 3, even when run from the same + system. Check your own system for the behavior on your system, or do + not rely on the defaults by passing in the encodings explicitly + (e.g. to the `Renderer` class). + +Unicode +------- + +This section describes how Pystache handles unicode, strings, and +encodings. + +Internally, Pystache uses [only unicode +strings](http://docs.python.org/howto/unicode.html#tips-for-writing-unicode-aware-programs) +(`str` in Python 3 and `unicode` in Python 2). For input, Pystache +accepts both unicode strings and byte strings (`bytes` in Python 3 and +`str` in Python 2). For output, Pystache's template rendering methods +return only unicode. + +Pystache's `Renderer` class supports a number of attributes to control +how Pystache converts byte strings to unicode on input. These include +the `file_encoding`, `string_encoding`, and `decode_errors` attributes. + +The `file_encoding` attribute is the encoding the renderer uses to +convert to unicode any files read from the file system. Similarly, +`string_encoding` is the encoding the renderer uses to convert any other +byte strings encountered during the rendering process into unicode (e.g. +context values that are encoded byte strings). + +The `decode_errors` attribute is what the renderer passes as the +`errors` argument to Python's built-in unicode-decoding function +(`str()` in Python 3 and `unicode()` in Python 2). The valid values for +this argument are `strict`, `ignore`, and `replace`. + +Each of these attributes can be set via the `Renderer` class's +constructor using a keyword argument of the same name. See the Renderer +class's docstrings for further details. In addition, the `file_encoding` +attribute can be controlled on a per-view basis by subclassing the +`TemplateSpec` class. When not specified explicitly, these attributes +default to values set in Pystache's `defaults` module. + +Develop +------- + +To test from a source distribution (without installing)-- + + python test_pystache.py + +To test Pystache with multiple versions of Python (with a single +command!), you can use [tox](http://pypi.python.org/pypi/tox): + + pip install tox + tox + +If you do not have all Python versions listed in `tox.ini`-- + + tox -e py26,py32 # for example + +The source distribution tests also include doctests and tests from the +Mustache spec. To include tests from the Mustache spec in your test +runs: + + git submodule init + git submodule update + +The test harness parses the spec's (more human-readable) yaml files if +[PyYAML](http://pypi.python.org/pypi/PyYAML) is present. Otherwise, it +parses the json files. To install PyYAML-- + + pip install pyyaml + +To run a subset of the tests, you can use +[nose](http://somethingaboutorange.com/mrl/projects/nose/0.11.1/testing.html): + + pip install nose + nosetests --tests pystache/tests/test_context.py:GetValueTests.test_dictionary__key_present + +**Running Pystache from source with Python 3.** Pystache is written in +Python 2 and must be converted with +[2to3](http://docs.python.org/library/2to3.html) prior to running under +Python 3. The installation process (and tox) do this conversion +automatically. + +To `import pystache` from a source distribution while using Python 3, be +sure that you are importing from a directory containing a converted +version (e.g. from your site-packages directory after manually +installing) and not from the original source directory. Otherwise, you +will get a syntax error. You can help ensure this by not running the +Python IDE from the project directory when importing Pystache. + +Mailing List +------------ + +There is a [mailing list](http://librelist.com/browser/pystache/). Note +that there is a bit of a delay between posting a message and seeing it +appear in the mailing list archive. + +Authors +------- + + >>> context = { 'author': 'Chris Wanstrath', 'maintainer': 'Chris Jerdonek' } + >>> print pystache.render("Author: {{author}}\nMaintainer: {{maintainer}}", context) + Author: Chris Wanstrath + Maintainer: Chris Jerdonek diff --git a/README.rst b/README.rst deleted file mode 100644 index c8d8446..0000000 --- a/README.rst +++ /dev/null @@ -1,246 +0,0 @@ -======== -Pystache -======== - -.. image:: https://s3.amazonaws.com/webdev_bucket/pystache.png - -Pystache_ is a Python implementation of Mustache_. -Mustache is a framework-agnostic, logic-free templating system inspired -by ctemplate_ and et_. Like ctemplate, Mustache "emphasizes -separating logic from presentation: it is impossible to embed application -logic in this template language." - -The `mustache(5)`_ man page provides a good introduction to Mustache's -syntax. For a more complete (and more current) description of Mustache's -behavior, see the official `Mustache spec`_. - -Pystache is `semantically versioned`_ and can be found on PyPI_. This -version of Pystache passes all tests in `version 1.1.2`_ of the spec. - -Logo: `David Phillips`_ - - -Requirements -============ - -Pystache is tested with-- - -* Python 2.4 (requires simplejson `version 2.0.9`_ or earlier) -* Python 2.5 (requires simplejson_) -* Python 2.6 -* Python 2.7 -* Python 3.1 -* Python 3.2 - -JSON support is needed only for the command-line interface and to run the -spec tests. We require simplejson for earlier versions of Python since -Python's json_ module was added in Python 2.6. - -For Python 2.4 we require an earlier version of simplejson since simplejson -stopped officially supporting Python 2.4 in simplejson version 2.1.0. -Earlier versions of simplejson can be installed manually, as follows: :: - - pip install 'simplejson<2.1.0' - - -Install It -========== - -:: - - pip install pystache - pystache-test - -To install and test from source (e.g. from GitHub), see the Develop section. - - -Use It -====== - -:: - - >>> import pystache - >>> print pystache.render('Hi {{person}}!', {'person': 'Mom'}) - Hi Mom! - -You can also create dedicated view classes to hold your view logic. - -Here's your view class (in .../examples/readme.py):: - - class SayHello(object): - def to(self): - return "Pizza" - -Instantiating like so:: - - >>> from pystache.tests.examples.readme import SayHello - >>> hello = SayHello() - -Then your template, say_hello.mustache (by default in the same directory -as your class definition):: - - Hello, {{to}}! - -Pull it together:: - - >>> renderer = pystache.Renderer() - >>> print renderer.render(hello) - Hello, Pizza! - -For greater control over rendering (e.g. to specify a custom template directory), -use the ``Renderer`` class like above. One can pass attributes to the -Renderer class constructor or set them on a Renderer instance. -To customize template loading on a per-view basis, subclass ``TemplateSpec``. -See the docstrings of the Renderer_ class and TemplateSpec_ class for -more information. - -You can also pre-parse a template: :: - - >>> parsed = pystache.parse(u"Hey {{#who}}{{.}}!{{/who}}") - >>> print parsed - [u'Hey ', _SectionNode(key=u'who', index_begin=12, index_end=18, parsed=[_EscapeNode(key=u'.'), u'!'])] - -And then:: - - >>> print renderer.render(parsed, {'who': 'Pops'}) - Hey Pops! - >>> print renderer.render(parsed, {'who': 'you'}) - Hey you! - - -Python 3 -======== - -Pystache has supported Python 3 since version 0.5.1. Pystache behaves -slightly differently between Python 2 and 3, as follows: - -* In Python 2, the default html-escape function ``cgi.escape()`` does not - escape single quotes; whereas in Python 3, the default escape function - ``html.escape()`` does escape single quotes. -* In both Python 2 and 3, the string and file encodings default to - ``sys.getdefaultencoding()``. However, this function can return different - values under Python 2 and 3, even when run from the same system. Check - your own system for the behavior on your system, or do not rely on the - defaults by passing in the encodings explicitly (e.g. to the ``Renderer`` class). - - -Unicode -======= - -This section describes how Pystache handles unicode, strings, and encodings. - -Internally, Pystache uses `only unicode strings`_ (``str`` in Python 3 and -``unicode`` in Python 2). For input, Pystache accepts both unicode strings -and byte strings (``bytes`` in Python 3 and ``str`` in Python 2). For output, -Pystache's template rendering methods return only unicode. - -Pystache's ``Renderer`` class supports a number of attributes to control how -Pystache converts byte strings to unicode on input. These include the -``file_encoding``, ``string_encoding``, and ``decode_errors`` attributes. - -The ``file_encoding`` attribute is the encoding the renderer uses to convert -to unicode any files read from the file system. Similarly, ``string_encoding`` -is the encoding the renderer uses to convert any other byte strings encountered -during the rendering process into unicode (e.g. context values that are -encoded byte strings). - -The ``decode_errors`` attribute is what the renderer passes as the ``errors`` -argument to Python's built-in unicode-decoding function (``str()`` in Python 3 -and ``unicode()`` in Python 2). The valid values for this argument are -``strict``, ``ignore``, and ``replace``. - -Each of these attributes can be set via the ``Renderer`` class's constructor -using a keyword argument of the same name. See the Renderer class's -docstrings for further details. In addition, the ``file_encoding`` -attribute can be controlled on a per-view basis by subclassing the -``TemplateSpec`` class. When not specified explicitly, these attributes -default to values set in Pystache's ``defaults`` module. - - -Develop -======= - -To test from a source distribution (without installing)-- :: - - python test_pystache.py - -To test Pystache with multiple versions of Python (with a single command!), -you can use tox_: :: - - pip install tox - tox - -If you do not have all Python versions listed in ``tox.ini``-- :: - - tox -e py26,py32 # for example - -The source distribution tests also include doctests and tests from the -Mustache spec. To include tests from the Mustache spec in your test runs: :: - - git submodule init - git submodule update - -The test harness parses the spec's (more human-readable) yaml files if PyYAML_ -is present. Otherwise, it parses the json files. To install PyYAML-- :: - - pip install pyyaml - -To run a subset of the tests, you can use nose_: :: - - pip install nose - nosetests --tests pystache/tests/test_context.py:GetValueTests.test_dictionary__key_present - -**Running Pystache from source with Python 3.** Pystache is written in -Python 2 and must be converted with 2to3_ prior to running under Python 3. -The installation process (and tox) do this conversion automatically. - -To ``import pystache`` from a source distribution while using Python 3, -be sure that you are importing from a directory containing a converted -version (e.g. from your site-packages directory after manually installing) -and not from the original source directory. Otherwise, you will get a -syntax error. You can help ensure this by not running the Python IDE -from the project directory when importing Pystache. - - -Mailing List -============ - -There is a `mailing list`_. Note that there is a bit of a delay between -posting a message and seeing it appear in the mailing list archive. - - -Authors -======= - -:: - - >>> context = { 'author': 'Chris Wanstrath', 'maintainer': 'Chris Jerdonek' } - >>> print pystache.render("Author: {{author}}\nMaintainer: {{maintainer}}", context) - Author: Chris Wanstrath - Maintainer: Chris Jerdonek - - -.. _2to3: http://docs.python.org/library/2to3.html -.. _built-in unicode function: http://docs.python.org/library/functions.html#unicode -.. _ctemplate: http://code.google.com/p/google-ctemplate/ -.. _David Phillips: http://davidphillips.us/ -.. _Distribute: http://pypi.python.org/pypi/distribute -.. _et: http://www.ivan.fomichev.name/2008/05/erlang-template-engine-prototype.html -.. _json: http://docs.python.org/library/json.html -.. _mailing list: http://librelist.com/browser/pystache/ -.. _Mustache: http://mustache.github.com/ -.. _Mustache spec: https://github.com/mustache/spec -.. _mustache(5): http://mustache.github.com/mustache.5.html -.. _nose: http://somethingaboutorange.com/mrl/projects/nose/0.11.1/testing.html -.. _only unicode strings: http://docs.python.org/howto/unicode.html#tips-for-writing-unicode-aware-programs -.. _PyPI: http://pypi.python.org/pypi/pystache -.. _Pystache: https://github.com/defunkt/pystache -.. _PyYAML: http://pypi.python.org/pypi/PyYAML -.. _Renderer: https://github.com/defunkt/pystache/blob/master/pystache/renderer.py -.. _semantically versioned: http://semver.org -.. _simplejson: http://pypi.python.org/pypi/simplejson/ -.. _TemplateSpec: https://github.com/defunkt/pystache/blob/master/pystache/template_spec.py -.. _test: http://packages.python.org/distribute/setuptools.html#test -.. _tox: http://pypi.python.org/pypi/tox -.. _version 1.1.2: https://github.com/mustache/spec/tree/v1.1.2 -.. _version 2.0.9: http://pypi.python.org/pypi/simplejson/2.0.9 diff --git a/pystache/tests/common.py b/pystache/tests/common.py index 24b24dc..307a2be 100644 --- a/pystache/tests/common.py +++ b/pystache/tests/common.py @@ -22,7 +22,7 @@ PROJECT_DIR = os.path.join(PACKAGE_DIR, '..') SPEC_TEST_DIR = os.path.join(PROJECT_DIR, 'ext', 'spec', 'specs') # TEXT_DOCTEST_PATHS: the paths to text files (i.e. non-module files) # containing doctests. The paths should be relative to the project directory. -TEXT_DOCTEST_PATHS = ['README.rst'] +TEXT_DOCTEST_PATHS = ['README.md'] UNITTEST_FILE_PREFIX = "test_" @@ -7,7 +7,25 @@ This script supports publishing Pystache to PyPI. This docstring contains instructions to Pystache maintainers on how to release a new version of Pystache. -(1) Push to PyPI. To release a new version of Pystache to PyPI-- +(1) Prepare the release. + +Make sure the code is finalized and merged to master. Bump the version +number in setup.py, etc. + +Generate the reStructuredText long_description using-- + + python setup.py prep + +and be sure this new version is checked in. You must have pandoc installed +to do this step: + + http://johnmacfarlane.net/pandoc/ + +It helps to review this auto-generated file on GitHub prior to uploading +because the long description will be sent to PyPI and appear there after +publishing. + +(2) Push to PyPI. To release a new version of Pystache to PyPI-- http://pypi.python.org/pypi/pystache @@ -15,8 +33,7 @@ create a PyPI user account if you do not already have one. The user account will need permissions to push to PyPI. A current "Package Index Owner" of Pystache can grant you those permissions. -When you have permissions, run the following (after preparing the release, -merging to master, bumping the version number in setup.py, etc): +When you have permissions, run the following: python setup.py publish @@ -35,7 +52,7 @@ as described here, for example: http://docs.python.org/release/2.5.2/dist/pypirc.html -(2) Tag the release on GitHub. Here are some commands for tagging. +(3) Tag the release on GitHub. Here are some commands for tagging. List current tags: @@ -52,8 +69,10 @@ Push a tag to GitHub: """ import os +import shutil import sys + py_version = sys.version_info # Distribute works with Python 2.3.5 and above: @@ -67,16 +86,20 @@ else: import setuptools as dist setup = dist.setup -# TODO: use the logging module instead of printing. -# TODO: include the following in a verbose mode. -# print("Using: version %s of %s" % (repr(dist.__version__), repr(dist))) - VERSION = '0.5.2-rc.1' # Also change in pystache/__init__.py. -HISTORY_PATH = 'HISTORY.rst' +FILE_ENCODING = 'utf-8' + +README_PATH = 'README.md' +HISTORY_PATH = 'HISTORY.md' LICENSE_PATH = 'LICENSE' -README_PATH = 'README.rst' + +DESCRIPTION_PATH = 'setup_description.rst' + +TEMP_REST_EXTENSION = '.temp.rst' + +PREP_COMMAND = 'prep' CLASSIFIERS = ( 'Development Status :: 4 - Beta', @@ -106,15 +129,83 @@ def read(path): finally: f.close() - return b.decode('utf-8') + return b.decode(FILE_ENCODING) + + +def write(u, path): + """ + Write a unicode string to a file (as utf-8). + + """ + print("Writing to: %s" % path) + # This function implementation was chosen to be compatible across Python 2/3. + f = open(path, "wb") + try: + b = u.encode(FILE_ENCODING) + f.write(b) + finally: + f.close() + + +def make_temp_path(path): + root, ext = os.path.splitext(path) + temp_path = root + TEMP_REST_EXTENSION + return temp_path + + +def make_description_file(target_path): + """ + Generate the long_description needed for setup.py. + + The long description needs to be formatted as reStructuredText: + http://docs.python.org/distutils/setupscript.html#additional-meta-data + + """ + # Comments in reST begin with two dots. + intro = """\ +.. This file is auto-generated by setup.py, so it should not be edited. +""" + + readme_path = convert_md_to_rst(README_PATH) + history_path = convert_md_to_rst(HISTORY_PATH) + + license = """\ +License +======= + +""" + read(LICENSE_PATH) + + sections = [intro, read(readme_path), read(history_path), license] + + description = '\n'.join(sections) + + write(description, target_path) + + +def prep(): + make_description_file(DESCRIPTION_PATH) def publish(): """ Publish this package to PyPI (aka "the Cheeseshop"). """ - answer = raw_input("Are you sure (yes/no)?") + temp_path = make_temp_path(DESCRIPTION_PATH) + make_description_file(temp_path) + + if read(temp_path) != read(DESCRIPTION_PATH): + print("""\ +Description file not up-to-date: %s +Run the following command and commit the changes-- + + python setup.py %s +""" % (DESCRIPTION_PATH, PREP_COMMAND)) + sys.exit() + + print("Description up-to-date: %s" % DESCRIPTION_PATH) + + answer = raw_input("Are you sure you want to publish to PyPI (yes/no)?") if answer != "yes": exit("Aborted: nothing published") @@ -122,19 +213,21 @@ def publish(): os.system('python setup.py sdist upload') -def make_long_description(): +def convert_md_to_rst(path): """ - Return the long description for the package. + Convert the given file from markdown to reStructuredText. + + Returns the new path. """ - license = """\ -License -======= + temp_path = make_temp_path(path) + print("Converting: %s to %s" % (path, temp_path)) -""" + read(LICENSE_PATH) + # Pandoc uses the UTF-8 character encoding for both input and output. + command = "pandoc --write=rst --output=%s %s" % (temp_path, path) + os.system(command) - sections = [read(README_PATH), read(HISTORY_PATH), license] - return '\n\n'.join(sections) + return temp_path # We follow the guidance here for compatibility with using setuptools instead @@ -183,11 +276,20 @@ PACKAGES = [ def main(sys_argv): - if sys.argv[-1] == 'publish': + # TODO: use the logging module instead of printing. + # TODO: include the following in a verbose mode. + print("pystache: using: version %s of %s" % (repr(dist.__version__), repr(dist))) + + command = sys_argv[-1] + + if command == 'publish': publish() sys.exit() + elif command == PREP_COMMAND: + prep() + sys.exit() - long_description = make_long_description() + long_description = read(DESCRIPTION_PATH) template_files = ['*.mustache', '*.txt'] setup(name='pystache', @@ -198,6 +300,7 @@ def main(sys_argv): author='Chris Wanstrath', author_email='chris@ozmm.org', maintainer='Chris Jerdonek', + maintainer_email='chris.jerdonek@gmail.com', url='http://github.com/defunkt/pystache', install_requires=INSTALL_REQUIRES, packages=PACKAGES, diff --git a/setup_description.rst b/setup_description.rst new file mode 100644 index 0000000..b0a4109 --- /dev/null +++ b/setup_description.rst @@ -0,0 +1,440 @@ +.. This file is auto-generated by setup.py, so it should not be edited. + +Pystache +======== + +.. figure:: https://s3.amazonaws.com/webdev_bucket/pystache.png + :align: center + :alt: mustachioed, monocled snake by David Phillips + +`Pystache <https://github.com/defunkt/pystache>`_ is a Python +implementation of `Mustache <http://mustache.github.com/>`_. Mustache is +a framework-agnostic, logic-free templating system inspired by +`ctemplate <http://code.google.com/p/google-ctemplate/>`_ and +`et <http://www.ivan.fomichev.name/2008/05/erlang-template-engine-prototype.html>`_. +Like ctemplate, Mustache "emphasizes separating logic from presentation: +it is impossible to embed application logic in this template language." + +The `mustache(5) <http://mustache.github.com/mustache.5.html>`_ man page +provides a good introduction to Mustache's syntax. For a more complete +(and more current) description of Mustache's behavior, see the official +`Mustache spec <https://github.com/mustache/spec>`_. + +Pystache is `semantically versioned <http://semver.org>`_ and can be +found on `PyPI <http://pypi.python.org/pypi/pystache>`_. This version of +Pystache passes all tests in `version +1.1.2 <https://github.com/mustache/spec/tree/v1.1.2>`_ of the spec. + +Logo: `David Phillips <http://davidphillips.us/>`_ + +Requirements +------------ + +Pystache is tested with-- + +- Python 2.4 (requires simplejson `version + 2.0.9 <http://pypi.python.org/pypi/simplejson/2.0.9>`_ or earlier) +- Python 2.5 (requires + `simplejson <http://pypi.python.org/pypi/simplejson/>`_) +- Python 2.6 +- Python 2.7 +- Python 3.1 +- Python 3.2 + +JSON support is needed only for the command-line interface and to run +the spec tests. We require simplejson for earlier versions of Python +since Python's `json <http://docs.python.org/library/json.html>`_ module +was added in Python 2.6. + +For Python 2.4 we require an earlier version of simplejson since +simplejson stopped officially supporting Python 2.4 in simplejson +version 2.1.0. Earlier versions of simplejson can be installed manually, +as follows: + +:: + + pip install 'simplejson<2.1.0' + +Install It +---------- + +:: + + pip install pystache + pystache-test + +To install and test from source (e.g. from GitHub), see the Develop +section. + +Use It +------ + +:: + + >>> import pystache + >>> print pystache.render('Hi {{person}}!', {'person': 'Mom'}) + Hi Mom! + +You can also create dedicated view classes to hold your view logic. + +Here's your view class (in .../examples/readme.py): + +:: + + class SayHello(object): + def to(self): + return "Pizza" + +Instantiating like so: + +:: + + >>> from pystache.tests.examples.readme import SayHello + >>> hello = SayHello() + +Then your template, say\_hello.mustache (by default in the same +directory as your class definition): + +:: + + Hello, {{to}}! + +Pull it together: + +:: + + >>> renderer = pystache.Renderer() + >>> print renderer.render(hello) + Hello, Pizza! + +For greater control over rendering (e.g. to specify a custom template +directory), use the ``Renderer`` class like above. One can pass +attributes to the Renderer class constructor or set them on a Renderer +instance. To customize template loading on a per-view basis, subclass +``TemplateSpec``. See the docstrings of the +`Renderer <https://github.com/defunkt/pystache/blob/master/pystache/renderer.py>`_ +class and +`TemplateSpec <https://github.com/defunkt/pystache/blob/master/pystache/template_spec.py>`_ +class for more information. + +You can also pre-parse a template: + +:: + + >>> parsed = pystache.parse(u"Hey {{#who}}{{.}}!{{/who}}") + >>> print parsed + [u'Hey ', _SectionNode(key=u'who', index_begin=12, index_end=18, parsed=[_EscapeNode(key=u'.'), u'!'])] + +And then: + +:: + + >>> print renderer.render(parsed, {'who': 'Pops'}) + Hey Pops! + >>> print renderer.render(parsed, {'who': 'you'}) + Hey you! + +Python 3 +-------- + +Pystache has supported Python 3 since version 0.5.1. Pystache behaves +slightly differently between Python 2 and 3, as follows: + +- In Python 2, the default html-escape function ``cgi.escape()`` does + not escape single quotes; whereas in Python 3, the default escape + function ``html.escape()`` does escape single quotes. +- In both Python 2 and 3, the string and file encodings default to + ``sys.getdefaultencoding()``. However, this function can return + different values under Python 2 and 3, even when run from the same + system. Check your own system for the behavior on your system, or do + not rely on the defaults by passing in the encodings explicitly (e.g. + to the ``Renderer`` class). + +Unicode +------- + +This section describes how Pystache handles unicode, strings, and +encodings. + +Internally, Pystache uses `only unicode +strings <http://docs.python.org/howto/unicode.html#tips-for-writing-unicode-aware-programs>`_ +(``str`` in Python 3 and ``unicode`` in Python 2). For input, Pystache +accepts both unicode strings and byte strings (``bytes`` in Python 3 and +``str`` in Python 2). For output, Pystache's template rendering methods +return only unicode. + +Pystache's ``Renderer`` class supports a number of attributes to control +how Pystache converts byte strings to unicode on input. These include +the ``file_encoding``, ``string_encoding``, and ``decode_errors`` +attributes. + +The ``file_encoding`` attribute is the encoding the renderer uses to +convert to unicode any files read from the file system. Similarly, +``string_encoding`` is the encoding the renderer uses to convert any +other byte strings encountered during the rendering process into unicode +(e.g. context values that are encoded byte strings). + +The ``decode_errors`` attribute is what the renderer passes as the +``errors`` argument to Python's built-in unicode-decoding function +(``str()`` in Python 3 and ``unicode()`` in Python 2). The valid values +for this argument are ``strict``, ``ignore``, and ``replace``. + +Each of these attributes can be set via the ``Renderer`` class's +constructor using a keyword argument of the same name. See the Renderer +class's docstrings for further details. In addition, the +``file_encoding`` attribute can be controlled on a per-view basis by +subclassing the ``TemplateSpec`` class. When not specified explicitly, +these attributes default to values set in Pystache's ``defaults`` +module. + +Develop +------- + +To test from a source distribution (without installing)-- + +:: + + python test_pystache.py + +To test Pystache with multiple versions of Python (with a single +command!), you can use `tox <http://pypi.python.org/pypi/tox>`_: + +:: + + pip install tox + tox + +If you do not have all Python versions listed in ``tox.ini``-- + +:: + + tox -e py26,py32 # for example + +The source distribution tests also include doctests and tests from the +Mustache spec. To include tests from the Mustache spec in your test +runs: + +:: + + git submodule init + git submodule update + +The test harness parses the spec's (more human-readable) yaml files if +`PyYAML <http://pypi.python.org/pypi/PyYAML>`_ is present. Otherwise, it +parses the json files. To install PyYAML-- + +:: + + pip install pyyaml + +To run a subset of the tests, you can use +`nose <http://somethingaboutorange.com/mrl/projects/nose/0.11.1/testing.html>`_: + +:: + + pip install nose + nosetests --tests pystache/tests/test_context.py:GetValueTests.test_dictionary__key_present + +**Running Pystache from source with Python 3.** Pystache is written in +Python 2 and must be converted with +`2to3 <http://docs.python.org/library/2to3.html>`_ prior to running +under Python 3. The installation process (and tox) do this conversion +automatically. + +To ``import pystache`` from a source distribution while using Python 3, +be sure that you are importing from a directory containing a converted +version (e.g. from your site-packages directory after manually +installing) and not from the original source directory. Otherwise, you +will get a syntax error. You can help ensure this by not running the +Python IDE from the project directory when importing Pystache. + +Mailing List +------------ + +There is a `mailing list <http://librelist.com/browser/pystache/>`_. +Note that there is a bit of a delay between posting a message and seeing +it appear in the mailing list archive. + +Authors +------- + +:: + + >>> context = { 'author': 'Chris Wanstrath', 'maintainer': 'Chris Jerdonek' } + >>> print pystache.render("Author: {{author}}\nMaintainer: {{maintainer}}", context) + Author: Chris Wanstrath + Maintainer: Chris Jerdonek + + +History +======= + +0.5.3 (TBD) +----------- + +- Added option of raising errors on missing tags/partials: + ``Renderer(missing_tags='strict')`` (issue #110). +- Added a ``parse()`` function that yields a printable, pre-compiled + parse tree. +- Added support for rendering pre-compiled templates. +- Bugfix: exceptions raised from a property are no longer swallowed + when getting a key from a context stack (issue #110). +- Bugfix: lambda section values can now return non-ascii, non-unicode + strings (issue #118). +- More robust handling of byte strings in Python 3. + +0.5.2 (2012-05-03) +------------------ + +- Added support for dot notation and version 1.1.2 of the spec (issue + #99). [rbp] +- Missing partials now render as empty string per latest version of + spec (issue #115). +- Bugfix: falsey values now coerced to strings using str(). +- Bugfix: lambda return values for sections no longer pushed onto + context stack (issue #113). +- Bugfix: lists of lambdas for sections were not rendered (issue #114). + +0.5.1 (2012-04-24) +------------------ + +- Added support for Python 3.1 and 3.2. +- Added tox support to test multiple Python versions. +- Added test script entry point: pystache-test. +- Added \_\_version\_\_ package attribute. +- Test harness now supports both YAML and JSON forms of Mustache spec. +- Test harness no longer requires nose. + +0.5.0 (2012-04-03) +------------------ + +This version represents a major rewrite and refactoring of the code base +that also adds features and fixes many bugs. All functionality and +nearly all unit tests have been preserved. However, some backwards +incompatible changes to the API have been made. + +Below is a selection of some of the changes (not exhaustive). + +Highlights: + +- Pystache now passes all tests in version 1.0.3 of the `Mustache + spec <https://github.com/mustache/spec>`_. [pvande] +- Removed View class: it is no longer necessary to subclass from View + or from any other class to create a view. +- Replaced Template with Renderer class: template rendering behavior + can be modified via the Renderer constructor or by setting attributes + on a Renderer instance. +- Added TemplateSpec class: template rendering can be specified on a + per-view basis by subclassing from TemplateSpec. +- Introduced separation of concerns and removed circular dependencies + (e.g. between Template and View classes, cf. `issue + #13 <https://github.com/defunkt/pystache/issues/13>`_). +- Unicode now used consistently throughout the rendering process. +- Expanded test coverage: nosetests now runs doctests and ~105 test + cases from the Mustache spec (increasing the number of tests from 56 + to ~315). +- Added a rudimentary benchmarking script to gauge performance while + refactoring. +- Extensive documentation added (e.g. docstrings). + +Other changes: + +- Added a command-line interface. [vrde] +- The main rendering class now accepts a custom partial loader (e.g. a + dictionary) and a custom escape function. +- Non-ascii characters in str strings are now supported while + rendering. +- Added string encoding, file encoding, and errors options for decoding + to unicode. +- Removed the output encoding option. +- Removed the use of markupsafe. + +Bug fixes: + +- Context values no longer processed as template strings. + [jakearchibald] +- Whitespace surrounding sections is no longer altered, per the spec. + [heliodor] +- Zeroes now render correctly when using PyPy. [alex] +- Multline comments now permitted. [fczuardi] +- Extensionless template files are now supported. +- Passing ``**kwargs`` to ``Template()`` no longer modifies the + context. +- Passing ``**kwargs`` to ``Template()`` with no context no longer + raises an exception. + +0.4.1 (2012-03-25) +------------------ + +- Added support for Python 2.4. [wangtz, jvantuyl] + +0.4.0 (2011-01-12) +------------------ + +- Add support for nested contexts (within template and view) +- Add support for inverted lists +- Decoupled template loading + +0.3.1 (2010-05-07) +------------------ + +- Fix package + +0.3.0 (2010-05-03) +------------------ + +- View.template\_path can now hold a list of path +- Add {{& blah}} as an alias for {{{ blah }}} +- Higher Order Sections +- Inverted sections + +0.2.0 (2010-02-15) +------------------ + +- Bugfix: Methods returning False or None are not rendered +- Bugfix: Don't render an empty string when a tag's value is 0. + [enaeseth] +- Add support for using non-callables as View attributes. + [joshthecoder] +- Allow using View instances as attributes. [joshthecoder] +- Support for Unicode and non-ASCII-encoded bytestring output. + [enaeseth] +- Template file encoding awareness. [enaeseth] + +0.1.1 (2009-11-13) +------------------ + +- Ensure we're dealing with strings, always +- Tests can be run by executing the test file directly + +0.1.0 (2009-11-12) +------------------ + +- First release + + +License +======= + +Copyright (C) 2012 Chris Jerdonek. All rights reserved. + +Copyright (c) 2009 Chris Wanstrath + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |