Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'next' of git@github.com:rtyler/cheetah

  • Loading branch information...
commit 45f570f03abfbe929a14a7c23e2aa2a39ce152c5 2 parents 2fc2c59 + 1c42c23
R. Tyler Ballance authored
Showing with 6,285 additions and 1,475 deletions.
  1. +3 −0  .gitignore
  2. +1 −15 BUGS
  3. +14 −3 CHANGES
  4. +3 −2 SetupConfig.py
  5. +6 −14 TODO
  6. +339 −0 contrib/editors/kde-cheetah.xml
  7. +0 −4 docs/devel_guide_src/.cvsignore
  8. +0 −1  docs/users_guide_2_src/.cvsignore
  9. +0 −4 docs/users_guide_src/.cvsignore
  10. +0 −2  src/.cvsignore
  11. +24 −59 src/CheetahWrapper.py
  12. +19 −6 src/Compiler.py
  13. +40 −0 src/DummyTransaction.py
  14. +97 −31 src/Filters.py
  15. +6 −1 src/ImportManager.py
  16. +25 −0 src/Parser.py
  17. +23 −17 src/Template.py
  18. +0 −3  src/Templates/.cvsignore
  19. +0 −2  src/Tests/.cvsignore
  20. +1 −1  src/Tests/CheetahWrapper.py
  21. +0 −55 src/Tests/FileRefresh.py
  22. +65 −0 src/Tests/Filters.py
  23. +55 −11 src/Tests/Regressions.py
  24. +1 −1  src/Tests/Template.py
  25. +21 −44 src/Tests/Test.py
  26. +73 −0 src/Tests/Unicode.py
  27. +3 −2 src/Tests/unittest_local_copy.py
  28. +28 −25 src/Tests/xmlrunner.py
  29. +0 −2  src/Tools/.cvsignore
  30. +21 −15 src/Tools/RecursiveNull.py
  31. +0 −2  src/Utils/.cvsignore
  32. +0 −2  src/Utils/optik/.cvsignore
  33. +0 −32 src/Utils/optik/__init__.py
  34. +0 −52 src/Utils/optik/errors.py
  35. +0 −354 src/Utils/optik/option.py
  36. +0 −667 src/Utils/optik/option_parser.py
  37. +304 −0 src/Utils/statprof.py
  38. +2 −2 src/Version.py
  39. +45 −44 src/_namemapper.c
  40. 0  src/contrib/__init__.py
  41. +30 −0 src/contrib/markdown/LICENSE
  42. +603 −0 src/contrib/markdown/__init__.py
  43. +95 −0 src/contrib/markdown/blockparser.py
  44. +460 −0 src/contrib/markdown/blockprocessors.py
  45. +96 −0 src/contrib/markdown/commandline.py
  46. +33 −0 src/contrib/markdown/etree_loader.py
  47. 0  src/contrib/markdown/extensions/__init__.py
  48. +95 −0 src/contrib/markdown/extensions/abbr.py
  49. +224 −0 src/contrib/markdown/extensions/codehilite.py
  50. +104 −0 src/contrib/markdown/extensions/def_list.py
  51. +49 −0 src/contrib/markdown/extensions/extra.py
  52. +117 −0 src/contrib/markdown/extensions/fenced_code.py
  53. +293 −0 src/contrib/markdown/extensions/footnotes.py
  54. +195 −0 src/contrib/markdown/extensions/headerid.py
  55. +62 −0 src/contrib/markdown/extensions/html_tidy.py
  56. +119 −0 src/contrib/markdown/extensions/imagelinks.py
  57. +468 −0 src/contrib/markdown/extensions/legacy.py
  58. +90 −0 src/contrib/markdown/extensions/meta.py
  59. +114 −0 src/contrib/markdown/extensions/rss.py
  60. +97 −0 src/contrib/markdown/extensions/tables.py
  61. +140 −0 src/contrib/markdown/extensions/toc.py
  62. +155 −0 src/contrib/markdown/extensions/wikilinks.py
  63. +274 −0 src/contrib/markdown/html4.py
  64. +371 −0 src/contrib/markdown/inlinepatterns.py
  65. +162 −0 src/contrib/markdown/odict.py
  66. +77 −0 src/contrib/markdown/postprocessors.py
  67. +214 −0 src/contrib/markdown/preprocessors.py
  68. +329 −0 src/contrib/markdown/treeprocessors.py
View
3  .gitignore
@@ -1,3 +1,6 @@
*.pyc
*.swp
*.so
+www/*.html
+build
+*.py.bak
View
16 BUGS
@@ -1,16 +1,2 @@
-Known Bugs in Cheetah
---------------------------
- - See the file CHANGES for a list of bugs that have been resolved.
- - Developers: if a bug was significant and affected a released version of
- Cheetah, be sure to note its fix in the CHANGES file!
---------------------------
-
-Dict method bug
----------------
-Do not use placeholder names identical to Python dict methods, or Cheetah will
-return the wrong value. The most notorious names are $update, $keys, $values,
-$items. A complete list is at http://docs.python.org/lib/typesmapping.html.
-Note that future versions of Python may add dict methods. This bug is
-difficult to fix given Cheetah's NameMapper, so it will remain around for a
-long time. (MO 2006/02/11)
+Please see http://bugs.communitycheetah.org
View
17 CHANGES
@@ -1,6 +1,17 @@
-Please initial your changes (there's a key at bottom) and add a date for each
-release
-================================================================================
+
+2.1.1 (April 16, 2009)
+ - Support __eq__() and __ne__() the way you might expect in src/Tools/RecursiveNull (patch suggested by Peter Warasin <peter@endian.com>)
+ - Applied patch to avoid hitting the filesystem to get the file modification time everytime a #include directive is processed (Jean-Baptiste Quenot <jbq@caraldi.com>)
+ - Applied patch to fix some annoying cases when Cheetah writes to stderr instead of propagating the exception (Jean-Baptiste Quenot <jbq@caraldi.com>)
+ - Added KDE editor support
+ - Applied patch to correct importHook behavior on Python 2.6 (reported/patched by Toshio Ernie Kuratomi <a.badger@gmail.com>)
+ - Correct unicode issue when calling/embedding unicode templates inside of other templtes (testcase Tests.Unicode.JPQ_UTF8_Test3. reported by Jean-Baptiste Quenot <jbq@caraldi.com>)
+ - Added --shbang option (e.g. "cheetah compile --shbang '#!/usr/bin/python2.6' ")
+ - Removed dependency on optik OptionParser in favor of builtin Python optparse module
+ - Introduction of the #transform directive for whole-document filtering
+ - Introduction of Cheetah.contrib.markdown and Cheetah.Filters.Markdown for outputting a markdown processed template (meant for #transform)
+ - Cheetah.Filters.CodeHighlighter, pygments-based code highlighting filter for use with #transform
+ - Addition of "useLegacyImportMode" compiler setting (defaulted to True) to allow for older (read: broken) import behavior
2.1.0.1 (March 27, 2009)
- Fix inline import issue introduced in v2.1.0
View
5 SetupConfig.py
@@ -1,5 +1,5 @@
#-------Main Package Settings-----------#
-name = "Cheetah Community Edition"
+name = 'Cheetah'
from src.Version import Version as version
maintainer = "R. Tyler Ballance"
author = "Tavis Rudd"
@@ -11,7 +11,8 @@
'Cheetah.Tests',
'Cheetah.Tools',
'Cheetah.Utils',
- 'Cheetah.Utils.optik',
+ 'Cheetah.contrib',
+ 'Cheetah.contrib.markdown',
]
classifiers = [line.strip() for line in '''\
#Development Status :: 4 - Beta
View
20 TODO
@@ -1,16 +1,9 @@
-Cheetah TODO list
------------------
-* If you are working on a task please put your initials at the end of the
- description
-* When a task is completed please remember to note it in the CHANGES file
-* Unresolved bugs are listed in the BUGS file. Resolved bugs are be listed
- in the CHANGES file if the bug is considered significant enough and it
- affected a released version of Cheetah.
-
-Required for Cheetah 2.0
-========================
-- Replace Optik with Python's optparse. Optik license has been removed from
- Users' Guide.
+NOTE: Please see http://bugs.communitycheetah.org
+ for future feature requests/bugs/TODO
+
+
+===============================================================================
+===============================================================================
Desired for Cheetah 2.0
=======================
@@ -38,7 +31,6 @@ TODO Items (many are just ideas. This is not an official roadmap!)
leak from one fill to the next.
- CheetahWrapper stuff: (MO)
- * "cheetah compile --shbang '#!/usr/bin/python2.2'"
* "cheetah preview [options] [FILES]" print template-specific portion of main
method(s) to stdout, with line numbers based on the .py template module.
Make a Template method to do the same thing, a la .generatedModuleCode().
View
339 contrib/editors/kde-cheetah.xml
@@ -0,0 +1,339 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE language SYSTEM "language.dtd"
+[
+ <!ENTITY name "[A-Za-z_:][\w.:_-]*">
+ <!ENTITY ident "[A-Za-z_][A-Za-z_0-9]*">
+ <!ENTITY entref "&amp;(#[0-9]+|#[xX][0-9A-Fa-f]+|&name;);">
+ <!ENTITY block "block|def">
+ <!ENTITY idcmd "attr|del|encoding|errorCatcher|extends|implements|import|include(\s+raw)?|raise|shBang">
+]>
+<!--
+ This file is part of KDE's kate project.
+
+ copyright : (C) 2008 by David Zaslavsky
+ email : dzaslavs@ellipsix.net
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+-->
+<!--
+ You'll find the "Writing a Kate Highlighting XML File HOWTO" at
+ http://kate.kde.org/doc/hlhowto.php
+ This is a template for the XML format used for syntax highlight descriptions
+ for the Kate text editor (http://kate.kde.org), which is part of the KDE
+ desktop environment (http://www.kde.org).
+
+ Use it as the base for your own syntax files.
+
+ Look at language.dtd for some documentation of the allowed elements and their attributes.
+ There is also a description of how to validate your syntax file.
+
+ You'll find the "Writing a Kate Highlighting XML File HOWTO" at
+ http://kate.kde.org/doc/hlhowto.php
+ -->
+
+<language version="1.00" kateversion="2.4" name="Cheetah" section="Markup" extensions="*.tmpl" mimetype="text/plain" author="David Zaslavsky" licence="GPL">
+<highlighting>
+ <list name="specialvars">
+ <item>None</item>
+ <item>False</item>
+ <item>True</item>
+ </list>
+ <contexts>
+ <context name="Start" attribute="Normal Text" lineEndContext="#stay">
+ <DetectSpaces/>
+ <IncludeRules context="FindCheetah"/>
+ <IncludeRules context="FindHTML"/>
+ </context>
+ <context name="FindCheetah" attribute="Normal Text" lineEndContext="#stay">
+ <RegExpr attribute="Comment" String="##.*$" context="#stay"/>
+ <Detect2Chars char="#" char1="*" attribute="Comment" context="LongComment" beginRegion="MLComment"/>
+ <RegExpr String="#raw\s*($|#)" attribute="Command" context="Raw"/>
+ <RegExpr String="#from\s+&ident;\s+import\s+&ident;\s*($|#)" attribute="Command" context="#stay"/>
+ <RegExpr String="#block\s+&ident;\s*($|#)" attribute="Command" context="#stay" beginRegion="block"/>
+ <RegExpr String="#def\s+&ident;\s*($|#)" attribute="Command" context="#stay" beginRegion="def"/>
+ <RegExpr String="#block\s+&ident;\s*\(" attribute="Command" context="Def Expression" beginRegion="block"/>
+ <RegExpr String="#def\s+&ident;\s*\(" attribute="Command" context="Def Expression" beginRegion="def"/>
+ <StringDetect String="#for" attribute="Command" context="For Expression" beginRegion="for"/>
+ <StringDetect String="#if" attribute="Command" context="If Expression" beginRegion="if"/>
+ <RegExpr String="#(else\s+if|elif)" attribute="Command" context="Expression" endRegion="if" beginRegion="if"/>
+ <StringDetect String="#repeat" attribute="Command" context="Expression" beginRegion="repeat"/>
+ <StringDetect String="#unless" attribute="Command" context="Expression" beginRegion="unless"/>
+ <StringDetect String="#while" attribute="Command" context="Expression" beginRegion="while"/>
+ <RegExpr String="#end block(\s+&ident;)?\s*($|#)" attribute="Command" context="#stay" endRegion="block"/>
+ <RegExpr String="#end def(\s+&ident;)?\s*($|#)" attribute="Command" context="#stay" endRegion="def"/>
+ <RegExpr String="#end for\s*($|#)" attribute="Command" context="#stay" endRegion="for"/>
+ <RegExpr String="#end if\s*($|#)" attribute="Command" context="#stay" endRegion="if"/>
+ <RegExpr String="#end repeat\s*($|#)" attribute="Command" context="#stay" endRegion="repeat"/>
+ <RegExpr String="#end unless\s*($|#)" attribute="Command" context="#stay" endRegion="unless"/>
+ <RegExpr String="#end while\s*($|#)" attribute="Command" context="#stay" endRegion="while"/>
+ <!-- short-form block directives -->
+ <RegExpr String="#(block|def) &ident;:" attribute="Command" context="Short Block Body"/>
+ <!-- no-argument directives -->
+ <RegExpr String="#(break|breakpoint|cache|compiler-settings|continue|finally|else|indent|pass|raw|slurp|stop|try)\s*($|#)" attribute="Command" context="#stay"/>
+ <!-- one-argument directives -->
+ <RegExpr String="#(attr|del|encoding|errorCatcher|extends|implements|import|include(\s+raw)?|shBang)\s+&ident;\s*($|#)" attribute="Command" context="#stay"/>
+ <!-- expression-argument directives -->
+ <RegExpr String="#(assert|echo|except|filter|raise|set|silent)" attribute="Command" context="Expression"/>
+ <StringDetect String="&lt;%" attribute="Element" context="Python"/>
+ <StringDetect String="&lt;%=" attribute="Element" context="Python"/>
+ <DetectChar char="$" attribute="Placeholder" context="Placeholder"/>
+ </context>
+ <context name="FindHTML" attribute="Normal Text" lineEndContext="#stay">
+ <DetectSpaces/>
+ <DetectIdentifier/>
+ <StringDetect attribute="Comment" context="HTMLComment" String="&lt;!--" beginRegion="HTMLComment" />
+ <StringDetect attribute="CDATA" context="CDATA" String="&lt;![CDATA[" beginRegion="cdata" />
+ <RegExpr attribute="Doctype" context="Doctype" String="&lt;!DOCTYPE\s+" beginRegion="doctype" />
+ <RegExpr attribute="Processing Instruction" context="PI" String="&lt;\?[\w:-]*" beginRegion="pi" />
+ <RegExpr attribute="Element" context="CSS" String="&lt;style\b" insensitive="TRUE" beginRegion="style" />
+ <RegExpr attribute="Element" context="JS" String="&lt;script\b" insensitive="TRUE" beginRegion="script" />
+ <RegExpr attribute="Element" context="El Open" String="&lt;pre\b" insensitive="TRUE" beginRegion="pre" />
+ <RegExpr attribute="Element" context="El Open" String="&lt;div\b" insensitive="TRUE" beginRegion="div" />
+ <RegExpr attribute="Element" context="El Open" String="&lt;table\b" insensitive="TRUE" beginRegion="table" />
+ <RegExpr attribute="Element" context="El Open" String="&lt;&name;" />
+ <RegExpr attribute="Element" context="El Close" String="&lt;/pre\b" insensitive="TRUE" endRegion="pre" />
+ <RegExpr attribute="Element" context="El Close" String="&lt;/div\b" insensitive="TRUE" endRegion="div" />
+ <RegExpr attribute="Element" context="El Close" String="&lt;/table\b" insensitive="TRUE" endRegion="table" />
+ <RegExpr attribute="Element" context="El Close" String="&lt;/&name;" />
+ <IncludeRules context="FindEntityRefs" />
+ </context>
+ <context name="Directive" attribute="Command" lineEndContext="#pop">
+ <DetectChar char="#" attribute="Command" context="#pop"/>
+ </context>
+ <context name="Expression" attribute="Command" lineEndContext="#pop">
+ <DetectChar char="#" attribute="Command" context="#pop"/>
+ <DetectChar char="$" attribute="Placeholder" context="Placeholder"/>
+ <RangeDetect char="'" char1="'" attribute="String" context="#stay"/>
+ <RangeDetect char="&quot;" char1="&quot;" attribute="String" context="#stay"/>
+ <keyword String="specialvars" attribute="Special Variable" context="#stay"/>
+ </context>
+ <context name="Def Expression" attribute="Command" lineEndContext="#pop">
+ <DetectChar char=")" attribute="Command" context="#stay"/>
+ <IncludeRules context="Expression"/>
+ </context>
+ <context name="For Expression" attribute="Command" lineEndContext="#pop">
+ <StringDetect String="in" attribute="Command" context="#stay"/>
+ <IncludeRules context="Expression"/>
+ </context>
+ <context name="If Expression" attribute="Command" lineEndContext="#pop">
+ <StringDetect String="then" attribute="Command" context="Then Clause" endRegion="if"/>
+ <IncludeRules context="Expression"/>
+ </context>
+ <context name="Then Clause" attribute="Normal Text" lineEndContext="#pop#pop">
+ <DetectChar char="#" attribute="Command" context="#pop#pop"/>
+ <StringDetect String="else" attribute="Command" context="#stay"/>
+ <keyword String="specialvars" attribute="Special Variable" context="#stay"/>
+ <DetectChar char="$" attribute="Placeholder" context="Placeholder"/>
+ <IncludeRules context="FindHTML"/>
+ </context>
+ <context name="Short Block Body" attribute="Normal Text" lineEndContext="#pop#pop">
+ <DetectChar char="#" attribute="Command" context="#pop#pop"/>
+ <DetectChar char="$" attribute="Placeholder" context="Placeholder"/>
+ <IncludeRules context="FindHTML"/>
+ </context>
+ <context name="Raw" attribute="Command" lineEndContext="Raw content">
+ <DetectChar char="#" attribute="Command" context="Raw content"/>
+ </context>
+ <context name="Raw content" attribute="Normal Text" lineEndContext="#stay">
+ <StringDetect String="#end raw" attribute="Command" context="#pop#pop#pop"/>
+ </context>
+ <context name="Placeholder" attribute="Placeholder" lineEndContext="#pop">
+ <RegExpr String="([[({])" attribute="Placeholder" context="Placeholder Brackets"/>
+ <RegExpr String="[A-Za-z_][A-Za-z_0-9]*" attribute="Placeholder" context="#stay"/>
+ <DetectChar char="." attribute="Placeholder" context="#stay"/>
+ <DetectSpaces attribute="Normal Text" context="#pop"/>
+ <RegExpr String="." context="#pop" lookAhead="true"/>
+ </context>
+ <context name="Placeholder Brackets" attribute="Placeholder" lineEndContext="#pop">
+ <RegExpr String="([[({])" attribute="Placeholder" context="Placeholder Brackets"/>
+ <DetectChar char="]" attribute="Placeholder" context="#pop"/>
+ <DetectChar char=")" attribute="Placeholder" context="#pop"/>
+ <DetectChar char="}" attribute="Placeholder" context="#pop"/>
+ <RangeDetect char="'" char1="'" attribute="String" context="#stay"/>
+ <RangeDetect char="&quot;" char1="&quot;" attribute="String" context="#stay"/>
+ <keyword String="specialvars" attribute="Special Variable" context="#stay"/>
+ <DetectChar char="#" attribute="Error" context="#stay"/>
+ </context>
+ <context name="ShortComment" attribute="Comment" lineEndContext="#pop">
+ <DetectSpaces/>
+ <IncludeRules context="##Alerts" />
+ </context>
+ <context name="LongComment" attribute="Comment" lineEndContext="#stay">
+ <DetectSpaces/>
+ <Detect2Chars char="*" char1="#" attribute="Comment" context="#pop" endRegion="MLComment"/>
+ <IncludeRules context="##Alerts" />
+ </context>
+ <context name="HTMLComment" attribute="Comment" lineEndContext="#stay">
+ <DetectSpaces/>
+ <IncludeRules context="FindCheetah"/>
+ <IncludeRules context="##Alerts"/>
+ <DetectIdentifier/>
+ <StringDetect attribute="Comment" context="#pop" String="--&gt;" endRegion="HTMLComment" />
+ <RegExpr attribute="Error" context="#stay" String="-(-(?!-&gt;))+" />
+ </context>
+ <context name="Python" attribute="Normal Text" lineEndContext="#stay">
+ <Detect2Chars char="%" char1="&gt;" attribute="Normal Text" context="#pop"/>
+ <IncludeRules context="##Python" includeAttrib="true"/>
+ </context>
+ <context name="FindEntityRefs" attribute="Normal Text" lineEndContext="#stay">
+ <IncludeRules context="FindCheetah"/>
+ <RegExpr attribute="EntityRef" context="#stay" String="&entref;" />
+ <AnyChar attribute="Error" context="#stay" String="&amp;&lt;" />
+ </context>
+ <context name="FindPEntityRefs" attribute="Normal Text" lineEndContext="#stay">
+ <IncludeRules context="FindCheetah"/>
+ <RegExpr attribute="EntityRef" context="#stay" String="&entref;" />
+ <RegExpr attribute="PEntityRef" context="#stay" String="%&name;;" />
+ <AnyChar attribute="Error" context="#stay" String="&amp;%" />
+ </context>
+ <context name="FindAttributes" attribute="Normal Text" lineEndContext="#stay">
+ <IncludeRules context="FindCheetah"/>
+ <RegExpr attribute="Attribute" context="#stay" String="&name;" column="0"/>
+ <RegExpr attribute="Attribute" context="#stay" String="\s+&name;" />
+ <DetectChar attribute="Attribute" context="Value" char="=" />
+ </context>
+ <context name="CDATA" attribute="Normal Text" lineEndContext="#stay">
+ <DetectSpaces/>
+ <DetectIdentifier/>
+ <IncludeRules context="FindCheetah"/>
+ <StringDetect attribute="CDATA" context="#pop" String="]]&gt;" endRegion="cdata" />
+ <StringDetect attribute="EntityRef" context="#stay" String="]]&amp;gt;" />
+ </context>
+ <context name="PI" attribute="Normal Text" lineEndContext="#stay">
+ <IncludeRules context="FindCheetah"/>
+ <Detect2Chars attribute="Processing Instruction" context="#pop" char="?" char1="&gt;" endRegion="pi" />
+ </context>
+ <context name="Doctype" attribute="Normal Text" lineEndContext="#stay">
+ <IncludeRules context="FindCheetah"/>
+ <DetectChar attribute="Doctype" context="#pop" char="&gt;" endRegion="doctype" />
+ <DetectChar attribute="Doctype" context="Doctype Internal Subset" char="[" beginRegion="int_subset" />
+ </context>
+ <context name="Doctype Internal Subset" attribute="Normal Text" lineEndContext="#stay">
+ <IncludeRules context="FindCheetah"/>
+ <DetectChar attribute="Doctype" context="#pop" char="]" endRegion="int_subset" />
+ <StringDetect attribute="Comment" context="LongComment" String="&lt;!--" beginRegion="MLComment" />
+ <RegExpr attribute="Processing Instruction" context="PI" String="&lt;\?[\w:-]*" beginRegion="pi" />
+ <IncludeRules context="FindPEntityRefs" />
+ </context>
+ <context name="Doctype Markupdecl" attribute="Normal Text" lineEndContext="#stay">
+ <IncludeRules context="FindCheetah"/>
+ <DetectChar attribute="Doctype" context="#pop" char="&gt;" />
+ <DetectChar attribute="Value" context="Doctype Markupdecl DQ" char="&quot;" />
+ <DetectChar attribute="Value" context="Doctype Markupdecl SQ" char="&apos;" />
+ </context>
+ <context name="Doctype Markupdecl DQ" attribute="Value" lineEndContext="#stay">
+ <IncludeRules context="FindCheetah"/>
+ <DetectChar attribute="Value" context="#pop" char="&quot;" />
+ <IncludeRules context="FindPEntityRefs" />
+ </context>
+ <context name="Doctype Markupdecl SQ" attribute="Value" lineEndContext="#stay">
+ <IncludeRules context="FindCheetah"/>
+ <DetectChar attribute="Value" context="#pop" char="&apos;" />
+ <IncludeRules context="FindPEntityRefs" />
+ </context>
+ <context name="El Open" attribute="Normal Text" lineEndContext="#stay">
+ <IncludeRules context="FindCheetah"/>
+ <Detect2Chars attribute="Element" context="#pop" char="/" char1="&gt;" />
+ <DetectChar attribute="Element" context="#pop" char="&gt;" />
+ <IncludeRules context="FindAttributes" />
+ <RegExpr attribute="Error" context="#stay" String="\S" />
+ </context>
+ <context name="El Close" attribute="Normal Text" lineEndContext="#stay">
+ <IncludeRules context="FindCheetah"/>
+ <DetectChar attribute="Element" context="#pop" char="&gt;" />
+ <RegExpr attribute="Error" context="#stay" String="\S" />
+ </context>
+ <context name="El Close 2" attribute="Normal Text" lineEndContext="#stay">
+ <IncludeRules context="FindCheetah"/>
+ <DetectChar attribute="Element" context="#pop#pop#pop" char="&gt;" />
+ <RegExpr attribute="Error" context="#stay" String="\S" />
+ </context>
+ <context name="El Close 3" attribute="Normal Text" lineEndContext="#stay">
+ <IncludeRules context="FindCheetah"/>
+ <DetectChar attribute="Element" context="#pop#pop#pop#pop" char="&gt;" />
+ <RegExpr attribute="Error" context="#stay" String="\S" />
+ </context>
+ <context name="CSS" attribute="Normal Text" lineEndContext="#stay">
+ <IncludeRules context="FindCheetah"/>
+ <Detect2Chars attribute="Element" context="#pop" char="/" char1="&gt;" endRegion="style" />
+ <DetectChar attribute="Element" context="CSS content" char="&gt;" />
+ <IncludeRules context="FindAttributes" />
+ <RegExpr attribute="Error" context="#stay" String="\S" />
+ </context>
+ <context name="CSS content" attribute="Normal Text" lineEndContext="#stay">
+ <IncludeRules context="FindCheetah"/>
+ <RegExpr attribute="Element" context="El Close 2" String="&lt;/style\b" insensitive="TRUE" endRegion="style" />
+ <IncludeRules context="##CSS" includeAttrib="true"/>
+ </context>
+ <context name="JS" attribute="Normal Text" lineEndContext="#stay">
+ <IncludeRules context="FindCheetah"/>
+ <Detect2Chars attribute="Element" context="#pop" char="/" char1="&gt;" endRegion="script" />
+ <DetectChar attribute="Element" context="JS content" char="&gt;" />
+ <IncludeRules context="FindAttributes" />
+ <RegExpr attribute="Error" context="#stay" String="\S" />
+ </context>
+ <context name="JS content" attribute="Normal Text" lineEndContext="#stay">
+ <IncludeRules context="FindCheetah"/>
+ <RegExpr attribute="Element" context="El Close 2" String="&lt;/script\b" insensitive="TRUE" endRegion="script" />
+ <RegExpr attribute="Comment" context="JS comment close" String="//(?=.*&lt;/script\b)" insensitive="TRUE" />
+ <IncludeRules context="##JavaScript" includeAttrib="true"/>
+ </context>
+ <context name="JS comment close" attribute="Comment" lineEndContext="#pop">
+ <IncludeRules context="FindCheetah"/>
+ <RegExpr attribute="Element" context="El Close 3" String="&lt;/script\b" insensitive="TRUE" endRegion="script" />
+ <IncludeRules context="##Alerts" />
+ </context>
+ <context name="Value" attribute="Normal Text" lineEndContext="#stay" fallthrough="true" fallthroughContext="Value NQ">
+ <IncludeRules context="FindCheetah"/>
+ <DetectChar attribute="Value" context="Value DQ" char="&quot;" />
+ <DetectChar attribute="Value" context="Value SQ" char="&apos;" />
+ <DetectSpaces />
+ </context>
+ <context name="Value NQ" attribute="Normal Text" lineEndContext="#pop#pop" fallthrough="true" fallthroughContext="#pop#pop">
+ <IncludeRules context="FindCheetah"/>
+ <IncludeRules context="FindEntityRefs" />
+ <RegExpr attribute="Value" context="#stay" String="/(?!&gt;)" />
+ <RegExpr attribute="Value" context="#stay" String="[^/&gt;&lt;&quot;&apos;\s]" />
+ </context>
+ <context name="Value DQ" attribute="Value" lineEndContext="#stay">
+ <IncludeRules context="FindCheetah"/>
+ <DetectChar attribute="Value" context="#pop#pop" char="&quot;" />
+ <IncludeRules context="FindEntityRefs" />
+ </context>
+ <context name="Value SQ" attribute="Value" lineEndContext="#stay">
+ <IncludeRules context="FindCheetah"/>
+ <DetectChar attribute="Value" context="#pop#pop" char="&apos;" />
+ <IncludeRules context="FindEntityRefs" />
+ </context>
+ </contexts>
+ <itemDatas>
+ <itemData name="Normal Text" defStyleNum="dsNormal"/>
+ <itemData name="Command" defStyleNum="dsFunction"/>
+ <itemData name="Comment" defStyleNum="dsComment"/>
+ <itemData name="String" defStyleNum="dsString"/>
+ <itemData name="Special Variable" defStyleNum="dsOthers"/>
+ <itemData name="Placeholder" defStyleNum="dsKeyword" color="#5555ff" selColor="#ffffff" bold="0" italic="0" />
+ <itemData name="CDATA" defStyleNum="dsBaseN" bold="1" />
+ <itemData name="Processing Instruction" defStyleNum="dsKeyword" />
+ <itemData name="Doctype" defStyleNum="dsDataType" bold="1" />
+ <itemData name="Element" defStyleNum="dsKeyword" />
+ <itemData name="Attribute" defStyleNum="dsOthers" />
+ <itemData name="Value" defStyleNum="dsString" color="#a00" />
+ <itemData name="EntityRef" defStyleNum="dsDecVal" />
+ <itemData name="PEntityRef" defStyleNum="dsDecVal" />
+ <itemData name="Error" defStyleNum="dsError" />
+ </itemDatas>
+</highlighting>
+<general>
+ <keywords casesensitive="1" additionalDeliminator="#"/>
+ <comments>
+ <comment name="singleLine" start="##"/>
+ <comment name="multiLine" start="#*" end="*#" region="MLComment"/>
+ <comment name="multiLine" start="&lt;!--" end="--&gt;" region="HTMLComment"/>
+ </comments>
+</general>
+</language>
+<!-- kate: space-indent on; indent-width 4; replace-tabs on; indent-mode xml; -->
View
4 docs/devel_guide_src/.cvsignore
@@ -1,4 +0,0 @@
-.cvsignore
-*.aux
-*.l2h
-devel_guide
View
1  docs/users_guide_2_src/.cvsignore
@@ -1 +0,0 @@
-*.html
View
4 docs/users_guide_src/.cvsignore
@@ -1,4 +0,0 @@
-.cvsignore
-*.aux
-*.l2h
-users_guide
View
2  src/.cvsignore
@@ -1,2 +0,0 @@
-.cvsignore
-*.pyc
View
83 src/CheetahWrapper.py
@@ -18,11 +18,11 @@
import getopt, glob, os, pprint, re, shutil, sys
import cPickle as pickle
+from optparse import OptionParser
from Cheetah.Version import Version
from Cheetah.Template import Template, DEFAULT_COMPILER_SETTINGS
from Cheetah.Utils.Misc import mkdirsWithPyInitFiles
-from Cheetah.Utils.optik import OptionParser
optionDashesRE = re.compile( R"^-{1,2}" )
moduleNameRE = re.compile( R"^[a-zA-Z_][a-zA-Z_0-9]*$" )
@@ -53,18 +53,6 @@ def __repr__(self):
return "<Bundle %r>" % self.__dict__
-class MyOptionParser(OptionParser):
- standard_option_list = [] # We use commands for Optik's standard options.
-
- def error(self, msg):
- """Print our usage+error page."""
- usage(HELP_PAGE2, msg)
-
- def print_usage(self, file=None):
- """Our usage+error page already has this."""
- pass
-
-
##################################################
## USAGE FUNCTION & MESSAGES
@@ -108,36 +96,10 @@ def usage(usageMessage, errorMessage="", out=sys.stderr):
Run "cheetah options" for the list of valid options.
"""
-HELP_PAGE2 = """\
-OPTIONS FOR "compile" AND "fill":
----------------------------------
- --idir DIR, --odir DIR : input/output directories (default: current dir)
- --iext EXT, --oext EXT : input/output filename extensions
- (default for compile: tmpl/py, fill: tmpl/html)
- -R : recurse subdirectories looking for input files
- --debug : print lots of diagnostic output to standard error
- --env : put the environment in the searchList
- --flat : no destination subdirectories
- --nobackup : don't make backups
- --pickle FILE : unpickle FILE and put that object in the searchList
- --stdout, -p : output to standard output (pipe)
- --settings : a string representing the compiler settings to use
- e.g. --settings='useNameMapper=False,useFilters=False'
- This string is eval'd in Python so it should contain
- valid Python syntax.
- --templateAPIClass : a string representing a subclass of
- Cheetah.Template:Template to use for compilation
-
- --parallel : compile or fill templates in parallel, e.g.
- --parallel 4
-
-Run "cheetah help" for the main help screen.
-"""
-
##################################################
## CheetahWrapper CLASS
-class CheetahWrapper:
+class CheetahWrapper(object):
MAKE_BACKUPS = True
BACKUP_SUFFIX = ".bak"
_templateClass = None
@@ -150,6 +112,7 @@ def __init__(self):
self.pathArgs = None
self.sourceFiles = []
self.searchList = []
+ self.parser = None
##################################################
## MAIN ROUTINE
@@ -192,24 +155,25 @@ def parseOpts(self, args):
C, D, W = self.chatter, self.debug, self.warn
self.isCompile = isCompile = self.command[0] == 'c'
defaultOext = isCompile and ".py" or ".html"
- parser = MyOptionParser()
- pao = parser.add_option
- pao("--idir", action="store", dest="idir", default="")
- pao("--odir", action="store", dest="odir", default="")
- pao("--iext", action="store", dest="iext", default=".tmpl")
- pao("--oext", action="store", dest="oext", default=defaultOext)
- pao("-R", action="store_true", dest="recurse", default=False)
- pao("--stdout", "-p", action="store_true", dest="stdout", default=False)
- pao("--debug", action="store_true", dest="debug", default=False)
- pao("--env", action="store_true", dest="env", default=False)
- pao("--pickle", action="store", dest="pickle", default="")
- pao("--flat", action="store_true", dest="flat", default=False)
- pao("--nobackup", action="store_true", dest="nobackup", default=False)
- pao("--settings", action="store", dest="compilerSettingsString", default=None)
- pao("--templateAPIClass", action="store", dest="templateClassName", default=None)
- pao("--parallel", action="store", type="int", dest="parallel", default=1)
-
- self.opts, self.pathArgs = opts, files = parser.parse_args(args)
+ self.parser = OptionParser()
+ pao = self.parser.add_option
+ pao("--idir", action="store", dest="idir", default='', help='Input directory (defaults to current directory)')
+ pao("--odir", action="store", dest="odir", default="", help='Output directory (defaults to current directory)')
+ pao("--iext", action="store", dest="iext", default=".tmpl", help='File input extension (defaults: compile: .tmpl, fill: .tmpl)')
+ pao("--oext", action="store", dest="oext", default=defaultOext, help='File output extension (defaults: compile: .py, fill: .html)')
+ pao("-R", action="store_true", dest="recurse", default=False, help='Recurse through subdirectories looking for input files')
+ pao("--stdout", "-p", action="store_true", dest="stdout", default=False, help='Verbosely print informational messages to stdout')
+ pao("--debug", action="store_true", dest="debug", default=False, help='Print diagnostic/debug information to stderr')
+ pao("--env", action="store_true", dest="env", default=False, help='Pass the environment into the search list')
+ pao("--pickle", action="store", dest="pickle", default="", help='Unpickle FILE and pass it through in the search list')
+ pao("--flat", action="store_true", dest="flat", default=False, help='Do not build destination subdirectories')
+ pao("--nobackup", action="store_true", dest="nobackup", default=False, help='Do not make backup files when generating new ones')
+ pao("--settings", action="store", dest="compilerSettingsString", default=None, help='String of compiler settings to pass through, e.g. --settings="useNameMapper=False,useFilters=False"')
+ pao("--templateAPIClass", action="store", dest="templateClassName", default=None, help='Name of a subclass of Cheetah.Template.Template to use for compilation, e.g. MyTemplateClass')
+ pao("--parallel", action="store", type="int", dest="parallel", default=1, help='Compile/fill templates in parallel, e.g. --parallel=4')
+ pao('--shbang', dest='shbang', default='#!/usr/bin/env python', help='Specify the shbang to place at the top of compiled templates, e.g. --shbang="#!/usr/bin/python2.6"')
+
+ self.opts, self.pathArgs = opts, files = self.parser.parse_args(args)
D("""\
cheetah compile %s
Options are
@@ -252,7 +216,7 @@ def help(self):
usage(HELP_PAGE1, "", sys.stdout)
def options(self):
- usage(HELP_PAGE2, "", sys.stdout)
+ return self.parser.print_help()
def test(self):
# @@MO: Ugly kludge.
@@ -604,6 +568,7 @@ def _compileOrFillBundle(self, b):
pysrc = TemplateClass.compile(file=src, returnAClass=False,
moduleName=basename,
className=basename,
+ commandlineopts=self.opts,
compilerSettings=compilerSettings)
output = pysrc
else:
View
25 src/Compiler.py
@@ -63,6 +63,7 @@ class Error(Exception): pass
'alwaysFilterNone':True, # filter out None, before the filter is called
'useFilters':True, # use str instead if =False
'includeRawExprInFilterArgs':True,
+ 'useLegacyImportMode' : True,
#'lookForTransactionAttr':False,
'autoAssignDummyTransactionToSelf':False,
@@ -973,9 +974,16 @@ def setErrorCatcher(self, errorCatcherName):
def nextFilterRegionID(self):
return self.nextCacheID()
+
+ def setTransform(self, transformer, isKlass):
+ self.addChunk('trans = TransformerTransaction()')
+ self.addChunk('trans._response = trans.response()')
+ self.addChunk('trans._response._filter = %s' % transformer)
+ self.addChunk('write = trans._response.write')
def setFilter(self, theFilter, isKlass):
- class FilterDetails: pass
+ class FilterDetails:
+ pass
filterDetails = FilterDetails()
filterDetails.ID = ID = self.nextFilterRegionID()
filterDetails.theFilter = theFilter
@@ -1566,8 +1574,8 @@ def __init__(self, source=None, file=None,
self._fileDirName, self._fileBaseName = os.path.split(self._filePath)
self._fileBaseNameRoot, self._fileBaseNameExt = os.path.splitext(self._fileBaseName)
- if not isinstance(source, (str,unicode)):
- source = str(source)
+ if not isinstance(source, basestring):
+ source = unicode(source)
# by converting to string here we allow objects such as other Templates
# to be passed in
@@ -1638,7 +1646,7 @@ def _setupCompilerState(self):
"from Cheetah.Version import MinCompatibleVersion as RequiredCheetahVersion",
"from Cheetah.Version import MinCompatibleVersionTuple as RequiredCheetahVersionTuple",
"from Cheetah.Template import Template",
- "from Cheetah.DummyTransaction import DummyTransaction",
+ "from Cheetah.DummyTransaction import *",
"from Cheetah.NameMapper import NotFound, valueForName, valueFromSearchList, valueFromFrameOrSearchList",
"from Cheetah.CacheRegion import CacheRegion",
"import Cheetah.Filters as Filters",
@@ -1712,9 +1720,10 @@ def importedVarNames(self):
return self._importedVarNames
def addImportedVarNames(self, varNames, raw_statement=None):
+ settings = self.settings()
if not varNames:
return
- if self._methodBodyChunks and raw_statement:
+ if self._methodBodyChunks and raw_statement and not settings.get('useLegacyImportMode'):
self.addChunk(raw_statement)
else:
self._importedVarNames.extend(varNames)
@@ -1836,7 +1845,11 @@ def addSpecialVar(self, basename, contents, includeUnderscores=True):
self._specialVars[name] = contents.strip()
def addImportStatement(self, impStatement):
- self._importStatements.append(impStatement)
+ settings = self.settings()
+ if not self._methodBodyChunks or settings.get('useLegacyImportMode'):
+ # In the case where we are importing inline in the middle of a source block
+ # we don't want to inadvertantly import the module at the top of the file either
+ self._importStatements.append(impStatement)
#@@TR 2005-01-01: there's almost certainly a cleaner way to do this!
importVarNames = impStatement[impStatement.find('import') + len('import'):].split(',')
View
40 src/DummyTransaction.py
@@ -15,6 +15,8 @@
__author__ = "Tavis Rudd <tavis@damnsimple.com>"
__revision__ = "$Revision: 1.13 $"[11:-2]
+import types
+
def flush():
pass
@@ -56,3 +58,41 @@ def __init__(self, DummyResponse=DummyResponse):
def response(resp=DummyResponse()):
return resp
self.response = response
+
+class TransformerResponse(object):
+ def __init__(self, *args, **kwargs):
+ self._output = []
+ self._filter = None
+
+ def write(self, value):
+ self._output.append(value)
+
+ def flush(self):
+ pass
+
+ def writeln(self, line):
+ self.write(line)
+ self.write('\n')
+
+ def writelines(self, *lines):
+ [self.writeln(line) for line in lines]
+
+ def getvalue(self, **kwargs):
+ output = kwargs.get('outputChunks') or self._output
+ rc = ''.join(output)
+ if self._filter:
+ _filter = self._filter
+ if isinstance(_filter, types.TypeType):
+ _filter = _filter()
+ return _filter.filter(rc)
+ return rc
+
+
+class TransformerTransaction(object):
+ def __init__(self, *args, **kwargs):
+ self._response = None
+ def response(self):
+ if self._response:
+ return self._response
+ return TransformerResponse()
+
View
128 src/Filters.py
@@ -1,27 +1,17 @@
#!/usr/bin/env python
-# $Id: Filters.py,v 1.33 2007/12/29 23:08:18 tavis_rudd Exp $
-"""Filters for the #filter directive; output filters Cheetah's $placeholders .
-
-Meta-Data
-================================================================================
-Author: Tavis Rudd <tavis@damnsimple.com>
-Version: $Revision: 1.33 $
-Start Date: 2001/08/01
-Last Revision Date: $Date: 2007/12/29 23:08:18 $
-"""
-__author__ = "Tavis Rudd <tavis@damnsimple.com>"
-__revision__ = "$Revision: 1.33 $"[11:-2]
+'''
+ Filters for the #filter directive as well as #transform
+
+ #filter results in output filters Cheetah's $placeholders .
+ #transform results in a filter on the entirety of the output
+'''
+import sys
+import Cheetah.contrib
# Additional entities WebSafe knows how to transform. No need to include
# '<', '>' or '&' since those will have been done already.
webSafeEntities = {' ': '&nbsp;', '"': '&quot;'}
-class Error(Exception):
- pass
-
-##################################################
-## BASE CLASS
-
class Filter(object):
"""A baseclass for the Cheetah Filters."""
@@ -49,13 +39,14 @@ def filter(self, val,
elif val is None:
filtered = ''
else:
- filtered = str(val)
+ try:
+ filtered = str(val)
+ except UnicodeEncodeError:
+ filtered = unicode(val)
return filtered
RawOrEncodedUnicode = Filter
-##################################################
-## ENHANCED FILTERS
class EncodeUnicode(Filter):
def filter(self, val,
@@ -73,18 +64,93 @@ def filter(self, val,
>>> print t
"""
if isinstance(val, unicode):
- filtered = val.encode(encoding)
- elif val is None:
- filtered = ''
- else:
- filtered = str(val)
- return filtered
+ return val.encode(encoding)
+ if val is None:
+ return ''
+ return str(val)
+
+
+class Markdown(EncodeUnicode):
+ '''
+ Markdown will change regular strings to Markdown
+ (http://daringfireball.net/projects/markdown/)
+
+ Such that:
+ My Header
+ =========
+ Becaomes:
+ <h1>My Header</h1>
+
+ and so on.
+
+ Markdown is meant to be used with the #transform
+ tag, as it's usefulness with #filter is marginal at
+ best
+ '''
+ def filter(self, value, **kwargs):
+ # This is a bit of a hack to allow outright embedding of the markdown module
+ try:
+ markdown_path = '/'.join(Cheetah.contrib.__file__.split('/')[:-1])
+ sys.path.append(markdown_path)
+ from Cheetah.contrib import markdown
+ sys.path.pop()
+ except:
+ print '>>> Exception raised importing the "markdown" module'
+ print '>>> Are you sure you have the ElementTree module installed?'
+ print ' http://effbot.org/downloads/#elementtree'
+ raise
+
+ encoded = super(Markdown, self).filter(value, **kwargs)
+ return markdown.markdown(encoded)
+
+class CodeHighlighter(EncodeUnicode):
+ '''
+ The CodeHighlighter filter depends on the "pygments" module which you can
+ download and install from: http://pygments.org
+
+ What the CodeHighlighter assumes the string that it's receiving is source
+ code and uses pygments.lexers.guess_lexer() to try to guess which parser
+ to use when highlighting it.
+
+ CodeHighlighter will return the HTML and CSS to render the code block, syntax
+ highlighted, in a browser
+
+ NOTE: I had an issue installing pygments on Linux/amd64/Python 2.6 dealing with
+ importing of pygments.lexers, I was able to correct the failure by adding:
+ raise ImportError
+ to line 39 of pygments/plugin.py (since importing pkg_resources was causing issues)
+ '''
+ def filter(self, source, **kwargs):
+ encoded = super(CodeHighlighter, self).filter(source, **kwargs)
+ try:
+ from pygments import highlight
+ from pygments import lexers
+ from pygments import formatters
+ except ImportError, ex:
+ print '<%s> - Failed to import pygments! (%s)' % (self.__class__.__name__, ex)
+ print '-- You may need to install it from: http://pygments.org'
+ return encoded
+
+ lexer = None
+ try:
+ lexer = lexers.guess_lexer(source)
+ except lexers.ClassNotFound:
+ lexer = lexers.PythonLexer()
+
+ formatter = formatters.HtmlFormatter(cssclass='code_highlighter')
+ encoded = highlight(encoded, lexer, formatter)
+ css = formatter.get_style_defs('.code_highlighter')
+ return '''<style type="text/css"><!--
+ %(css)s
+ --></style>%(source)s''' % {'css' : css, 'source' : encoded}
+
+
class MaxLen(Filter):
def filter(self, val, **kw):
"""Replace None with '' and cut off at maxlen."""
- output = super(MaxLen, self).filter(val, **kw)
+ output = super(MaxLen, self).filter(val, **kw)
if kw.has_key('maxlen') and len(output) > kw['maxlen']:
return output[:kw['maxlen']]
return output
@@ -93,7 +159,7 @@ class WebSafe(Filter):
"""Escape HTML entities in $placeholders.
"""
def filter(self, val, **kw):
- s = super(WebSafe, self).filter(val, **kw)
+ s = super(WebSafe, self).filter(val, **kw)
# These substitutions are copied from cgi.escape().
s = s.replace("&", "&amp;") # Must be done first!
s = s.replace("<", "&lt;")
@@ -127,7 +193,7 @@ class Strip(Filter):
with the proposed #sed directive (which has not been ratified yet.)
"""
def filter(self, val, **kw):
- s = super(Strip, self).filter(val, **kw)
+ s = super(Strip, self).filter(val, **kw)
result = []
start = 0 # The current line will be s[start:end].
while 1: # Loop through each line.
@@ -150,7 +216,7 @@ class StripSqueeze(Filter):
input is joined into one ling line with NO trailing newline.
"""
def filter(self, val, **kw):
- s = super(StripSqueeze, self).filter(val, **kw)
+ s = super(StripSqueeze, self).filter(val, **kw)
s = s.split()
return " ".join(s)
View
7 src/ImportManager.py
@@ -407,7 +407,12 @@ def install(self):
__builtin__.__import__ = self.importHook
__builtin__.reload = self.reloadHook
- def importHook(self, name, globals=None, locals=None, fromlist=None):
+ def importHook(self, name, globals=None, locals=None, fromlist=None, level=-1):
+ '''
+ NOTE: Currently importHook will accept the keyword-argument "level"
+ but it will *NOT* use it (currently). Details about the "level" keyword
+ argument can be found here: http://www.python.org/doc/2.5.2/lib/built-in-funcs.html
+ '''
# first see if we could be importing a relative name
#print "importHook(%s, %s, locals, %s)" % (name, globals['__name__'], fromlist)
_sys_modules_get = sys.modules.get
View
25 src/Parser.py
@@ -172,6 +172,7 @@ def makeTripleQuoteRe(start, end):
'filter': 'eatFilter',
'echo': None,
'silent': None,
+ 'transform' : 'eatTransform',
'call': 'eatCall',
'arg': 'eatCallArg',
@@ -2473,6 +2474,30 @@ def eatFilter(self):
self.pushToOpenDirectivesStack("filter")
self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLinePos)
self._compiler.setFilter(theFilter, isKlass)
+
+ def eatTransform(self):
+ isLineClearToStartToken = self.isLineClearToStartToken()
+ endOfFirstLinePos = self.findEOL()
+
+ self.getDirectiveStartToken()
+ self.advance(len('transform'))
+ self.getWhiteSpace()
+ startPos = self.pos()
+ if self.matchCheetahVarStart():
+ isKlass = True
+ transformer = self.getExpression(pyTokensToBreakAt=[':'])
+ else:
+ isKlass = False
+ transformer = self.getIdentifier()
+ self.getWhiteSpace()
+ transformer = self._applyExpressionFilters(transformer, 'transform', startPos=startPos)
+
+ if self.peek()==':':
+ self.advance()
+ self.getWhiteSpace()
+ self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLinePos)
+ self._compiler.setTransform(transformer, isKlass)
+
def eatErrorCatcher(self):
isLineClearToStartToken = self.isLineClearToStartToken()
View
40 src/Template.py
@@ -71,8 +71,15 @@ def release(self): pass
from Cheetah.Unspecified import Unspecified
-class Error(Exception): pass
-class PreprocessError(Error): pass
+# Decide whether to use the file modification time in file's cache key
+__checkFileMtime = True
+def checkFileMtime(value):
+ globals()['__checkFileMtime'] = value
+
+class Error(Exception):
+ pass
+class PreprocessError(Error):
+ pass
def hashList(l):
hashedList = []
@@ -339,7 +346,7 @@ def compile(klass, source=None, file=None,
preprocessors=Unspecified,
cacheModuleFilesForTracebacks=Unspecified,
cacheDirForModuleFiles=Unspecified,
-
+ commandlineopts=None,
keepRefToGeneratedCode=Unspecified,
):
@@ -617,7 +624,6 @@ def __str__(self): return self.respond()
vt(compilerSettings, 'compilerSettings', [D], 'dictionary')
compilerClass = valOrDefault(compilerClass, klass._getCompilerClass(source, file))
-
preprocessors = valOrDefault(preprocessors, klass._CHEETAH_preprocessors)
keepRefToGeneratedCode = valOrDefault(
@@ -679,7 +685,7 @@ def __str__(self): return self.respond()
cacheHash = None
cacheItem = None
- if source or isinstance(file, (str, unicode)):
+ if source or isinstance(file, basestring):
compilerSettingsHash = None
if compilerSettings:
compilerSettingsHash = hashDict(compilerSettings)
@@ -690,7 +696,9 @@ def __str__(self): return self.respond()
fileHash = None
if file:
- fileHash = str(hash(file))+str(os.path.getmtime(file))
+ fileHash = str(hash(file))
+ if globals()['__checkFileMtime']:
+ fileHash += str(os.path.getmtime(file))
try:
# @@TR: find some way to create a cacheHash that is consistent
@@ -723,6 +731,8 @@ def __str__(self): return self.respond()
baseclassName=baseclassName,
mainMethodName=mainMethodName,
settings=(compilerSettings or {}))
+ if commandlineopts:
+ compiler.setShBang(commandlineopts.shbang)
compiler.compile()
generatedModuleCode = compiler.getModuleCode()
@@ -744,12 +754,8 @@ def __str__(self): return self.respond()
__file__ = os.path.join(cacheDirForModuleFiles, __file__)
# @@TR: might want to assert that it doesn't already exist
- try:
- open(__file__, 'w').write(generatedModuleCode)
- # @@TR: should probably restrict the perms, etc.
- except OSError:
- # @@ TR: should this optionally raise?
- traceback.print_exc(file=sys.stderr)
+ open(__file__, 'w').write(generatedModuleCode)
+ # @@TR: should probably restrict the perms, etc.
mod = new.module(str(uniqueModuleName))
if moduleGlobals:
@@ -771,7 +777,6 @@ def __str__(self): return self.respond()
parseError = genParserErrorFromPythonException(
source, file, generatedModuleCode, exception=e)
except:
- traceback.print_exc()
updateLinecache(__file__, generatedModuleCode)
e.generatedModuleCode = generatedModuleCode
raise e
@@ -979,10 +984,12 @@ def _addCheetahPlumbingCodeToClass(klass, concreteTemplateClass):
mainMethNameAttr = '_mainCheetahMethod_for_'+concreteTemplateClass.__name__
mainMethName = getattr(concreteTemplateClass,mainMethNameAttr, None)
if mainMethName:
- def __str__(self): return getattr(self, mainMethName)()
+ def __str__(self):
+ return getattr(self, mainMethName)()
elif (hasattr(concreteTemplateClass, 'respond')
and concreteTemplateClass.respond!=Servlet.respond):
- def __str__(self): return self.respond()
+ def __str__(self):
+ return self.respond()
else:
def __str__(self):
if hasattr(self, mainMethNameAttr):
@@ -1413,10 +1420,9 @@ def _initCheetahInstance(self,
self._CHEETAH__searchList.append(self)
else:
# create our own searchList
- self._CHEETAH__searchList = [self._CHEETAH__globalSetVars]
+ self._CHEETAH__searchList = [self._CHEETAH__globalSetVars, self]
if searchList is not None:
self._CHEETAH__searchList.extend(list(searchList))
- self._CHEETAH__searchList.append( self )
self._CHEETAH__cheetahIncludes = {}
self._CHEETAH__cacheRegions = {}
self._CHEETAH__indenter = Indenter()
View
3  src/Templates/.cvsignore
@@ -1,3 +0,0 @@
-.cvsignore
-*.pyc
-*.py_bak
View
2  src/Tests/.cvsignore
@@ -1,2 +0,0 @@
-.cvsignore
-*.pyc
View
2  src/Tests/CheetahWrapper.py
@@ -29,8 +29,8 @@
import unittest_local_copy as unittest
import re # Used by listTests.
+from optparse import OptionParser
from Cheetah.CheetahWrapper import CheetahWrapper # Used by NoBackup.
-from Cheetah.Utils.optik import OptionParser # Used by main.
##################################################
## CONSTANTS & GLOBALS ##
View
55 src/Tests/FileRefresh.py
@@ -1,55 +0,0 @@
-#!/usr/bin/env python
-# $Id: FileRefresh.py,v 1.6 2002/10/01 17:52:03 tavis_rudd Exp $
-"""Tests to make sure that the file-update-monitoring code is working properly
-
-THIS TEST MODULE IS JUST A SHELL AT THE MOMENT. Feel like filling it in??
-
-Meta-Data
-================================================================================
-Author: Tavis Rudd <tavis@damnsimple.com>,
-Version: $Revision: 1.6 $
-Start Date: 2001/10/01
-Last Revision Date: $Date: 2002/10/01 17:52:03 $
-"""
-__author__ = "Tavis Rudd <tavis@damnsimple.com>"
-__revision__ = "$Revision: 1.6 $"[11:-2]
-
-
-##################################################
-## DEPENDENCIES ##
-
-import sys
-import types
-import os
-import os.path
-
-
-import unittest_local_copy as unittest
-from Cheetah.Template import Template
-
-##################################################
-## CONSTANTS & GLOBALS ##
-
-try:
- True,False
-except NameError:
- True, False = (1==1),(1==0)
-
-##################################################
-## TEST DATA FOR USE IN THE TEMPLATES ##
-
-##################################################
-## TEST BASE CLASSES
-
-class TemplateTest(unittest.TestCase):
- pass
-
-##################################################
-## TEST CASE CLASSES
-
-
-##################################################
-## if run from the command line ##
-
-if __name__ == '__main__':
- unittest.main()
View
65 src/Tests/Filters.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+
+import sys
+
+import Cheetah.Template
+import Cheetah.Filters
+
+import unittest_local_copy as unittest
+
+class BasicMarkdownFilterTest(unittest.TestCase):
+ '''
+ Test that our markdown filter works
+ '''
+ def test_BasicHeader(self):
+ template = '''
+#from Cheetah.Filters import Markdown
+#transform Markdown
+$foo
+
+Header
+======
+ '''
+ expected = '''<p>bar</p>
+<h1>Header</h1>'''
+ try:
+ template = Cheetah.Template.Template(template, searchList=[{'foo' : 'bar'}])
+ template = str(template)
+ assert template == expected
+ except Exception, ex:
+ if ex.__class__.__name__ == 'MarkdownException' and sys.version_info[0] == 2 and sys.version_info[1] < 5:
+ print '>>> NOTE: Support for the Markdown filter will be broken for you. Markdown says: %s' % ex
+ return
+ raise
+
+
+class BasicCodeHighlighterFilterTest(unittest.TestCase):
+ '''
+ Test that our code highlighter filter works
+ '''
+ def test_Python(self):
+ template = '''
+#from Cheetah.Filters import CodeHighlighter
+#transform CodeHighlighter
+
+def foo(self):
+ return '$foo'
+ '''
+ template = Cheetah.Template.Template(template, searchList=[{'foo' : 'bar'}])
+ template = str(template)
+ assert template, (template, 'We should have some content here...')
+
+ def test_Html(self):
+ template = '''
+#from Cheetah.Filters import CodeHighlighter
+#transform CodeHighlighter
+
+<html><head></head><body>$foo</body></html>
+ '''
+ template = Cheetah.Template.Template(template, searchList=[{'foo' : 'bar'}])
+ template = str(template)
+ assert template, (template, 'We should have some content here...')
+
+
+if __name__ == '__main__':
+ unittest.main()
View
66 src/Tests/Regressions.py
@@ -2,8 +2,9 @@
import Cheetah.NameMapper
import Cheetah.Template
+import pdb
-import unittest
+import unittest_local_copy as unittest # This is just stupid
class GetAttrException(Exception):
pass
@@ -36,19 +37,19 @@ def test_NotFoundException(self):
template = Cheetah.Template.Template.compile(template, compilerSettings={}, keepRefToGeneratedCode=True)
template = template(searchList=[{'obj' : CustomGetAttrClass()}])
- assert template, 'We should have a vallid template object by now'
+ assert template, 'We should have a valid template object by now'
self.failUnlessRaises(GetAttrException, template.raiseme)
-class InlineFromImportTest(unittest.TestCase):
- '''
- Verify that a bug introduced in v2.1.0 where an inline:
- #from module import class
- would result in the following code being generated:
- improt class
- '''
- def runTest(self):
+class InlineImportTest(unittest.TestCase):
+ def test_FromFooImportThing(self):
+ '''
+ Verify that a bug introduced in v2.1.0 where an inline:
+ #from module import class
+ would result in the following code being generated:
+ import class
+ '''
template = '''
#def myfunction()
#if True
@@ -58,7 +59,7 @@ def runTest(self):
#end if
#end def
'''
- template = Cheetah.Template.Template.compile(template, compilerSettings={}, keepRefToGeneratedCode=True)
+ template = Cheetah.Template.Template.compile(template, compilerSettings={'useLegacyImportMode' : False}, keepRefToGeneratedCode=True)
template = template(searchList=[{}])
assert template, 'We should have a valid template object by now'
@@ -66,6 +67,49 @@ def runTest(self):
rc = template.myfunction()
assert rc == 17, (template, 'Didn\'t get a proper return value')
+ def test_ImportFailModule(self):
+ template = '''
+ #try
+ #import invalidmodule
+ #except
+ #set invalidmodule = dict(FOO='BAR!')
+ #end try
+
+ $invalidmodule.FOO
+ '''
+ template = Cheetah.Template.Template.compile(template, compilerSettings={'useLegacyImportMode' : False}, keepRefToGeneratedCode=True)
+ template = template(searchList=[{}])
+
+ assert template, 'We should have a valid template object by now'
+ assert str(template), 'We weren\'t able to properly generate the result from the template'
+
+ def test_ProperImportOfBadModule(self):
+ template = '''
+ #from invalid import fail
+
+ This should totally $fail
+ '''
+ self.failUnlessRaises(ImportError, Cheetah.Template.Template.compile, template, compilerSettings={'useLegacyImportMode' : False}, keepRefToGeneratedCode=True)
+
+ def test_AutoImporting(self):
+ template = '''
+ #extends FakeyTemplate
+
+ Boo!
+ '''
+ self.failUnlessRaises(ImportError, Cheetah.Template.Template.compile, template)
+
+ def test_StuffBeforeImport_Legacy(self):
+ template = '''
+###
+### I like comments before import
+###
+#extends Foo
+Bar
+'''
+ self.failUnlessRaises(ImportError, Cheetah.Template.Template.compile, template, compilerSettings={'useLegacyImportMode' : True}, keepRefToGeneratedCode=True)
+
+
if __name__ == '__main__':
unittest.main()
View
2  src/Tests/Template.py
@@ -319,7 +319,7 @@ def test_FailCase(self):
#end def
'''
# This should raise an IndentationError (if the bug exists)
- klass = Template.compile(source=source)
+ klass = Template.compile(source=source, compilerSettings={'useLegacyImportMode' : False})
t = klass(namespaces={'foo' : 1234})
View
65 src/Tests/Test.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-# $Id: Test.py,v 1.44 2006/01/15 20:45:10 tavis_rudd Exp $
-"""Core module of Cheetah's Unit-testing framework
+'''
+Core module of Cheetah's Unit-testing framework
TODO
================================================================================
@@ -8,63 +8,40 @@
# negative test cases for expected exceptions
# black-box vs clear-box testing
# do some tests that run the Template for long enough to check that the refresh code works
-
-Meta-Data
-================================================================================
-Author: Tavis Rudd <tavis@damnsimple.com>,
-License: This software is released for unlimited distribution under the
- terms of the MIT license. See the LICENSE file.
-Version: $Revision: 1.44 $
-Start Date: 2001/03/30
-Last Revision Date: $Date: 2006/01/15 20:45:10 $
-"""
-__author__ = "Tavis Rudd <tavis@damnsimple.com>"
-__revision__ = "$Revision: 1.44 $"[11:-2]
-
-
-##################################################
-## DEPENDENCIES ##
+'''
import sys
import unittest_local_copy as unittest
-##################################################
-## CONSTANTS & GLOBALS
-try:
- True, False
-except NameError:
- True, False = (1==1),(1==0)
-
-##################################################
-## TESTS
import SyntaxAndOutput
import NameMapper
import Template
-import FileRefresh
import CheetahWrapper
+import Regressions
+import Unicode
-SyntaxSuite = unittest.findTestCases(SyntaxAndOutput)
-NameMapperSuite = unittest.findTestCases(NameMapper)
-TemplateSuite = unittest.findTestCases(Template)
-FileRefreshSuite = unittest.findTestCases(FileRefresh)
-if not sys.platform.startswith('java'):
- CheetahWrapperSuite = unittest.findTestCases(CheetahWrapper)
-
-from SyntaxAndOutput import *
-from NameMapper import *
-from Template import *
-from FileRefresh import *
+suites = [
+ unittest.findTestCases(SyntaxAndOutput),
+ unittest.findTestCases(NameMapper),
+ unittest.findTestCases(Template),
+ unittest.findTestCases(Regressions),
+ unittest.findTestCases(Unicode),
+]
if not sys.platform.startswith('java'):
- from CheetahWrapper import *
-
-##################################################
-## if run from the command line
+ suites.append(unittest.findTestCases(CheetahWrapper))
if __name__ == '__main__':
- unittest.main()
+ runner = unittest.TextTestRunner()
+ if 'xml' in sys.argv:
+ import xmlrunner
+ runner = xmlrunner.XMLTestRunner(filename='Cheetah-Tests.xml')
+
+ results = runner.run(unittest.TestSuite(suites))
+
+
View
73 src/Tests/Unicode.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+# -*- encoding: utf8 -*-
+
+from Cheetah.Template import Template
+import traceback
+import unittest_local_copy as unittest # This is stupid
+
+class JPQ_UTF8_Test1(unittest.TestCase):
+ def runTest(self):
+ t = Template.compile(source="""Main file with |$v|
+
+ $other""")
+
+ otherT = Template.compile(source="Other template with |$v|")
+ other = otherT()
+ t.other = other
+
+ t.v = u'Unicode String'
+ t.other.v = u'Unicode String'
+
+ assert t()
+
+class JPQ_UTF8_Test2(unittest.TestCase):
+ def runTest(self):
+ t = Template.compile(source="""Main file with |$v|
+
+ $other""")
+
+ otherT = Template.compile(source="Other template with |$v|")
+ other = otherT()
+ t.other = other
+
+ t.v = u'Unicode String with eacute é'
+ t.other.v = u'Unicode String'
+
+ assert unicode(t())
+ assert t().__str__()
+
+
+class JPQ_UTF8_Test3(unittest.TestCase):
+ def runTest(self):
+ t = Template.compile(source="""Main file with |$v|
+
+ $other""")
+
+ otherT = Template.compile(source="Other template with |$v|")
+ other = otherT()
+ t.other = other
+
+ t.v = u'Unicode String with eacute é'
+ t.other.v = u'Unicode String and an eacute é'
+
+ assert unicode(t())
+
+class JPQ_UTF8_Test4(unittest.TestCase):
+ def runTest(self):
+ t = Template.compile(source="""Main file with |$v| and eacute in the template é""")
+
+ t.v = 'Unicode String'
+
+ assert t()
+
+class JPQ_UTF8_Test5(unittest.TestCase):
+ def runTest(self):
+ t = Template.compile(source="""#encoding utf-8
+ Main file with |$v| and eacute in the template é""")
+
+ t.v = u'Unicode String'
+ rc = t().__str__()
+ assert rc
+
+if __name__ == '__main__':
+ unittest.main()
View
5 src/Tests/unittest_local_copy.py
@@ -834,8 +834,9 @@ def loadTestsFromNames(self, names, module=None):
def getTestCaseNames(self, testCaseClass):
"""Return a sorted sequence of method names found within testCaseClass.
"""
- testFnNames = filter(lambda n,p=self.testMethodPrefix: n[:len(p)] == p,
- dir(testCaseClass))
+ testFnNames = [fn for fn in dir(testCaseClass) if fn.startswith(self.testMethodPrefix)]
+ if hasattr(testCaseClass, 'runTest'):
+ testFnNames.append('runTest')
for baseclass in testCaseClass.__bases__:
for testFnName in self.getTestCaseNames(baseclass):
if testFnName not in testFnNames: # handle overridden methods
View
53 src/Tests/xmlrunner.py
@@ -19,6 +19,7 @@
from StringIO import StringIO
+
class _TestInfo(object):
"""Information about a particular test.
@@ -28,29 +29,12 @@ class _TestInfo(object):
"""
def __init__(self, test, time):
- (self._class, self._method) = test.id().rsplit(".", 1)
+ _pieces = test.id().split('.')
+ (self._class, self._method) = ('.'.join(_pieces[:-1]), _pieces[-1])
self._time = time
self._error = None
self._failure = None
- @staticmethod
- def create_success(test, time):
- """Create a _TestInfo instance for a successful test."""
- return _TestInfo(test, time)
-
- @staticmethod
- def create_failure(test, time, failure):
- """Create a _TestInfo instance for a failed test."""
- info = _TestInfo(test, time)
- info._failure = failure
- return info
-
- @staticmethod
- def create_error(test, time, error):
- """Create a _TestInfo instance for an erroneous test."""
- info = _TestInfo(test, time)
- info._error = error
- return info
def print_report(self, stream):
"""Print information about this test case in XML format to the
@@ -74,13 +58,29 @@ def _print_error(self, stream, tagname, error):
text = escape(str(error[1]))
stream.write('\n')
stream.write(' <%s type="%s">%s\n' \
- % (tagname, str(error[0]), text))
+ % (tagname, issubclass(error[0], Exception) and error[0].__name__ or str(error[0]), text))
tb_stream = StringIO()
traceback.print_tb(error[2], None, tb_stream)
stream.write(escape(tb_stream.getvalue()))
stream.write(' </%s>\n' % tagname)
stream.write(' ')
+# Module level functions since Python 2.3 doesn't grok decorators
+def create_success(test, time):
+ """Create a _TestInfo instance for a successful test."""
+ return _TestInfo(test, time)
+
+def create_failure(test, time, failure):
+ """Create a _TestInfo instance for a failed test."""
+ info = _TestInfo(test, time)
+ info._failure = failure
+ return info
+
+def create_error(test, time, error):
+ """Create a _TestInfo instance for an erroneous test."""
+ info = _TestInfo(test, time)
+ info._error = error
+ return info
class _XMLTestResult(unittest.TestResult):
@@ -108,11 +108,11 @@ def stopTest(self, test):
time_taken = time.time() - self._start_time
unittest.TestResult.stopTest(self, test)
if self._error:
- info = _TestInfo.create_error(test, time_taken, self._error)
+ info = create_error(test, time_taken, self._error)
elif self._failure:
- info = _TestInfo.create_failure(test, time_taken, self._failure)
+ info = create_failure(test, time_taken, self._failure)
else:
- info = _TestInfo.create_success(test, time_taken)
+ info = create_success(test, time_taken)
self._tests.append(info)
def addError(self, test, err):
@@ -158,8 +158,9 @@ class XMLTestRunner(object):
"""
- def __init__(self, stream=None):
- self._stream = stream
+ def __init__(self, *args, **kwargs):
+ self._stream = kwargs.get('stream')
+ self._filename = kwargs.get('filename')
self._path = "."
def run(self, test):
@@ -168,6 +169,8 @@ def run(self, test):
classname = class_.__module__ + "." + class_.__name__
if self._stream == None:
filename = "TEST-%s.xml" % classname
+ if self._filename:
+ filename = self._filename
stream = file(os.path.join(self._path, filename), "w")
stream.write('<?xml version="1.0" encoding="utf-8"?>\n')
else:
View
2  src/Tools/.cvsignore
@@ -1,2 +0,0 @@
-.cvsignore
-*.pyc
View
36 src/Tools/RecursiveNull.py
@@ -1,23 +1,29 @@
#!/usr/bin/env python
-"""Nothing, but in a friendly way. Good for filling in for objects you want to
+"""
+Nothing, but in a friendly way. Good for filling in for objects you want to
hide. If $form.f1 is a RecursiveNull object, then
$form.f1.anything["you"].might("use") will resolve to the empty string.
This module was contributed by Ian Bicking.
"""
-class RecursiveNull:
- __doc__ = __doc__ # Use the module's docstring for the class's docstring.
- def __getattr__(self, attr):
- return self
- def __getitem__(self, item):
- return self
- def __call__(self, *vars, **kw):
- return self
- def __str__(self):
- return ''
- def __repr__(self):
- return ''
- def __nonzero__(self):
- return 0
+class RecursiveNull(object):
+ def __getattr__(self, attr):
+ return self
+ def __getitem__(self, item):
+ return self
+ def __call__(self, *args, **kwargs):
+ return self
+ def __str__(self):
+ return ''
+ def __repr__(self):
+ return ''
+ def __nonzero__(self):
+ return 0
+ def __eq__(self, x):
+ if x:
+ return False
+ return True
+ def __ne__(self, x):
+ return x and True or False
View
2  src/Utils/.cvsignore
@@ -1,2 +0,0 @@
-.cvsignore
-*.pyc
View
2  src/Utils/optik/.cvsignore
@@ -1,2 +0,0 @@
-.cvsignore
-*.pyc
View
32 src/Utils/optik/__init__.py
@@ -1,32 +0,0 @@
-"""optik
-
-A powerful, extensible, and easy-to-use command-line parser for Python.
-
-By Greg Ward <gward@python.net>
-
-See http://optik.sourceforge.net/
-
-Cheetah modifications: added "Cheetah.Utils.optik." prefix to
- all intra-Optik imports.
-"""
-
-# Copyright (c) 2001 Gregory P. Ward. All rights reserved.
-# See the README.txt distributed with Optik for licensing terms.
-
-__revision__ = "$Id: __init__.py,v 1.2 2002/09/12 06:56:51 hierro Exp $"
-
-__version__ = "1.3"
-
-
-# Re-import these for convenience
-from Cheetah.Utils.optik.option import Option
-from Cheetah.Utils.optik.option_parser import \
- OptionParser, SUPPRESS_HELP, SUPPRESS_USAGE, STD_HELP_OPTION
-from Cheetah.Utils.optik.errors import OptionValueError
-
-
-# Some day, there might be many Option classes. As of Optik 1.3, the
-# preferred way to instantiate Options is indirectly, via make_option(),
-# which will become a factory function when there are many Option
-# classes.
-make_option = Option
View
52 src/Utils/optik/errors.py
@@ -1,52 +0,0 @@
-"""optik.errors
-
-Exception classes used by Optik.
-"""
-
-__revision__ = "$Id: errors.py,v 1.1 2002/08/24 17:10:06 hierro Exp $"
-
-# Copyright (c) 2001 Gregory P. Ward. All rights reserved.
-# See the README.txt distributed with Optik for licensing terms.
-
-# created 2001/10/17 GPW (from optik.py)
-
-
-class OptikError (Exception):
- def __init__ (self, msg):
- self.msg = msg
-
- def __str__ (self):
- return self.msg
-
-
-class OptionError (OptikError):
- """
- Raised if an Option instance is created with invalid or
- inconsistent arguments.
- """
-
- def __init__ (self, msg, option):
- self.msg = msg
- self.option_id = str(option)
-
- def __str__ (self):
- if self.option_id:
- return "option %s: %s" % (self.option_id, self.msg)
- else:
- return self.msg
-
-class OptionConflictError (OptionError):
- """
- Raised if conflicting options are added to an OptionParser.
- """
-
-class OptionValueError (OptikError):
- """
- Raised if an invalid option value is encountered on the command
- line.
- """
-
-class BadOptionError (OptikError):
- """
- Raised if an invalid or ambiguous option is seen on the command-line.
- """
View
354 src/Utils/optik/option.py
@@ -1,354 +0,0 @@
-"""optik.option
-
-Defines the Option class and some standard value-checking functions.
-
-Cheetah modifications: added "Cheetah.Utils.optik." prefix to
- all intra-Optik imports.
-"""
-
-__revision__ = "$Id: option.py,v 1.2 2002/09/12 06:56:51 hierro Exp $"
-
-# Copyright (c) 2001 Gregory P. Ward. All rights reserved.
-# See the README.txt distributed with Optik for licensing terms.
-
-# created 2001/10/17, GPW (from optik.py)
-
-import sys
-from types import TupleType, DictType
-from Cheetah.Utils.optik.errors import OptionError, OptionValueError
-
-_builtin_cvt = { "int" : (int, "integer"),
- "long" : (long, "long integer"),
- "float" : (float, "floating-point"),
- "complex" : (complex, "complex") }
-
-def check_builtin (option, opt, value):
- (cvt, what) = _builtin_cvt[option.type]
- try:
- return cvt(value)
- except ValueError:
- raise OptionValueError(
- #"%s: invalid %s argument %r" % (opt, what, value))
- "option %s: invalid %s value: %r" % (opt, what, value))
-
-# Not supplying a default is different from a default of None,
-# so we need an explicit "not supplied" value.
-NO_DEFAULT = "NO"+"DEFAULT"
-
-
-class Option:
- """
- Instance attributes:
- _short_opts : [string]
- _long_opts : [string]
-
- action : string
- type : string
- dest : string
- default : any
- nargs : int
- const : any
- callback : function
- callback_args : (any*)
- callback_kwargs : { string : any }
- help : string
- metavar : string
- """
-
- # The list of instance attributes that may be set through
- # keyword args to the constructor.
- ATTRS = ['action',
- 'type',
- 'dest',
- 'default',
- 'nargs',
- 'const',
- 'callback',
- 'callback_args',
- 'callback_kwargs',
- 'help',
- 'metavar']
-
- # The set of actions allowed by option parsers. Explicitly listed
- # here so the constructor can validate its arguments.
- ACTIONS = ("store",
- "store_const",
- "store_true",
- "store_false",
- "append",
- "count",
- "callback",
- "help",
- "version")
-