PK(8(yEGG-INFO/SOURCES.txtCHANGES LICENSE MANIFEST.in README SetupConfig.py SetupTools.py TODO cachedCompile.py cheetah-mem.py closure.py ez_setup.py foo.py setup.cfg setup.py syntaxtest.py test2.2.py timingTests.py Cheetah.egg-info/PKG-INFO Cheetah.egg-info/SOURCES.txt Cheetah.egg-info/dependency_links.txt Cheetah.egg-info/top_level.txt bin/cheetah bin/cheetah-compile src/CacheRegion.py src/CacheStore.py src/CheetahWrapper.py src/Compiler.py src/DummyTransaction.py src/ErrorCatchers.py src/FileUtils.py src/Filters.py src/ImportHooks.py src/ImportManager.py src/NameMapper.py src/Parser.py src/Servlet.py src/SettingsManager.py src/SourceReader.py src/Template.py src/TemplateCmdLineIface.py src/Unspecified.py src/Version.py src/__init__.py src/_namemapper.c src/convertTmplPathToModuleName.py src/Macros/I18n.py src/Macros/__init__.py src/Templates/SkeletonPage.py src/Templates/SkeletonPage.tmpl src/Templates/_SkeletonPage.py src/Templates/__init__.py src/Tests/CheetahWrapper.py src/Tests/FileRefresh.py src/Tests/NameMapper.py src/Tests/SyntaxAndOutput.py src/Tests/Template.py src/Tests/Test.py src/Tests/__init__.py src/Tests/unittest_local_copy.py src/Tools/CGITemplate.py src/Tools/MondoReport.py src/Tools/MondoReportDoc.txt src/Tools/RecursiveNull.py src/Tools/SiteHierarchy.py src/Tools/__init__.py src/Tools/turbocheetah/__init__.py src/Tools/turbocheetah/cheetahsupport.py src/Tools/turbocheetah/tests/__init__.py src/Tools/turbocheetah/tests/test_template.py src/Utils/Indenter.py src/Utils/Misc.py src/Utils/VerifyType.py src/Utils/WebInputMixin.py src/Utils/__init__.py src/Utils/htmlDecode.py src/Utils/htmlEncode.py src/Utils/memcache.py src/Utils/optik/__init__.py src/Utils/optik/errors.py src/Utils/optik/option.py src/Utils/optik/option_parser.py PK(82EGG-INFO/dependency_links.txt PK(8BvEGG-INFO/PKG-INFOMetadata-Version: 1.0 Name: Cheetah Version: 2.0 Summary: Cheetah is a template engine and code generation tool. Home-page: http://www.CheetahTemplate.org/ Author: Tavis Rudd Author-email: cheetahtemplate-discuss@lists.sf.net License: UNKNOWN Description: Cheetah is an open source template engine and code generation tool. It can be used standalone or combined with other tools and frameworks. Web development is its principle use, but Cheetah is very flexible and is also being used to generate C++ game code, Java, sql, form emails and even Python code. Documentation ================================================================================ For a high-level introduction to Cheetah please refer to the User's Guide at http://cheetahtemplate.org/learn.html Mailing list ================================================================================ cheetahtemplate-discuss@lists.sourceforge.net Subscribe at http://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss Credits ================================================================================ http://cheetahtemplate.org/credits.html Praise ================================================================================ "I'm enamored with Cheetah" - Sam Ruby, senior member of IBM Emerging Technologies Group & director of Apache Software Foundation "Give Cheetah a try. You won't regret it. ... Cheetah is a truly powerful system. ... Cheetah is a serious contender for the 'best of breed' Python templating." - Alex Martelli "People with a strong PHP background absolutely love Cheetah for being Smarty, but much, much better." - Marek Baczynski "I am using Smarty and I know it very well, but compiled Cheetah Templates with its inheritance approach is much powerful and easier to use than Smarty." - Jaroslaw Zabiello "There is no better solution than Cheetah" - Wilk "A cheetah template can inherit from a python class, or a cheetah template, and a Python class can inherit from a cheetah template. This brings the full power of OO programming facilities to the templating system, and simply blows away other templating systems" - Mike Meyer "Cheetah has successfully been introduced as a replacement for the overweight XSL Templates for code generation. Despite the power of XSL (and notably XPath expressions), code generation is better suited to Cheetah as templates are much easier to implement and manage." - The FEAR development team (http://fear.sourceforge.net/docs/latest/guide/Build.html#id2550573) "I've used Cheetah quite a bit and it's a very good package" - Kevin Dangoor, lead developer of TurboGears. Recent Changes ================================================================================ See http://cheetahtemplate.org/docs/CHANGES for full details. Please initial your changes (there's a key at bottom) and add a date for each release ================================================================================ 2.0 (Oct 12, 2007) !!!THIS RELEASE REQUIRES RECOMPILATION OF ALL COMPILED CHEETAH TEMPLATES!!! - fixed exception handling issue in the C implemenation of NameMapper [patch from Eric Huss] - fixed filtering of #included subtemplates [patch from Brian Bird] See the release notes from 2.0b1-5 and 2.0rc1-8 for other changes since Cheetah 1.0. 2.0rc8 (April 11, 2007) !!!THIS RELEASE REQUIRES RECOMPILATION OF ALL COMPILED CHEETAH TEMPLATES!!! Core Changes: [TR] - added a '#unicode ' directive to indicate that the output of the template should be a unicode string even if the template source is a normal byte string. - #unicode and #encoding are mutually exclusive. Use one or the other. - #unicode must be on a line by itself. - Strings in embedded code must be explictly marked as unicode if they contain non-ascii chars: #unicode latin-1 $f(u"") ## right $f("") ## wrong However, this works fine: #unicode latin-1 blah blah blah blah - fixed several unicode bugs in the compiler. - fixed some unicode issues in the standard filters. - fixed a few minor bugs in code that never gets called. Thanks to Alejandro Dubrovsky for pointing them out. - make RawOrEncodedUnicode the baseclass of all filters and remove some unused/redudant filters - added new compiler setting 'addTimestampsToCompilerOutput'. See Brian Bird's post about it. He stores his cheetah generated .py files in subversion and needed to disable the timestamp code so svn wouldn't care when he recompiles those .py modules. - added the #super directive, which calls the method from the parent class which has the same as the current #def or #block method. #def foo ... child output #super ## includes output of super(, self).foo() ... child output #end def #def bar(arg) ... child output #super(arg) ## includes output of super(, self).bar(arg) ... child output #end def - added some unit tests for the new directives 2.0rc7 (July 4, 2006) !!!THIS RELEASE REQUIRES RECOMPILATION OF ALL COMPILED CHEETAH TEMPLATES!!! Core Changes: [TR] - extended the #implements directive so an arguments list can be declared in the same fashion as #def and #block. - made the parser raise ParseError when $*placeholder, $*5*placeholder, $(placeholder), etc. are found within expressions. They are only valid in top-level text. - tweaked the parser so it's possible to place a comment on the same line as a directive without needing to explicitly close the directive first. This works regardless of whether or not you added a colon. self.verify("#if 1:\n$aStr\n#end if\n", "blarg\n") self.verify("#if 1: \n$aStr\n#end if\n", "blarg\n") self.verify("#if 1: ##comment \n$aStr\n#end if\n", "blarg\n") self.verify("#if 1 ##comment \n$aStr\n#end if\n", "blarg\n") Previously, that last test would have required an extra # to close the #if directive before the comment directive started: self.verify("#if 1 ###comment \n$aStr\n#end if\n", "blarg\n") Code that makes use of explicit directive close tokens immediately followed by another directive will still work as expected: #if test##for i in range(10)# foo $i#end for##end if - safer handling of the baseclass arg to Template.compile(). It now does the right thing if the user passes in an instance rather than a class. ImportHooks: [TR] - made it possible to specify a list of template filename extentions that are looped through while searching for template modules. E.g.: import Cheetah.ImportHooks Cheetah.ImportHooks.install(templateFileExtensions=('.tmpl','.cheetah')) Core changes by MO: - Filters are now new-style classes. - WebSafe and the other optional filters in Filters.py now use RawOrEncodedUnicode instead of Filter as a base class. This allows them to work with Unicode values containing non-ASCII characters. User-written custom filters should inherit from RawOrEncodedUnicode and call the superclass .filter() instead of str(). str() as of Python 2.4.2 still converts Unicode to string using ASCII codec, which raises UnicodeEncodeError if it contains non-ASCII characters. 2.0rc6 (Feb 4, 2006) !!!THIS RELEASE REQUIRES RECOMPILATION OF ALL COMPILED CHEETAH TEMPLATES!!! Core Changes: [TR] - added a Cheetah version dependency check that raises an assertion if a template was compiled with a previous version of Cheetah whose templates must be recompiled. - made the Cheetah compilation metadata accessible via class attributes in addition to module globals - major improvement to exception reporting in cases where bad Python syntax slips past the Cheetah parser: """ File "/usr/lib/python2.4/site-packages/Cheetah/Template.py", line 792, in compile raise parseError Cheetah.Parser.ParseError: Error in the Python code which Cheetah generated for this template: ================================================================================ invalid syntax (DynamicallyCompiledCheetahTemplate.py, line 86) Line|Python Code ----|------------------------------------------------------------- 84 | 85 | write('\n\n') 86 | for i an range(10): # generated from line 4, col 1 ^ 87 | _v = i # '$i' on line 5, col 3 88 | if _v is not None: write(_filter(_v, rawExpr='$i')) # from line 5, col 3. 89 | write('\n') ================================================================================ Here is the corresponding Cheetah code: Line 4, column 1 Line|Cheetah Code ----|------------------------------------------------------------- 2 |#compiler useNameMapper=False 3 | 4 |#for i an range(10) ^ 5 | $i 6 |#end for 7 | """ 2.0rc5 (Feb 3, 2006) !!!THIS RELEASE REQUIRES RECOMPILATION OF ALL COMPILED CHEETAH TEMPLATES!!! Core Changes: [TR] - fixed a memory leak in Template.compile(), reported by Andrea Arcangeli - simplified concurrency locking and compile caching in Template.compile() The command line tool (CheetahWrapper.py): - added new option --settings for supplying compiler settings - added new option --templateAPIClass to replace the environment var CHEETAH_TEMPLATE_CLASS lookup I added in 2.0b1 2.0rc4 (Jan 31, 2006) !!!THIS RELEASE REQUIRES RECOMPILATION OF ALL COMPILED CHEETAH TEMPLATES!!! Core Changes: [TR] - fixed a typo-bug in the compile hashing code in Template.compile() - improved the macros framework and made it possible to implement macros in Python code so they can be shared between templates - more work on the #i18n directive. It's now a macro directive. - added new Cheetah.Macros package - more tests 2.0rc3 (Jan 29, 2006) !!!THIS RELEASE REQUIRES RECOMPILATION OF ALL COMPILED CHEETAH TEMPLATES!!! Core Changes: [TR] - added short-form single line versions of all directives that have an #end tag, except for #errorCatcher: #if, #else, #elif, #unless, #for, #while, #repeat, #try, #except, #finally, #cache, #raw #call, #capture The #def and #block directives already had single-line versions. #if cond: foo #elif cond2: bar #else: blarg #for i, val in enumerate(vals): $i-$val Note that if you accidentally leave a colon at the end of one of these directives but nothing else follows it, aside from whitespace, the parser will treat it as a normal multi-line directive. The first leading space after the colon is discarded. Any additional spaces will be included in the output. Also note, if you use the short form versions of #if/#else/#elif you must it for all three. The following is not valid: #if cond: foo #elif cond2 bar #else: blarg - added support for $!silentModePlaceholders This is the same as quiet mode in Velocity: http://jakarta.apache.org/velocity/docs/user-guide.html#Quiet%20Reference%20Notation - added support for function/method @decorators. It also works with blocks. As in vanilla Python, the @decorator statement must be followed with a function/method definition (i.e. #def or #block). #from xxx import aDecorator ... ... #@aDecorator #def func foo #end def #@aDecorator #def singleLineShortFormfunc: foo #@aDecorator #block func2 bar #end block - added a new callback hook 'handlerForExtendsDirective' to the compiler settings. It can be used to customize the handling of #extends directives. The callback can dynamically add import statements or rewrite the baseclass' name if needed: baseClassName = handler(compiler, baseClassName) See the discussion on the mailing list on Jan 25th for more details. - changed the default filter to the one that doesn't try to encode Unicode It was 'EncodeUnicode' and is now 'RawOrEncodedUnicode'. - added optional support for parsing whitespace between the directive start token (#) and directive names, per Christophe Eymard's request. For the argument behind this see the mailing list archives for Jan 29th. This is off by default. You must turn it on using the compiler setting allowWhitespaceAfterDirectiveStartToken=True #for $something in $another # for $somethin2 in $another2 blahblah $something in $something2 # end for #end for - made the handling of Template.compile()'s preprocessors arg simpler and fixed a bug in it. - fixed attribute name bug in the .compile() method (it affected the feature that allows generated module files to be cached for better exception tracebacks) - refactored the #cache/CacheRegions code to support abitrary backend cache data stores. - added MemcachedCacheStore, which allows cache data to be stored in a memcached backend. See http://www.linuxjournal.com/article/7451 and http://www.danga.com/memcached/. This is only appropriate for systems running many Python server processes that need to share cached data to reduce memory requirements. Don't bother with this unless you actually need it. If you have a limited number of Python server processes it is much faster, simpler, and more secure to just cache in the memory of each process. KEEP MEMCACHED'S LIMITED SECURITY IN MIND!! It has no authentication or encryption and will introduce a gaping hole in your defenses unless you are careful. If you are caching sensitive data you should take measures to ensure that a) untrusted local system users cannot connect to memcached server, b) untrusted external servers cannot connect, and c) untrusted users on trusted external servers cannot connect. Case (a) can be dealt with via iptable's owner match module for one way to do this: "iptables -A ... -m owner ..." Cases (b) and (c) can be handled by tunnelling memcached network connections over stunnel and implementing stunnel authentication with mandatory peer/client certs. - some under-the-hood refactoring of the parser - made it possible to add custom directives, or customize the parsing/handling of existing ones, via the compiler settings 'directiveNamesAndParsers' and 'endDirectiveNamesAndHandlers' - added a compile-time macro facility to Cheetah. These macros are very similar to macros in Lisp: http://www.apl.jhu.edu/~hall/Lisp-Notes/Macros.html. As with Lisp macros, they take source code (Cheetah source) as input and return source code (again Cheetah source) as output. They are executed at compile-time, just like in Lisp and C. The resultant code gets executed at run-time. The new #defmacro directive allows users to create macros inside the source of their templates. Macros can also be provided via the compiler setting 'macroDirectives'. The 'macroDirectives' setting allows you to share common macros between templates. The syntax for the opening tag of #defmacro is the same as for #def and #block. It expects a macro name followed by an optional argument list in brackets. A `src` argument is automatically added to the beginning of every macro's argument list. The value of the `src` is the block of input source code that is provided during a macro call (see below). #defmacro [(argspec)] #end defmacro All of Cheetah's syntax is available for use inside macros, but the placeholderStartToken is @ instead of $ and the directiveStartToken/EndToken is % instead of #. Any syntax using the standard $/# tokens will be treated as plain text and included in the output of the macro. Here are some examples: #defmacro addHeaderFooter header @src footer #end defmacro #defmacro addHeaderFooter(header='h', footer='f') @header @src @footer #end defmacro There is a single-line short form like for other directives: #defmacro addHeaderFooter: header @src footer #defmacro addHeaderFooter(header='h', footer='f'): @header @src @footer The syntax for calling a macro is similar to the simplest usage of the #call directive: #addHeaderFooter Source $code to wrap #end addHeaderFooter #addHeaderFooter: Source $code to wrap #addHeaderFooter header='header', footer='footer: Source $code to wrap In Elisp you write (defmacro inc (var) (list 'setq var (list '1+ var))) to define the macro `inc` and write (inc x) which expands to (setq x (1+ x)) In Cheetah you'd write #defmacro inc: #set @src +=1 #inc: $i which expands to #set $i += 1 print Template("""\ #defmacro inc: #set @src +=1 #set i = 1 #inc: $i $i""").strip()==2 - fixed some bugs related to advanced usage of Template.compile(). These were found via new unit tests. No one had actually run into them yet. - added the initial bits of an #i18n directive. It has the same semantics as #call self.handleI18n Some $var cheetah source #end call but has a simpler syntax: #i18n Some $var cheetah source #end i18n ## single-line short form: #i18n: Some $var cheetah source The method it calls, self.handleI18n, is just a stub at the moment, but it will soon be a wrapper around gettext. It currently has one required positional argument `message`. I anticipate supporting the following optional arguments: id = msgid in the translation catalog domain = translation domain source = source lang target = a specific target lang comment = a comment to the translation team plural = the plural form of the message n = a sized argument to distinguish between single and plural forms #i18n is executed at runtime, but it can also be used in conjunction with a Cheetah preprocessor or macro (see above) to support compile time translation of strings that don't have to deal with plural forms. - added Cheetah.Utils.htmlEncode and Cheetah.Utils.htmlDecode - more docstring text Unit tests: [TR] - extended the caching tests - added tests for the various calling styles of Template.compile() - added copies of all the SyntaxAndOutput tests that use a template baseclass other than `Template`. This ensures that all syntax & core features work with 2.0's support for arbitrary baseclasses. - added tests for all the new directives and the new single-line short forms 2.0rc2 (Jan 13th, 2006) !!!THIS RELEASE REQUIRES RECOMPILATION OF ALL COMPILED CHEETAH TEMPLATES!!! Core Changes: [TR] - fixed some python 2.4isms that slipped in. All the tests pass with Python 2.2 now - added lots more docstring content in the Template class - made multiline comments gobble whitespace like other directives, per JJ's request. The rather longwinded compiler setting gobbleWhitespaceAroundMultiLineComments can be used to go back to the old non-gobbling behaviour if needed. - added #capture directive to complement the #call directive. #call executes a region of Cheetah code and passes its output into a function call #capture executes a region of Cheetah code and assigns its output to a variable - extended the compile caching code in Template.compile so it works with the 'file' arg. - added cacheModuleFilesForTracebacks and cacheDirForModuleFiles args to Template.compile(). See the docstring for details. - misc internal refactoring in the parser - improved handling of keyword args in the __init__ method and fixed a potential clash between the namespaces and searchList args WWW: [TR] - added the source for the new Cheetah website layout/content 2.0rc1 (Jan 10, 2006) !!!THIS RELEASE REQUIRES RECOMPILATION OF ALL COMPILED CHEETAH TEMPLATES!!! Core Changes: [TR] - made it possible nest #filter directives - added lots more docstring content in the Template class - added Template.subclass() classmethod for quickly creating subclasses of existing Cheetah template classes. It takes the same args as the .compile() classmethod and returns a template that is a subclass of the template .subclass() is called from: T1 = Template.compile(' foo - $meth1 - bar\n#def meth1: this is T1.meth1') T2 = T1.subclass('#implements meth1\n this is T2.meth1') - added baseclass arg to Template.compile(). It simplifies the reuse of dynamically compiled templates: # example 1, quickly subclassing a normal Python class and using its # __init__ call signature: dictTemplate = Template.compile('hello $name from $caller', baseclass=dict) print dictTemplate(name='world', caller='me') # example 2, mixing a Cheetah method into a class definition: class Foo(dict): def meth1(self): return 'foo' def meth2(self): return 'bar' Foo = Template.compile('#implements meth3\nhello $name from $caller', baseclass=Foo) print Foo(name='world', caller='me') A side-benefit is the possibility to use the same Cheetah source with several baseclass, as the baseclass is orthogonal to the source code, unlike the #extends directive. - added 'namespaces' as an alias for 'searchList' in Template.__init__ - made it possible to pass in a single namespace to 'searchList', which will automatically be converted into a list. - fixed issue with buffering and use of #call when template is used as a webkit servlet - added Cheetah.Utils.htmlEncode and htmlDecode The command line tool (CheetahWrapper.py): - changed insertion order for the --env and --pickle options so they match the commandline UI of the compiled template modules themselves [TR] 2.0b5 (Jan 7, 2006) !!!THIS RELEASE REQUIRES RECOMPILATION OF ALL COMPILED CHEETAH TEMPLATES!!! Core Changes: [TR] - made Cheetah.Template a new-style class by inserting 'object' into its' inheritance tree. Templates can now use super(), properties and all the other goodies that come with new-style classes. - removed the WebInputMixin by placing its one method directly in the Template class. - removed the SettingsManager Mixin. It wasn't being used by anything anymore. - added a framework for caching the results of compilations in Template.compile(). This is on by default and protects against bad performance issues that are due to programmers misguidedly compiling templates inside tight loops. It also saves on memory usage. - misc attr name changes to avoid namespace pollution - more + improved docstrings - replaced the oldstyle dynamic compile hacks with a wrapper around Template.compile(). The old usage pattern Template(src) now benefits from most of the recent changes. Template(src).__class__ == Template.compile(src) - removed all the extra imports required by oldstyle dynamic compile hacks - converted the cheetah #include mechanism to newstyle compilation and made it more flexible - made the #include mechanism work with file objects in addition to file names - made the handling of args to Template.compile() more flexible. You can now provide defaults via class attributes. - made preprocessors for Template.compile() work with file arguments - added support for specifying a __metaclass__ on cheetah template classes - refactored both the class and instance initialization processes - improved the handling of __str__ in _assignRequiredMethodsToClass The command line tool (CheetahWrapper.py): [TR] - improved error output in CheetahWrapper - switched fill command over to new style compile usage Unit tests: [TR] - fixed format string bug in unittest_local_copy.py 2.0b4 (Jan 6, 2006) !!!THIS RELEASE REQUIRES RECOMPILATION OF ALL COMPILED CHEETAH TEMPLATES!!! Core Changes: [TR] - fixed up parsing of target lists in for loops. This was previously limited to fairly simple target lists. #for ($i, $j) in [('aa','bb'),('cc','dd')] $i.upper,$j.upper #end for" #for (i, j) in [('aa','bb'),('cc','dd')] $i.upper,$j.upper #end for" #for i,(j, k) in enumerate([('aa','bb'),('cc','dd')]) $j.upper,$k.upper #end for" - refactored the class initialization process - improved handling of target lists in #set directive. This was previously limited to fairly simple target lists. #set i,j = [1,2] ... #set $i,$j = [1,2] #set (i,j) = [1,2] ... #set ($i,$j) = [1,2] #set i, (j,k) = [1,(2,3)] ... #set $i, ($j,$k) = [1,(2,3)] - made it possible for the expressionFilter hooks to modify the code chunks they are fed. Also documented the hooks in a docstring. Thus the hooks can be used as preprocessors for expressions, 'restricted execution', or even enforcement of style guidelines. - removed cheetah junk from docstrings and placed it all in comments or __moduleVars__. Per JJ's suggestion. - made it possible to nest #cache directives to any level - made it possible to nest #call directives to any level Unit Tests [TR] - extended tests for #for directive - expanded tests for #set directive - expanded tests for #call directive - expanded tests for #cache directive - added basic tests for the new $placeholder string expressions: c'text $placeholder text' 2.0b3 (Jan 5, 2006) !!!THIS RELEASE REQUIRES RECOMPILATION OF ALL COMPILED CHEETAH TEMPLATES!!! Core Changes: [TR] - added #yield statement - added ability to create nested scopes/functions via nested #def statements - added new #call directive and related #arg directive, per Ian Bicking's suggestion. - added new expression syntax c"text $placeholder text" for those basic function calling cases where you just need to pass in a small bit of cheetah output as an argument: c'a string with $placeholders', c'''a string with $placeholders''', c"a string with $placeholders", c"""a string with $placeholders""" - They can't contain #directives, but accept any valid $placeholder syntax except caching placeholders. Caching placeholders don't make any sense in this context. - They can be used *any* place where a python expression is expected. - They can be nested to any depth. $func(c'
  • $var1-$var2
  • ') $func(c'
  • $var1-$var2
  • ', doSomething=True) $func(content=c'
  • $var1-$var2
  • ', doSomething=True) $func(lambda x,y: c'
  • $x-$y
  • ') $func(callback=lambda x,y: c'
  • $x-$y
  • ') $func(lambda x,y: c'
  • $x-$y-$varInSearchList
  • ') $func(c'
  • $var1-$var2-$(var3*10)-$(94.3*58)
  • ') $func(c'
  • $var1-$var2-$func2(c"a nested expr $var99")
  • ') #if $cond then c'
  • $var1-$var2
  • ' else c'

    $var1-$var2

    ' #def foo(arg1=c'$var1$var2'): blah $arg1 blah $foo(c'$var1$var2') - added preprocessor hooks to Template.compile() can be used for partial completion or 'compile-time-caching' ... more details and examples coming. It's very useful, but takes a bit of explaining. - added '#set module varName = expr' for adding module globals. JJ's suggestion - improved generated docstring notes about cached vars - fixed silly bug related to """ in docstring comments and statements like this '#def foo: $str("""foo""")'. Reported by JJ. - changed the handling of single-line defs so that '#def xxx:\n' will be treated as a multi-line #def. The same applies to #block. There's a compiler setting to turn this off if you really need empty single-line #def:'s. JJ reported that this was causing great confusion with beginners. - improved error message for unclosed directives, per Mike Orr's suggestion. - added optional support for passing the trans arg to methods via **KWS rather than trans=None. See the discussion on the mailing list Jan 4th (JJ's post) for details. The purpose is to avoid a positional argument clash that apparently is very confusing for beginners. Note that any existing client code that passing the trans arg in positionally rather than as a keyword will break as a result. WebKit does this with the .respond method so I've kept the old style there. You can also turn this new behaviour off by either manually including the trans arg in your method signature (see the example below) or by using the compiler setting 'useKWsDictArgForPassingTrans'=False. #def manualOverride(arg1, trans=None) foo $arg1 #end def ImportHooks: - made the ImportHook more robust against compilation errors during import [TR] Install scripts: [TR] - added optional support for pje's setuptools - added cheeseshop classifiers - removed out of date install instructions in __init__.py Servlet Base Class For Webkit: [TR] - disabled assignment of self.application (was a webware hack) Unit Tests: [TR] - unit tests for most of the new syntax elements - tidied up some old tests - misc refactoring 2.0b2 (Dec 30, 2005) !!!THIS RELEASE REQUIRES RECOMPILATION OF ALL COMPILED CHEETAH TEMPLATES!!! Core Changes: - In previous versions of Cheetah tracebacks from exceptions that were raised inside dynamically compiled Cheetah templates were opaque because Python didn't have access to a python source file to use in the traceback: File "xxxx.py", line 192, in getTextiledContent content = str(template(searchList=searchList)) File "cheetah_yyyy.py", line 202, in __str__ File "cheetah_yyyy.py", line 187, in respond File "cheetah_yyyy.py", line 139, in writeBody ZeroDivisionError: integer division or modulo by zero It is now possible to keep the generated source code from the python classes returned by Template.compile() in a cache dir. Having these files around allows Python to include the actual source lines in tracebacks and makes them much easier to understand: File "/usr/local/unsnarl/lib/python/us/ui/views/WikiPageRenderer.py", line 192, in getTextiledContent content = str(template(searchList=searchList)) File "/tmp/CheetahCacheDir/cheetah_yyyy.py", line 202, in __str__ def __str__(self): return self.respond() File "/tmp/CheetahCacheDir/cheetah_yyyy.py", line 187, in respond self.writeBody(trans=trans) File "/tmp/CheetahCacheDir/cheetah_yyyy.py", line 139, in writeBody __v = 0/0 # $(0/0) ZeroDivisionError: integer division or modulo by zero This is turned off by default. To turn it on, do this: class NiceTracebackTemplate(Template): _CHEETAH_cacheModuleFilesForTracebacks = True _CHEETAH_cacheDirForModuleFiles = '/tmp/CheetahCacheDir' # change to a dirname templateClass = NiceTracebackTemplate.compile(src) # or templateClass = Template.compile(src, cacheModuleFilesForTracebacks=True, cacheDirForModuleFiles='/tmp/CheetahCacheDir') This only works with the new Template.compile(src) usage style! Note, Cheetah generated modules that are compiled on the command line have never been affected by this issue. [TR] - added an extra comment per $placeholder to generated python code so it is easier to grok. [TR] 2.0b1 (Dec 29, 2005) !!!THIS RELEASE REQUIRES RECOMPILATION OF ALL COMPILED CHEETAH TEMPLATES!!! Core Changes: - enabled use of any expression in ${placeholders}. See the examples I posted to the email list on Dec 12th. All use cases of the #echo directive can now be handled with ${placeholders}. This came from a suggestion by Mike Orr. [TR] - made it possible for templates to #extend (aka subclass) any arbitrary baseclass, including Python's new style classes. You must either compile your classes on the command line or use the new classmethod Template.compile() as described below. The old Template(src) interface still works, provided you don't try to use this new arbitrary baseclass stuff. See my messages to the email list for more details. [TR] - made it possible to create template classes dynamically, rather than just instances. See the new classmethod Template.compile(). See my messages to the email list for more details. [TR] klass = Template.compile(src) - made it easier to work with custom compiler settings, particularly from the command line tool. You can now define a subclass of Template which will compile your templates using custom compilerSettings, or even a custom compiler class, without requiring you to manually pass in your compilerSettings each time or define them in the template src itself via the #compiler directive. You can make the command line tool use your subclass by defining the environment variable CHEETAH_TEMPLATE_CLASS. It should be in the form 'package.module:class'. See my messages to the email list for more details. [TR] - made it possible to pass the searchList in as an argument to #def'ined methods. This makes all lookup that occur within the scope of that method use the provided searchList rather than self._searchList. This does not carry over to other methods called within the top method, unless they explicitly accept the searchList in their signature AND you pass it to them when calling them. This behaviour can be turned off with the corresponding compilerSetting 'allowSearchListAsMethArg' [TR] - added hooks for filtering / restricting dangerous stuff in cheetah source code at compile time. These hooks can be used to enable Cheetah template authoring by untrusted users. See my messages to the email list for more details. Note, it filters expressions at parse/compile time, unlike Python's old rexec module which restricted the Python environment at runtime. [TR] # Here are the relevant compiler settings: # use lower case keys here!! 'disabledDirectives':[], # list of directive keys, without the start token 'enabledDirectives':[], # list of directive keys, without the start token 'disabledDirectiveHooks':[], # callable(parser, directiveKey), # called when a disabled directive is found, prior to raising an exception 'preparseDirectiveHooks':[], # callable(parser, directiveKey) 'postparseDirectiveHooks':[], # callable(parser, directiveKey) 'preparsePlaceholderHooks':[], # callable(parser) 'postparsePlaceholderHooks':[], # callable(parser) 'expressionFilterHooks':[], # callable(parser, expr, exprType, rawExpr=None, startPos=None) # exprType is the name of the directive, 'psp', or 'placeholder'. #all lowercase - added support for a short EOLSlurpToken to supplement the #slurp directive. It's currently re.compile('#\s*\n') (i.e # followed by arbitrary whitespace and a new line), but this is not set in stone. One other suggestion was the backslash char, but I believe Python's own interpretation of backslashes will lead to confusion. The compiler setting 'EOLSlurpToken' controls this. You can turn it off completely by setting 'EOLSlurpToken' to None. See the email list for more details. [TR] - added '_CHEETAH_' prefix to all instance attribute names in compiled templates. This is related to the arbitrary baseclass change. [TR] - shifted instance attribute setup to _initCheetahAttributes() method. This is related to the arbitrary baseclass change. [TR] - made it possible to use full expressions in the #extends directive, rather than just dotted names. This allows you to do things like this: #from xx.TemplateRepository import getTemplateClass #extends getTemplateClass('someName') I don't expect this to be used much. I needed it for a wiki system in which the baseclasses for the templates are dynamically compiled at run time and are not available via simple imports. [TR] - added compiler setting autoImportForExtendDirective=True, so this existing default behaviour can be turned off when needed. [TR] - fixed a bug in the parsing of single-line #def's and #block's when they are enclosed within #if ... #end if. Reported by Marcin Gajda [TR] - tweak to remove needless write('') calls in generated code [TR] The command line tool (CheetahWrapper.py): - added code to cleanup trailing slashes on path arguments (code originally from Mike Orr) [TR] - turned on the ImportHooks by default for the 'cheetah fill' command. See the discussion on the email list [TR] ImportHooks: - fixed a name error bug in the ImportHooks [TR] Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: Intended Audience :: System Administrators Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Topic :: Internet :: WWW/HTTP Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content Classifier: Topic :: Internet :: WWW/HTTP :: Site Management Classifier: Topic :: Software Development :: Code Generators Classifier: Topic :: Software Development :: Libraries :: Python Modules Classifier: Topic :: Software Development :: User Interfaces Classifier: Topic :: Text Processing PK(8\;EGG-INFO/top_level.txtCheetah PK(82EGG-INFO/not-zip-safe PK(8-'+.eeEGG-INFO/scripts/cheetah#!/usr/local/bin/python2.3 from Cheetah.CheetahWrapper import CheetahWrapper CheetahWrapper().main() PK(8n EGG-INFO/scripts/cheetah-compile#!/usr/local/bin/python2.3 import sys from Cheetah.CheetahWrapper import CheetahWrapper sys.argv.insert(1, "compile") CheetahWrapper().main() PKz4שCCheetah/ImportHooks.py#!/usr/bin/env python # $Id: ImportHooks.py,v 1.25 2006/06/20 19:23:27 tavis_rudd Exp $ """Provides some import hooks to allow Cheetah's .tmpl files to be imported directly like Python .py modules. To use these: import Cheetah.ImportHooks Cheetah.ImportHooks.install() Meta-Data ================================================================================ Author: Tavis Rudd License: This software is released for unlimited distribution under the terms of the MIT license. See the LICENSE file. Version: $Revision: 1.25 $ Start Date: 2001/03/30 Last Revision Date: $Date: 2006/06/20 19:23:27 $ """ __author__ = "Tavis Rudd " __revision__ = "$Revision: 1.25 $"[11:-2] import sys import os.path import types import __builtin__ import new import imp from threading import Lock import string import traceback from Cheetah import ImportManager from Cheetah.ImportManager import DirOwner from Cheetah.Compiler import Compiler from Cheetah.convertTmplPathToModuleName import convertTmplPathToModuleName _installed = False ################################################## ## HELPER FUNCS _cacheDir = [] def setCacheDir(cacheDir): global _cacheDir _cacheDir.append(cacheDir) ################################################## ## CLASSES class CheetahDirOwner(DirOwner): _lock = Lock() _acquireLock = _lock.acquire _releaseLock = _lock.release templateFileExtensions = ('.tmpl',) def getmod(self, name): try: self._acquireLock() mod = DirOwner.getmod(self, name) if mod: return mod for ext in self.templateFileExtensions: tmplPath = os.path.join(self.path, name + ext) if os.path.exists(tmplPath): try: return self._compile(name, tmplPath) except: # @@TR: log the error exc_txt = traceback.format_exc() exc_txt =' '+(' \n'.join(exc_txt.splitlines())) raise ImportError( 'Error while compiling Cheetah module' ' %(name)s, original traceback follows:\n%(exc_txt)s'%locals()) ## return None finally: self._releaseLock() def _compile(self, name, tmplPath): ## @@ consider adding an ImportError raiser here code = str(Compiler(file=tmplPath, moduleName=name, mainClassName=name)) if _cacheDir: __file__ = os.path.join(_cacheDir[0], convertTmplPathToModuleName(tmplPath)) + '.py' try: open(__file__, 'w').write(code) except OSError: ## @@ TR: need to add some error code here traceback.print_exc(file=sys.stderr) __file__ = tmplPath else: __file__ = tmplPath co = compile(code+'\n', __file__, 'exec') mod = imp.new_module(name) mod.__file__ = co.co_filename if _cacheDir: mod.__orig_file__ = tmplPath # @@TR: this is used in the WebKit # filemonitoring code mod.__co__ = co return mod ################################################## ## FUNCTIONS def install(templateFileExtensions=('.tmpl',)): """Install the Cheetah Import Hooks""" global _installed if not _installed: CheetahDirOwner.templateFileExtensions = templateFileExtensions import __builtin__ if type(__builtin__.__import__) == types.BuiltinFunctionType: global __oldimport__ __oldimport__ = __builtin__.__import__ ImportManager._globalOwnerTypes.insert(0, CheetahDirOwner) #ImportManager._globalOwnerTypes.append(CheetahDirOwner) global _manager _manager=ImportManager.ImportManager() _manager.setThreaded() _manager.install() def uninstall(): """Uninstall the Cheetah Import Hooks""" global _installed if not _installed: import __builtin__ if type(__builtin__.__import__) == types.MethodType: __builtin__.__import__ = __oldimport__ global _manager del _manager if __name__ == '__main__': install() PKA7g??Cheetah/Template.py#!/usr/bin/env python # $Id: Template.py,v 1.185 2007/10/02 01:36:26 tavis_rudd Exp $ """Provides the core API for Cheetah. See the docstring in the Template class and the Users' Guide for more information Meta-Data ================================================================================ Author: Tavis Rudd License: This software is released for unlimited distribution under the terms of the MIT license. See the LICENSE file. Version: $Revision: 1.185 $ Start Date: 2001/03/30 Last Revision Date: $Date: 2007/10/02 01:36:26 $ """ __author__ = "Tavis Rudd " __revision__ = "$Revision: 1.185 $"[11:-2] ################################################################################ ## DEPENDENCIES import sys # used in the error handling code import re # used to define the internal delims regex import new # used to bind methods and create dummy modules import string import os.path import time # used in the cache refresh code from random import randrange import imp import inspect import StringIO import traceback import pprint import cgi # Used by .webInput() if the template is a CGI script. import types from types import StringType, ClassType try: from types import StringTypes except ImportError: StringTypes = (types.StringType,types.UnicodeType) try: from types import BooleanType boolTypeAvailable = True except ImportError: boolTypeAvailable = False try: from threading import Lock except ImportError: class Lock: def acquire(self): pass def release(self): pass from Cheetah.Version import convertVersionStringToTuple, MinCompatibleVersionTuple from Cheetah.Version import MinCompatibleVersion # Base classes for Template from Cheetah.Servlet import Servlet # More intra-package imports ... from Cheetah.Parser import ParseError, SourceReader from Cheetah.Compiler import Compiler, DEFAULT_COMPILER_SETTINGS from Cheetah import ErrorCatchers # for placeholder tags from Cheetah import Filters # the output filters from Cheetah.convertTmplPathToModuleName import convertTmplPathToModuleName from Cheetah.Utils import VerifyType # Used in Template.__init__ from Cheetah.Utils.Misc import checkKeywords # Used in Template.__init__ from Cheetah.Utils.Indenter import Indenter # Used in Template.__init__ and for # placeholders from Cheetah.NameMapper import NotFound, valueFromSearchList from Cheetah.CacheStore import MemoryCacheStore, MemcachedCacheStore from Cheetah.CacheRegion import CacheRegion from Cheetah.Utils.WebInputMixin import _Converter, _lookup, NonNumericInputError from Cheetah.Unspecified import Unspecified class Error(Exception): pass class PreprocessError(Error): pass def hashList(l): hashedList = [] for v in l: if isinstance(v, dict): v = hashDict(v) elif isinstance(v, list): v = hashList(v) hashedList.append(v) return hash(tuple(hashedList)) def hashDict(d): items = d.items() items.sort() hashedList = [] for k, v in items: if isinstance(v, dict): v = hashDict(v) elif isinstance(v, list): v = hashList(v) hashedList.append((k,v)) return hash(tuple(hashedList)) ################################################################################ ## MODULE GLOBALS AND CONSTANTS def _genUniqueModuleName(baseModuleName): """The calling code is responsible for concurrency locking. """ if baseModuleName not in sys.modules: finalName = baseModuleName else: finalName = ('cheetah_%s_%s_%s'%(baseModuleName, str(time.time()).replace('.','_'), str(randrange(10000, 99999)))) return finalName # Cache of a cgi.FieldStorage() instance, maintained by .webInput(). # This is only relavent to templates used as CGI scripts. _formUsedByWebInput = None # used in Template.compile() def valOrDefault(val, default): if val is not Unspecified: return val else: return default def updateLinecache(filename, src): import linecache size = len(src) mtime = time.time() lines = src.splitlines() fullname = filename linecache.cache[filename] = size, mtime, lines, fullname class CompileCacheItem: pass class TemplatePreprocessor: """This is used with the preprocessors argument to Template.compile(). See the docstring for Template.compile ** Preprocessors are an advanced topic ** """ def __init__(self, settings): self._settings = settings def preprocess(self, source, file): """Create an intermediate template and return the source code it outputs """ settings = self._settings if not source: # @@TR: this needs improving if isinstance(file, (str, unicode)): # it's a filename. f = open(file) source = f.read() f.close() elif hasattr(file, 'read'): source = file.read() file = None templateAPIClass = settings.templateAPIClass possibleKwArgs = [ arg for arg in inspect.getargs(templateAPIClass.compile.im_func.func_code)[0] if arg not in ('klass', 'source', 'file',)] compileKwArgs = {} for arg in possibleKwArgs: if hasattr(settings, arg): compileKwArgs[arg] = getattr(settings, arg) tmplClass = templateAPIClass.compile(source=source, file=file, **compileKwArgs) tmplInstance = tmplClass(**settings.templateInitArgs) outputSource = settings.outputTransformer(tmplInstance) outputFile = None return outputSource, outputFile class Template(Servlet): """This class provides a) methods used by templates at runtime and b) methods for compiling Cheetah source code into template classes. This documentation assumes you already know Python and the basics of object oriented programming. If you don't know Python, see the sections of the Cheetah Users' Guide for non-programmers. It also assumes you have read about Cheetah's syntax in the Users' Guide. The following explains how to use Cheetah from within Python programs or via the interpreter. If you statically compile your templates on the command line using the 'cheetah' script, this is not relevant to you. Statically compiled Cheetah template modules/classes (e.g. myTemplate.py: MyTemplateClasss) are just like any other Python module or class. Also note, most Python web frameworks (Webware, Aquarium, mod_python, Turbogears, CherryPy, Quixote, etc.) provide plugins that handle Cheetah compilation for you. There are several possible usage patterns: 1) tclass = Template.compile(src) t1 = tclass() # or tclass(namespaces=[namespace,...]) t2 = tclass() # or tclass(namespaces=[namespace2,...]) outputStr = str(t1) # or outputStr = t1.aMethodYouDefined() Template.compile provides a rich and very flexible API via its optional arguments so there are many possible variations of this pattern. One example is: tclass = Template.compile('hello $name from $caller', baseclass=dict) print tclass(name='world', caller='me') See the Template.compile() docstring for more details. 2) tmplInstance = Template(src) # or Template(src, namespaces=[namespace,...]) outputStr = str(tmplInstance) # or outputStr = tmplInstance.aMethodYouDefined(...args...) Notes on the usage patterns: usage pattern 1) This is the most flexible, but it is slightly more verbose unless you write a wrapper function to hide the plumbing. Under the hood, all other usage patterns are based on this approach. Templates compiled this way can #extend (subclass) any Python baseclass: old-style or new-style (based on object or a builtin type). usage pattern 2) This was Cheetah's original usage pattern. It returns an instance, but you can still access the generated class via tmplInstance.__class__. If you want to use several different namespace 'searchLists' with a single template source definition, you're better off with Template.compile (1). Limitations (use pattern 1 instead): - Templates compiled this way can only #extend subclasses of the new-style 'object' baseclass. Cheetah.Template is a subclass of 'object'. You also can not #extend dict, list, or other builtin types. - If your template baseclass' __init__ constructor expects args there is currently no way to pass them in. If you need to subclass a dynamically compiled Cheetah class, do something like this: from Cheetah.Template import Template T1 = Template.compile('$meth1 #def meth1: this is meth1 in T1') T2 = Template.compile('#implements meth1\nthis is meth1 redefined in T2', baseclass=T1) print T1, T1() print T2, T2() Note about class and instance attribute names: Attributes used by Cheetah have a special prefix to avoid confusion with the attributes of the templates themselves or those of template baseclasses. Class attributes which are used in class methods look like this: klass._CHEETAH_useCompilationCache (_CHEETAH_xxx) Instance attributes look like this: klass._CHEETAH__globalSetVars (_CHEETAH__xxx with 2 underscores) """ # this is used by ._addCheetahPlumbingCodeToClass() _CHEETAH_requiredCheetahMethods = ( '_initCheetahInstance', 'searchList', 'errorCatcher', 'getVar', 'varExists', 'getFileContents', 'i18n', 'runAsMainProgram', 'respond', 'shutdown', 'webInput', 'serverSidePath', 'generatedClassCode', 'generatedModuleCode', '_getCacheStore', '_getCacheStoreIdPrefix', '_createCacheRegion', 'getCacheRegion', 'getCacheRegions', 'refreshCache', '_handleCheetahInclude', '_getTemplateAPIClassForIncludeDirectiveCompilation', ) _CHEETAH_requiredCheetahClassMethods = ('subclass',) _CHEETAH_requiredCheetahClassAttributes = ('cacheRegionClass','cacheStore', 'cacheStoreIdPrefix','cacheStoreClass') ## the following are used by .compile(). Most are documented in its docstring. _CHEETAH_cacheModuleFilesForTracebacks = False _CHEETAH_cacheDirForModuleFiles = None # change to a dirname _CHEETAH_compileCache = dict() # cache store for compiled code and classes # To do something other than simple in-memory caching you can create an # alternative cache store. It just needs to support the basics of Python's # mapping/dict protocol. E.g.: # class AdvCachingTemplate(Template): # _CHEETAH_compileCache = MemoryOrFileCache() _CHEETAH_compileLock = Lock() # used to prevent race conditions _CHEETAH_defaultMainMethodName = None _CHEETAH_compilerSettings = None _CHEETAH_compilerClass = Compiler _CHEETAH_cacheCompilationResults = True _CHEETAH_useCompilationCache = True _CHEETAH_keepRefToGeneratedCode = True _CHEETAH_defaultBaseclassForTemplates = None _CHEETAH_defaultClassNameForTemplates = None # defaults to DEFAULT_COMPILER_SETTINGS['mainMethodName']: _CHEETAH_defaultMainMethodNameForTemplates = None _CHEETAH_defaultModuleNameForTemplates = 'DynamicallyCompiledCheetahTemplate' _CHEETAH_defaultModuleGlobalsForTemplates = None _CHEETAH_preprocessors = None _CHEETAH_defaultPreprocessorClass = TemplatePreprocessor ## The following attributes are used by instance methods: _CHEETAH_generatedModuleCode = None NonNumericInputError = NonNumericInputError _CHEETAH_cacheRegionClass = CacheRegion _CHEETAH_cacheStoreClass = MemoryCacheStore #_CHEETAH_cacheStoreClass = MemcachedCacheStore _CHEETAH_cacheStore = None _CHEETAH_cacheStoreIdPrefix = None def _getCompilerClass(klass, source=None, file=None): return klass._CHEETAH_compilerClass _getCompilerClass = classmethod(_getCompilerClass) def _getCompilerSettings(klass, source=None, file=None): return klass._CHEETAH_compilerSettings _getCompilerSettings = classmethod(_getCompilerSettings) def compile(klass, source=None, file=None, returnAClass=True, compilerSettings=Unspecified, compilerClass=Unspecified, moduleName=None, className=Unspecified, mainMethodName=Unspecified, baseclass=Unspecified, moduleGlobals=Unspecified, cacheCompilationResults=Unspecified, useCache=Unspecified, preprocessors=Unspecified, cacheModuleFilesForTracebacks=Unspecified, cacheDirForModuleFiles=Unspecified, keepRefToGeneratedCode=Unspecified, ): """ The core API for compiling Cheetah source code into template classes. This class method compiles Cheetah source code and returns a python class. You then create template instances using that class. All Cheetah's other compilation API's use this method under the hood. Internally, this method a) parses the Cheetah source code and generates Python code defining a module with a single class in it, b) dynamically creates a module object with a unique name, c) execs the generated code in that module's namespace then inserts the module into sys.modules, and d) returns a reference to the generated class. If you want to get the generated python source code instead, pass the argument returnAClass=False. It caches generated code and classes. See the descriptions of the arguments'cacheCompilationResults' and 'useCache' for details. This doesn't mean that templates will automatically recompile themselves when the source file changes. Rather, if you call Template.compile(src) or Template.compile(file=path) repeatedly it will attempt to return a cached class definition instead of recompiling. Hooks are provided template source preprocessing. See the notes on the 'preprocessors' arg. If you are an advanced user and need to customize the way Cheetah parses source code or outputs Python code, you should check out the compilerSettings argument. Arguments: You must provide either a 'source' or 'file' arg, but not both: - source (string or None) - file (string path, file-like object, or None) The rest of the arguments are strictly optional. All but the first have defaults in attributes of the Template class which can be overridden in subclasses of this class. Working with most of these is an advanced topic. - returnAClass=True If false, return the generated module code rather than a class. - compilerSettings (a dict) Default: Template._CHEETAH_compilerSettings=None a dictionary of settings to override those defined in DEFAULT_COMPILER_SETTINGS. These can also be overridden in your template source code with the #compiler or #compiler-settings directives. - compilerClass (a class) Default: Template._CHEETAH_compilerClass=Cheetah.Compiler.Compiler a subclass of Cheetah.Compiler.Compiler. Mucking with this is a very advanced topic. - moduleName (a string) Default: Template._CHEETAH_defaultModuleNameForTemplates ='DynamicallyCompiledCheetahTemplate' What to name the generated Python module. If the provided value is None and a file arg was given, the moduleName is created from the file path. In all cases if the moduleName provided is already in sys.modules it is passed through a filter that generates a unique variant of the name. - className (a string) Default: Template._CHEETAH_defaultClassNameForTemplates=None What to name the generated Python class. If the provided value is None, the moduleName is use as the class name. - mainMethodName (a string) Default: Template._CHEETAH_defaultMainMethodNameForTemplates =None (and thus DEFAULT_COMPILER_SETTINGS['mainMethodName']) What to name the main output generating method in the compiled template class. - baseclass (a string or a class) Default: Template._CHEETAH_defaultBaseclassForTemplates=None Specifies the baseclass for the template without manually including an #extends directive in the source. The #extends directive trumps this arg. If the provided value is a string you must make sure that a class reference by that name is available to your template, either by using an #import directive or by providing it in the arg 'moduleGlobals'. If the provided value is a class, Cheetah will handle all the details for you. - moduleGlobals (a dict) Default: Template._CHEETAH_defaultModuleGlobalsForTemplates=None A dict of vars that will be added to the global namespace of the module the generated code is executed in, prior to the execution of that code. This should be Python values, not code strings! - cacheCompilationResults (True/False) Default: Template._CHEETAH_cacheCompilationResults=True Tells Cheetah to cache the generated code and classes so that they can be reused if Template.compile() is called multiple times with the same source and options. - useCache (True/False) Default: Template._CHEETAH_useCompilationCache=True Should the compilation cache be used? If True and a previous compilation created a cached template class with the same source code, compiler settings and other options, the cached template class will be returned. - cacheModuleFilesForTracebacks (True/False) Default: Template._CHEETAH_cacheModuleFilesForTracebacks=False In earlier versions of Cheetah tracebacks from exceptions that were raised inside dynamically compiled Cheetah templates were opaque because Python didn't have access to a python source file to use in the traceback: File "xxxx.py", line 192, in getTextiledContent content = str(template(searchList=searchList)) File "cheetah_yyyy.py", line 202, in __str__ File "cheetah_yyyy.py", line 187, in respond File "cheetah_yyyy.py", line 139, in writeBody ZeroDivisionError: integer division or modulo by zero It is now possible to keep those files in a cache dir and allow Python to include the actual source lines in tracebacks and makes them much easier to understand: File "xxxx.py", line 192, in getTextiledContent content = str(template(searchList=searchList)) File "/tmp/CheetahCacheDir/cheetah_yyyy.py", line 202, in __str__ def __str__(self): return self.respond() File "/tmp/CheetahCacheDir/cheetah_yyyy.py", line 187, in respond self.writeBody(trans=trans) File "/tmp/CheetahCacheDir/cheetah_yyyy.py", line 139, in writeBody __v = 0/0 # $(0/0) ZeroDivisionError: integer division or modulo by zero - cacheDirForModuleFiles (a string representing a dir path) Default: Template._CHEETAH_cacheDirForModuleFiles=None See notes on cacheModuleFilesForTracebacks. - preprocessors Default: Template._CHEETAH_preprocessors=None ** THIS IS A VERY ADVANCED TOPIC ** These are used to transform the source code prior to compilation. They provide a way to use Cheetah as a code generator for Cheetah code. In other words, you use one Cheetah template to output the source code for another Cheetah template. The major expected use cases are: a) 'compile-time caching' aka 'partial template binding', wherein an intermediate Cheetah template is used to output the source for the final Cheetah template. The intermediate template is a mix of a modified Cheetah syntax (the 'preprocess syntax') and standard Cheetah syntax. The preprocessor syntax is executed at compile time and outputs Cheetah code which is then compiled in turn. This approach allows one to completely soft-code all the elements in the template which are subject to change yet have it compile to extremely efficient Python code with everything but the elements that must be variable at runtime (per browser request, etc.) compiled as static strings. Examples of this usage pattern will be added to the Cheetah Users' Guide. The'preprocess syntax' is just Cheetah's standard one with alternatives for the $ and # tokens: e.g. '@' and '%' for code like this @aPreprocessVar $aRuntimeVar %if aCompileTimeCondition then yyy else zzz %% preprocessor comment #if aRunTimeCondition then aaa else bbb ## normal comment $aRuntimeVar b) adding #import and #extends directives dynamically based on the source If preprocessors are provided, Cheetah pipes the source code through each one in the order provided. Each preprocessor should accept the args (source, file) and should return a tuple (source, file). The argument value should be a list, but a single non-list value is acceptable and will automatically be converted into a list. Each item in the list will be passed through Template._normalizePreprocessor(). The items should either match one of the following forms: - an object with a .preprocess(source, file) method - a callable with the following signature: source, file = f(source, file) or one of the forms below: - a single string denoting the 2 'tokens' for the preprocess syntax. The tokens should be in the order (placeholderToken, directiveToken) and should separated with a space: e.g. '@ %' klass = Template.compile(src, preprocessors='@ %') # or klass = Template.compile(src, preprocessors=['@ %']) - a dict with the following keys or an object with the following attributes (all are optional, but nothing will happen if you don't provide at least one): - tokens: same as the single string described above. You can also provide a tuple of 2 strings. - searchList: the searchList used for preprocess $placeholders - compilerSettings: used in the compilation of the intermediate template - templateAPIClass: an optional subclass of `Template` - outputTransformer: a simple hook for passing in a callable which can do further transformations of the preprocessor output, or do something else like debug logging. The default is str(). + any keyword arguments to Template.compile which you want to provide for the compilation of the intermediate template. klass = Template.compile(src, preprocessors=[ dict(tokens='@ %', searchList=[...]) ] ) """ ################################################## ## normalize and validate args try: vt = VerifyType.VerifyType vtc = VerifyType.VerifyTypeClass N = types.NoneType; S = types.StringType; U = types.UnicodeType D = types.DictType; F = types.FileType C = types.ClassType; M = types.ModuleType I = types.IntType if boolTypeAvailable: B = types.BooleanType vt(source, 'source', [N,S,U], 'string or None') vt(file, 'file',[N,S,U,F], 'string, file-like object, or None') baseclass = valOrDefault(baseclass, klass._CHEETAH_defaultBaseclassForTemplates) if isinstance(baseclass, Template): baseclass = baseclass.__class__ vt(baseclass, 'baseclass', [N,S,C,type], 'string, class or None') cacheCompilationResults = valOrDefault( cacheCompilationResults, klass._CHEETAH_cacheCompilationResults) if boolTypeAvailable: vt(cacheCompilationResults, 'cacheCompilationResults', [I,B], 'boolean') useCache = valOrDefault(useCache, klass._CHEETAH_useCompilationCache) if boolTypeAvailable: vt(cacheCompilationResults, 'cacheCompilationResults', [I,B], 'boolean') compilerSettings = valOrDefault( compilerSettings, klass._getCompilerSettings(source, file) or {}) vt(compilerSettings, 'compilerSettings', [D], 'dictionary') compilerClass = valOrDefault(compilerClass, klass._getCompilerClass(source, file)) preprocessors = valOrDefault(preprocessors, klass._CHEETAH_preprocessors) keepRefToGeneratedCode = valOrDefault( keepRefToGeneratedCode, klass._CHEETAH_keepRefToGeneratedCode) if boolTypeAvailable: vt(cacheCompilationResults, 'cacheCompilationResults', [I,B], 'boolean') vt(moduleName, 'moduleName', [N,S], 'string or None') __orig_file__ = None if not moduleName: if file and type(file) in StringTypes: moduleName = convertTmplPathToModuleName(file) __orig_file__ = file else: moduleName = klass._CHEETAH_defaultModuleNameForTemplates className = valOrDefault( className, klass._CHEETAH_defaultClassNameForTemplates) vt(className, 'className', [N,S], 'string or None') className = className or moduleName mainMethodName = valOrDefault( mainMethodName, klass._CHEETAH_defaultMainMethodNameForTemplates) vt(mainMethodName, 'mainMethodName', [N,S], 'string or None') moduleGlobals = valOrDefault( moduleGlobals, klass._CHEETAH_defaultModuleGlobalsForTemplates) cacheModuleFilesForTracebacks = valOrDefault( cacheModuleFilesForTracebacks, klass._CHEETAH_cacheModuleFilesForTracebacks) if boolTypeAvailable: vt(cacheModuleFilesForTracebacks, 'cacheModuleFilesForTracebacks', [I,B], 'boolean') cacheDirForModuleFiles = valOrDefault( cacheDirForModuleFiles, klass._CHEETAH_cacheDirForModuleFiles) vt(cacheDirForModuleFiles, 'cacheDirForModuleFiles', [N,S], 'string or None') except TypeError, reason: raise TypeError(reason) ################################################## ## handle any preprocessors if preprocessors: origSrc = source source, file = klass._preprocessSource(source, file, preprocessors) ################################################## ## compilation, using cache if requested/possible baseclassValue = None baseclassName = None if baseclass: if type(baseclass) in StringTypes: baseclassName = baseclass elif type(baseclass) in (ClassType, type): # @@TR: should soft-code this baseclassName = 'CHEETAH_dynamicallyAssignedBaseClass_'+baseclass.__name__ baseclassValue = baseclass cacheHash = None cacheItem = None if source or isinstance(file, (str, unicode)): compilerSettingsHash = None if compilerSettings: compilerSettingsHash = hashDict(compilerSettings) moduleGlobalsHash = None if moduleGlobals: moduleGlobalsHash = hashDict(moduleGlobals) fileHash = None if file: fileHash = str(hash(file))+str(os.path.getmtime(file)) try: # @@TR: find some way to create a cacheHash that is consistent # between process restarts. It would allow for caching the # compiled module on disk and thereby reduce the startup time # for applications that use a lot of dynamically compiled # templates. cacheHash = ''.join([str(v) for v in [hash(source), fileHash, className, moduleName, mainMethodName, hash(compilerClass), hash(baseclass), compilerSettingsHash, moduleGlobalsHash, hash(cacheDirForModuleFiles), ]]) except: #@@TR: should add some logging to this pass if useCache and cacheHash and cacheHash in klass._CHEETAH_compileCache: cacheItem = klass._CHEETAH_compileCache[cacheHash] generatedModuleCode = cacheItem.code else: compiler = compilerClass(source, file, moduleName=moduleName, mainClassName=className, baseclassName=baseclassName, mainMethodName=mainMethodName, settings=(compilerSettings or {})) compiler.compile() generatedModuleCode = compiler.getModuleCode() if not returnAClass: return generatedModuleCode else: if cacheItem: cacheItem.lastCheckoutTime = time.time() return cacheItem.klass try: klass._CHEETAH_compileLock.acquire() uniqueModuleName = _genUniqueModuleName(moduleName) __file__ = uniqueModuleName+'.py' # relative file path with no dir part if cacheModuleFilesForTracebacks: if not os.path.exists(cacheDirForModuleFiles): raise Exception('%s does not exist'%cacheDirForModuleFiles) __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) mod = new.module(uniqueModuleName) if moduleGlobals: for k, v in moduleGlobals.items(): setattr(mod, k, v) mod.__file__ = __file__ if __orig_file__ and os.path.exists(__orig_file__): # this is used in the WebKit filemonitoring code mod.__orig_file__ = __orig_file__ if baseclass and baseclassValue: setattr(mod, baseclassName, baseclassValue) ## try: co = compile(generatedModuleCode, __file__, 'exec') exec co in mod.__dict__ except SyntaxError, e: try: parseError = genParserErrorFromPythonException( source, file, generatedModuleCode, exception=e) except: traceback.print_exc() updateLinecache(__file__, generatedModuleCode) e.generatedModuleCode = generatedModuleCode raise e else: raise parseError except Exception, e: updateLinecache(__file__, generatedModuleCode) e.generatedModuleCode = generatedModuleCode raise ## sys.modules[uniqueModuleName] = mod finally: klass._CHEETAH_compileLock.release() templateClass = getattr(mod, className) if (cacheCompilationResults and cacheHash and cacheHash not in klass._CHEETAH_compileCache): cacheItem = CompileCacheItem() cacheItem.cacheTime = cacheItem.lastCheckoutTime = time.time() cacheItem.code = generatedModuleCode cacheItem.klass = templateClass templateClass._CHEETAH_isInCompilationCache = True klass._CHEETAH_compileCache[cacheHash] = cacheItem else: templateClass._CHEETAH_isInCompilationCache = False if keepRefToGeneratedCode or cacheCompilationResults: templateClass._CHEETAH_generatedModuleCode = generatedModuleCode return templateClass compile = classmethod(compile) def subclass(klass, *args, **kws): """Takes the same args as the .compile() classmethod and returns a template that is a subclass of the template this method is called from. T1 = Template.compile(' foo - $meth1 - bar\n#def meth1: this is T1.meth1') T2 = T1.subclass('#implements meth1\n this is T2.meth1') """ kws['baseclass'] = klass if isinstance(klass, Template): templateAPIClass = klass else: templateAPIClass = Template return templateAPIClass.compile(*args, **kws) subclass = classmethod(subclass) def _preprocessSource(klass, source, file, preprocessors): """Iterates through the .compile() classmethod's preprocessors argument and pipes the source code through each each preprocessor. It returns the tuple (source, file) which is then used by Template.compile to finish the compilation. """ if not isinstance(preprocessors, (list, tuple)): preprocessors = [preprocessors] for preprocessor in preprocessors: preprocessor = klass._normalizePreprocessorArg(preprocessor) source, file = preprocessor.preprocess(source, file) return source, file _preprocessSource = classmethod(_preprocessSource) def _normalizePreprocessorArg(klass, arg): """Used to convert the items in the .compile() classmethod's preprocessors argument into real source preprocessors. This permits the use of several shortcut forms for defining preprocessors. """ if hasattr(arg, 'preprocess'): return arg elif callable(arg): class WrapperPreprocessor: def preprocess(self, source, file): return arg(source, file) return WrapperPreprocessor() else: class Settings(object): placeholderToken = None directiveToken = None settings = Settings() if isinstance(arg, str) or isinstance(arg, (list, tuple)): settings.tokens = arg elif isinstance(arg, dict): for k, v in arg.items(): setattr(settings, k, v) else: settings = arg settings = klass._normalizePreprocessorSettings(settings) return klass._CHEETAH_defaultPreprocessorClass(settings) _normalizePreprocessorArg = classmethod(_normalizePreprocessorArg) def _normalizePreprocessorSettings(klass, settings): settings.keepRefToGeneratedCode = True def normalizeSearchList(searchList): if not isinstance(searchList, (list, tuple)): searchList = [searchList] return searchList def normalizeTokens(tokens): if isinstance(tokens, str): return tokens.split() # space delimited string e.g.'@ %' elif isinstance(tokens, (list, tuple)): return tokens else: raise PreprocessError('invalid tokens argument: %r'%tokens) if hasattr(settings, 'tokens'): (settings.placeholderToken, settings.directiveToken) = normalizeTokens(settings.tokens) if (not getattr(settings,'compilerSettings', None) and not getattr(settings, 'placeholderToken', None) ): raise TypeError( 'Preprocessor requires either a "tokens" or a "compilerSettings" arg.' ' Neither was provided.') if not hasattr(settings, 'templateInitArgs'): settings.templateInitArgs = {} if 'searchList' not in settings.templateInitArgs: if not hasattr(settings, 'searchList') and hasattr(settings, 'namespaces'): settings.searchList = settings.namespaces elif not hasattr(settings, 'searchList'): settings.searchList = [] settings.templateInitArgs['searchList'] = settings.searchList settings.templateInitArgs['searchList'] = ( normalizeSearchList(settings.templateInitArgs['searchList'])) if not hasattr(settings, 'outputTransformer'): settings.outputTransformer = unicode if not hasattr(settings, 'templateAPIClass'): class PreprocessTemplateAPIClass(klass): pass settings.templateAPIClass = PreprocessTemplateAPIClass if not hasattr(settings, 'compilerSettings'): settings.compilerSettings = {} klass._updateSettingsWithPreprocessTokens( compilerSettings=settings.compilerSettings, placeholderToken=settings.placeholderToken, directiveToken=settings.directiveToken ) return settings _normalizePreprocessorSettings = classmethod(_normalizePreprocessorSettings) def _updateSettingsWithPreprocessTokens( klass, compilerSettings, placeholderToken, directiveToken): if (placeholderToken and 'cheetahVarStartToken' not in compilerSettings): compilerSettings['cheetahVarStartToken'] = placeholderToken if directiveToken: if 'directiveStartToken' not in compilerSettings: compilerSettings['directiveStartToken'] = directiveToken if 'directiveEndToken' not in compilerSettings: compilerSettings['directiveEndToken'] = directiveToken if 'commentStartToken' not in compilerSettings: compilerSettings['commentStartToken'] = directiveToken*2 if 'multiLineCommentStartToken' not in compilerSettings: compilerSettings['multiLineCommentStartToken'] = ( directiveToken+'*') if 'multiLineCommentEndToken' not in compilerSettings: compilerSettings['multiLineCommentEndToken'] = ( '*'+directiveToken) if 'EOLSlurpToken' not in compilerSettings: compilerSettings['EOLSlurpToken'] = directiveToken _updateSettingsWithPreprocessTokens = classmethod(_updateSettingsWithPreprocessTokens) def _addCheetahPlumbingCodeToClass(klass, concreteTemplateClass): """If concreteTemplateClass is not a subclass of Cheetah.Template, add the required cheetah methods and attributes to it. This is called on each new template class after it has been compiled. If concreteTemplateClass is not a subclass of Cheetah.Template but already has method with the same name as one of the required cheetah methods, this will skip that method. """ for methodname in klass._CHEETAH_requiredCheetahMethods: if not hasattr(concreteTemplateClass, methodname): method = getattr(Template, methodname) newMethod = new.instancemethod(method.im_func, None, concreteTemplateClass) #print methodname, method setattr(concreteTemplateClass, methodname, newMethod) for classMethName in klass._CHEETAH_requiredCheetahClassMethods: if not hasattr(concreteTemplateClass, classMethName): meth = getattr(klass, classMethName) setattr(concreteTemplateClass, classMethName, classmethod(meth.im_func)) for attrname in klass._CHEETAH_requiredCheetahClassAttributes: attrname = '_CHEETAH_'+attrname if not hasattr(concreteTemplateClass, attrname): attrVal = getattr(klass, attrname) setattr(concreteTemplateClass, attrname, attrVal) if (not hasattr(concreteTemplateClass, '__str__') or concreteTemplateClass.__str__ is object.__str__): mainMethNameAttr = '_mainCheetahMethod_for_'+concreteTemplateClass.__name__ mainMethName = getattr(concreteTemplateClass,mainMethNameAttr, None) if mainMethName: def __str__(self): return getattr(self, mainMethName)() elif (hasattr(concreteTemplateClass, 'respond') and concreteTemplateClass.respond!=Servlet.respond): def __str__(self): return self.respond() else: def __str__(self): if hasattr(self, mainMethNameAttr): return getattr(self,mainMethNameAttr)() elif hasattr(self, 'respond'): return self.respond() else: return super(self.__class__, self).__str__() __str__ = new.instancemethod(__str__, None, concreteTemplateClass) setattr(concreteTemplateClass, '__str__', __str__) _addCheetahPlumbingCodeToClass = classmethod(_addCheetahPlumbingCodeToClass) ## end classmethods ## def __init__(self, source=None, namespaces=None, searchList=None, # use either or. They are aliases for the same thing. file=None, filter='RawOrEncodedUnicode', # which filter from Cheetah.Filters filtersLib=Filters, errorCatcher=None, compilerSettings=Unspecified, # control the behaviour of the compiler _globalSetVars=None, # used internally for #include'd templates _preBuiltSearchList=None # used internally for #include'd templates ): """a) compiles a new template OR b) instantiates an existing template. Read this docstring carefully as there are two distinct usage patterns. You should also read this class' main docstring. a) to compile a new template: t = Template(source=aSourceString) # or t = Template(file='some/path') # or t = Template(file=someFileObject) # or namespaces = [{'foo':'bar'}] t = Template(source=aSourceString, namespaces=namespaces) # or t = Template(file='some/path', namespaces=namespaces) print t b) to create an instance of an existing, precompiled template class: ## i) first you need a reference to a compiled template class: tclass = Template.compile(source=src) # or just Template.compile(src) # or tclass = Template.compile(file='some/path') # or tclass = Template.compile(file=someFileObject) # or # if you used the command line compiler or have Cheetah's ImportHooks # installed your template class is also available via Python's # standard import mechanism: from ACompileTemplate import AcompiledTemplate as tclass ## ii) then you create an instance t = tclass(namespaces=namespaces) # or t = tclass(namespaces=namespaces, filter='RawOrEncodedUnicode') print t Arguments: for usage pattern a) If you are compiling a new template, you must provide either a 'source' or 'file' arg, but not both: - source (string or None) - file (string path, file-like object, or None) Optional args (see below for more) : - compilerSettings Default: Template._CHEETAH_compilerSettings=None a dictionary of settings to override those defined in DEFAULT_COMPILER_SETTINGS. See Cheetah.Template.DEFAULT_COMPILER_SETTINGS and the Users' Guide for details. You can pass the source arg in as a positional arg with this usage pattern. Use keywords for all other args. for usage pattern b) Do not use positional args with this usage pattern, unless your template subclasses something other than Cheetah.Template and you want to pass positional args to that baseclass. E.g.: dictTemplate = Template.compile('hello $name from $caller', baseclass=dict) tmplvars = dict(name='world', caller='me') print dictTemplate(tmplvars) This usage requires all Cheetah args to be passed in as keyword args. optional args for both usage patterns: - namespaces (aka 'searchList') Default: None an optional list of namespaces (dictionaries, objects, modules, etc.) which Cheetah will search through to find the variables referenced in $placeholders. If you provide a single namespace instead of a list, Cheetah will automatically convert it into a list. NOTE: Cheetah does NOT force you to use the namespaces search list and related features. It's on by default, but you can turn if off using the compiler settings useSearchList=False or useNameMapper=False. - filter Default: 'EncodeUnicode' Which filter should be used for output filtering. This should either be a string which is the name of a filter in the 'filtersLib' or a subclass of Cheetah.Filters.Filter. . See the Users' Guide for more details. - filtersLib Default: Cheetah.Filters A module containing subclasses of Cheetah.Filters.Filter. See the Users' Guide for more details. - errorCatcher Default: None This is a debugging tool. See the Users' Guide for more details. Do not use this or the #errorCatcher diretive with live production systems. Do NOT mess with the args _globalSetVars or _preBuiltSearchList! """ ################################################## ## Verify argument keywords and types S = types.StringType; U = types.UnicodeType L = types.ListType; T = types.TupleType D = types.DictType; F = types.FileType C = types.ClassType; M = types.ModuleType N = types.NoneType vt = VerifyType.VerifyType vtc = VerifyType.VerifyTypeClass try: vt(source, 'source', [N,S,U], 'string or None') vt(file, 'file', [N,S,U,F], 'string, file open for reading, or None') vtc(filter, 'filter', [S,C,type], 'string or class', Filters.Filter, '(if class, must be subclass of Cheetah.Filters.Filter)') vt(filtersLib, 'filtersLib', [S,M], 'string or module', '(if module, must contain subclasses of Cheetah.Filters.Filter)') vtc(errorCatcher, 'errorCatcher', [N,S,C,type], 'string, class or None', ErrorCatchers.ErrorCatcher, '(if class, must be subclass of Cheetah.ErrorCatchers.ErrorCatcher)') if compilerSettings is not Unspecified: vt(compilerSettings, 'compilerSettings', [D], 'dictionary') except TypeError, reason: # Re-raise the exception here so that the traceback will end in # this function rather than in some utility function. raise TypeError(reason) if source is not None and file is not None: raise TypeError("you must supply either a source string or the" + " 'file' keyword argument, but not both") ################################################## ## Do superclass initialization. Servlet.__init__(self) ################################################## ## Do required version check if not hasattr(self, '_CHEETAH_versionTuple'): try: mod = sys.modules[self.__class__.__module__] compiledVersion = mod.__CHEETAH_version__ compiledVersionTuple = convertVersionStringToTuple(compiledVersion) if compiledVersionTuple < MinCompatibleVersionTuple: raise AssertionError( 'This template was compiled with Cheetah version' ' %s. Templates compiled before version %s must be recompiled.'%( compiledVersion, MinCompatibleVersion)) except AssertionError: raise except: pass ################################################## ## Setup instance state attributes used during the life of template ## post-compile self._initCheetahInstance( searchList=searchList, namespaces=namespaces, filter=filter, filtersLib=filtersLib, errorCatcher=errorCatcher, _globalSetVars=_globalSetVars, _preBuiltSearchList=_preBuiltSearchList) ################################################## ## Now, compile if we're meant to if (source is not None) or (file is not None): self._compile(source, file, compilerSettings=compilerSettings) def generatedModuleCode(self): """Return the module code the compiler generated, or None if no compilation took place. """ return self._CHEETAH_generatedModuleCode def generatedClassCode(self): """Return the class code the compiler generated, or None if no compilation took place. """ return self._CHEETAH_generatedModuleCode[ self._CHEETAH_generatedModuleCode.find('\nclass '): self._CHEETAH_generatedModuleCode.find('\n## END CLASS DEFINITION')] def searchList(self): """Return a reference to the searchlist """ return self._CHEETAH__searchList def errorCatcher(self): """Return a reference to the current errorCatcher """ return self._CHEETAH__errorCatcher ## cache methods ## def _getCacheStore(self): if not self._CHEETAH__cacheStore: if self._CHEETAH_cacheStore is not None: self._CHEETAH__cacheStore = self._CHEETAH_cacheStore else: # @@TR: might want to provide a way to provide init args self._CHEETAH__cacheStore = self._CHEETAH_cacheStoreClass() return self._CHEETAH__cacheStore def _getCacheStoreIdPrefix(self): if self._CHEETAH_cacheStoreIdPrefix is not None: return self._CHEETAH_cacheStoreIdPrefix else: return str(id(self)) def _createCacheRegion(self, regionID): return self._CHEETAH_cacheRegionClass( regionID=regionID, templateCacheIdPrefix=self._getCacheStoreIdPrefix(), cacheStore=self._getCacheStore()) def getCacheRegion(self, regionID, cacheInfo=None, create=True): cacheRegion = self._CHEETAH__cacheRegions.get(regionID) if not cacheRegion and create: cacheRegion = self._createCacheRegion(regionID) self._CHEETAH__cacheRegions[regionID] = cacheRegion return cacheRegion def getCacheRegions(self): """Returns a dictionary of the 'cache regions' initialized in a template. Each #cache directive block or $*cachedPlaceholder is a separate 'cache region'. """ # returns a copy to prevent users mucking it up return self._CHEETAH__cacheRegions.copy() def refreshCache(self, cacheRegionId=None, cacheItemId=None): """Refresh a cache region or a specific cache item within a region. """ if not cacheRegionId: for key, cregion in self.getCacheRegions(): cregion.clear() else: cregion = self._CHEETAH__cacheRegions.get(cacheRegionId) if not cregion: return if not cacheItemId: # clear the desired region and all its cacheItems cregion.clear() else: # clear one specific cache of a specific region cache = cregion.getCacheItem(cacheItemId) if cache: cache.clear() ## end cache methods ## def shutdown(self): """Break reference cycles before discarding a servlet. """ try: Servlet.shutdown(self) except: pass self._CHEETAH__searchList = None self.__dict__ = {} ## utility functions ## def getVar(self, varName, default=Unspecified, autoCall=True): """Get a variable from the searchList. If the variable can't be found in the searchList, it returns the default value if one was given, or raises NameMapper.NotFound. """ try: return valueFromSearchList(self.searchList(), varName.replace('$',''), autoCall) except NotFound: if default is not Unspecified: return default else: raise def varExists(self, varName, autoCall=True): """Test if a variable name exists in the searchList. """ try: valueFromSearchList(self.searchList(), varName.replace('$',''), autoCall) return True except NotFound: return False hasVar = varExists def i18n(self, message, plural=None, n=None, id=None, domain=None, source=None, target=None, comment=None ): """This is just a stub at this time. plural = the plural form of the message n = a sized argument to distinguish between single and plural forms id = msgid in the translation catalog domain = translation domain source = source lang target = a specific target lang comment = a comment to the translation team See the following for some ideas http://www.zope.org/DevHome/Wikis/DevSite/Projects/ComponentArchitecture/ZPTInternationalizationSupport Other notes: - There is no need to replicate the i18n:name attribute from plone / PTL, as cheetah placeholders serve the same purpose """ return message def getFileContents(self, path): """A hook for getting the contents of a file. The default implementation just uses the Python open() function to load local files. This method could be reimplemented to allow reading of remote files via various protocols, as PHP allows with its 'URL fopen wrapper' """ fp = open(path,'r') output = fp.read() fp.close() return output def runAsMainProgram(self): """Allows the Template to function as a standalone command-line program for static page generation. Type 'python yourtemplate.py --help to see what it's capabable of. """ from TemplateCmdLineIface import CmdLineIface CmdLineIface(templateObj=self).run() ################################################## ## internal methods -- not to be called by end-users def _initCheetahInstance(self, searchList=None, namespaces=None, filter='RawOrEncodedUnicode', # which filter from Cheetah.Filters filtersLib=Filters, errorCatcher=None, _globalSetVars=None, _preBuiltSearchList=None): """Sets up the instance attributes that cheetah templates use at run-time. This is automatically called by the __init__ method of compiled templates. Note that the names of instance attributes used by Cheetah are prefixed with '_CHEETAH__' (2 underscores), where class attributes are prefixed with '_CHEETAH_' (1 underscore). """ if getattr(self, '_CHEETAH__instanceInitialized', False): return if namespaces is not None: assert searchList is None, ( 'Provide "namespaces" or "searchList", not both!') searchList = namespaces if searchList is not None and not isinstance(searchList, (list, tuple)): searchList = [searchList] self._CHEETAH__globalSetVars = {} if _globalSetVars is not None: # this is intended to be used internally by Nested Templates in #include's self._CHEETAH__globalSetVars = _globalSetVars if _preBuiltSearchList is not None: # happens with nested Template obj creation from #include's self._CHEETAH__searchList = list(_preBuiltSearchList) self._CHEETAH__searchList.append(self) else: # create our own searchList self._CHEETAH__searchList = [self._CHEETAH__globalSetVars] 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() self._CHEETAH__filtersLib = filtersLib self._CHEETAH__filters = {} if type(filter) in StringTypes: filterName = filter klass = getattr(self._CHEETAH__filtersLib, filterName) else: klass = filter filterName = klass.__name__ self._CHEETAH__currentFilter = self._CHEETAH__filters[filterName] = klass(self).filter self._CHEETAH__initialFilter = self._CHEETAH__currentFilter self._CHEETAH__errorCatchers = {} if errorCatcher: if type(errorCatcher) in StringTypes: errorCatcherClass = getattr(ErrorCatchers, errorCatcher) elif type(errorCatcher) == ClassType: errorCatcherClass = errorCatcher self._CHEETAH__errorCatcher = ec = errorCatcherClass(self) self._CHEETAH__errorCatchers[errorCatcher.__class__.__name__] = ec else: self._CHEETAH__errorCatcher = None self._CHEETAH__initErrorCatcher = self._CHEETAH__errorCatcher if not hasattr(self, 'transaction'): self.transaction = None self._CHEETAH__instanceInitialized = True self._CHEETAH__isBuffering = False self._CHEETAH__isControlledByWebKit = False self._CHEETAH__cacheStore = None if self._CHEETAH_cacheStore is not None: self._CHEETAH__cacheStore = self._CHEETAH_cacheStore def _compile(self, source=None, file=None, compilerSettings=Unspecified, moduleName=None, mainMethodName=None): """Compile the template. This method is automatically called by Template.__init__ it is provided with 'file' or 'source' args. USERS SHOULD *NEVER* CALL THIS METHOD THEMSELVES. Use Template.compile instead. """ if compilerSettings is Unspecified: compilerSettings = self._getCompilerSettings(source, file) or {} mainMethodName = mainMethodName or self._CHEETAH_defaultMainMethodName self._fileMtime = None self._fileDirName = None self._fileBaseName = None if file and type(file) in StringTypes: file = self.serverSidePath(file) self._fileMtime = os.path.getmtime(file) self._fileDirName, self._fileBaseName = os.path.split(file) self._filePath = file templateClass = self.compile(source, file, moduleName=moduleName, mainMethodName=mainMethodName, compilerSettings=compilerSettings, keepRefToGeneratedCode=True) self.__class__ = templateClass # must initialize it so instance attributes are accessible templateClass.__init__(self, #_globalSetVars=self._CHEETAH__globalSetVars, #_preBuiltSearchList=self._CHEETAH__searchList ) if not hasattr(self, 'transaction'): self.transaction = None def _handleCheetahInclude(self, srcArg, trans=None, includeFrom='file', raw=False): """Called at runtime to handle #include directives. """ _includeID = srcArg if not self._CHEETAH__cheetahIncludes.has_key(_includeID): if not raw: if includeFrom == 'file': source = None if type(srcArg) in StringTypes: if hasattr(self, 'serverSidePath'): file = path = self.serverSidePath(srcArg) else: file = path = os.path.normpath(srcArg) else: file = srcArg ## a file-like object else: source = srcArg file = None # @@TR: might want to provide some syntax for specifying the # Template class to be used for compilation so compilerSettings # can be changed. compiler = self._getTemplateAPIClassForIncludeDirectiveCompilation(source, file) nestedTemplateClass = compiler.compile(source=source,file=file) nestedTemplate = nestedTemplateClass(_preBuiltSearchList=self.searchList(), _globalSetVars=self._CHEETAH__globalSetVars) # Set the inner template filters to the initial filter of the # outer template: # this is the only really safe way to use # filter='WebSafe'. nestedTemplate._CHEETAH__initialFilter = self._CHEETAH__initialFilter nestedTemplate._CHEETAH__currentFilter = self._CHEETAH__initialFilter self._CHEETAH__cheetahIncludes[_includeID] = nestedTemplate else: if includeFrom == 'file': path = self.serverSidePath(srcArg) self._CHEETAH__cheetahIncludes[_includeID] = self.getFileContents(path) else: self._CHEETAH__cheetahIncludes[_includeID] = srcArg ## if not raw: self._CHEETAH__cheetahIncludes[_includeID].respond(trans) else: trans.response().write(self._CHEETAH__cheetahIncludes[_includeID]) def _getTemplateAPIClassForIncludeDirectiveCompilation(self, source, file): """Returns the subclass of Template which should be used to compile #include directives. This abstraction allows different compiler settings to be used in the included template than were used in the parent. """ if issubclass(self.__class__, Template): return self.__class__ else: return Template ## functions for using templates as CGI scripts def webInput(self, names, namesMulti=(), default='', src='f', defaultInt=0, defaultFloat=0.00, badInt=0, badFloat=0.00, debug=False): """Method for importing web transaction variables in bulk. This works for GET/POST fields both in Webware servlets and in CGI scripts, and for cookies and session variables in Webware servlets. If you try to read a cookie or session variable in a CGI script, you'll get a RuntimeError. 'In a CGI script' here means 'not running as a Webware servlet'. If the CGI environment is not properly set up, Cheetah will act like there's no input. The public method provided is: def webInput(self, names, namesMulti=(), default='', src='f', defaultInt=0, defaultFloat=0.00, badInt=0, badFloat=0.00, debug=False): This method places the specified GET/POST fields, cookies or session variables into a dictionary, which is both returned and put at the beginning of the searchList. It handles: * single vs multiple values * conversion to integer or float for specified names * default values/exceptions for missing or bad values * printing a snapshot of all values retrieved for debugging All the 'default*' and 'bad*' arguments have 'use or raise' behavior, meaning that if they're a subclass of Exception, they're raised. If they're anything else, that value is substituted for the missing/bad value. The simplest usage is: #silent $webInput(['choice']) $choice dic = self.webInput(['choice']) write(dic['choice']) Both these examples retrieves the GET/POST field 'choice' and print it. If you leave off the'#silent', all the values would be printed too. But a better way to preview the values is #silent $webInput(['name'], $debug=1) because this pretty-prints all the values inside HTML
     tags.
    
            ** KLUDGE: 'debug' is supposed to insert into the template output, but it
            wasn't working so I changed it to a'print' statement.  So the debugging
            output will appear wherever standard output is pointed, whether at the
            terminal, in a Webware log file, or whatever. ***
    
            Since we didn't specify any coversions, the value is a string.  It's a
            'single' value because we specified it in 'names' rather than
            'namesMulti'. Single values work like this:
            
                * If one value is found, take it.
                * If several values are found, choose one arbitrarily and ignore the rest.
                * If no values are found, use or raise the appropriate 'default*' value.
    
            Multi values work like this:
                * If one value is found, put it in a list.
                * If several values are found, leave them in a list.
                * If no values are found, use the empty list ([]).  The 'default*' 
                  arguments are *not* consulted in this case.
    
            Example: assume 'days' came from a set of checkboxes or a multiple combo
            box on a form, and the user  chose'Monday', 'Tuesday' and 'Thursday'.
    
                #silent $webInput([], ['days'])
                The days you chose are: #slurp
                #for $day in $days
                $day #slurp
                #end for
    
                dic = self.webInput([], ['days'])
                write('The days you chose are: ')
                for day in dic['days']:
                    write(day + ' ')
    
            Both these examples print:  'The days you chose are: Monday Tuesday Thursday'.
    
            By default, missing strings are replaced by '' and missing/bad numbers
            by zero.  (A'bad number' means the converter raised an exception for
            it, usually because of non-numeric characters in the value.)  This
            mimics Perl/PHP behavior, and simplifies coding for many applications
            where missing/bad values *should* be blank/zero.  In those relatively
            few cases where you must distinguish between empty-string/zero on the
            one hand and missing/bad on the other, change the appropriate
            'default*' and 'bad*' arguments to something like: 
    
                * None
                * another constant value
                * $NonNumericInputError/self.NonNumericInputError
                * $ValueError/ValueError
                
            (NonNumericInputError is defined in this class and is useful for
            distinguishing between bad input vs a TypeError/ValueError thrown for
            some other rason.)
    
            Here's an example using multiple values to schedule newspaper
            deliveries.  'checkboxes' comes from a form with checkboxes for all the
            days of the week.  The days the user previously chose are preselected.
            The user checks/unchecks boxes as desired and presses Submit.  The value
            of 'checkboxes' is a list of checkboxes that were checked when Submit
            was pressed.  Our task now is to turn on the days the user checked, turn
            off the days he unchecked, and leave on or off the days he didn't
            change.
    
                dic = self.webInput([], ['dayCheckboxes'])
                wantedDays = dic['dayCheckboxes'] # The days the user checked.
                for day, on in self.getAllValues():
                    if   not on and wantedDays.has_key(day):
                        self.TurnOn(day)
                        # ... Set a flag or insert a database record ...
                    elif on and not wantedDays.has_key(day):
                        self.TurnOff(day)
                        # ... Unset a flag or delete a database record ...
    
            'source' allows you to look up the variables from a number of different
            sources:
                'f'   fields (CGI GET/POST parameters)
                'c'   cookies
                's'   session variables
                'v'   'values', meaning fields or cookies
    
            In many forms, you're dealing only with strings, which is why the
            'default' argument is third and the numeric arguments are banished to
            the end.  But sometimes you want automatic number conversion, so that
            you can do numeric comparisions in your templates without having to
            write a bunch of conversion/exception handling code.  Example:
    
                #silent $webInput(['name', 'height:int'])
                $name is $height cm tall.
                #if $height >= 300
                Wow, you're tall!
                #else
                Pshaw, you're short.
                #end if
    
                dic = self.webInput(['name', 'height:int'])
                name = dic[name]
                height = dic[height]
                write('%s is %s cm tall.' % (name, height))
                if height > 300:
                    write('Wow, you're tall!')
                else:
                    write('Pshaw, you're short.')
    
            To convert a value to a number, suffix ':int' or ':float' to the name.
            The method will search first for a 'height:int' variable and then for a
            'height' variable.  (It will be called 'height' in the final
            dictionary.)  If a numeric conversion fails, use or raise 'badInt' or
            'badFloat'.  Missing values work the same way as for strings, except the
            default is 'defaultInt' or 'defaultFloat' instead of 'default'.
    
            If a name represents an uploaded file, the entire file will be read into
            memory.  For more sophistocated file-upload handling, leave that name
            out of the list and do your own handling, or wait for
            Cheetah.Utils.UploadFileMixin.
    
            This only in a subclass that also inherits from Webware's Servlet or
            HTTPServlet.  Otherwise you'll get an AttributeError on 'self.request'.
    
            EXCEPTIONS: ValueError if 'source' is not one of the stated characters.
            TypeError if a conversion suffix is not ':int' or ':float'.
    
            FUTURE EXPANSION: a future version of this method may allow source
            cascading; e.g., 'vs' would look first in 'values' and then in session
            variables.
    
            Meta-Data
            ================================================================================
            Author: Mike Orr 
            License: This software is released for unlimited distribution under the
                     terms of the MIT license.  See the LICENSE file.
            Version: $Revision: 1.185 $
            Start Date: 2002/03/17
            Last Revision Date: $Date: 2007/10/02 01:36:26 $
            """ 
            src = src.lower()
            isCgi = not self._CHEETAH__isControlledByWebKit
            if   isCgi and src in ('f', 'v'):
                global _formUsedByWebInput
                if _formUsedByWebInput is None:
                    _formUsedByWebInput = cgi.FieldStorage()
                source, func = 'field',   _formUsedByWebInput.getvalue
            elif isCgi and src == 'c':
                raise RuntimeError("can't get cookies from a CGI script")
            elif isCgi and src == 's':
                raise RuntimeError("can't get session variables from a CGI script")
            elif isCgi and src == 'v':
                source, func = 'value',   self.request().value
            elif isCgi and src == 's':
                source, func = 'session', self.request().session().value
            elif src == 'f':
                source, func = 'field',   self.request().field
            elif src == 'c':
                source, func = 'cookie',  self.request().cookie
            elif src == 'v':
                source, func = 'value',   self.request().value
            elif src == 's':
                source, func = 'session', self.request().session().value
            else:
                raise TypeError("arg 'src' invalid")
            sources = source + 's'
            converters = {
                ''     : _Converter('string', None, default,      default ),
                'int'  : _Converter('int',     int, defaultInt,   badInt  ),
                'float': _Converter('float', float, defaultFloat, badFloat),  }
            #pprint.pprint(locals());  return {}
            dic = {} # Destination.
            for name in names:
                k, v = _lookup(name, func, False, converters)
                dic[k] = v
            for name in namesMulti:
                k, v = _lookup(name, func, True, converters)
                dic[k] = v
            # At this point, 'dic' contains all the keys/values we want to keep.
            # We could split the method into a superclass
            # method for Webware/WebwareExperimental and a subclass for Cheetah.
            # The superclass would merely 'return dic'.  The subclass would
            # 'dic = super(ThisClass, self).webInput(names, namesMulti, ...)'
            # and then the code below.
            if debug:
               print "
    \n" + pprint.pformat(dic) + "\n
    \n\n" self.searchList().insert(0, dic) return dic T = Template # Short and sweet for debugging at the >>> prompt. def genParserErrorFromPythonException(source, file, generatedPyCode, exception): #print dir(exception) filename = isinstance(file, (str, unicode)) and file or None sio = StringIO.StringIO() traceback.print_exc(1, sio) formatedExc = sio.getvalue() if hasattr(exception, 'lineno'): pyLineno = exception.lineno else: pyLineno = int(re.search('[ \t]*File.*line (\d+)', formatedExc).group(1)) lines = generatedPyCode.splitlines() prevLines = [] # (i, content) for i in range(1,4): if pyLineno-i <=0: break prevLines.append( (pyLineno+1-i,lines[pyLineno-i]) ) nextLines = [] # (i, content) for i in range(1,4): if not pyLineno+i < len(lines): break nextLines.append( (pyLineno+i,lines[pyLineno+i]) ) nextLines.reverse() report = 'Line|Python Code\n' report += '----|-------------------------------------------------------------\n' while prevLines: lineInfo = prevLines.pop() report += "%(row)-4d|%(line)s\n"% {'row':lineInfo[0], 'line':lineInfo[1]} if hasattr(exception, 'offset'): report += ' '*(3+(exception.offset or 0)) + '^\n' while nextLines: lineInfo = nextLines.pop() report += "%(row)-4d|%(line)s\n"% {'row':lineInfo[0], 'line':lineInfo[1]} message = [ "Error in the Python code which Cheetah generated for this template:", '='*80, '', str(exception), '', report, '='*80, ] cheetahPosMatch = re.search('line (\d+), col (\d+)', formatedExc) if cheetahPosMatch: lineno = int(cheetahPosMatch.group(1)) col = int(cheetahPosMatch.group(2)) #if hasattr(exception, 'offset'): # col = exception.offset message.append('\nHere is the corresponding Cheetah code:\n') else: lineno = None col = None cheetahPosMatch = re.search('line (\d+), col (\d+)', '\n'.join(lines[max(pyLineno-2, 0):])) if cheetahPosMatch: lineno = int(cheetahPosMatch.group(1)) col = int(cheetahPosMatch.group(2)) message.append('\nHere is the corresponding Cheetah code.') message.append('** I had to guess the line & column numbers,' ' so they are probably incorrect:\n') message = '\n'.join(message) reader = SourceReader(source, filename=filename) return ParseError(reader, message, lineno=lineno,col=col) # vim: shiftwidth=4 tabstop=4 expandtab PKۡ(82YCCCheetah/ImportHooks.pyc; /KDc@sdZdZddd!ZdkZdkZdkZdkZdkZdk Z dk l Z dk Z dk Z dklZdklZd klZd klZeagad Zd efd YZdfdZdZedjo endS(s"Provides some import hooks to allow Cheetah's .tmpl files to be imported directly like Python .py modules. To use these: import Cheetah.ImportHooks Cheetah.ImportHooks.install() Meta-Data ================================================================================ Author: Tavis Rudd License: This software is released for unlimited distribution under the terms of the MIT license. See the LICENSE file. Version: $Revision: 1.25 $ Start Date: 2001/03/30 Last Revision Date: $Date: 2006/06/20 19:23:27 $ s!Tavis Rudd s$Revision: 1.25 $i iN(sLock(s ImportManager(sDirOwner(sCompiler(sconvertTmplPathToModuleNamecCsti|dS(N(s _cacheDirsappendscacheDir(scacheDir((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportHooks.pys setCacheDir+ssCheetahDirOwnercBs>tZeZeiZeiZdfZdZ dZ RS(Ns.tmplcCsz|iti||}|o|Snx|iD]}ti i |i ||}ti i |oZy|i ||SWqti}ddi |i}tdtqXq8q8WtSWd|iXdS(Ns s sVError while compiling Cheetah module %(name)s, original traceback follows: %(exc_txt)s(sselfs _acquireLocksDirOwnersgetmodsnamesmodstemplateFileExtensionssextsosspathsjoinstmplPathsexistss_compiles tracebacks format_excsexc_txts splitliness ImportErrorslocalssNones _releaseLock(sselfsnamestmplPathsexc_txtsextsmod((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportHooks.pysgetmod9s$   cCsttd|d|d|}toptiitdt |d}yt |di |Wqt j o tidti|}qXn|}t|d|d}ti|}|i|_ to ||_n||_|SdS( Nsfiles moduleNames mainClassNameis.pysws sexec(sstrsCompilerstmplPathsnamescodes _cacheDirsosspathsjoinsconvertTmplPathToModuleNames__file__sopenswritesOSErrors tracebacks print_excssyssstderrscompilescosimps new_modulesmods co_filenames __orig_file__s__co__(sselfsnamestmplPathscodes__file__scosmod((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportHooks.pys_compileRs$   ( s__name__s __module__sLocks_locksacquires _acquireLocksreleases _releaseLockstemplateFileExtensionssgetmods_compile(((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportHooks.pysCheetahDirOwner2s      s.tmplcCs{t oo|t_dk}t|itijo@|iat i i dtt i a t i t iqwndS(s Install the Cheetah Import HooksNi(s _installedstemplateFileExtensionssCheetahDirOwners __builtin__stypes __import__stypessBuiltinFunctionTypes __oldimport__s ImportManagers_globalOwnerTypessinserts_managers setThreadedsinstall(stemplateFileExtensionss __builtin__((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportHooks.pysinstallos     cCsBt o6dk}t|itijot|_bq>ndS(s"Uninstall the Cheetah Import HooksN(s _installeds __builtin__stypes __import__stypess MethodTypes __oldimport__s_manager(s __builtin__((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportHooks.pys uninstalls  s__main__(s__doc__s __author__s __revision__ssyssos.pathsosstypess __builtin__snewsimps threadingsLocksstrings tracebacksCheetahs ImportManagersCheetah.ImportManagersDirOwnersCheetah.CompilersCompilers#Cheetah.convertTmplPathToModuleNamesconvertTmplPathToModuleNamesFalses _installeds _cacheDirs setCacheDirsCheetahDirOwnersinstalls uninstalls__name__(s ImportManagersconvertTmplPathToModuleNames __builtin__s __revision__sDirOwnersimpsnewsCompilersstrings __author__s setCacheDirsCheetahDirOwnerstypesssyssLocks tracebacksinstallsoss uninstall((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportHooks.pys?s.               = PK(8JSSCheetah/ImportManager.pyc; HFc@sdZdZddd!ZdkZdkZdkZyeefWn1ej o%ddjddjf\ZZnXeZ e dZ e a aaad Zed Zd Zd Zd ZdZdfdYZdefdYZdefdYZdefdYZdefdYZdefdYZdefdYZdZdfdYZeegZ dS( sProvides an emulator/replacement for Python's standard import system. @@TR: Be warned that Import Hooks are in the deepest, darkest corner of Python's jungle. If you need to start hacking with this, be prepared to get lost for a while. Also note, this module predates the newstyle import hooks in Python 2.3 http://www.python.org/peps/pep-0302.html. This is a hacked/documented version of Gordon McMillan's iu.py. I have: - made it a little less terse - added docstrings and explanatations - standardized the variable naming scheme - reorganized the code layout to enhance readability Meta-Data ================================================================================ Author: Tavis Rudd based on Gordon McMillan's iu.py License: This software is released for unlimited distribution under the terms of the MIT license. See the LICENSE file. Version: $Revision: 1.6 $ Start Date: 2001/03/30 Last Revision Date: $Date: 2007/04/03 01:56:24 $ s!Tavis Rudd s$Revision: 1.6 $i iNiiscCsGti}t}}d|jod}dkl}l }nd|jod}dk l}l }nd|jod}dk l}l }nad|jod}dk l}l }n7d|jo dk l}l }d }n td |tjo|d }n|tjo|d }n|a|a|a|ad S(sISet up 'os' module replacement functions for use during import bootstrap.sposixs/(sstatsgetcwdsnts\sdossos2smaccCs[|djo|Snd|jod|}n|ddjo|d}n||SdS(Nss:i(sasb(sasb((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pysjoinPs  sno os specific module foundcCsU|djo|Sn|d}|djp ||jo ||Sn|||SdS(Nsis/(sasbslastcharssep(sasbssepslastchar((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pysjoin\s    cCs_xTtt|dddD]6}||}|djp ||jo || SqqWdSdS(Niis/s(srangeslensasiscssep(sassepscsi((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pysdirnamees  N(ssyssbuiltin_module_namessnamessNonesjoinsdirnamessepsposixsstatsgetcwdsntsdossos2smacs ImportErrors_os_stats _os_path_joins_os_path_dirnames _os_getcwd(sjoinssepsgetcwdsstatsnamessdirname((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pys _os_bootstrap<s>          cCsMx>tt|dddD]}||djoPqqWdS|| SdS(Niis.s(srangeslensssi(sssi((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pys packageNamezs  cCsg}d}}xMtt|D]9}||djo"|i|||!|d}q#q#W|t|jo|i||n|SdS(Nis.i(srsltsisjsrangeslensssappend(sssisjsrslt((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pys nameSplits cCsLxAtt|dddD]#}||djo ||SqqWdSdS(Niis.s(srangeslensfnmsi(sfnmsi((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pys getPathExts cCs@yt|}Wntj o tSnX|dd@djSdS(s&Local replacement for os.path.isdir().iii@N(s_os_statspathnamesssOSErrorsNone(spathnamess((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pys pathIsDirs  cCsNt|}x;tiD]-\}}}||jo|||fSqqWdS(N(s getPathExtsfnmsextsimps get_suffixesssuffixsmodestyp(sfnmssuffixsextsmodestyp((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pysgetDescrs    sOwnercBs)tZdZdZdZdZRS(sAn Owner does imports from a particular piece of turf That is, there's an Owner for each thing on sys.path There are owners for directories and .pyz files. There could be owners for zip files, or even URLs. A shadowpath (a dictionary mapping the names in sys.path to their owners) is used so that sys.path (or a package's __path__) is still a bunch of strings, cCs ||_dS(N(spathsself(sselfspath((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pys__init__scCs |iSdS(N(sselfspath(sself((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pys__str__scCstSdS(N(sNone(sselfsnm((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pysgetmods(s__name__s __module__s__doc__s__init__s__str__sgetmod(((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pysOwners   sDirOwnercBs,tZdZeieieidZRS(NcCsM|djo t}nt| otd|nti||dS(Nss%s is not a directory(spaths _os_getcwds pathIsDirs ValueErrorsOwners__init__sself(sselfspath((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pys__init__s   c Cst|i|}|dtfg} t|o&| idt|dd|fnt}}x| D]\}} } x|D]\}}}||} yt| }WnqX|tijoAt| d} ti|| | |||f}| |_|Sq|tijo| |f}q| |f}qW|p|oPqhqhW|tjo |tjotSnxno|tjp!|o|dd|ddjofy2tt|ddid|dd}PWqntj o!}d |dGH|i!GHqnXqq|oTt|ddi}y||d}PWqnt$t%fj o t}qnXqqtSqxW||}|i'|_| o+| g|_(t)|i(}|i+|_,n||_-|SdS( Nis__init__isrbisrs sexecsInvalid syntax in %s(.s _os_path_joinsselfspathsnmspthsNones possibless pathIsDirsinsertspyspycsispkgspkgpths getsuffixessextsmodestypsattempts_os_statsstsimps C_EXTENSIONsopensfps load_modulesmods__file__s PY_SOURCEscompilesreadscos SyntaxErrorsesargssstuffsloadcos ValueErrorsEOFErrorsnewmods co_filenames__path__sPathImportDirectors subimportersgetmods __importsub__s__co__(sselfsnms getsuffixessloadcosnewmodscospthspycspys possiblessfpspkgpthsattemptsispkgstypsmods subimportersstsextsstuffsmodese((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pysgetmodsh &   !  1-       ( s__name__s __module__s__init__simps get_suffixessmarshalsloadss new_modulesgetmod(((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pysDirOwners sImportDirectorcBstZdZRS(sImportDirectors live on the metapath There's one for builtins, one for frozen modules, and one for sys.path Windows gets one for modules gotten from the Registry Mac would have them for PY_RESOURCE modules etc. A generalization of Owner - their concept of 'turf' is broader(s__name__s __module__s__doc__(((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pysImportDirectors sBuiltinImportDirectorcBs&tZdZdZeidZRS(s"Directs imports of builtin modulescCs d|_dS(NsBuiltins(sselfspath(sself((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pys__init__scCsA||o,ti|t|ddtif}|SntSdS(Ns(s isbuiltinsnmsimps load_modulesNones C_BUILTINsmod(sselfsnms isbuiltinsmod((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pysgetmods $(s__name__s __module__s__doc__s__init__simps is_builtinsgetmod(((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pysBuiltinImportDirectors  sFrozenImportDirectorcBs,tZdZdZeieidZRS(s!Directs imports of frozen modulescCs d|_dS(Ns FrozenModules(sselfspath(sself((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pys__init__scCsd||oO||t|ddtif}t|do||d|_ n|SntSdS(Nss__path__cCs|i|d|S(Ns.(sownersgetmodspnamesname(snamespnamesowner((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pyss( sisFrozensnmsloadModsNonesimps PY_FROZENsmodshasattrsselfs __importsub__(sselfsnmsisFrozensloadModsmod((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pysgetmods  !(s__name__s __module__s__doc__s__init__simps is_frozens load_modulesgetmod(((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pysFrozenImportDirector s  sRegistryImportDirectorcBs tZdZdZdZRS(s9Directs imports of modules stored in the Windows RegistrycCs<d|_h|_y dk}Wntj onXd}d} d}dti } x|| fD]}y|i || d|}WnqaX|i|\}}} xt|D]s}|i||}|i ||d|} |i| d}t|d} |d| f|i|<| iqW|iPqaWdS(NsWindowsRegistryiii?s%Software\Python\PythonCore\%s\Modulesis(sselfspathsmapswin32apis ImportErrorsHKEY_CURRENT_USERsHKEY_LOCAL_MACHINEsKEY_ALL_ACCESSssysswinverssubkeysroots RegOpenKeyExshkeysRegQueryInfoKeys numsubkeyss numvaluess lastmodifiedsrangesis RegEnumKeys subkeynameshskeysRegQueryValueExsvalsgetDescrsdescsClose(sselfs numsubkeyssHKEY_CURRENT_USERsKEY_ALL_ACCESSsisvalshkeys numvaluess subkeynameshskeysHKEY_LOCAL_MACHINEssubkeys lastmodifiedsdescsrootswin32api((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pys__init__s6       cCse|ii|}|oD|\}}t|d}t i ||||}||_ |Snt SdS(Nsrb(sselfsmapsgetsnmsstuffsfnmsdescsopensfpsimps load_modulesmods__file__sNone(sselfsnmsfpsstuffsfnmsmodsdesc((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pysgetmod=s  (s__name__s __module__s__doc__s__init__sgetmod(((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pysRegistryImportDirectors  sPathImportDirectorcBs2tZdZeeedZdZdZRS(s4Directs imports of modules stored on the filesystem.cCs||tjoti|_n ||_|tjo t|_n ||_|o ||_ n h|_ t |_ h|_ dS(N( spathlistsNonessysspathsselfs ownertypess_globalOwnerTypess _ownertypess importerss _shadowPathsFalses _inMakeOwners _building(sselfspathlists importerss ownertypes((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ImportManager.pys__init__Js        cCst}x|iD]}t|tjo^|ii|d}|djo|i |}|i| Version: $Revision: 1.7 $ Start Date: 2001/08/01 Last Revision Date: $Date: 2005/01/03 19:59:07 $ s!Tavis Rudd s$Revision: 1.7 $i iN(sNotFoundsErrorcBstZRS(N(s__name__s __module__(((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ErrorCatchers.pysErrorss ErrorCatchercBs,tZefZdZdZdZRS(NcCsdS(N((sselfs templateObj((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ErrorCatchers.pys__init__scCs |iSdS(N(sselfs_exceptionsToCatch(sself((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ErrorCatchers.pys exceptionsscCs|SdS(N(srawCode(sselfsexc_valscodesrawCodeslineCol((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ErrorCatchers.pyswarns(s__name__s __module__sNotFounds_exceptionsToCatchs__init__s exceptionsswarn(((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ErrorCatchers.pys ErrorCatchers   sBigEchocBstZdZRS(NcCs ddd|dddSdS(Ns=is<s could not be found>(srawCode(sselfsexc_valscodesrawCodeslineCol((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ErrorCatchers.pyswarn$s(s__name__s __module__swarn(((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ErrorCatchers.pysBigEcho#ssKeyErrorcBstZdZRS(NcCstd|dS(Ns-no '%s' in this Template Object's Search List(sKeyErrorsrawCode(sselfsexc_valscodesrawCodeslineCol((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ErrorCatchers.pyswarn(s(s__name__s __module__swarn(((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ErrorCatchers.pysKeyError'ss ListErrorscBs/tZdZdZdZdZdZRS(sAccumulate a list of errors.s%ccCsti||g|_dS(N(s ErrorCatchers__init__sselfs templateObjs_errors(sselfs templateObj((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ErrorCatchers.pys__init__/scCsVti}|d=ti|ititi|d<|ii ||SdS(Nsselfstime( slocalsscopysdictstimesstrftimesselfs _timeFormats localtimes_errorssappendsrawCode(sselfsexc_valscodesrawCodeslineColsdict((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ErrorCatchers.pyswarn3s  cCs |iSdS(sReturn the list of errors.N(sselfs_errors(sself((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ErrorCatchers.pys listErrors;s(s__name__s __module__s__doc__s _timeFormats__init__swarns listErrors(((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ErrorCatchers.pys ListErrors+s   ( s__doc__s __author__s __revision__stimesCheetah.NameMappersNotFounds ExceptionsErrors ErrorCatchersEchosBigEchosKeyErrors ListErrors( sNotFounds __revision__s ErrorCatcherstimesKeyErrors __author__sBigEchos ListErrorssErrorsEcho((s:build/bdist.darwin-8.0.1-i386/egg/Cheetah/ErrorCatchers.pys? s    PKݡ(8 Cheetah/TemplateCmdLineIface.pyc; [Cc@sdZdZddd!ZdkZdkZdkZdkZydklZWn e j odk lZnXdk l Z de fd YZd fd YZdS( s1Provides a command line interface to compiled Cheetah template modules. Meta-Data ================================================================================ Author: Tavis Rudd Version: $Revision: 1.13 $ Start Date: 2001/12/06 Last Revision Date: $Date: 2006/01/10 20:34:35 $ s!Tavis Rudd s$Revision: 1.13 $i iN(sload(sVersionsErrorcBstZRS(N(s__name__s __module__(((sAbuild/bdist.darwin-8.0.1-i386/egg/Cheetah/TemplateCmdLineIface.pysErrorss CmdLineIfacecBsRtZdZeiieideiddZdZ dZ dZ RS(s>A command line interface to compiled Cheetah template modules.iicCs||_||_||_dS(N(s templateObjsselfs _templates scriptNames _scriptNames cmdLineArgss _cmdLineArgs(sselfs templateObjs scriptNames cmdLineArgs((sAbuild/bdist.darwin-8.0.1-i386/egg/Cheetah/TemplateCmdLineIface.pys__init__!s  cCs|i|iGHdS(sThe main program controller.N(sselfs_processCmdLineArgss _template(sself((sAbuild/bdist.darwin-8.0.1-i386/egg/Cheetah/TemplateCmdLineIface.pysrun)s cCsey1ti|iddddg\|_|_Wn5tij o&}|GH|iGHti dnXx|iD]\}}|ddfjo|iGHti n|djo |i i id tin|d jox|d jo,tti}|i i id |q]t|}t|}|i|i i id |qsqsWdS( Nshshelpsenvspickle=is-hs--helps--envis--pickles-(sgetoptsselfs _cmdLineArgss_optss_argss GetoptErrorsvsusagessyssexitsosas _templates searchListsinsertsossenvironsloadsstdins unpickledsopensfsclose(sselfsasfs unpickledsosv((sAbuild/bdist.darwin-8.0.1-i386/egg/Cheetah/TemplateCmdLineIface.pys_processCmdLineArgs/s*1          cCs!dhd|i<dt<SdS(NsCheetah %(Version)s template module command-line interface Usage ----- %(scriptName)s [OPTION] Options ------- -h, --help Print this help information --env Use shell ENVIRONMENT variables to fill the $placeholders in the template. --pickle Use a variables from a dictionary stored in Python pickle file to fill $placeholders in the template. If is - stdin is used: '%(scriptName)s --pickle -' Description ----------- This interface allows you to execute a Cheetah template from the command line and collect the output. It can prepend the shell ENVIRONMENT or a pickled Python dictionary to the template's $placeholder searchList, overriding the defaults for the $placeholders. s scriptNamesVersion(sselfs _scriptNamesVersion(sself((sAbuild/bdist.darwin-8.0.1-i386/egg/Cheetah/TemplateCmdLineIface.pysusageMs( s__name__s __module__s__doc__sosspathsbasenamessyssargvs__init__sruns_processCmdLineArgssusage(((sAbuild/bdist.darwin-8.0.1-i386/egg/Cheetah/TemplateCmdLineIface.pys CmdLineIfaces )  (s__doc__s __author__s __revision__ssyssossgetoptsos.pathscPicklesloads ImportErrorspicklesCheetah.VersionsVersions ExceptionsErrors CmdLineIface( sloads __revision__s __author__ssyssVersions CmdLineIfacesErrorsgetoptsos((sAbuild/bdist.darwin-8.0.1-i386/egg/Cheetah/TemplateCmdLineIface.pys? s      PK6L66Cheetah/Compiler.py#!/usr/bin/env python # $Id: Compiler.py,v 1.155 2007/04/04 00:28:35 tavis_rudd Exp $ """Compiler classes for Cheetah: ModuleCompiler aka 'Compiler' ClassCompiler MethodCompiler If you are trying to grok this code start with ModuleCompiler.__init__, ModuleCompiler.compile, and ModuleCompiler.__getattr__. Meta-Data ================================================================================ Author: Tavis Rudd Version: $Revision: 1.155 $ Start Date: 2001/09/19 Last Revision Date: $Date: 2007/04/04 00:28:35 $ """ __author__ = "Tavis Rudd " __revision__ = "$Revision: 1.155 $"[11:-2] import sys import os import os.path from os.path import getmtime, exists import re import types import time import random import warnings import __builtin__ import copy from Cheetah.Version import Version, VersionTuple from Cheetah.SettingsManager import SettingsManager from Cheetah.Utils.Indenter import indentize # an undocumented preprocessor from Cheetah import ErrorCatchers from Cheetah import NameMapper from Cheetah.Parser import Parser, ParseError, specialVarRE, \ STATIC_CACHE, REFRESH_CACHE, SET_LOCAL, SET_GLOBAL,SET_MODULE, \ unicodeDirectiveRE, encodingDirectiveRE,escapedNewlineRE from Cheetah.NameMapper import NotFound, valueForName, valueFromSearchList, valueFromFrameOrSearchList VFFSL=valueFromFrameOrSearchList VFSL=valueFromSearchList VFN=valueForName currentTime=time.time class Error(Exception): pass DEFAULT_COMPILER_SETTINGS = { ## controlling the handling of Cheetah $placeholders 'useNameMapper': True, # Unified dotted notation and the searchList 'useSearchList': True, # if false, assume the first # portion of the $variable (before the first dot) is a global, # builtin, or local var that doesn't need # looking up in the searchlist BUT use # namemapper on the rest of the lookup 'allowSearchListAsMethArg': True, 'useAutocalling': True, # detect and call callable()'s, requires NameMapper 'useStackFrames': True, # use NameMapper.valueFromFrameOrSearchList # rather than NameMapper.valueFromSearchList 'useErrorCatcher':False, 'alwaysFilterNone':True, # filter out None, before the filter is called 'useFilters':True, # use str instead if =False 'includeRawExprInFilterArgs':True, #'lookForTransactionAttr':False, 'autoAssignDummyTransactionToSelf':False, 'useKWsDictArgForPassingTrans':True, ## controlling the aesthetic appearance / behaviour of generated code 'commentOffset': 1, 'outputRowColComments':True, # should #block's be wrapped in a comment in the template's output 'includeBlockMarkers': False, 'blockMarkerStart':('\n\n'), 'blockMarkerEnd':('\n\n'), 'defDocStrMsg':'Autogenerated by CHEETAH: The Python-Powered Template Engine', 'setup__str__method': False, 'mainMethodName':'respond', 'mainMethodNameForSubclasses':'writeBody', 'indentationStep': ' '*4, 'initialMethIndentLevel': 2, 'monitorSrcFile':False, 'outputMethodsBeforeAttributes': True, 'addTimestampsToCompilerOutput': True, ## customizing the #extends directive 'autoImportForExtendsDirective':True, 'handlerForExtendsDirective':None, # baseClassName = handler(compiler, baseClassName) # a callback hook for customizing the # #extends directive. It can manipulate # the compiler's state if needed. # also see allowExpressionsInExtendsDirective # input filtering/restriction # use lower case keys here!! 'disabledDirectives':[], # list of directive keys, without the start token 'enabledDirectives':[], # list of directive keys, without the start token 'disabledDirectiveHooks':[], # callable(parser, directiveKey) 'preparseDirectiveHooks':[], # callable(parser, directiveKey) 'postparseDirectiveHooks':[], # callable(parser, directiveKey) 'preparsePlaceholderHooks':[], # callable(parser) 'postparsePlaceholderHooks':[], # callable(parser) # the above hooks don't need to return anything 'expressionFilterHooks':[], # callable(parser, expr, exprType, rawExpr=None, startPos=None) # exprType is the name of the directive, 'psp', or 'placeholder'. all # lowercase. The filters *must* return the expr or raise an exception. # They can modify the expr if needed. 'templateMetaclass':None, # strictly optional. Only works with new-style baseclasses 'i18NFunctionName':'self.i18n', ## These are used in the parser, but I've put them here for the time being to ## facilitate separating the parser and compiler: 'cheetahVarStartToken':'$', 'commentStartToken':'##', 'multiLineCommentStartToken':'#*', 'multiLineCommentEndToken':'*#', 'gobbleWhitespaceAroundMultiLineComments':True, 'directiveStartToken':'#', 'directiveEndToken':'#', 'allowWhitespaceAfterDirectiveStartToken':False, 'PSPStartToken':'<%', 'PSPEndToken':'%>', 'EOLSlurpToken':'#', 'gettextTokens': ["_", "N_", "ngettext"], 'allowExpressionsInExtendsDirective': False, # the default restricts it to # accepting dotted names 'allowEmptySingleLineMethods': False, 'allowNestedDefScopes': True, 'allowPlaceholderFilterArgs': True, ## See Parser.initDirectives() for the use of the next 3 #'directiveNamesAndParsers':{} #'endDirectiveNamesAndHandlers':{} #'macroDirectives':{} } class GenUtils: """An abstract baseclass for the Compiler classes that provides methods that perform generic utility functions or generate pieces of output code from information passed in by the Parser baseclass. These methods don't do any parsing themselves. """ def genTimeInterval(self, timeString): ##@@ TR: need to add some error handling here if timeString[-1] == 's': interval = float(timeString[:-1]) elif timeString[-1] == 'm': interval = float(timeString[:-1])*60 elif timeString[-1] == 'h': interval = float(timeString[:-1])*60*60 elif timeString[-1] == 'd': interval = float(timeString[:-1])*60*60*24 elif timeString[-1] == 'w': interval = float(timeString[:-1])*60*60*24*7 else: # default to minutes interval = float(timeString)*60 return interval def genCacheInfo(self, cacheTokenParts): """Decipher a placeholder cachetoken """ cacheInfo = {} if cacheTokenParts['REFRESH_CACHE']: cacheInfo['type'] = REFRESH_CACHE cacheInfo['interval'] = self.genTimeInterval(cacheTokenParts['interval']) elif cacheTokenParts['STATIC_CACHE']: cacheInfo['type'] = STATIC_CACHE return cacheInfo # is empty if no cache def genCacheInfoFromArgList(self, argList): cacheInfo = {'type':REFRESH_CACHE} for key, val in argList: if val[0] in '"\'': val = val[1:-1] if key == 'timer': key = 'interval' val = self.genTimeInterval(val) cacheInfo[key] = val return cacheInfo def genCheetahVar(self, nameChunks, plain=False): if nameChunks[0][0] in self.setting('gettextTokens'): self.addGetTextVar(nameChunks) if self.setting('useNameMapper') and not plain: return self.genNameMapperVar(nameChunks) else: return self.genPlainVar(nameChunks) def addGetTextVar(self, nameChunks): """Output something that gettext can recognize. This is a harmless side effect necessary to make gettext work when it is scanning compiled templates for strings marked for translation. @@TR: another marginally more efficient approach would be to put the output in a dummy method that is never called. """ # @@TR: this should be in the compiler not here self.addChunk("if False:") self.indent() self.addChunk(self.genPlainVar(nameChunks[:])) self.dedent() def genPlainVar(self, nameChunks): """Generate Python code for a Cheetah $var without using NameMapper (Unified Dotted Notation with the SearchList). """ nameChunks.reverse() chunk = nameChunks.pop() pythonCode = chunk[0] + chunk[2] while nameChunks: chunk = nameChunks.pop() pythonCode = (pythonCode + '.' + chunk[0] + chunk[2]) return pythonCode def genNameMapperVar(self, nameChunks): """Generate valid Python code for a Cheetah $var, using NameMapper (Unified Dotted Notation with the SearchList). nameChunks = list of var subcomponents represented as tuples [ (name,useAC,remainderOfExpr), ] where: name = the dotted name base useAC = where NameMapper should use autocalling on namemapperPart remainderOfExpr = any arglist, index, or slice If remainderOfExpr contains a call arglist (e.g. '(1234)') then useAC is False, otherwise it defaults to True. It is overridden by the global setting 'useAutocalling' if this setting is False. EXAMPLE ------------------------------------------------------------------------ if the raw Cheetah Var is $a.b.c[1].d().x.y.z nameChunks is the list [ ('a.b.c',True,'[1]'), # A ('d',False,'()'), # B ('x.y.z',True,''), # C ] When this method is fed the list above it returns VFN(VFN(VFFSL(SL, 'a.b.c',True)[1], 'd',False)(), 'x.y.z',True) which can be represented as VFN(B`, name=C[0], executeCallables=(useAC and C[1]))C[2] where: VFN = NameMapper.valueForName VFFSL = NameMapper.valueFromFrameOrSearchList VFSL = NameMapper.valueFromSearchList # optionally used instead of VFFSL SL = self.searchList() useAC = self.setting('useAutocalling') # True in this example A = ('a.b.c',True,'[1]') B = ('d',False,'()') C = ('x.y.z',True,'') C` = VFN( VFN( VFFSL(SL, 'a.b.c',True)[1], 'd',False)(), 'x.y.z',True) = VFN(B`, name='x.y.z', executeCallables=True) B` = VFN(A`, name=B[0], executeCallables=(useAC and B[1]))B[2] A` = VFFSL(SL, name=A[0], executeCallables=(useAC and A[1]))A[2] Note, if the compiler setting useStackFrames=False (default is true) then A` = VFSL([locals()]+SL+[globals(), __builtin__], name=A[0], executeCallables=(useAC and A[1]))A[2] This option allows Cheetah to be used with Psyco, which doesn't support stack frame introspection. """ defaultUseAC = self.setting('useAutocalling') useSearchList = self.setting('useSearchList') nameChunks.reverse() name, useAC, remainder = nameChunks.pop() if not useSearchList: firstDotIdx = name.find('.') if firstDotIdx != -1 and firstDotIdx < len(name): beforeFirstDot, afterDot = name[:firstDotIdx], name[firstDotIdx+1:] pythonCode = ('VFN(' + beforeFirstDot + ',"' + afterDot + '",' + repr(defaultUseAC and useAC) + ')' + remainder) else: pythonCode = name+remainder elif self.setting('useStackFrames'): pythonCode = ('VFFSL(SL,' '"'+ name + '",' + repr(defaultUseAC and useAC) + ')' + remainder) else: pythonCode = ('VFSL([locals()]+SL+[globals(), __builtin__],' '"'+ name + '",' + repr(defaultUseAC and useAC) + ')' + remainder) ## while nameChunks: name, useAC, remainder = nameChunks.pop() pythonCode = ('VFN(' + pythonCode + ',"' + name + '",' + repr(defaultUseAC and useAC) + ')' + remainder) return pythonCode ################################################## ## METHOD COMPILERS class MethodCompiler(GenUtils): def __init__(self, methodName, classCompiler, initialMethodComment=None, decorator=None): self._settingsManager = classCompiler self._classCompiler = classCompiler self._moduleCompiler = classCompiler._moduleCompiler self._methodName = methodName self._initialMethodComment = initialMethodComment self._setupState() self._decorator = decorator def setting(self, key): return self._settingsManager.setting(key) def _setupState(self): self._indent = self.setting('indentationStep') self._indentLev = self.setting('initialMethIndentLevel') self._pendingStrConstChunks = [] self._methodSignature = None self._methodDef = None self._docStringLines = [] self._methodBodyChunks = [] self._cacheRegionsStack = [] self._callRegionsStack = [] self._captureRegionsStack = [] self._filterRegionsStack = [] self._isErrorCatcherOn = False self._hasReturnStatement = False self._isGenerator = False def cleanupState(self): """Called by the containing class compiler instance """ pass def methodName(self): return self._methodName def setMethodName(self, name): self._methodName = name ## methods for managing indentation def indentation(self): return self._indent * self._indentLev def indent(self): self._indentLev +=1 def dedent(self): if self._indentLev: self._indentLev -=1 else: raise Error('Attempt to dedent when the indentLev is 0') ## methods for final code wrapping def methodDef(self): if self._methodDef: return self._methodDef else: return self.wrapCode() __str__ = methodDef __unicode__ = methodDef def wrapCode(self): self.commitStrConst() methodDefChunks = ( self.methodSignature(), '\n', self.docString(), self.methodBody() ) methodDef = ''.join(methodDefChunks) self._methodDef = methodDef return methodDef def methodSignature(self): return self._indent + self._methodSignature + ':' def setMethodSignature(self, signature): self._methodSignature = signature def methodBody(self): return ''.join( self._methodBodyChunks ) def docString(self): if not self._docStringLines: return '' ind = self._indent*2 docStr = (ind + '"""\n' + ind + ('\n' + ind).join([ln.replace('"""',"'''") for ln in self._docStringLines]) + '\n' + ind + '"""\n') return docStr ## methods for adding code def addMethDocString(self, line): self._docStringLines.append(line.replace('%','%%')) def addChunk(self, chunk): self.commitStrConst() chunk = "\n" + self.indentation() + chunk self._methodBodyChunks.append(chunk) def appendToPrevChunk(self, appendage): self._methodBodyChunks[-1] = self._methodBodyChunks[-1] + appendage def addWriteChunk(self, chunk): self.addChunk('write(' + chunk + ')') def addFilteredChunk(self, chunk, filterArgs=None, rawExpr=None, lineCol=None): if filterArgs is None: filterArgs = '' if self.setting('includeRawExprInFilterArgs') and rawExpr: filterArgs += ', rawExpr=%s'%repr(rawExpr) if self.setting('alwaysFilterNone'): if rawExpr and rawExpr.find('\n')==-1 and rawExpr.find('\r')==-1: self.addChunk("_v = %s # %r"%(chunk, rawExpr)) if lineCol: self.appendToPrevChunk(' on line %s, col %s'%lineCol) else: self.addChunk("_v = %s"%chunk) if self.setting('useFilters'): self.addChunk("if _v is not None: write(_filter(_v%s))"%filterArgs) else: self.addChunk("if _v is not None: write(str(_v))") else: if self.setting('useFilters'): self.addChunk("write(_filter(%s%s))"%(chunk,filterArgs)) else: self.addChunk("write(str(%s))"%chunk) def _appendToPrevStrConst(self, strConst): if self._pendingStrConstChunks: self._pendingStrConstChunks.append(strConst) else: self._pendingStrConstChunks = [strConst] def _unescapeCheetahVars(self, theString): """Unescape any escaped Cheetah \$vars in the string. """ token = self.setting('cheetahVarStartToken') return theString.replace('\\' + token, token) def _unescapeDirectives(self, theString): """Unescape any escaped Cheetah \$vars in the string. """ token = self.setting('directiveStartToken') return theString.replace('\\' + token, token) def commitStrConst(self): """Add the code for outputting the pending strConst without chopping off any whitespace from it. """ if self._pendingStrConstChunks: strConst = self._unescapeCheetahVars(''.join(self._pendingStrConstChunks)) strConst = self._unescapeDirectives(strConst) self._pendingStrConstChunks = [] if not strConst: return else: reprstr = repr(strConst).replace('\\012','\n') i = 0 out = [] if reprstr.startswith('u'): i = 1 out = ['u'] body = escapedNewlineRE.sub('\n', reprstr[i+1:-1]) if reprstr[i]=="'": out.append("'''") out.append(body) out.append("'''") else: out.append('"""') out.append(body) out.append('"""') self.addWriteChunk(''.join(out)) def handleWSBeforeDirective(self): """Truncate the pending strCont to the beginning of the current line. """ if self._pendingStrConstChunks: src = self._pendingStrConstChunks[-1] BOL = max(src.rfind('\n')+1, src.rfind('\r')+1, 0) if BOL < len(src): self._pendingStrConstChunks[-1] = src[:BOL] def isErrorCatcherOn(self): return self._isErrorCatcherOn def turnErrorCatcherOn(self): self._isErrorCatcherOn = True def turnErrorCatcherOff(self): self._isErrorCatcherOn = False # @@TR: consider merging the next two methods into one def addStrConst(self, strConst): self._appendToPrevStrConst(strConst) def addRawText(self, text): self.addStrConst(text) def addMethComment(self, comm): offSet = self.setting('commentOffset') self.addChunk('#' + ' '*offSet + comm) def addPlaceholder(self, expr, filterArgs, rawPlaceholder, cacheTokenParts, lineCol, silentMode=False): cacheInfo = self.genCacheInfo(cacheTokenParts) if cacheInfo: cacheInfo['ID'] = repr(rawPlaceholder)[1:-1] self.startCacheRegion(cacheInfo, lineCol, rawPlaceholder=rawPlaceholder) if self.isErrorCatcherOn(): methodName = self._classCompiler.addErrorCatcherCall( expr, rawCode=rawPlaceholder, lineCol=lineCol) expr = 'self.' + methodName + '(localsDict=locals())' if silentMode: self.addChunk('try:') self.indent() self.addFilteredChunk(expr, filterArgs, rawPlaceholder, lineCol=lineCol) self.dedent() self.addChunk('except NotFound: pass') else: self.addFilteredChunk(expr, filterArgs, rawPlaceholder, lineCol=lineCol) if self.setting('outputRowColComments'): self.appendToPrevChunk(' # from line %s, col %s' % lineCol + '.') if cacheInfo: self.endCacheRegion() def addSilent(self, expr): self.addChunk( expr ) def addEcho(self, expr, rawExpr=None): self.addFilteredChunk(expr, rawExpr=rawExpr) def addSet(self, expr, exprComponents, setStyle): if setStyle is SET_GLOBAL: (LVALUE, OP, RVALUE) = (exprComponents.LVALUE, exprComponents.OP, exprComponents.RVALUE) # we need to split the LVALUE to deal with globalSetVars splitPos1 = LVALUE.find('.') splitPos2 = LVALUE.find('[') if splitPos1 > 0 and splitPos2==-1: splitPos = splitPos1 elif splitPos1 > 0 and splitPos1 < max(splitPos2,0): splitPos = splitPos1 else: splitPos = splitPos2 if splitPos >0: primary = LVALUE[:splitPos] secondary = LVALUE[splitPos:] else: primary = LVALUE secondary = '' LVALUE = 'self._CHEETAH__globalSetVars["' + primary + '"]' + secondary expr = LVALUE + ' ' + OP + ' ' + RVALUE.strip() if setStyle is SET_MODULE: self._moduleCompiler.addModuleGlobal(expr) else: self.addChunk(expr) def addInclude(self, sourceExpr, includeFrom, isRaw): self.addChunk('self._handleCheetahInclude(' + sourceExpr + ', trans=trans, ' + 'includeFrom="' + includeFrom + '", raw=' + repr(isRaw) + ')') def addWhile(self, expr, lineCol=None): self.addIndentingDirective(expr, lineCol=lineCol) def addFor(self, expr, lineCol=None): self.addIndentingDirective(expr, lineCol=lineCol) def addRepeat(self, expr, lineCol=None): #the _repeatCount stuff here allows nesting of #repeat directives self._repeatCount = getattr(self, "_repeatCount", -1) + 1 self.addFor('for __i%s in range(%s)' % (self._repeatCount,expr), lineCol=lineCol) def addIndentingDirective(self, expr, lineCol=None): if expr and not expr[-1] == ':': expr = expr + ':' self.addChunk( expr ) if lineCol: self.appendToPrevChunk(' # generated from line %s, col %s'%lineCol ) self.indent() def addReIndentingDirective(self, expr, dedent=True, lineCol=None): self.commitStrConst() if dedent: self.dedent() if not expr[-1] == ':': expr = expr + ':' self.addChunk( expr ) if lineCol: self.appendToPrevChunk(' # generated from line %s, col %s'%lineCol ) self.indent() def addIf(self, expr, lineCol=None): """For a full #if ... #end if directive """ self.addIndentingDirective(expr, lineCol=lineCol) def addOneLineIf(self, expr, lineCol=None): """For a full #if ... #end if directive """ self.addIndentingDirective(expr, lineCol=lineCol) def addTernaryExpr(self, conditionExpr, trueExpr, falseExpr, lineCol=None): """For a single-lie #if ... then .... else ... directive then else """ self.addIndentingDirective(conditionExpr, lineCol=lineCol) self.addFilteredChunk(trueExpr) self.dedent() self.addIndentingDirective('else') self.addFilteredChunk(falseExpr) self.dedent() def addElse(self, expr, dedent=True, lineCol=None): expr = re.sub(r'else[ \f\t]+if','elif', expr) self.addReIndentingDirective(expr, dedent=dedent, lineCol=lineCol) def addElif(self, expr, dedent=True, lineCol=None): self.addElse(expr, dedent=dedent, lineCol=lineCol) def addUnless(self, expr, lineCol=None): self.addIf('if not (' + expr + ')') def addClosure(self, functionName, argsList, parserComment): argStringChunks = [] for arg in argsList: chunk = arg[0] if not arg[1] == None: chunk += '=' + arg[1] argStringChunks.append(chunk) signature = "def " + functionName + "(" + ','.join(argStringChunks) + "):" self.addIndentingDirective(signature) self.addChunk('#'+parserComment) def addTry(self, expr, lineCol=None): self.addIndentingDirective(expr, lineCol=lineCol) def addExcept(self, expr, dedent=True, lineCol=None): self.addReIndentingDirective(expr, dedent=dedent, lineCol=lineCol) def addFinally(self, expr, dedent=True, lineCol=None): self.addReIndentingDirective(expr, dedent=dedent, lineCol=lineCol) def addReturn(self, expr): assert not self._isGenerator self.addChunk(expr) self._hasReturnStatement = True def addYield(self, expr): assert not self._hasReturnStatement self._isGenerator = True if expr.replace('yield','').strip(): self.addChunk(expr) else: self.addChunk('if _dummyTrans:') self.indent() self.addChunk('yield trans.response().getvalue()') self.addChunk('trans = DummyTransaction()') self.addChunk('write = trans.response().write') self.dedent() self.addChunk('else:') self.indent() self.addChunk( 'raise TypeError("This method cannot be called with a trans arg")') self.dedent() def addPass(self, expr): self.addChunk(expr) def addDel(self, expr): self.addChunk(expr) def addAssert(self, expr): self.addChunk(expr) def addRaise(self, expr): self.addChunk(expr) def addBreak(self, expr): self.addChunk(expr) def addContinue(self, expr): self.addChunk(expr) def addPSP(self, PSP): self.commitStrConst() autoIndent = False if PSP[0] == '=': PSP = PSP[1:] if PSP: self.addWriteChunk('_filter(' + PSP + ')') return elif PSP.lower() == 'end': self.dedent() return elif PSP[-1] == '$': autoIndent = True PSP = PSP[:-1] elif PSP[-1] == ':': autoIndent = True for line in PSP.splitlines(): self.addChunk(line) if autoIndent: self.indent() def nextCacheID(self): return ('_'+str(random.randrange(100, 999)) + str(random.randrange(10000, 99999))) def startCacheRegion(self, cacheInfo, lineCol, rawPlaceholder=None): # @@TR: we should add some runtime logging to this ID = self.nextCacheID() interval = cacheInfo.get('interval',None) test = cacheInfo.get('test',None) customID = cacheInfo.get('id',None) if customID: ID = customID varyBy = cacheInfo.get('varyBy', repr(ID)) self._cacheRegionsStack.append(ID) # attrib of current methodCompiler # @@TR: add this to a special class var as well self.addChunk('') self.addChunk('## START CACHE REGION: ID='+ID+ '. line %s, col %s'%lineCol + ' in the source.') self.addChunk('_RECACHE_%(ID)s = False'%locals()) self.addChunk('_cacheRegion_%(ID)s = self.getCacheRegion(regionID='%locals() + repr(ID) + ', cacheInfo=%r'%cacheInfo + ')') self.addChunk('if _cacheRegion_%(ID)s.isNew():'%locals()) self.indent() self.addChunk('_RECACHE_%(ID)s = True'%locals()) self.dedent() self.addChunk('_cacheItem_%(ID)s = _cacheRegion_%(ID)s.getCacheItem('%locals() +varyBy+')') self.addChunk('if _cacheItem_%(ID)s.hasExpired():'%locals()) self.indent() self.addChunk('_RECACHE_%(ID)s = True'%locals()) self.dedent() if test: self.addChunk('if ' + test + ':') self.indent() self.addChunk('_RECACHE_%(ID)s = True'%locals()) self.dedent() self.addChunk('if (not _RECACHE_%(ID)s) and _cacheItem_%(ID)s.getRefreshTime():'%locals()) self.indent() #self.addChunk('print "DEBUG"+"-"*50') self.addChunk('try:') self.indent() self.addChunk('_output = _cacheItem_%(ID)s.renderOutput()'%locals()) self.dedent() self.addChunk('except KeyError:') self.indent() self.addChunk('_RECACHE_%(ID)s = True'%locals()) #self.addChunk('print "DEBUG"+"*"*50') self.dedent() self.addChunk('else:') self.indent() self.addWriteChunk('_output') self.addChunk('del _output') self.dedent() self.dedent() self.addChunk('if _RECACHE_%(ID)s or not _cacheItem_%(ID)s.getRefreshTime():'%locals()) self.indent() self.addChunk('_orig_trans%(ID)s = trans'%locals()) self.addChunk('trans = _cacheCollector_%(ID)s = DummyTransaction()'%locals()) self.addChunk('write = _cacheCollector_%(ID)s.response().write'%locals()) if interval: self.addChunk(("_cacheItem_%(ID)s.setExpiryTime(currentTime() +"%locals()) + str(interval) + ")") def endCacheRegion(self): ID = self._cacheRegionsStack.pop() self.addChunk('trans = _orig_trans%(ID)s'%locals()) self.addChunk('write = trans.response().write') self.addChunk('_cacheData = _cacheCollector_%(ID)s.response().getvalue()'%locals()) self.addChunk('_cacheItem_%(ID)s.setData(_cacheData)'%locals()) self.addWriteChunk('_cacheData') self.addChunk('del _cacheData') self.addChunk('del _cacheCollector_%(ID)s'%locals()) self.addChunk('del _orig_trans%(ID)s'%locals()) self.dedent() self.addChunk('## END CACHE REGION: '+ID) self.addChunk('') def nextCallRegionID(self): return self.nextCacheID() def startCallRegion(self, functionName, args, lineCol, regionTitle='CALL'): class CallDetails: pass callDetails = CallDetails() callDetails.ID = ID = self.nextCallRegionID() callDetails.functionName = functionName callDetails.args = args callDetails.lineCol = lineCol callDetails.usesKeywordArgs = False self._callRegionsStack.append((ID, callDetails)) # attrib of current methodCompiler self.addChunk('## START %(regionTitle)s REGION: '%locals() +ID +' of '+functionName +' at line %s, col %s'%lineCol + ' in the source.') self.addChunk('_orig_trans%(ID)s = trans'%locals()) self.addChunk('_wasBuffering%(ID)s = self._CHEETAH__isBuffering'%locals()) self.addChunk('self._CHEETAH__isBuffering = True') self.addChunk('trans = _callCollector%(ID)s = DummyTransaction()'%locals()) self.addChunk('write = _callCollector%(ID)s.response().write'%locals()) def setCallArg(self, argName, lineCol): ID, callDetails = self._callRegionsStack[-1] if callDetails.usesKeywordArgs: self._endCallArg() else: callDetails.usesKeywordArgs = True self.addChunk('_callKws%(ID)s = {}'%locals()) self.addChunk('_currentCallArgname%(ID)s = %(argName)r'%locals()) callDetails.currentArgname = argName def _endCallArg(self): ID, callDetails = self._callRegionsStack[-1] currCallArg = callDetails.currentArgname self.addChunk(('_callKws%(ID)s[%(currCallArg)r] =' ' _callCollector%(ID)s.response().getvalue()')%locals()) self.addChunk('del _callCollector%(ID)s'%locals()) self.addChunk('trans = _callCollector%(ID)s = DummyTransaction()'%locals()) self.addChunk('write = _callCollector%(ID)s.response().write'%locals()) def endCallRegion(self, regionTitle='CALL'): ID, callDetails = self._callRegionsStack[-1] functionName, initialKwArgs, lineCol = ( callDetails.functionName, callDetails.args, callDetails.lineCol) def reset(ID=ID): self.addChunk('trans = _orig_trans%(ID)s'%locals()) self.addChunk('write = trans.response().write') self.addChunk('self._CHEETAH__isBuffering = _wasBuffering%(ID)s '%locals()) self.addChunk('del _wasBuffering%(ID)s'%locals()) self.addChunk('del _orig_trans%(ID)s'%locals()) if not callDetails.usesKeywordArgs: reset() self.addChunk('_callArgVal%(ID)s = _callCollector%(ID)s.response().getvalue()'%locals()) self.addChunk('del _callCollector%(ID)s'%locals()) if initialKwArgs: initialKwArgs = ', '+initialKwArgs self.addFilteredChunk('%(functionName)s(_callArgVal%(ID)s%(initialKwArgs)s)'%locals()) self.addChunk('del _callArgVal%(ID)s'%locals()) else: if initialKwArgs: initialKwArgs = initialKwArgs+', ' self._endCallArg() reset() self.addFilteredChunk('%(functionName)s(%(initialKwArgs)s**_callKws%(ID)s)'%locals()) self.addChunk('del _callKws%(ID)s'%locals()) self.addChunk('## END %(regionTitle)s REGION: '%locals() +ID +' of '+functionName +' at line %s, col %s'%lineCol + ' in the source.') self.addChunk('') self._callRegionsStack.pop() # attrib of current methodCompiler def nextCaptureRegionID(self): return self.nextCacheID() def startCaptureRegion(self, assignTo, lineCol): class CaptureDetails: pass captureDetails = CaptureDetails() captureDetails.ID = ID = self.nextCaptureRegionID() captureDetails.assignTo = assignTo captureDetails.lineCol = lineCol self._captureRegionsStack.append((ID,captureDetails)) # attrib of current methodCompiler self.addChunk('## START CAPTURE REGION: '+ID +' '+assignTo +' at line %s, col %s'%lineCol + ' in the source.') self.addChunk('_orig_trans%(ID)s = trans'%locals()) self.addChunk('_wasBuffering%(ID)s = self._CHEETAH__isBuffering'%locals()) self.addChunk('self._CHEETAH__isBuffering = True') self.addChunk('trans = _captureCollector%(ID)s = DummyTransaction()'%locals()) self.addChunk('write = _captureCollector%(ID)s.response().write'%locals()) def endCaptureRegion(self): ID, captureDetails = self._captureRegionsStack.pop() assignTo, lineCol = (captureDetails.assignTo, captureDetails.lineCol) self.addChunk('trans = _orig_trans%(ID)s'%locals()) self.addChunk('write = trans.response().write') self.addChunk('self._CHEETAH__isBuffering = _wasBuffering%(ID)s '%locals()) self.addChunk('%(assignTo)s = _captureCollector%(ID)s.response().getvalue()'%locals()) self.addChunk('del _orig_trans%(ID)s'%locals()) self.addChunk('del _captureCollector%(ID)s'%locals()) self.addChunk('del _wasBuffering%(ID)s'%locals()) def setErrorCatcher(self, errorCatcherName): self.turnErrorCatcherOn() self.addChunk('if self._CHEETAH__errorCatchers.has_key("' + errorCatcherName + '"):') self.indent() self.addChunk('self._CHEETAH__errorCatcher = self._CHEETAH__errorCatchers["' + errorCatcherName + '"]') self.dedent() self.addChunk('else:') self.indent() self.addChunk('self._CHEETAH__errorCatcher = self._CHEETAH__errorCatchers["' + errorCatcherName + '"] = ErrorCatchers.' + errorCatcherName + '(self)' ) self.dedent() def nextFilterRegionID(self): return self.nextCacheID() def setFilter(self, theFilter, isKlass): class FilterDetails: pass filterDetails = FilterDetails() filterDetails.ID = ID = self.nextFilterRegionID() filterDetails.theFilter = theFilter filterDetails.isKlass = isKlass self._filterRegionsStack.append((ID, filterDetails)) # attrib of current methodCompiler self.addChunk('_orig_filter%(ID)s = _filter'%locals()) if isKlass: self.addChunk('_filter = self._CHEETAH__currentFilter = ' + theFilter.strip() + '(self).filter') else: if theFilter.lower() == 'none': self.addChunk('_filter = self._CHEETAH__initialFilter') else: # is string representing the name of a builtin filter self.addChunk('filterName = ' + repr(theFilter)) self.addChunk('if self._CHEETAH__filters.has_key("' + theFilter + '"):') self.indent() self.addChunk('_filter = self._CHEETAH__currentFilter = self._CHEETAH__filters[filterName]') self.dedent() self.addChunk('else:') self.indent() self.addChunk('_filter = self._CHEETAH__currentFilter' +' = \\\n\t\t\tself._CHEETAH__filters[filterName] = ' + 'getattr(self._CHEETAH__filtersLib, filterName)(self).filter') self.dedent() def closeFilterBlock(self): ID, filterDetails = self._filterRegionsStack.pop() #self.addChunk('_filter = self._CHEETAH__initialFilter') self.addChunk('_filter = _orig_filter%(ID)s'%locals()) class AutoMethodCompiler(MethodCompiler): def _setupState(self): MethodCompiler._setupState(self) self._argStringList = [ ("self",None) ] self._streamingEnabled = True def _useKWsDictArgForPassingTrans(self): alreadyHasTransArg = [argname for argname,defval in self._argStringList if argname=='trans'] return (self.methodName()!='respond' and not alreadyHasTransArg and self.setting('useKWsDictArgForPassingTrans')) def cleanupState(self): MethodCompiler.cleanupState(self) self.commitStrConst() if self._cacheRegionsStack: self.endCacheRegion() if self._callRegionsStack: self.endCallRegion() if self._streamingEnabled: kwargsName = None positionalArgsListName = None for argname,defval in self._argStringList: if argname.strip().startswith('**'): kwargsName = argname.strip().replace('**','') break elif argname.strip().startswith('*'): positionalArgsListName = argname.strip().replace('*','') if not kwargsName and self._useKWsDictArgForPassingTrans(): kwargsName = 'KWS' self.addMethArg('**KWS', None) self._kwargsName = kwargsName if not self._useKWsDictArgForPassingTrans(): if not kwargsName and not positionalArgsListName: self.addMethArg('trans', 'None') else: self._streamingEnabled = False self._indentLev = self.setting('initialMethIndentLevel') mainBodyChunks = self._methodBodyChunks self._methodBodyChunks = [] self._addAutoSetupCode() self._methodBodyChunks.extend(mainBodyChunks) self._addAutoCleanupCode() def _addAutoSetupCode(self): if self._initialMethodComment: self.addChunk(self._initialMethodComment) if self._streamingEnabled: if self._useKWsDictArgForPassingTrans() and self._kwargsName: self.addChunk('trans = %s.get("trans")'%self._kwargsName) self.addChunk('if (not trans and not self._CHEETAH__isBuffering' ' and not callable(self.transaction)):') self.indent() self.addChunk('trans = self.transaction' ' # is None unless self.awake() was called') self.dedent() self.addChunk('if not trans:') self.indent() self.addChunk('trans = DummyTransaction()') if self.setting('autoAssignDummyTransactionToSelf'): self.addChunk('self.transaction = trans') self.addChunk('_dummyTrans = True') self.dedent() self.addChunk('else: _dummyTrans = False') else: self.addChunk('trans = DummyTransaction()') self.addChunk('_dummyTrans = True') self.addChunk('write = trans.response().write') if self.setting('useNameMapper'): argNames = [arg[0] for arg in self._argStringList] allowSearchListAsMethArg = self.setting('allowSearchListAsMethArg') if allowSearchListAsMethArg and 'SL' in argNames: pass elif allowSearchListAsMethArg and 'searchList' in argNames: self.addChunk('SL = searchList') else: self.addChunk('SL = self._CHEETAH__searchList') if self.setting('useFilters'): self.addChunk('_filter = self._CHEETAH__currentFilter') self.addChunk('') self.addChunk("#" *40) self.addChunk('## START - generated method body') self.addChunk('') def _addAutoCleanupCode(self): self.addChunk('') self.addChunk("#" *40) self.addChunk('## END - generated method body') self.addChunk('') if not self._isGenerator: self.addStop() self.addChunk('') def addStop(self, expr=None): self.addChunk('return _dummyTrans and trans.response().getvalue() or ""') def addMethArg(self, name, defVal=None): self._argStringList.append( (name,defVal) ) def methodSignature(self): argStringChunks = [] for arg in self._argStringList: chunk = arg[0] if not arg[1] == None: chunk += '=' + arg[1] argStringChunks.append(chunk) argString = (', ').join(argStringChunks) output = [] if self._decorator: output.append(self._indent + self._decorator+'\n') output.append(self._indent + "def " + self.methodName() + "(" + argString + "):\n\n") return ''.join(output) ################################################## ## CLASS COMPILERS _initMethod_initCheetah = """\ if not self._CHEETAH__instanceInitialized: cheetahKWArgs = {} allowedKWs = 'searchList namespaces filter filtersLib errorCatcher'.split() for k,v in KWs.items(): if k in allowedKWs: cheetahKWArgs[k] = v self._initCheetahInstance(**cheetahKWArgs) """.replace('\n','\n'+' '*8) class ClassCompiler(GenUtils): methodCompilerClass = AutoMethodCompiler methodCompilerClassForInit = MethodCompiler def __init__(self, className, mainMethodName='respond', moduleCompiler=None, fileName=None, settingsManager=None): self._settingsManager = settingsManager self._fileName = fileName self._className = className self._moduleCompiler = moduleCompiler self._mainMethodName = mainMethodName self._setupState() methodCompiler = self._spawnMethodCompiler( mainMethodName, initialMethodComment='## CHEETAH: main method generated for this template') self._setActiveMethodCompiler(methodCompiler) if fileName and self.setting('monitorSrcFile'): self._addSourceFileMonitoring(fileName) def setting(self, key): return self._settingsManager.setting(key) def __getattr__(self, name): """Provide access to the methods and attributes of the MethodCompiler at the top of the activeMethods stack: one-way namespace sharing WARNING: Use .setMethods to assign the attributes of the MethodCompiler from the methods of this class!!! or you will be assigning to attributes of this object instead.""" if self.__dict__.has_key(name): return self.__dict__[name] elif hasattr(self.__class__, name): return getattr(self.__class__, name) elif self._activeMethodsList and hasattr(self._activeMethodsList[-1], name): return getattr(self._activeMethodsList[-1], name) else: raise AttributeError, name def _setupState(self): self._classDef = None self._decoratorForNextMethod = None self._activeMethodsList = [] # stack while parsing/generating self._finishedMethodsList = [] # store by order self._methodsIndex = {} # store by name self._baseClass = 'Template' self._classDocStringLines = [] # printed after methods in the gen class def: self._generatedAttribs = ['_CHEETAH__instanceInitialized = False'] self._generatedAttribs.append('_CHEETAH_version = __CHEETAH_version__') self._generatedAttribs.append( '_CHEETAH_versionTuple = __CHEETAH_versionTuple__') if self.setting('addTimestampsToCompilerOutput'): self._generatedAttribs.append('_CHEETAH_genTime = __CHEETAH_genTime__') self._generatedAttribs.append('_CHEETAH_genTimestamp = __CHEETAH_genTimestamp__') self._generatedAttribs.append('_CHEETAH_src = __CHEETAH_src__') self._generatedAttribs.append( '_CHEETAH_srcLastModified = __CHEETAH_srcLastModified__') if self.setting('templateMetaclass'): self._generatedAttribs.append('__metaclass__ = '+self.setting('templateMetaclass')) self._initMethChunks = [] self._blockMetaData = {} self._errorCatcherCount = 0 self._placeholderToErrorCatcherMap = {} def cleanupState(self): while self._activeMethodsList: methCompiler = self._popActiveMethodCompiler() self._swallowMethodCompiler(methCompiler) self._setupInitMethod() if self._mainMethodName == 'respond': if self.setting('setup__str__method'): self._generatedAttribs.append('def __str__(self): return self.respond()') self.addAttribute('_mainCheetahMethod_for_' + self._className + '= ' + repr(self._mainMethodName) ) def _setupInitMethod(self): __init__ = self._spawnMethodCompiler('__init__', klass=self.methodCompilerClassForInit) __init__.setMethodSignature("def __init__(self, *args, **KWs)") __init__.addChunk("%s.__init__(self, *args, **KWs)" % self._baseClass) __init__.addChunk(_initMethod_initCheetah%{'className':self._className}) for chunk in self._initMethChunks: __init__.addChunk(chunk) __init__.cleanupState() self._swallowMethodCompiler(__init__, pos=0) def _addSourceFileMonitoring(self, fileName): # @@TR: this stuff needs auditing for Cheetah 2.0 # the first bit is added to init self.addChunkToInit('self._filePath = ' + repr(fileName)) self.addChunkToInit('self._fileMtime = ' + str(getmtime(fileName)) ) # the rest is added to the main output method of the class ('mainMethod') self.addChunk('if exists(self._filePath) and ' + 'getmtime(self._filePath) > self._fileMtime:') self.indent() self.addChunk('self._compile(file=self._filePath, moduleName='+self._className + ')') self.addChunk( 'write(getattr(self, self._mainCheetahMethod_for_' + self._className + ')(trans=trans))') self.addStop() self.dedent() def setClassName(self, name): self._className = name def className(self): return self._className def setBaseClass(self, baseClassName): self._baseClass = baseClassName def setMainMethodName(self, methodName): if methodName == self._mainMethodName: return ## change the name in the methodCompiler and add new reference mainMethod = self._methodsIndex[self._mainMethodName] mainMethod.setMethodName(methodName) self._methodsIndex[methodName] = mainMethod ## make sure that fileUpdate code still works properly: chunkToChange = ('write(self.' + self._mainMethodName + '(trans=trans))') chunks = mainMethod._methodBodyChunks if chunkToChange in chunks: for i in range(len(chunks)): if chunks[i] == chunkToChange: chunks[i] = ('write(self.' + methodName + '(trans=trans))') ## get rid of the old reference and update self._mainMethodName del self._methodsIndex[self._mainMethodName] self._mainMethodName = methodName def setMainMethodArgs(self, argsList): mainMethodCompiler = self._methodsIndex[self._mainMethodName] for argName, defVal in argsList: mainMethodCompiler.addMethArg(argName, defVal) def _spawnMethodCompiler(self, methodName, klass=None, initialMethodComment=None): if klass is None: klass = self.methodCompilerClass decorator = None if self._decoratorForNextMethod: decorator = self._decoratorForNextMethod self._decoratorForNextMethod = None methodCompiler = klass(methodName, classCompiler=self, decorator=decorator, initialMethodComment=initialMethodComment) self._methodsIndex[methodName] = methodCompiler return methodCompiler def _setActiveMethodCompiler(self, methodCompiler): self._activeMethodsList.append(methodCompiler) def _getActiveMethodCompiler(self): return self._activeMethodsList[-1] def _popActiveMethodCompiler(self): return self._activeMethodsList.pop() def _swallowMethodCompiler(self, methodCompiler, pos=None): methodCompiler.cleanupState() if pos==None: self._finishedMethodsList.append( methodCompiler ) else: self._finishedMethodsList.insert(pos, methodCompiler) return methodCompiler def startMethodDef(self, methodName, argsList, parserComment): methodCompiler = self._spawnMethodCompiler( methodName, initialMethodComment=parserComment) self._setActiveMethodCompiler(methodCompiler) for argName, defVal in argsList: methodCompiler.addMethArg(argName, defVal) def _finishedMethods(self): return self._finishedMethodsList def addDecorator(self, decoratorExpr): """Set the decorator to be used with the next method in the source. See _spawnMethodCompiler() and MethodCompiler for the details of how this is used. """ self._decoratorForNextMethod = decoratorExpr def addClassDocString(self, line): self._classDocStringLines.append( line.replace('%','%%')) def addChunkToInit(self,chunk): self._initMethChunks.append(chunk) def addAttribute(self, attribExpr): ## first test to make sure that the user hasn't used any fancy Cheetah syntax # (placeholders, directives, etc.) inside the expression if attribExpr.find('VFN(') != -1 or attribExpr.find('VFFSL(') != -1: raise ParseError(self, 'Invalid #attr directive.' + ' It should only contain simple Python literals.') ## now add the attribute self._generatedAttribs.append(attribExpr) def addSuper(self, argsList, parserComment=None): className = self._className #self._baseClass methodName = self._getActiveMethodCompiler().methodName() argStringChunks = [] for arg in argsList: chunk = arg[0] if not arg[1] == None: chunk += '=' + arg[1] argStringChunks.append(chunk) argString = ','.join(argStringChunks) self.addFilteredChunk( 'super(%(className)s, self).%(methodName)s(%(argString)s)'%locals()) def addErrorCatcherCall(self, codeChunk, rawCode='', lineCol=''): if self._placeholderToErrorCatcherMap.has_key(rawCode): methodName = self._placeholderToErrorCatcherMap[rawCode] if not self.setting('outputRowColComments'): self._methodsIndex[methodName].addMethDocString( 'plus at line %s, col %s'%lineCol) return methodName self._errorCatcherCount += 1 methodName = '__errorCatcher' + str(self._errorCatcherCount) self._placeholderToErrorCatcherMap[rawCode] = methodName catcherMeth = self._spawnMethodCompiler( methodName, klass=MethodCompiler, initialMethodComment=('## CHEETAH: Generated from ' + rawCode + ' at line %s, col %s'%lineCol + '.') ) catcherMeth.setMethodSignature('def ' + methodName + '(self, localsDict={})') # is this use of localsDict right? catcherMeth.addChunk('try:') catcherMeth.indent() catcherMeth.addChunk("return eval('''" + codeChunk + "''', globals(), localsDict)") catcherMeth.dedent() catcherMeth.addChunk('except self._CHEETAH__errorCatcher.exceptions(), e:') catcherMeth.indent() catcherMeth.addChunk("return self._CHEETAH__errorCatcher.warn(exc_val=e, code= " + repr(codeChunk) + " , rawCode= " + repr(rawCode) + " , lineCol=" + str(lineCol) +")") catcherMeth.cleanupState() self._swallowMethodCompiler(catcherMeth) return methodName def closeDef(self): self.commitStrConst() methCompiler = self._popActiveMethodCompiler() self._swallowMethodCompiler(methCompiler) def closeBlock(self): self.commitStrConst() methCompiler = self._popActiveMethodCompiler() methodName = methCompiler.methodName() if self.setting('includeBlockMarkers'): endMarker = self.setting('blockMarkerEnd') methCompiler.addStrConst(endMarker[0] + methodName + endMarker[1]) self._swallowMethodCompiler(methCompiler) #metaData = self._blockMetaData[methodName] #rawDirective = metaData['raw'] #lineCol = metaData['lineCol'] ## insert the code to call the block, caching if #cache directive is on codeChunk = 'self.' + methodName + '(trans=trans)' self.addChunk(codeChunk) #self.appendToPrevChunk(' # generated from ' + repr(rawDirective) ) #if self.setting('outputRowColComments'): # self.appendToPrevChunk(' at line %s, col %s' % lineCol + '.') ## code wrapping methods def classDef(self): if self._classDef: return self._classDef else: return self.wrapClassDef() __str__ = classDef __unicode__ = classDef def wrapClassDef(self): ind = self.setting('indentationStep') classDefChunks = [self.classSignature(), self.classDocstring(), ] def addMethods(): classDefChunks.extend([ ind + '#'*50, ind + '## CHEETAH GENERATED METHODS', '\n', self.methodDefs(), ]) def addAttributes(): classDefChunks.extend([ ind + '#'*50, ind + '## CHEETAH GENERATED ATTRIBUTES', '\n', self.attributes(), ]) if self.setting('outputMethodsBeforeAttributes'): addMethods() addAttributes() else: addAttributes() addMethods() classDef = '\n'.join(classDefChunks) self._classDef = classDef return classDef def classSignature(self): return "class %s(%s):" % (self.className(), self._baseClass) def classDocstring(self): if not self._classDocStringLines: return '' ind = self.setting('indentationStep') docStr = ('%(ind)s"""\n%(ind)s' + '\n%(ind)s'.join(self._classDocStringLines) + '\n%(ind)s"""\n' ) % {'ind':ind} return docStr def methodDefs(self): methodDefs = [methGen.methodDef() for methGen in self._finishedMethods()] return '\n\n'.join(methodDefs) def attributes(self): attribs = [self.setting('indentationStep') + str(attrib) for attrib in self._generatedAttribs ] return '\n\n'.join(attribs) class AutoClassCompiler(ClassCompiler): pass ################################################## ## MODULE COMPILERS class ModuleCompiler(SettingsManager, GenUtils): parserClass = Parser classCompilerClass = AutoClassCompiler def __init__(self, source=None, file=None, moduleName='DynamicallyCompiledCheetahTemplate', mainClassName=None, # string mainMethodName=None, # string baseclassName=None, # string extraImportStatements=None, # list of strings settings=None # dict ): SettingsManager.__init__(self) if settings: self.updateSettings(settings) # disable useStackFrames if the C version of NameMapper isn't compiled # it's painfully slow in the Python version and bites Windows users all # the time: if not NameMapper.C_VERSION: if not sys.platform.startswith('java'): warnings.warn( "\nYou don't have the C version of NameMapper installed! " "I'm disabling Cheetah's useStackFrames option as it is " "painfully slow with the Python version of NameMapper. " "You should get a copy of Cheetah with the compiled C version of NameMapper." ) self.setSetting('useStackFrames', False) self._compiled = False self._moduleName = moduleName if not mainClassName: self._mainClassName = moduleName else: self._mainClassName = mainClassName self._mainMethodNameArg = mainMethodName if mainMethodName: self.setSetting('mainMethodName', mainMethodName) self._baseclassName = baseclassName self._filePath = None self._fileMtime = None if source and file: raise TypeError("Cannot compile from a source string AND file.") elif isinstance(file, (str, unicode)): # it's a filename. f = open(file) # Raises IOError. source = f.read() f.close() self._filePath = file self._fileMtime = os.path.getmtime(file) elif hasattr(file, 'read'): source = file.read() # Can't set filename or mtime--they're not accessible. elif file: raise TypeError("'file' argument must be a filename string or file-like object") if self._filePath: 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) # by converting to string here we allow objects such as other Templates # to be passed in # Handle the #indent directive by converting it to other directives. # (Over the long term we'll make it a real directive.) if source == "": warnings.warn("You supplied an empty string for the source!", ) else: unicodeMatch = unicodeDirectiveRE.search(source) if unicodeMatch: if encodingDirectiveRE.match(source): raise ParseError( self, "#encoding and #unicode are mutually exclusive! " "Use one or the other.") source = unicodeDirectiveRE.sub('', source) if isinstance(source, str): encoding = unicodeMatch.group(1) or 'ascii' source = unicode(source, encoding) #print encoding if source.find('#indent') != -1: #@@TR: undocumented hack source = indentize(source) self._parser = self.parserClass(source, filename=self._filePath, compiler=self) self._setupCompilerState() def __getattr__(self, name): """Provide one-way access to the methods and attributes of the ClassCompiler, and thereby the MethodCompilers as well. WARNING: Use .setMethods to assign the attributes of the ClassCompiler from the methods of this class!!! or you will be assigning to attributes of this object instead. """ if self.__dict__.has_key(name): return self.__dict__[name] elif hasattr(self.__class__, name): return getattr(self.__class__, name) elif self._activeClassesList and hasattr(self._activeClassesList[-1], name): return getattr(self._activeClassesList[-1], name) else: raise AttributeError, name def _initializeSettings(self): self.updateSettings(copy.deepcopy(DEFAULT_COMPILER_SETTINGS)) def _setupCompilerState(self): self._activeClassesList = [] self._finishedClassesList = [] # listed by ordered self._finishedClassIndex = {} # listed by name self._moduleDef = None self._moduleShBang = '#!/usr/bin/env python' self._moduleEncoding = 'ascii' self._moduleEncodingStr = '' self._moduleHeaderLines = [] self._moduleDocStringLines = [] self._specialVars = {} self._importStatements = [ "import sys", "import os", "import os.path", "from os.path import getmtime, exists", "import time", "import types", "import __builtin__", "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.NameMapper import NotFound, valueForName, valueFromSearchList, valueFromFrameOrSearchList", "from Cheetah.CacheRegion import CacheRegion", "import Cheetah.Filters as Filters", "import Cheetah.ErrorCatchers as ErrorCatchers", ] self._importedVarNames = ['sys', 'os', 'os.path', 'time', 'types', 'Template', 'DummyTransaction', 'NotFound', 'Filters', 'ErrorCatchers', 'CacheRegion', ] self._moduleConstants = [ "try:", " True, False", "except NameError:", " True, False = (1==1), (1==0)", "VFFSL=valueFromFrameOrSearchList", "VFSL=valueFromSearchList", "VFN=valueForName", "currentTime=time.time", ] def compile(self): classCompiler = self._spawnClassCompiler(self._mainClassName) if self._baseclassName: classCompiler.setBaseClass(self._baseclassName) self._addActiveClassCompiler(classCompiler) self._parser.parse() self._swallowClassCompiler(self._popActiveClassCompiler()) self._compiled = True self._parser.cleanup() def _spawnClassCompiler(self, className, klass=None): if klass is None: klass = self.classCompilerClass classCompiler = klass(className, moduleCompiler=self, mainMethodName=self.setting('mainMethodName'), fileName=self._filePath, settingsManager=self, ) return classCompiler def _addActiveClassCompiler(self, classCompiler): self._activeClassesList.append(classCompiler) def _getActiveClassCompiler(self): return self._activeClassesList[-1] def _popActiveClassCompiler(self): return self._activeClassesList.pop() def _swallowClassCompiler(self, classCompiler): classCompiler.cleanupState() self._finishedClassesList.append( classCompiler ) self._finishedClassIndex[classCompiler.className()] = classCompiler return classCompiler def _finishedClasses(self): return self._finishedClassesList def importedVarNames(self): return self._importedVarNames def addImportedVarNames(self, varNames): self._importedVarNames.extend(varNames) ## methods for adding stuff to the module and class definitions def setBaseClass(self, baseClassName): if self._mainMethodNameArg: self.setMainMethodName(self._mainMethodNameArg) else: self.setMainMethodName(self.setting('mainMethodNameForSubclasses')) if self.setting('handlerForExtendsDirective'): handler = self.setting('handlerForExtendsDirective') baseClassName = handler(compiler=self, baseClassName=baseClassName) self._getActiveClassCompiler().setBaseClass(baseClassName) elif (not self.setting('autoImportForExtendsDirective') or baseClassName=='object' or baseClassName in self.importedVarNames()): self._getActiveClassCompiler().setBaseClass(baseClassName) # no need to import else: ################################################## ## If the #extends directive contains a classname or modulename that isn't # in self.importedVarNames() already, we assume that we need to add # an implied 'from ModName import ClassName' where ModName == ClassName. # - This is the case in WebKit servlet modules. # - We also assume that the final . separates the classname from the # module name. This might break if people do something really fancy # with their dots and namespaces. chunks = baseClassName.split('.') if len(chunks)==1: self._getActiveClassCompiler().setBaseClass(baseClassName) if baseClassName not in self.importedVarNames(): modName = baseClassName # we assume the class name to be the module name # and that it's not a builtin: importStatement = "from %s import %s" % (modName, baseClassName) self.addImportStatement(importStatement) self.addImportedVarNames( [baseClassName,] ) else: needToAddImport = True modName = chunks[0] #print chunks, ':', self.importedVarNames() for chunk in chunks[1:-1]: if modName in self.importedVarNames(): needToAddImport = False finalBaseClassName = baseClassName.replace(modName+'.', '') self._getActiveClassCompiler().setBaseClass(finalBaseClassName) break else: modName += '.'+chunk if needToAddImport: modName, finalClassName = '.'.join(chunks[:-1]), chunks[-1] #if finalClassName != chunks[:-1][-1]: if finalClassName != chunks[-2]: # we assume the class name to be the module name modName = '.'.join(chunks) self._getActiveClassCompiler().setBaseClass(finalClassName) importStatement = "from %s import %s" % (modName, finalClassName) self.addImportStatement(importStatement) self.addImportedVarNames( [finalClassName,] ) def setCompilerSetting(self, key, valueExpr): self.setSetting(key, eval(valueExpr) ) self._parser.configureParser() def setCompilerSettings(self, keywords, settingsStr): KWs = keywords merge = True if 'nomerge' in KWs: merge = False if 'reset' in KWs: # @@TR: this is actually caught by the parser at the moment. # subject to change in the future self._initializeSettings() self._parser.configureParser() return elif 'python' in KWs: settingsReader = self.updateSettingsFromPySrcStr # this comes from SettingsManager else: # this comes from SettingsManager settingsReader = self.updateSettingsFromConfigStr settingsReader(settingsStr) self._parser.configureParser() def setShBang(self, shBang): self._moduleShBang = shBang def setModuleEncoding(self, encoding): self._moduleEncoding = encoding self._moduleEncodingStr = '# -*- coding: %s -*-' %encoding def getModuleEncoding(self): return self._moduleEncoding def addModuleHeader(self, line): """Adds a header comment to the top of the generated module. """ self._moduleHeaderLines.append(line) def addModuleDocString(self, line): """Adds a line to the generated module docstring. """ self._moduleDocStringLines.append(line) def addModuleGlobal(self, line): """Adds a line of global module code. It is inserted after the import statements and Cheetah default module constants. """ self._moduleConstants.append(line) def addSpecialVar(self, basename, contents, includeUnderscores=True): """Adds module __specialConstant__ to the module globals. """ name = includeUnderscores and '__'+basename+'__' or basename self._specialVars[name] = contents.strip() def addImportStatement(self, impStatement): 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(',') importVarNames = [var.split()[-1] for var in importVarNames] # handles aliases importVarNames = [var for var in importVarNames if var!='*'] self.addImportedVarNames(importVarNames) #used by #extend for auto-imports def addAttribute(self, attribName, expr): self._getActiveClassCompiler().addAttribute(attribName + ' =' + expr) def addComment(self, comm): if re.match(r'#+$',comm): # skip bar comments return specialVarMatch = specialVarRE.match(comm) if specialVarMatch: # @@TR: this is a bit hackish and is being replaced with # #set module varName = ... return self.addSpecialVar(specialVarMatch.group(1), comm[specialVarMatch.end():]) elif comm.startswith('doc:'): addLine = self.addMethDocString comm = comm[len('doc:'):].strip() elif comm.startswith('doc-method:'): addLine = self.addMethDocString comm = comm[len('doc-method:'):].strip() elif comm.startswith('doc-module:'): addLine = self.addModuleDocString comm = comm[len('doc-module:'):].strip() elif comm.startswith('doc-class:'): addLine = self.addClassDocString comm = comm[len('doc-class:'):].strip() elif comm.startswith('header:'): addLine = self.addModuleHeader comm = comm[len('header:'):].strip() else: addLine = self.addMethComment for line in comm.splitlines(): addLine(line) ## methods for module code wrapping def getModuleCode(self): if not self._compiled: self.compile() if self._moduleDef: return self._moduleDef else: return self.wrapModuleDef() __str__ = getModuleCode def wrapModuleDef(self): self.addSpecialVar('CHEETAH_docstring', self.setting('defDocStrMsg')) self.addModuleGlobal('__CHEETAH_version__ = %r'%Version) self.addModuleGlobal('__CHEETAH_versionTuple__ = %r'%(VersionTuple,)) if self.setting('addTimestampsToCompilerOutput'): self.addModuleGlobal('__CHEETAH_genTime__ = %r'%time.time()) self.addModuleGlobal('__CHEETAH_genTimestamp__ = %r'%self.timestamp()) if self._filePath: timestamp = self.timestamp(self._fileMtime) self.addModuleGlobal('__CHEETAH_src__ = %r'%self._filePath) self.addModuleGlobal('__CHEETAH_srcLastModified__ = %r'%timestamp) else: self.addModuleGlobal('__CHEETAH_src__ = None') self.addModuleGlobal('__CHEETAH_srcLastModified__ = None') moduleDef = """%(header)s %(docstring)s ################################################## ## DEPENDENCIES %(imports)s ################################################## ## MODULE CONSTANTS %(constants)s %(specialVars)s if __CHEETAH_versionTuple__ < RequiredCheetahVersionTuple: raise AssertionError( 'This template was compiled with Cheetah version' ' %%s. Templates compiled before version %%s must be recompiled.'%%( __CHEETAH_version__, RequiredCheetahVersion)) ################################################## ## CLASSES %(classes)s ## END CLASS DEFINITION if not hasattr(%(mainClassName)s, '_initCheetahAttributes'): templateAPIClass = getattr(%(mainClassName)s, '_CHEETAH_templateClass', Template) templateAPIClass._addCheetahPlumbingCodeToClass(%(mainClassName)s) %(footer)s """ % {'header':self.moduleHeader(), 'docstring':self.moduleDocstring(), 'specialVars':self.specialVars(), 'imports':self.importStatements(), 'constants':self.moduleConstants(), 'classes':self.classDefs(), 'footer':self.moduleFooter(), 'mainClassName':self._mainClassName, } self._moduleDef = moduleDef return moduleDef def timestamp(self, theTime=None): if not theTime: theTime = time.time() return time.asctime(time.localtime(theTime)) def moduleHeader(self): header = self._moduleShBang + '\n' header += self._moduleEncodingStr + '\n' if self._moduleHeaderLines: offSet = self.setting('commentOffset') header += ( '#' + ' '*offSet + ('\n#'+ ' '*offSet).join(self._moduleHeaderLines) + '\n') return header def moduleDocstring(self): if not self._moduleDocStringLines: return '' return ('"""' + '\n'.join(self._moduleDocStringLines) + '\n"""\n') def specialVars(self): chunks = [] theVars = self._specialVars keys = theVars.keys() keys.sort() for key in keys: chunks.append(key + ' = ' + repr(theVars[key]) ) return '\n'.join(chunks) def importStatements(self): return '\n'.join(self._importStatements) def moduleConstants(self): return '\n'.join(self._moduleConstants) def classDefs(self): classDefs = [klass.classDef() for klass in self._finishedClasses()] return '\n\n'.join(classDefs) def moduleFooter(self): return """ # CHEETAH was developed by Tavis Rudd and Mike Orr # with code, advice and input from many other volunteers. # For more information visit http://www.CheetahTemplate.org/ ################################################## ## if run from command line: if __name__ == '__main__': from Cheetah.TemplateCmdLineIface import CmdLineIface CmdLineIface(templateObj=%(className)s()).run() """ % {'className':self._mainClassName} ################################################## ## Make Compiler an alias for ModuleCompiler Compiler = ModuleCompiler PK-4V\00Cheetah/__init__.py#!/usr/bin/env python # $Id: __init__.py,v 1.10 2006/01/14 04:44:07 tavis_rudd Exp $ """Cheetah is an open source template engine and code generation tool. It can be used standalone or combined with other tools and frameworks. Web development is its principle use, but Cheetah is very flexible and is also being used to generate C++ game code, Java, sql, form emails and even Python code. Homepage ================================================================================ http://www.CheetahTemplate.org/ Documentation ================================================================================ For a high-level introduction to Cheetah please refer to the User's Guide at http://cheetahtemplate.org/learn.html Mailing list ================================================================================ cheetahtemplate-discuss@lists.sourceforge.net Subscribe at http://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss """ __author__ = "Tavis Rudd " __revision__ = "$Revision: 1.10 $"[11:-2] from Version import Version PK(8մ??Cheetah/NameMapper.pyc; Fc@sdZdklZddZddd!ZdkZdklZlZlZl Z d k l Z dk Z e ZeZd d d d dddgZd efdYZdZdZdZdZe dZe dZe dZedZe edZe edZdZy5dk lZlZlZlZlZlZeZ!Wn e Z!nXdfdYZ"d Z#e$d!jo e#ndS("sThis module supports Cheetah's optional NameMapper syntax. Overview ================================================================================ NameMapper provides a simple syntax for accessing Python data structures, functions, and methods from Cheetah. It's called NameMapper because it 'maps' simple 'names' in Cheetah templates to possibly more complex syntax in Python. Its purpose is to make working with Cheetah easy for non-programmers. Specifically, non-programmers using Cheetah should NOT need to be taught (a) what the difference is between an object and a dictionary, (b) what functions and methods are, and (c) what 'self' is. A further aim (d) is to buffer the code in Cheetah templates from changes in the implementation of the Python data structures behind them. Consider this scenario: You are building a customer information system. The designers with you want to use information from your system on the client's website --AND-- they want to understand the display code and so they can maintian it themselves. You write a UI class with a 'customers' method that returns a dictionary of all the customer objects. Each customer object has an 'address' method that returns the a dictionary with information about the customer's address. The designers want to be able to access that information. Using PSP, the display code for the website would look something like the following, assuming your servlet subclasses the class you created for managing customer information: <%= self.customer()[ID].address()['city'] %> (42 chars) Using Cheetah's NameMapper syntax it could be any of the following: $self.customers()[$ID].address()['city'] (39 chars) --OR-- $customers()[$ID].address()['city'] --OR-- $customers()[$ID].address().city --OR-- $customers()[$ID].address.city --OR-- $customers()[$ID].address.city --OR-- $customers[$ID].address.city (27 chars) Which of these would you prefer to explain to the designers, who have no programming experience? The last form is 15 characters shorter than the PSP and, conceptually, is far more accessible. With PHP or ASP, the code would be even messier than the PSP This is a rather extreme example and, of course, you could also just implement '$getCustomer($ID).city' and obey the Law of Demeter (search Google for more on that). But good object orientated design isn't the point here. Details ================================================================================ The parenthesized letters below correspond to the aims in the second paragraph. DICTIONARY ACCESS (a) --------------------- NameMapper allows access to items in a dictionary using the same dotted notation used to access object attributes in Python. This aspect of NameMapper is known as 'Unified Dotted Notation'. For example, with Cheetah it is possible to write: $customers()['kerr'].address() --OR-- $customers().kerr.address() where the second form is in NameMapper syntax. This only works with dictionary keys that are also valid python identifiers: regex = '[a-zA-Z_][a-zA-Z_0-9]*' AUTOCALLING (b,d) ----------------- NameMapper automatically detects functions and methods in Cheetah $vars and calls them if the parentheses have been left off. For example if 'a' is an object, 'b' is a method $a.b is equivalent to $a.b() If b returns a dictionary, then following variations are possible $a.b.c --OR-- $a.b().c --OR-- $a.b()['c'] where 'c' is a key in the dictionary that a.b() returns. Further notes: * NameMapper autocalls the function or method without any arguments. Thus autocalling can only be used with functions or methods that either have no arguments or have default values for all arguments. * NameMapper only autocalls functions and methods. Classes and callable object instances will not be autocalled. * Autocalling can be disabled using Cheetah's 'useAutocalling' setting. LEAVING OUT 'self' (c,d) ------------------------ NameMapper makes it possible to access the attributes of a servlet in Cheetah without needing to include 'self' in the variable names. See the NAMESPACE CASCADING section below for details. NAMESPACE CASCADING (d) -------------------- ... Implementation details ================================================================================ * NameMapper's search order is dictionary keys then object attributes * NameMapper.NotFound is raised if a value can't be found for a name. Performance and the C version ================================================================================ Cheetah comes with both a C version and a Python version of NameMapper. The C version is significantly faster and the exception tracebacks are much easier to read. It's still slower than standard Python syntax, but you won't notice the difference in realistic usage scenarios. Cheetah uses the optimized C version (_namemapper.c) if it has been compiled or falls back to the Python version if not. Meta-Data ================================================================================ Authors: Tavis Rudd , Chuck Esterbrook Version: $Revision: 1.30 $ Start Date: 2001/04/03 Last Revision Date: $Date: 2007/04/03 01:58:20 $ (s generatorss"Tavis Rudd ,s) Chuck Esterbrook s$Revision: 1.30 $i iN(s StringTypes InstanceTypes ClassTypesTypeType(spformatsNotFoundshasKeys valueForKeys valueForNamesvalueFromSearchListsvalueFromFrameOrSearchListsvalueFromFramecBstZRS(N(s__name__s __module__(((s7build/bdist.darwin-8.0.1-i386/egg/Cheetah/NameMapper.pysNotFoundscCs9d|}to|dt|7}nt|dS(Nscannot find '%s's in the namespace %s(skeys excStrings._INCLUDE_NAMESPACE_REPR_IN_NOTFOUND_EXCEPTIONSspformats namespacesNotFound(skeys namespaces excString((s7build/bdist.darwin-8.0.1-i386/egg/Cheetah/NameMapper.pys_raiseNotFoundExceptions cCsvt ond|id}|iddjo=|d|7}to|dt|7}n|f|_ndS(Niswhile searchingis while searching for '%s's in the namespace %s( s&_ALLOW_WRAPPING_OF_NOTFOUND_EXCEPTIONSsexcsargssexcStrsfindsfullNames._INCLUDE_NAMESPACE_REPR_IN_NOTFOUND_EXCEPTIONSspformats namespace(sexcsfullNames namespacesexcStr((s7build/bdist.darwin-8.0.1-i386/egg/Cheetah/NameMapper.pys_wrapNotFoundExceptions cCsHt|do |i|otSnt||otSntSdS(sDetermine if 'obj' has 'key' shas_keyN(shasattrsobjshas_keyskeysTruesFalse(sobjskey((s7build/bdist.darwin-8.0.1-i386/egg/Cheetah/NameMapper.pyshasKeys  cCs^t|do |i|o ||Sn/t||ot||Snt||dS(Nshas_key(shasattrsobjshas_keyskeysgetattrs_raiseNotFoundException(sobjskey((s7build/bdist.darwin-8.0.1-i386/egg/Cheetah/NameMapper.pys valueForKeys   cCs|id}xtt|D]}||}t|do |i |o||}n1t||ot ||}nt |||o#t|ot|ttfjo |}q"|}q"W|SdS(Ns.shas_key(snamessplits nameChunkssrangeslensiskeyshasattrsobjshas_keysnextObjsgetattrs_raiseNotFoundExceptionsexecuteCallablesscallablestypes InstanceTypes ClassType(sobjsnamesexecuteCallabless nameChunkssisnextObjskey((s7build/bdist.darwin-8.0.1-i386/egg/Cheetah/NameMapper.pys _valueForNames   -  cCsFyt|||SWn+tj o}t|d|d|nXdS(NsfullNames namespace(s _valueForNamesobjsnamesexecuteCallablessNotFoundses_wrapNotFoundException(sobjsnamesexecuteCallablesse((s7build/bdist.darwin-8.0.1-i386/egg/Cheetah/NameMapper.pys valueForNamescCs\|idd}x5|D]-}t||ot||d|SqqWt||dS(Ns.isexecuteCallables( snamessplitskeys searchLists namespaceshasKeys _valueForNamesexecuteCallabless_raiseNotFoundException(s searchListsnamesexecuteCallabless namespaceskey((s7build/bdist.darwin-8.0.1-i386/egg/Cheetah/NameMapper.pysvalueFromSearchLists ccs6|iV|ox|D] }|VqWn|iVtVdS(N(s callerFramesf_localss searchLists namespaces f_globalss __builtins__(s callerFrames searchLists namespace((s7build/bdist.darwin-8.0.1-i386/egg/Cheetah/NameMapper.pys _namespacess csd}zy| otidd}nidd}x2t|D]!t |o |Sq[q[Wt |Wd~XdS(NcsIytdSWn+tj o}t|ddnXdS(NsexecuteCallablessfullNames namespace(s _valueForNames namespacesnamesexecuteCallablessNotFoundses_wrapNotFoundExceptions searchList(se(snames searchListsexecuteCallabless namespace(s7build/bdist.darwin-8.0.1-i386/egg/Cheetah/NameMapper.pys__valueForNamesiis.( s__valueForNamesframesinspectsstacksnamessplitskeys _namespacess searchLists namespaceshasKeys_raiseNotFoundException(s searchListsnamesexecuteCallablessframes namespaceskeys__valueForName((s searchListsnamesexecuteCallabless namespaces7build/bdist.darwin-8.0.1-i386/egg/Cheetah/NameMapper.pysvalueFromFrameOrSearchListsc CsNzC| otidd}ntdtd|d|d|SWd~XdS(Niis searchListsnamesexecuteCallablessframe(sframesinspectsstacksvalueFromFrameOrSearchListsNonesnamesexecuteCallables(snamesexecuteCallablessframe((s7build/bdist.darwin-8.0.1-i386/egg/Cheetah/NameMapper.pysvalueFromFrames cCs_|idd}t|| otSnyt||tSWntj o tSnXdS(s"Determine if 'obj' has the 'name' s.iN( snamessplitskeyshasKeysobjsFalses valueForNamesTruesNotFound(sobjsnameskey((s7build/bdist.darwin-8.0.1-i386/egg/Cheetah/NameMapper.pyshasNames (sNotFounds valueForKeys valueForNamesvalueFromSearchListsvalueFromFrameOrSearchListsvalueFromFramesMixincBs tZdZdZdZRS(s@@ document mecCst||SdS(N(s valueForNamesselfsname(sselfsname((s7build/bdist.darwin-8.0.1-i386/egg/Cheetah/NameMapper.pys valueForName-scCst||SdS(N(s valueForKeysselfskey(sselfskey((s7build/bdist.darwin-8.0.1-i386/egg/Cheetah/NameMapper.pys valueForKey0s(s__name__s __module__s__doc__s valueForNames valueForKey(((s7build/bdist.darwin-8.0.1-i386/egg/Cheetah/NameMapper.pysMixin+s  cCsdtfdY}d|fdY}|}d|_dd}hd|<d |i<d d <d hd |i<<|_d}t |id GHt |dGHt t dGHt t dGHt t dGHt t ddt GHt t ddt GHdS(NsAcBs2tZdZddZddZddZRS(Ns classVar valsmethod 1 default argcCs|SdS(N(sarg(sselfsarg((s7build/bdist.darwin-8.0.1-i386/egg/Cheetah/NameMapper.pysmethod9ssmeth 2 default argcCshd|             +   ) PK(8LdLdCheetah/CheetahWrapper.pyc; <Gc@sadZdZddd!ZdkZdkZdkZdkZdkZdkZdk Z dk Z dk l Z dklZlZdklZd klZeid Zeid Zd Zd efdYZdfdYZdefdYZde idZdeZ dZ!dZ"dfdYZ#e$djoe#i%ndS(sCheetah command-line interface. 2002-09-03 MSO: Total rewrite. 2002-09-04 MSO: Bugfix, compile command was using wrong output ext. 2002-11-08 MSO: Another rewrite. Meta-Data ================================================================================ Author: Tavis Rudd and Mike Orr > Version: $Revision: 1.26 $ Start Date: 2001/03/30 Last Revision Date: $Date: 2007/10/02 01:22:04 $ sETavis Rudd and Mike Orr s$Revision: 1.26 $i iN(sVersion(sTemplatesDEFAULT_COMPILER_SETTINGS(smkdirsWithPyInitFiles(s OptionParsers^-{1,2}s^[a-zA-Z_][a-zA-Z_0-9]*$cGsU|ddjo|d }n |d7}|o||}n|}|i|dS(Nis^s (sformatsargssmessagesstreamswrite(sstreamsformatsargssmessage((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pysfprintfMessages sErrorcBstZRS(N(s__name__s __module__(((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pysError)ssBundlecBs tZdZdZdZRS(sxWrap the source, destination and backup paths in one neat little class. Used by CheetahWrapper.getBundles(). cKs|ii|dS(N(sselfs__dict__supdateskw(sselfskw((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pys__init__1scCsd|iSdS(Ns (sselfs__dict__(sself((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pys__repr__4s(s__name__s __module__s__doc__s__init__s__repr__(((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pysBundle-s  sMyOptionParsercBs#tZgZdZedZRS(NcCstt|dS(sPrint our usage+error page.N(susages HELP_PAGE2smsg(sselfsmsg((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pyserror;scCsdS(s&Our usage+error page already has this.N((sselfsfile((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pys print_usage?s(s__name__s __module__sstandard_option_listserrorsNones print_usage(((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pysMyOptionParser8s scCs`|it|i|d}|o(|id|id|d}nti|dS(sGWrite help text, an optional error message, and abort the program. is s*** USAGE ERROR ***: %s iN(soutswrites WRAPPER_TOPs usageMessages exitStatuss errorMessagessyssexit(s usageMessages errorMessagesouts exitStatus((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pysusageGs    s7 __ ____________ __ \ \/ \/ / \/ * * \/ CHEETAH %(Version)s Command-Line Tool \ | / \ ==----== / by Tavis Rudd \__________/ and Mike Orr sUSAGE: ------ cheetah compile [options] [FILES ...] : Compile template definitions cheetah fill [options] [FILES ...] : Fill template definitions cheetah help : Print this help message cheetah options : Print options help message cheetah test [options] : Run Cheetah's regression tests : (same as for unittest) cheetah version : Print Cheetah version number You may abbreviate the command to the first letter; e.g., 'h' == 'help'. If FILES is a single "-", read standard input and write standard output. Run "cheetah options" for the list of valid options. soOPTIONS 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 Run "cheetah help" for the main help screen. sCheetahWrappercBstZeZdZeZeZdZedZ dZ dZ dZ dZ dZd Zd Zd Zd Zd ZdZdZdZdZdZdZdZdZdZdZdZRS(Ns.bakcCs:t|_t|_t|_t|_g|_g|_dS(N(sNonesselfsprogNamescommandsoptsspathArgss sourceFiless searchList(sself((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pys__init__s      cCsF|tjo ti}nymtii|d|_}ti d|d|_ }|djo|d|_ n|i |dWn t j ottdnX|i|i|i|i|i|if}xZ|D]R}|i}|d}|||fjo&tidcd|7<|dSqqWttd |dS( sThe main program controller.isistestis!not enough command-line argumentss Nsunknown command '%s'(sargvsNonessyssosspathsbasenamesselfsprogNamesoptionDashesREssubscommandstestOptss parseOptss IndexErrorsusages HELP_PAGE1scompilesfillshelpsoptionsstestsversionsmethssmeths__name__smethNames methInitial(sselfsargvsmethNamesmethssprogNamescommands methInitialsmeth((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pysmains*   *   c CsW|i|i|if\}} } |iddj|_}|odpd} t }|i }|ddddd d d |d dddd d d |dddddd d|dddddd | |dddddd t|ddddddd t|dddddd t|dddddd t|dddddd d |ddddd d t|d!dddd"d t|d#dddd$d t|d%dddd&d t|i|\|_|_\}}| d'|tit||gi}titigD]}|o||q1q1~}xtd d gD]f} x]|D]U}t|| t} | o | i!|o&| t"| } t#|| | PqoqoWqbW|i$|i%o|i&i'dti(n|i)oBt*|i)d(}t)i,|}|i.|i&i'd|n|i/ |_0dS()Niscs.pys.htmls--idirsactionsstoresdestsidirsdefaultss--odirsodirs--iextsiexts.tmpls--oextsoexts-Rs store_truesrecurses--stdouts-psstdouts--debugsdebugs--envsenvs--picklespickles--flatsflats --nobackupsnobackups --settingsscompilerSettingsStrings--templateAPIClassstemplateClassNames.cheetah compile %s Options are %s Files are %ssrb(1sselfschattersdebugswarnsCsDsWscommands isCompiles defaultOextsMyOptionParsersparsers add_optionspaosFalsesNones parse_argssargssoptsspathArgssfilesspprintspformatsvarssappends_[1]sosssepsaltsepssepssattrsgetattrspathsendswithslenssetattrs_fixExtssenvs searchListsinsertsenvironspicklesopensfsloads unpickledsclosesstdoutsverbose(sselfsargss isCompilessepsparsers unpickledspaosfilessCsDs defaultOextsWspathsattrsfs_[1]ssepssopts((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pys parseOptssN!  %">      cCs|idS(N(sselfs_compileOrFill(sself((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pyscompilescCs"dkl}||idS(N(sinstall(sCheetah.ImportHookssinstallsselfs_compileOrFill(sselfsinstall((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pysfills cCsttdtidS(Ns(susages HELP_PAGE1ssyssstdout(sself((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pyshelpscCsttdtidS(Ns(susages HELP_PAGE2ssyssstdout(sself((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pysoptionsscCsd}yt|d}WntidnX|iti|dkl }dk i i }tid3tii|i|id|dS(Ns&cheetah_test_file_creation_ability.tmpswsCannot run the tests because you don't have write permission in the current directory. The tests need to create temporary files. Change to a directory you do have write permission to and re-run the tests.(sTestismodule(sTEST_WRITE_FILENAMEsopensfssyssexitsclosesossremoves Cheetah.TestssTests!Cheetah.Tests.unittest_local_copysTestssunittest_local_copysunittestsargvsextendsselfstestOptssmain(sselfsfsTEST_WRITE_FILENAMEsTestsunittest((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pystests    cCs tGHdS(N(sVersion(sself((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pysversionscGs:|iip |ii odSntti||dS(stPrint a verbose message to stdout. But don't if .opts.stdout is true or .opts.verbose is false. N(sselfsoptssstdoutsverbosesfprintfMessagessyssformatsargs(sselfsformatsargs((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pyschatterscGs(|iiotti||ndS(sVPrint a debugging message to stderr, but don't if .debug is false. N(sselfsoptssdebugsfprintfMessagessyssstderrsformatsargs(sselfsformatsargs((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pysdebug$s cGstti||dS(s2Always print a warning message to stderr. N(sfprintfMessagessyssstderrsformatsargs(sselfsformatsargs((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pyswarn+scGs$tti||tiddS(sVAlways print a warning message to stderr and exit with an error code. iN(sfprintfMessagessyssstderrsformatsargssexit(sselfsformatsargs((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pyserror0scCs|iip td|ii|iif\}}|o|id od||i_n|o|id od||i_ndS(Nsoext is empty!s.(sselfsoptssoextsAssertionErrorsiexts startswith(sselfsoextsiext((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pys_fixExts:s c Cs|i|i|if\}}}|i|if\} }|dgjo|i dSn| o| i oe| i odpd} |d| g} tii|ii ti}tii||i| n2| ottdn|i|| i t} gi}| D]} |tii| q~} |d| |i| }|dt i!||ii"o|i#|nx|D]}|i%|qWdS(Ns-sidirscurrents,Drilling down recursively from %s directory.sNeither files nor -R specified!sAll source files found: %ssAll bundles: %s(&sselfschattersdebugswarnsCsDsWsoptsspathArgssfiless_compileOrFillStdinsrecursesidirswhichs sourceFilessosspathsjoinscurdirsdirswalks_expandSourceFilesWalksusages HELP_PAGE1s_expandSourceFilessTruesappends_[1]sxsnormpaths _getBundlessbundlesspprintspformatsflats_checkForCollisionssbs_compileOrFillBundle( sselfsfilessCsbsDsbundless_[1]sdirsWswhichsxs sourceFilessopts((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pys_compileOrFillDs.!  3  c Cs$|i|i|if\}}} t} h}xO|D]G}|i |i o||i i|iq4|ig||i %s^s (backup %s)ssn%s: base name %s contains invalid characters. It must be named according to the same rules as Python modules.sfiles returnAClasss moduleNames classNamescompilerSettingss searchListsw(0sselfschattersdebugswarnsCsDsWs_getTemplateClasss TemplateClasss_getCompilerSettingsscompilerSettingssbssrcsdstsbasesbasenamesosspathsdirnamesdstDirs isCompileswhatsexistssoptssnobackupsbaksNones moduleNameREsmatchstupsErrorscompilesFalsespysrcsoutputstclasssstrs searchListsshutilscopyfilesmkdirsWithPyInitFilessmakedirssstdoutssysswritesopensfsclose(sselfsbsdstsdstDirsbasenamespysrcswhatscompilerSettingssCsDstups TemplateClasssWssrcsfsbasesoutputstclasssbak((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pys_compileOrFillBundlesJ!      !         (s__name__s __module__sTrues MAKE_BACKUPSs BACKUP_SUFFIXsNones_templateClasss_compilerSettingss__init__smains parseOptsscompilesfillshelpsoptionsstestsversionschattersdebugswarnserrors_fixExtss_compileOrFills_checkForCollisionss_expandSourceFilesWalks_expandSourceFiless _getBundless_getTemplateClasss_getCompilerSettingss_compileOrFillStdins_compileOrFillBundle(((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pysCheetahWrappers6 " 3            ! * "  s__main__(&s__doc__s __author__s __revision__sgetoptsglobsosspprintsresshutilssysscPicklespicklesCheetah.VersionsVersionsCheetah.TemplatesTemplatesDEFAULT_COMPILER_SETTINGSsCheetah.Utils.MiscsmkdirsWithPyInitFilessCheetah.Utils.optiks OptionParserscompilesoptionDashesREs moduleNameREsfprintfMessages ExceptionsErrorsBundlesMyOptionParsersstderrsusagesglobalss WRAPPER_TOPs HELP_PAGE1s HELP_PAGE2sCheetahWrappers__name__smain(soptionDashesREs HELP_PAGE2s WRAPPER_TOPsVersionsTemplatesshutilsMyOptionParsers __revision__smkdirsWithPyInitFilesspprintsBundlesresusagesgetopts OptionParsersglobs __author__ssyssCheetahWrappers HELP_PAGE1sErrorsossfprintfMessages moduleNameREsDEFAULT_COMPILER_SETTINGSspickle((s;build/bdist.darwin-8.0.1-i386/egg/Cheetah/CheetahWrapper.pys?s, ?        PKm6EQQCheetah/SettingsManager.py#!/usr/bin/env python """Provides a mixin/base class for collecting and managing application settings Meta-Data ========== Author: Tavis Rudd Version: $Revision: 1.29 $ Start Date: 2001/05/30 Last Revision Date: $Date: 2007/04/03 02:03:26 $ """ # $Id: SettingsManager.py,v 1.29 2007/04/03 02:03:26 tavis_rudd Exp $ __author__ = "Tavis Rudd " __revision__ = "$Revision: 1.29 $"[11:-2] ################################################## ## DEPENDENCIES ## import sys import os.path import copy as copyModule from ConfigParser import ConfigParser import re from tokenize import Intnumber, Floatnumber, Number from types import * import types import new import tempfile import time from StringIO import StringIO # not cStringIO because of unicode support import imp # used by SettingsManager.updateSettingsFromPySrcFile() try: import threading from threading import Lock # used for thread lock on sys.path manipulations except: ## provide a dummy for non-threading Python systems class Lock: def acquire(self): pass def release(self): pass class BaseErrorClass: pass ################################################## ## CONSTANTS & GLOBALS ## try: True,False except NameError: True, False = (1==1),(1==0) numberRE = re.compile(Number) complexNumberRE = re.compile('[\(]*' +Number + r'[ \t]*\+[ \t]*' + Number + '[\)]*') convertableToStrTypes = (StringType, IntType, FloatType, LongType, ComplexType, NoneType, UnicodeType) ################################################## ## FUNCTIONS ## def mergeNestedDictionaries(dict1, dict2, copy=False, deepcopy=False): """Recursively merge the values of dict2 into dict1. This little function is very handy for selectively overriding settings in a settings dictionary that has a nested structure. """ if copy: dict1 = copyModule.copy(dict1) elif deepcopy: dict1 = copyModule.deepcopy(dict1) for key,val in dict2.items(): if dict1.has_key(key) and type(val) == types.DictType and \ type(dict1[key]) == types.DictType: dict1[key] = mergeNestedDictionaries(dict1[key], val) else: dict1[key] = val return dict1 def stringIsNumber(S): """Return True if theString represents a Python number, False otherwise. This also works for complex numbers and numbers with +/- in front.""" S = S.strip() if S[0] in '-+' and len(S) > 1: S = S[1:].strip() match = complexNumberRE.match(S) if not match: match = numberRE.match(S) if not match or (match.end() != len(S)): return False else: return True def convStringToNum(theString): """Convert a string representation of a Python number to the Python version""" if not stringIsNumber(theString): raise Error(theString + ' cannot be converted to a Python number') return eval(theString, {}, {}) ###### ident = r'[_a-zA-Z][_a-zA-Z0-9]*' firstChunk = r'^(?P\s*)(?P[_a-zA-Z][_a-zA-Z0-9]*)' customClassRe = re.compile(firstChunk + r'\s*:') baseClasses = r'(?P\(\s*([_a-zA-Z][_a-zA-Z0-9]*\s*(,\s*[_a-zA-Z][_a-zA-Z0-9]*\s*)*)\))' customClassWithBasesRe = re.compile(firstChunk + baseClasses + '\s*:') def translateClassBasedConfigSyntax(src): """Compiles a config file in the custom class-based SettingsContainer syntax to Vanilla Python # WebKit.config Applications: MyApp: Dirs: ROOT = '/home/www/Home' Products = '/home/www/Products' becomes: # WebKit.config from Cheetah.SettingsManager import SettingsContainer class Applications(SettingsContainer): class MyApp(SettingsContainer): class Dirs(SettingsContainer): ROOT = '/home/www/Home' Products = '/home/www/Products' """ outputLines = [] for line in src.splitlines(): if customClassRe.match(line) and \ line.strip().split(':')[0] not in ('else','try', 'except', 'finally'): line = customClassRe.sub( r'\gclass \g(SettingsContainer):', line) elif customClassWithBasesRe.match(line) and not line.strip().startswith('except'): line = customClassWithBasesRe.sub( r'\gclass \g\g:', line) outputLines.append(line) ## prepend this to the first line to make sure that tracebacks report the right line nums if outputLines[0].find('class ') == -1: initLine = 'from Cheetah.SettingsManager import SettingsContainer; True, False = 1, 0; ' else: initLine = 'from Cheetah.SettingsManager import SettingsContainer; True, False = 1, 0\n' return initLine + '\n'.join(outputLines) + '\n' ################################################## ## CLASSES ## class Error(BaseErrorClass): pass class NoDefault: pass class ConfigParserCaseSensitive(ConfigParser): """A case sensitive version of the standard Python ConfigParser.""" def optionxform(self, optionstr): """Don't change the case as is done in the default implemenation.""" return optionstr class SettingsContainer: """An abstract base class for 'classes' that are used to house settings.""" pass class _SettingsCollector: """An abstract base class that provides the methods SettingsManager uses to collect settings from config files and SettingsContainers. This class only collects settings it doesn't modify the _settings dictionary of SettingsManager instances in any way. SettingsCollector is designed to: - be able to read settings from Python src files (or strings) so that complex Python objects can be stored in the application's settings dictionary. For example, you might want to store references to various classes that are used by the application and plugins to the application might want to substitute one class for another. - be able to read/write .ini style config files (or strings) - allow sections in .ini config files to be extended by settings in Python src files - allow python literals to be used values in .ini config files - maintain the case of setting names, unlike the ConfigParser module """ _sysPathLock = Lock() # used by the updateSettingsFromPySrcFile() method _ConfigParserClass = ConfigParserCaseSensitive def __init__(self): pass def normalizePath(self, path): """A hook for any neccessary path manipulations. For example, when this is used with WebKit servlets all relative paths must be converted so they are relative to the servlet's directory rather than relative to the program's current working dir. The default implementation just normalizes the path for the current operating system.""" return os.path.normpath(path.replace("\\",'/')) def readSettingsFromContainer(self, container, ignoreUnderscored=True): """Returns all settings from a SettingsContainer or Python module. This method is recursive. """ S = {} if type(container) == ModuleType: attrs = vars(container) else: attrs = self._getAllAttrsFromContainer(container) for k, v in attrs.items(): if (ignoreUnderscored and k.startswith('_')) or v is SettingsContainer: continue if self._isContainer(v): S[k] = self.readSettingsFromContainer(v) else: S[k] = v return S # provide an alias readSettingsFromModule = readSettingsFromContainer def _isContainer(self, thing): """Check if 'thing' is a Python module or a subclass of SettingsContainer.""" return type(thing) == ModuleType or ( type(thing) == ClassType and issubclass(thing, SettingsContainer) ) def _getAllAttrsFromContainer(self, container): """Extract all the attributes of a SettingsContainer subclass. The 'container' is a class, so extracting all attributes from it, an instance of it, and all its base classes. This method is not recursive. """ attrs = container.__dict__.copy() # init an instance of the container and get all attributes attrs.update( container().__dict__ ) for base in container.__bases__: for k, v in base.__dict__.items(): if not attrs.has_key(k): attrs[k] = v return attrs def readSettingsFromPySrcFile(self, path): """Return new settings dict from variables in a Python source file. This method will temporarily add the directory of src file to sys.path so that import statements relative to that dir will work properly.""" path = self.normalizePath(path) dirName = os.path.dirname(path) tmpPath = tempfile.mkstemp('webware_temp') pySrc = translateClassBasedConfigSyntax(open(path).read()) modName = path.replace('.','_').replace('/','_').replace('\\','_') open(tmpPath, 'w').write(pySrc) try: fp = open(tmpPath) self._sysPathLock.acquire() sys.path.insert(0, dirName) module = imp.load_source(modName, path, fp) newSettings = self.readSettingsFromModule(module) del sys.path[0] self._sysPathLock.release() return newSettings finally: fp.close() try: os.remove(tmpPath) except: pass if os.path.exists(tmpPath + 'c'): try: os.remove(tmpPath + 'c') except: pass if os.path.exists(path + 'c'): try: os.remove(path + 'c') except: pass def readSettingsFromPySrcStr(self, theString): """Return a dictionary of the settings in a Python src string.""" globalsDict = {'True':1, 'False':0, 'SettingsContainer':SettingsContainer, } newSettings = {'self':self} exec theString in globalsDict, newSettings del newSettings['self'], newSettings['True'], newSettings['False'] module = new.module('temp_settings_module') module.__dict__.update(newSettings) return self.readSettingsFromModule(module) def readSettingsFromConfigFile(self, path, convert=True): path = self.normalizePath(path) fp = open(path) settings = self.readSettingsFromConfigFileObj(fp, convert=convert) fp.close() return settings def readSettingsFromConfigFileObj(self, inFile, convert=True): """Return the settings from a config file that uses the syntax accepted by Python's standard ConfigParser module (like Windows .ini files). NOTE: this method maintains case unlike the ConfigParser module, unless this class was initialized with the 'caseSensitive' keyword set to False. All setting values are initially parsed as strings. However, If the 'convert' arg is True this method will do the following value conversions: * all Python numeric literals will be coverted from string to number * The string 'None' will be converted to the Python value None * The string 'True' will be converted to a Python truth value * The string 'False' will be converted to a Python false value * Any string starting with 'python:' will be treated as a Python literal or expression that needs to be eval'd. This approach is useful for declaring lists and dictionaries. If a config section titled 'Globals' is present the options defined under it will be treated as top-level settings. """ p = self._ConfigParserClass() p.readfp(inFile) sects = p.sections() newSettings = {} sects = p.sections() newSettings = {} for s in sects: newSettings[s] = {} for o in p.options(s): if o != '__name__': newSettings[s][o] = p.get(s,o) ## loop through new settings -> deal with global settings, numbers, ## booleans and None ++ also deal with 'importSettings' commands for sect, subDict in newSettings.items(): for key, val in subDict.items(): if convert: if val.lower().startswith('python:'): subDict[key] = eval(val[7:],{},{}) if val.lower() == 'none': subDict[key] = None if val.lower() == 'true': subDict[key] = True if val.lower() == 'false': subDict[key] = False if stringIsNumber(val): subDict[key] = convStringToNum(val) ## now deal with any 'importSettings' commands if key.lower() == 'importsettings': if val.find(';') < 0: importedSettings = self.readSettingsFromPySrcFile(val) else: path = val.split(';')[0] rest = ''.join(val.split(';')[1:]).strip() parentDict = self.readSettingsFromPySrcFile(path) importedSettings = eval('parentDict["' + rest + '"]') subDict.update(mergeNestedDictionaries(subDict, importedSettings)) if sect.lower() == 'globals': newSettings.update(newSettings[sect]) del newSettings[sect] return newSettings class SettingsManager(_SettingsCollector): """A mixin class that provides facilities for managing application settings. SettingsManager is designed to work well with nested settings dictionaries of any depth. """ ## init methods def __init__(self): """MUST BE CALLED BY SUBCLASSES""" _SettingsCollector.__init__(self) self._settings = {} self._initializeSettings() def _defaultSettings(self): return {} def _initializeSettings(self): """A hook that allows for complex setting initialization sequences that involve references to 'self' or other settings. For example: self._settings['myCalcVal'] = self._settings['someVal'] * 15 This method should be called by the class' __init__() method when needed. The dummy implementation should be reimplemented by subclasses. """ pass ## core post startup methods def setting(self, name, default=NoDefault): """Get a setting from self._settings, with or without a default value.""" if default is NoDefault: return self._settings[name] else: return self._settings.get(name, default) def hasSetting(self, key): """True/False""" return self._settings.has_key(key) def setSetting(self, name, value): """Set a setting in self._settings.""" self._settings[name] = value def settings(self): """Return a reference to the settings dictionary""" return self._settings def copySettings(self): """Returns a shallow copy of the settings dictionary""" return copyModule.copy(self._settings) def deepcopySettings(self): """Returns a deep copy of the settings dictionary""" return copyModule.deepcopy(self._settings) def updateSettings(self, newSettings, merge=True): """Update the settings with a selective merge or a complete overwrite.""" if merge: mergeNestedDictionaries(self._settings, newSettings) else: self._settings.update(newSettings) ## source specific update methods def updateSettingsFromPySrcStr(self, theString, merge=True): """Update the settings from a code in a Python src string.""" newSettings = self.readSettingsFromPySrcStr(theString) self.updateSettings(newSettings, merge=newSettings.get('mergeSettings',merge) ) def updateSettingsFromPySrcFile(self, path, merge=True): """Update the settings from variables in a Python source file. This method will temporarily add the directory of src file to sys.path so that import statements relative to that dir will work properly.""" newSettings = self.readSettingsFromPySrcFile(path) self.updateSettings(newSettings, merge=newSettings.get('mergeSettings',merge) ) def updateSettingsFromConfigFile(self, path, **kw): """Update the settings from a text file using the syntax accepted by Python's standard ConfigParser module (like Windows .ini files). """ path = self.normalizePath(path) fp = open(path) self.updateSettingsFromConfigFileObj(fp, **kw) fp.close() def updateSettingsFromConfigFileObj(self, inFile, convert=True, merge=True): """See the docstring for .updateSettingsFromConfigFile() The caller of this method is responsible for closing the inFile file object.""" newSettings = self.readSettingsFromConfigFileObj(inFile, convert=convert) self.updateSettings(newSettings, merge=newSettings.get('mergeSettings',merge)) def updateSettingsFromConfigStr(self, configStr, convert=True, merge=True): """See the docstring for .updateSettingsFromConfigFile() """ configStr = '[globals]\n' + configStr inFile = StringIO(configStr) newSettings = self.readSettingsFromConfigFileObj(inFile, convert=convert) self.updateSettings(newSettings, merge=newSettings.get('mergeSettings',merge)) ## methods for output representations of the settings def _createConfigFile(self, outFile=None): """ Write all the settings that can be represented as strings to an .ini style config string. This method can only handle one level of nesting and will only work with numbers, strings, and None. """ if outFile is None: outFile = StringIO() iniSettings = {'Globals':{}} globals = iniSettings['Globals'] for key, theSetting in self.settings().items(): if type(theSetting) in convertableToStrTypes: globals[key] = theSetting if type(theSetting) is DictType: iniSettings[key] = {} for subKey, subSetting in theSetting.items(): if type(subSetting) in convertableToStrTypes: iniSettings[key][subKey] = subSetting sections = iniSettings.keys() sections.sort() outFileWrite = outFile.write # short-cut namebinding for efficiency for section in sections: outFileWrite("[" + section + "]\n") sectDict = iniSettings[section] keys = sectDict.keys() keys.sort() for key in keys: if key == "__name__": continue outFileWrite("%s = %s\n" % (key, sectDict[key])) outFileWrite("\n") return outFile def writeConfigFile(self, path): """Write all the settings that can be represented as strings to an .ini style config file.""" path = self.normalizePath(path) fp = open(path,'w') self._createConfigFile(fp) fp.close() def getConfigString(self): """Return a string with the settings in .ini file format.""" return self._createConfigFile().getvalue() # vim: shiftwidth=4 tabstop=4 expandtab PKQ|*47 Cheetah/TemplateCmdLineIface.py#!/usr/bin/env python # $Id: TemplateCmdLineIface.py,v 1.13 2006/01/10 20:34:35 tavis_rudd Exp $ """Provides a command line interface to compiled Cheetah template modules. Meta-Data ================================================================================ Author: Tavis Rudd Version: $Revision: 1.13 $ Start Date: 2001/12/06 Last Revision Date: $Date: 2006/01/10 20:34:35 $ """ __author__ = "Tavis Rudd " __revision__ = "$Revision: 1.13 $"[11:-2] import sys import os import getopt import os.path try: from cPickle import load except ImportError: from pickle import load from Cheetah.Version import Version class Error(Exception): pass class CmdLineIface: """A command line interface to compiled Cheetah template modules.""" def __init__(self, templateObj, scriptName=os.path.basename(sys.argv[0]), cmdLineArgs=sys.argv[1:]): self._template = templateObj self._scriptName = scriptName self._cmdLineArgs = cmdLineArgs def run(self): """The main program controller.""" self._processCmdLineArgs() print self._template def _processCmdLineArgs(self): try: self._opts, self._args = getopt.getopt( self._cmdLineArgs, 'h', ['help', 'env', 'pickle=', ]) except getopt.GetoptError, v: # print help information and exit: print v print self.usage() sys.exit(2) for o, a in self._opts: if o in ('-h','--help'): print self.usage() sys.exit() if o == '--env': self._template.searchList().insert(0, os.environ) if o == '--pickle': if a == '-': unpickled = load(sys.stdin) self._template.searchList().insert(0, unpickled) else: f = open(a) unpickled = load(f) f.close() self._template.searchList().insert(0, unpickled) def usage(self): return """Cheetah %(Version)s template module command-line interface Usage ----- %(scriptName)s [OPTION] Options ------- -h, --help Print this help information --env Use shell ENVIRONMENT variables to fill the $placeholders in the template. --pickle Use a variables from a dictionary stored in Python pickle file to fill $placeholders in the template. If is - stdin is used: '%(scriptName)s --pickle -' Description ----------- This interface allows you to execute a Cheetah template from the command line and collect the output. It can prepend the shell ENVIRONMENT or a pickled Python dictionary to the template's $placeholder searchList, overriding the defaults for the $placeholders. """ % {'scriptName':self._scriptName, 'Version':Version, } # vim: shiftwidth=4 tabstop=4 expandtab PK?4Cheetah/DummyTransaction.py#!/usr/bin/env python # $Id: DummyTransaction.py,v 1.13 2005/11/13 01:12:13 tavis_rudd Exp $ """Provides dummy Transaction and Response classes is used by Cheetah in place of real Webware transactions when the Template obj is not used directly as a Webware servlet. Meta-Data ========== Author: Tavis Rudd Version: $Revision: 1.13 $ Start Date: 2001/08/30 Last Revision Date: $Date: 2005/11/13 01:12:13 $ """ __author__ = "Tavis Rudd " __revision__ = "$Revision: 1.13 $"[11:-2] def flush(): pass class DummyResponse: """A dummy Response class is used by Cheetah in place of real Webware Response objects when the Template obj is not used directly as a Webware servlet. """ def __init__(self): self._outputChunks = outputChunks = [] self.write = write = outputChunks.append def getvalue(outputChunks=outputChunks): return ''.join(outputChunks) self.getvalue = getvalue def writeln(txt): write(txt) write('\n') self.writeln = writeln self.flush = flush def writelines(self, *lines): ## not used [self.writeln(ln) for ln in lines] class DummyTransaction: """A dummy Transaction class is used by Cheetah in place of real Webware transactions when the Template obj is not used directly as a Webware servlet. It only provides a response object and method. All other methods and attributes make no sense in this context. """ def __init__(self, DummyResponse=DummyResponse): def response(resp=DummyResponse()): return resp self.response = response PK6~p)ggCheetah/Servlet.py#!/usr/bin/env python # $Id: Servlet.py,v 1.41 2007/04/04 00:55:27 tavis_rudd Exp $ """Provides an abstract Servlet baseclass for Cheetah's Template class Meta-Data ================================================================================ Author: Tavis Rudd License: This software is released for unlimited distribution under the terms of the MIT license. See the LICENSE file. Version: $Revision: 1.41 $ Start Date: 2001/10/03 Last Revision Date: $Date: 2007/04/04 00:55:27 $ """ __author__ = "Tavis Rudd " __revision__ = "$Revision: 1.41 $"[11:-2] import sys import os.path isWebwareInstalled = False try: try: from ds.appserver.Servlet import Servlet as BaseServlet except: from WebKit.Servlet import Servlet as BaseServlet isWebwareInstalled = True if not issubclass(BaseServlet, object): class NewStyleBaseServlet(BaseServlet, object): pass BaseServlet = NewStyleBaseServlet except: class BaseServlet(object): _reusable = 1 _threadSafe = 0 def __init__(self): pass def awake(self, transaction): pass def sleep(self, transaction): pass def shutdown(self): pass ################################################## ## CLASSES class Servlet(BaseServlet): """This class is an abstract baseclass for Cheetah.Template.Template. It wraps WebKit.Servlet and provides a few extra convenience methods that are also found in WebKit.Page. It doesn't do any of the HTTP method resolution that is done in WebKit.HTTPServlet """ transaction = None application = None request = None session = None def __init__(self): BaseServlet.__init__(self) # this default will be changed by the .awake() method self._CHEETAH__isControlledByWebKit = False ## methods called by Webware during the request-response def awake(self, transaction): BaseServlet.awake(self, transaction) # a hack to signify that the servlet is being run directly from WebKit self._CHEETAH__isControlledByWebKit = True self.transaction = transaction #self.application = transaction.application self.response = response = transaction.response self.request = transaction.request # Temporary hack to accomodate bug in # WebKit.Servlet.Servlet.serverSidePath: it uses # self._request even though this attribute does not exist. # This attribute WILL disappear in the future. self._request = transaction.request() self.session = transaction.session self.write = response().write #self.writeln = response.writeln def respond(self, trans=None): raise NotImplementedError("""\ couldn't find the template's main method. If you are using #extends without #implements, try adding '#implements respond' to your template definition.""") def sleep(self, transaction): BaseServlet.sleep(self, transaction) self.session = None self.request = None self._request = None self.response = None self.transaction = None def shutdown(self): pass def serverSidePath(self, path=None, normpath=os.path.normpath, abspath=os.path.abspath ): if self._CHEETAH__isControlledByWebKit: return BaseServlet.serverSidePath(self, path) elif path: return normpath(abspath(path.replace("\\",'/'))) elif hasattr(self, '_filePath') and self._filePath: return normpath(abspath(self._filePath)) else: return None # vim: shiftwidth=4 tabstop=4 expandtab PKɡ(88і*ppCheetah/_namemapper.so__TEXT __text__TEXT__picsymbol_stub__TEXT44__cstring__TEXT@@@__picsymbolstub2__TEXTR__textcoal_nt__TEXT @__DATA  __data__DATA __dyld__DATA  __la_sym_ptr2__DATA "__nl_symbol_ptr__DATAP!P!D__bss__DATAd! 8__LINKEDIT00p 4FYBX/usr/lib/libSystem.B.dylib1Ri P'QI08Xs3X7UVS  L$4$D$D$ D$-$ D$Ƌ$D$  $D$D$*T$4$D$pJ4$L$D$Tj$-ƉT$$t u [^]Í$F4$PՐUS$UMT$E T$L$ $y1҅tED$E$ ƒ$[]ÐUWVM}SuEET$ D$E T$|$t$L$$_1҅}1щ $%MljuUE|$U$D$ EuNEt$D$ ED$E$ <$ED$E$2 UDցČ[^_]É<$y1UWVM}SuEET$ wD$E T$E|$t$L$$L1҅}1щ $MEuED$ED$EE$ EE$Eu4$c}4$t|$4$juq|$4$(uatKxtEEtUtE$!UĜ[^_]ËB$PڋF4$P몋EM4$D$ EL$D$> EtEt$$]xlF4$PT}L$E4$ |$4$}ED$<$4$T$<$D$ED$$E88Ep$V T$$1E$1UWVM}SuWEET$ D$E T$EE|$t$L$$1҅}1щ $kMEuED$ED$EE$E$}Ɖ$t|$4$u|$4$tWEM4$D$ EL$D$t$EE$FuE$UĜ[^_]E܋E$^ECu4$/}4$_t|$4$6ub|$4$uRtXXXkXXXXXXXYY)Y>YTYnYYYYYYY Z~Z)[>[T[f[y[[[[[ [@[@[[[$,DDD [D! \$&\2\ >\@J\T\^\_\$ `\$TD, D1 D7 D= D@ DF DL DS D a\D p\ D D D D \HD \$, \\ \\@\@ ]]]5]@E]@U]@e]]]@^@ ^&  9^F :^$ ;^E^P^g^@w^@^@^^@^@ ^&  ^+ ^7 ^$ D8 D1= DC D1I DL D1R D#X D1_ D,w D1~ D6 D8 D9 D8 D9 D! D$ D@ D@P DA[ DBd DCk DMk DN DO DP D? DF DP DL DP DO# DP* DQ2 DP< DQ? DRP DXn DY D: D; ^$8 __ _*_@6_@D_!U_"`_#w_%_@&_@'_(_)_@+_,_-_&/0 `R `@(`! )`R *` +`!<`"G`#^`%m`@&}`@'`(`)`@+`,`-`&/0 ` `@L` `Oa a aO$a %a &a 'a (a$DT Di DT Di DT Di DX Di DY Dc Di% DnC Dp D Dp D D Dq DDDDs*Dt5Ds7Dt:DUDXDtDzD{D|D}DDyD!D.D3D6D8DTDdDDDDDDDPDLDDPDODPDQDPDQDRDX2DYGDUDuDv)a$T VaSbaS naS|a@Sa@SaWaXaYa\a@]a@^a_ b`b@b,bc;bdKbeZb&g@ ~b b@b b b@b b bbWbXbYb\b@]b@^b_c`c@b0cc?cdOce^c&g@ nc!oc@zcU{c|c@c3c6c@c8cdc@ccc@ccc@LccOcccc@LccOccZcZc@LcudOdudddd$DDDDDDDDDDkDpDsDuDDDDDDDDDDD2D7D:D<D\DpDPDLDDODPDQDRDXDYDd$9dEd Qd_d@kd@yddd@d@dddd@d ee&P AeBe@MepNesOe@Zeu[e\e]ehee@e@eeee@eef&P ff@fff@*f+f2,f@7f78f:9f@Df<EfpFf@LQfRfOefffgfhf@LsftfOff f f@Lf&fOf&f7f7fFf$D^HDc\DxeDzgDdDeDdDeDgDeDgDhDsDuDv Di DjADk_f$^Hf]f] f_g_g_$g@_g$@D}DD}DDDDDDDDDDDDDDDD?g$}Tg|og| {g|g@|g@|g@~g@g@ggg$pDDDDD9DIDXDPhDOtDP{DQDRDXDYDg$gh h@h(h)hX*h9hh:hOMhhNhOh Ph$D DD$D'D?DHDUDuDDDDDDDDDDD$D=DHDPhDOqDPxDQDRDXDYDDD Qh$ rh}h hhhh@h@h@hhO ih i iOii  i1!i$("i( d!2i( h!Hi( l!ai&` id4C[0s ';KZk|-F^p!0@F__dyld_func_lookupdyld_stub_binding_helper__mh_bundle_header___i686.get_pc_thunk.ax___i686.get_pc_thunk.bx_init_namemapper_PyArg_ParseTuple_PyArg_ParseTupleAndKeywords_PyCallable_Check_PyClass_Type_PyDict_SetItemString_PyErr_CheckSignals_PyErr_Fetch_PyErr_GivenExceptionMatches_PyErr_NewException_PyErr_Occurred_PyErr_Restore_PyErr_SetObject_PyErr_SetString_PyEval_GetBuiltins_PyEval_GetGlobals_PyEval_GetLocals_PyExc_LookupError_PyExc_TypeError_PyImport_ImportModule_PyInstance_Type_PyInt_AsLong_PyIter_Next_PyMapping_Check_PyMapping_GetItemString_PyMapping_HasKeyString_PyModule_GetDict_PyObject_CallMethod_PyObject_CallObject_PyObject_GetAttrString_PyObject_GetIter_PyObject_HasAttrString_PyString_ConcatAndDel_PyType_IsSubtype_PyType_Type_Py_BuildValue_Py_FatalError_Py_InitModule4_free_malloc_NXArgc_NXArgv_PyArg_Parse_PyArg_UnpackTuple_PyArg_VaParse_PyBaseObject_Type_PyBaseString_Type_PyBool_FromLong_PyBool_Type_PyBuffer_FromMemory_PyBuffer_FromObject_PyBuffer_FromReadWriteMemory_PyBuffer_FromReadWriteObject_PyBuffer_New_PyBuffer_Type_PyCFunction_Call_PyCFunction_Fini_PyCFunction_GetFlags_PyCFunction_GetFunction_PyCFunction_GetSelf_PyCFunction_New_PyCFunction_NewEx_PyCFunction_Type_PyCObject_AsVoidPtr_PyCObject_FromVoidPtr_PyCObject_FromVoidPtrAndDesc_PyCObject_GetDesc_PyCObject_Import_PyCObject_Type_PyCallIter_New_PyCallIter_Type_PyCell_Get_PyCell_New_PyCell_Set_PyCell_Type_PyClassMethod_New_PyClassMethod_Type_PyClass_IsSubclass_PyClass_New_PyCode_Addr2Line_PyCode_New_PyCode_Type_PyCodec_BackslashReplaceErrors_PyCodec_Decode_PyCodec_Decoder_PyCodec_Encode_PyCodec_Encoder_PyCodec_IgnoreErrors_PyCodec_LookupError_PyCodec_Register_PyCodec_RegisterError_PyCodec_ReplaceErrors_PyCodec_StreamReader_PyCodec_StreamWriter_PyCodec_StrictErrors_PyCodec_XMLCharRefReplaceErrors_PyComplex_AsCComplex_PyComplex_FromCComplex_PyComplex_FromDoubles_PyComplex_ImagAsDouble_PyComplex_RealAsDouble_PyComplex_Type_PyDescr_NewClassMethod_PyDescr_NewGetSet_PyDescr_NewMember_PyDescr_NewMethod_PyDescr_NewWrapper_PyDictIter_Type_PyDictProxy_New_PyDict_Clear_PyDict_Copy_PyDict_DelItem_PyDict_DelItemString_PyDict_GetItem_PyDict_GetItemString_PyDict_Items_PyDict_Keys_PyDict_Merge_PyDict_MergeFromSeq2_PyDict_New_PyDict_Next_PyDict_SetItem_PyDict_Size_PyDict_Type_PyDict_Update_PyDict_Values_PyEnum_Type_PyErr_BadArgument_PyErr_BadInternalCall_PyErr_Clear_PyErr_Display_PyErr_ExceptionMatches_PyErr_Format_PyErr_NoMemory_PyErr_NormalizeException_PyErr_Print_PyErr_PrintEx_PyErr_ProgramText_PyErr_SetFromErrno_PyErr_SetFromErrnoWithFilename_PyErr_SetFromErrnoWithFilenameObject_PyErr_SetInterrupt_PyErr_SetNone_PyErr_SyntaxLocation_PyErr_Warn_PyErr_WarnExplicit_PyErr_WriteUnraisable_PyEval_AcquireLock_PyEval_AcquireThread_PyEval_CallFunction_PyEval_CallMethod_PyEval_CallObject_PyEval_CallObjectWithKeywords_PyEval_EvalCode_PyEval_EvalCodeEx_PyEval_GetCallStats_PyEval_GetFrame_PyEval_GetFuncDesc_PyEval_GetFuncName_PyEval_GetRestricted_PyEval_InitThreads_PyEval_MergeCompilerFlags_PyEval_ReInitThreads_PyEval_ReleaseLock_PyEval_ReleaseThread_PyEval_RestoreThread_PyEval_SaveThread_PyEval_SetProfile_PyEval_SetTrace_PyExc_ArithmeticError_PyExc_AssertionError_PyExc_AttributeError_PyExc_DeprecationWarning_PyExc_EOFError_PyExc_EnvironmentError_PyExc_Exception_PyExc_FloatingPointError_PyExc_FutureWarning_PyExc_IOError_PyExc_ImportError_PyExc_IndentationError_PyExc_IndexError_PyExc_KeyError_PyExc_KeyboardInterrupt_PyExc_MemoryError_PyExc_MemoryErrorInst_PyExc_NameError_PyExc_NotImplementedError_PyExc_OSError_PyExc_OverflowError_PyExc_OverflowWarning_PyExc_PendingDeprecationWarning_PyExc_ReferenceError_PyExc_RuntimeError_PyExc_RuntimeWarning_PyExc_StandardError_PyExc_StopIteration_PyExc_SyntaxError_PyExc_SyntaxWarning_PyExc_SystemError_PyExc_SystemExit_PyExc_TabError_PyExc_UnboundLocalError_PyExc_UnicodeDecodeError_PyExc_UnicodeEncodeError_PyExc_UnicodeError_PyExc_UnicodeTranslateError_PyExc_UserWarning_PyExc_ValueError_PyExc_Warning_PyExc_ZeroDivisionError_PyFPE_counter_PyFPE_dummy_PyFPE_jbuf_PyFile_AsFile_PyFile_FromFile_PyFile_FromString_PyFile_GetLine_PyFile_Name_PyFile_SetBufSize_PyFile_SetEncoding_PyFile_SoftSpace_PyFile_Type_PyFile_WriteObject_PyFile_WriteString_PyFloat_AsDouble_PyFloat_AsReprString_PyFloat_AsString_PyFloat_AsStringEx_PyFloat_Fini_PyFloat_FromDouble_PyFloat_FromString_PyFloat_Type_PyFrame_BlockPop_PyFrame_BlockSetup_PyFrame_FastToLocals_PyFrame_Fini_PyFrame_LocalsToFast_PyFrame_New_PyFrame_Type_PyFunction_GetClosure_PyFunction_GetCode_PyFunction_GetDefaults_PyFunction_GetGlobals_PyFunction_GetModule_PyFunction_New_PyFunction_SetClosure_PyFunction_SetDefaults_PyFunction_Type_PyGC_Collect_PyGILState_Ensure_PyGILState_GetThisThreadState_PyGILState_Release_PyGrammar_AddAccelerators_PyGrammar_FindDFA_PyGrammar_LabelRepr_PyGrammar_RemoveAccelerators_PyImport_AddModule_PyImport_AppendInittab_PyImport_Cleanup_PyImport_ExecCodeModule_PyImport_ExecCodeModuleEx_PyImport_ExtendInittab_PyImport_FrozenModules_PyImport_GetMagicNumber_PyImport_GetModuleDict_PyImport_Import_PyImport_ImportFrozenModule_PyImport_ImportModuleEx_PyImport_Inittab_PyImport_ReloadModule_PyInstance_New_PyInstance_NewRaw_PyInt_AsUnsignedLongLongMask_PyInt_AsUnsignedLongMask_PyInt_Fini_PyInt_FromLong_PyInt_FromString_PyInt_FromUnicode_PyInt_GetMax_PyInt_Type_PyInterpreterState_Clear_PyInterpreterState_Delete_PyInterpreterState_Head_PyInterpreterState_New_PyInterpreterState_Next_PyInterpreterState_ThreadHead_PyListIter_Type_PyList_Append_PyList_AsTuple_PyList_GetItem_PyList_GetSlice_PyList_Insert_PyList_New_PyList_Reverse_PyList_SetItem_PyList_SetSlice_PyList_Size_PyList_Sort_PyList_Type_PyLong_AsDouble_PyLong_AsLong_PyLong_AsLongLong_PyLong_AsUnsignedLong_PyLong_AsUnsignedLongLong_PyLong_AsUnsignedLongLongMask_PyLong_AsUnsignedLongMask_PyLong_AsVoidPtr_PyLong_FromDouble_PyLong_FromLong_PyLong_FromLongLong_PyLong_FromString_PyLong_FromUnicode_PyLong_FromUnsignedLong_PyLong_FromUnsignedLongLong_PyLong_FromVoidPtr_PyLong_Type_PyMapping_HasKey_PyMapping_Length_PyMapping_SetItemString_PyMapping_Size_PyMarshal_Init_PyMarshal_ReadLastObjectFromFile_PyMarshal_ReadLongFromFile_PyMarshal_ReadObjectFromFile_PyMarshal_ReadObjectFromString_PyMarshal_ReadShortFromFile_PyMarshal_WriteLongToFile_PyMarshal_WriteObjectToFile_PyMarshal_WriteObjectToString_PyMem_Free_PyMem_Malloc_PyMem_Realloc_PyMember_Get_PyMember_GetOne_PyMember_Set_PyMember_SetOne_PyMethod_Class_PyMethod_Fini_PyMethod_Function_PyMethod_New_PyMethod_Self_PyMethod_Type_PyModule_AddIntConstant_PyModule_AddObject_PyModule_AddStringConstant_PyModule_GetFilename_PyModule_GetName_PyModule_GetWarningsModule_PyModule_New_PyModule_Type_PyNode_AddChild_PyNode_Compile_PyNode_CompileFlags_PyNode_CompileSymtable_PyNode_Free_PyNode_Future_PyNode_New_PyNumber_Absolute_PyNumber_Add_PyNumber_And_PyNumber_Check_PyNumber_Coerce_PyNumber_CoerceEx_PyNumber_Divide_PyNumber_Divmod_PyNumber_Float_PyNumber_FloorDivide_PyNumber_InPlaceAdd_PyNumber_InPlaceAnd_PyNumber_InPlaceDivide_PyNumber_InPlaceFloorDivide_PyNumber_InPlaceLshift_PyNumber_InPlaceMultiply_PyNumber_InPlaceOr_PyNumber_InPlacePower_PyNumber_InPlaceRemainder_PyNumber_InPlaceRshift_PyNumber_InPlaceSubtract_PyNumber_InPlaceTrueDivide_PyNumber_InPlaceXor_PyNumber_Int_PyNumber_Invert_PyNumber_Long_PyNumber_Lshift_PyNumber_Multiply_PyNumber_Negative_PyNumber_Or_PyNumber_Positive_PyNumber_Power_PyNumber_Remainder_PyNumber_Rshift_PyNumber_Subtract_PyNumber_TrueDivide_PyNumber_Xor_PyOS_AfterFork_PyOS_FiniInterrupts_PyOS_GetLastModificationTime_PyOS_InitInterrupts_PyOS_InputHook_PyOS_InterruptOccurred_PyOS_Readline_PyOS_ReadlineFunctionPointer_PyOS_StdioReadline_PyOS_getsig_PyOS_setsig_PyOS_snprintf_PyOS_strtol_PyOS_strtoul_PyOS_vsnprintf_PyObject_AsCharBuffer_PyObject_AsFileDescriptor_PyObject_AsReadBuffer_PyObject_AsWriteBuffer_PyObject_Call_PyObject_CallFunction_PyObject_CallFunctionObjArgs_PyObject_CallMethodObjArgs_PyObject_CheckReadBuffer_PyObject_ClearWeakRefs_PyObject_Cmp_PyObject_Compare_PyObject_DelItem_PyObject_DelItemString_PyObject_Dir_PyObject_Free_PyObject_GC_Del_PyObject_GC_Track_PyObject_GC_UnTrack_PyObject_GenericGetAttr_PyObject_GenericSetAttr_PyObject_GetAttr_PyObject_GetItem_PyObject_HasAttr_PyObject_Hash_PyObject_Init_PyObject_InitVar_PyObject_IsInstance_PyObject_IsSubclass_PyObject_IsTrue_PyObject_Length_PyObject_Malloc_PyObject_Not_PyObject_Print_PyObject_Realloc_PyObject_Repr_PyObject_RichCompare_PyObject_RichCompareBool_PyObject_SelfIter_PyObject_SetAttr_PyObject_SetAttrString_PyObject_SetItem_PyObject_Size_PyObject_Str_PyObject_Type_PyObject_Unicode_PyParser_AddToken_PyParser_Delete_PyParser_New_PyParser_ParseFile_PyParser_ParseFileFlags_PyParser_ParseString_PyParser_ParseStringFlags_PyParser_ParseStringFlagsFilename_PyParser_SetError_PyParser_SimpleParseFile_PyParser_SimpleParseFileFlags_PyParser_SimpleParseString_PyParser_SimpleParseStringFilename_PyParser_SimpleParseStringFlags_PyParser_SimpleParseStringFlagsFilename_PyProperty_Type_PyRange_New_PyRange_Type_PyRun_AnyFile_PyRun_AnyFileEx_PyRun_AnyFileExFlags_PyRun_AnyFileFlags_PyRun_File_PyRun_FileEx_PyRun_FileExFlags_PyRun_FileFlags_PyRun_InteractiveLoop_PyRun_InteractiveLoopFlags_PyRun_InteractiveOne_PyRun_InteractiveOneFlags_PyRun_SimpleFile_PyRun_SimpleFileEx_PyRun_SimpleFileExFlags_PyRun_SimpleString_PyRun_SimpleStringFlags_PyRun_String_PyRun_StringFlags_PySeqIter_New_PySeqIter_Type_PySequence_Check_PySequence_Concat_PySequence_Contains_PySequence_Count_PySequence_DelItem_PySequence_DelSlice_PySequence_Fast_PySequence_GetItem_PySequence_GetSlice_PySequence_In_PySequence_InPlaceConcat_PySequence_InPlaceRepeat_PySequence_Index_PySequence_Length_PySequence_List_PySequence_Repeat_PySequence_SetItem_PySequence_SetSlice_PySequence_Size_PySequence_Tuple_PySlice_GetIndices_PySlice_GetIndicesEx_PySlice_New_PySlice_Type_PyStaticMethod_New_PyStaticMethod_Type_PyString_AsDecodedObject_PyString_AsDecodedString_PyString_AsEncodedObject_PyString_AsEncodedString_PyString_AsString_PyString_AsStringAndSize_PyString_Concat_PyString_Decode_PyString_DecodeEscape_PyString_Encode_PyString_Fini_PyString_Format_PyString_FromFormat_PyString_FromFormatV_PyString_FromString_PyString_FromStringAndSize_PyString_InternFromString_PyString_InternImmortal_PyString_InternInPlace_PyString_Repr_PyString_Size_PyString_Type_PyStructSequence_InitType_PyStructSequence_New_PyStructSequence_UnnamedField_PySuper_Type_PySymtableEntry_New_PySymtableEntry_Type_PySymtable_Free_PySys_AddWarnOption_PySys_GetFile_PySys_GetObject_PySys_ResetWarnOptions_PySys_SetArgv_PySys_SetObject_PySys_SetPath_PySys_WriteStderr_PySys_WriteStdout_PyThreadState_Clear_PyThreadState_Delete_PyThreadState_DeleteCurrent_PyThreadState_Get_PyThreadState_GetDict_PyThreadState_New_PyThreadState_Next_PyThreadState_SetAsyncExc_PyThreadState_Swap_PyThread__exit_thread_PyThread_acquire_lock_PyThread_allocate_lock_PyThread_create_key_PyThread_delete_key_PyThread_delete_key_value_PyThread_exit_thread_PyThread_free_lock_PyThread_get_key_value_PyThread_get_thread_ident_PyThread_init_thread_PyThread_release_lock_PyThread_set_key_value_PyThread_start_new_thread_PyToken_OneChar_PyToken_ThreeChars_PyToken_TwoChars_PyTokenizer_Free_PyTokenizer_FromFile_PyTokenizer_FromString_PyTokenizer_Get_PyTraceBack_Here_PyTraceBack_Print_PyTraceBack_Type_PyTupleIter_Type_PyTuple_Fini_PyTuple_GetItem_PyTuple_GetSlice_PyTuple_New_PyTuple_SetItem_PyTuple_Size_PyTuple_Type_PyType_GenericAlloc_PyType_GenericNew_PyType_Ready_PyUnicodeDecodeError_Create_PyUnicodeDecodeError_GetEncoding_PyUnicodeDecodeError_GetEnd_PyUnicodeDecodeError_GetObject_PyUnicodeDecodeError_GetReason_PyUnicodeDecodeError_GetStart_PyUnicodeDecodeError_SetEnd_PyUnicodeDecodeError_SetReason_PyUnicodeDecodeError_SetStart_PyUnicodeEncodeError_Create_PyUnicodeEncodeError_GetEncoding_PyUnicodeEncodeError_GetEnd_PyUnicodeEncodeError_GetObject_PyUnicodeEncodeError_GetReason_PyUnicodeEncodeError_GetStart_PyUnicodeEncodeError_SetEnd_PyUnicodeEncodeError_SetReason_PyUnicodeEncodeError_SetStart_PyUnicodeTranslateError_Create_PyUnicodeTranslateError_GetEnd_PyUnicodeTranslateError_GetObject_PyUnicodeTranslateError_GetReason_PyUnicodeTranslateError_GetStart_PyUnicodeTranslateError_SetEnd_PyUnicodeTranslateError_SetReason_PyUnicodeTranslateError_SetStart_PyUnicodeUCS4_AsASCIIString_PyUnicodeUCS4_AsCharmapString_PyUnicodeUCS4_AsEncodedString_PyUnicodeUCS4_AsLatin1String_PyUnicodeUCS4_AsRawUnicodeEscapeString_PyUnicodeUCS4_AsUTF16String_PyUnicodeUCS4_AsUTF8String_PyUnicodeUCS4_AsUnicode_PyUnicodeUCS4_AsUnicodeEscapeString_PyUnicodeUCS4_AsWideChar_PyUnicodeUCS4_Compare_PyUnicodeUCS4_Concat_PyUnicodeUCS4_Contains_PyUnicodeUCS4_Count_PyUnicodeUCS4_Decode_PyUnicodeUCS4_DecodeASCII_PyUnicodeUCS4_DecodeCharmap_PyUnicodeUCS4_DecodeLatin1_PyUnicodeUCS4_DecodeRawUnicodeEscape_PyUnicodeUCS4_DecodeUTF16_PyUnicodeUCS4_DecodeUTF8_PyUnicodeUCS4_DecodeUnicodeEscape_PyUnicodeUCS4_Encode_PyUnicodeUCS4_EncodeASCII_PyUnicodeUCS4_EncodeCharmap_PyUnicodeUCS4_EncodeDecimal_PyUnicodeUCS4_EncodeLatin1_PyUnicodeUCS4_EncodeRawUnicodeEscape_PyUnicodeUCS4_EncodeUTF16_PyUnicodeUCS4_EncodeUTF8_PyUnicodeUCS4_EncodeUnicodeEscape_PyUnicodeUCS4_Find_PyUnicodeUCS4_Format_PyUnicodeUCS4_FromEncodedObject_PyUnicodeUCS4_FromObject_PyUnicodeUCS4_FromOrdinal_PyUnicodeUCS4_FromUnicode_PyUnicodeUCS4_FromWideChar_PyUnicodeUCS4_GetDefaultEncoding_PyUnicodeUCS4_GetMax_PyUnicodeUCS4_GetSize_PyUnicodeUCS4_Join_PyUnicodeUCS4_Replace_PyUnicodeUCS4_Resize_PyUnicodeUCS4_SetDefaultEncoding_PyUnicodeUCS4_Split_PyUnicodeUCS4_Splitlines_PyUnicodeUCS4_Tailmatch_PyUnicodeUCS4_Translate_PyUnicodeUCS4_TranslateCharmap_PyUnicode_DecodeUTF7_PyUnicode_EncodeUTF7_PyUnicode_Type_PyWeakref_GetObject_PyWeakref_NewProxy_PyWeakref_NewRef_PyWrapperDescr_Type_PyWrapper_New_Py_AddPendingCall_Py_AtExit_Py_CompileString_Py_CompileStringFlags_Py_DebugFlag_Py_DivisionWarningFlag_Py_EndInterpreter_Py_Exit_Py_FdIsInteractive_Py_FileSystemDefaultEncoding_Py_Finalize_Py_FindMethod_Py_FindMethodInChain_Py_FlushLine_Py_FrozenFlag_Py_GetArgcArgv_Py_GetBuildInfo_Py_GetCompiler_Py_GetCopyright_Py_GetExecPrefix_Py_GetPath_Py_GetPlatform_Py_GetPrefix_Py_GetProgramFullPath_Py_GetProgramName_Py_GetPythonHome_Py_GetRecursionLimit_Py_GetVersion_Py_IgnoreEnvironmentFlag_Py_Initialize_Py_InteractiveFlag_Py_IsInitialized_Py_Main_Py_MakePendingCalls_Py_NewInterpreter_Py_NoSiteFlag_Py_OptimizeFlag_Py_ReprEnter_Py_ReprLeave_Py_SetProgramName_Py_SetPythonHome_Py_SetRecursionLimit_Py_SymtableString_Py_TabcheckFlag_Py_UnicodeFlag_Py_UniversalNewlineFgets_Py_UniversalNewlineFread_Py_UseClassExceptionsFlag_Py_VaBuildValue_Py_VerboseFlag__PyBuiltin_Init__PyCodec_Lookup__PyErr_BadInternalCall__PyEval_CallTracing__PyEval_SliceIndex__PyExc_Fini__PyExc_Init__PyFloat_Pack4__PyFloat_Pack8__PyFloat_Unpack4__PyFloat_Unpack8__PyFrame_Init__PyGC_Dump__PyGC_generation0__PyGILState_Fini__PyGILState_Init__PyImportHooks_Init__PyImport_DynLoadFiletab__PyImport_Filetab__PyImport_FindExtension__PyImport_Fini__PyImport_FixupExtension__PyImport_GetDynLoadFunc__PyImport_Init__PyImport_Inittab__PyImport_LoadDynamicModule__PyInstance_Lookup__PyInt_Init__PyLong_AsByteArray__PyLong_AsScaledDouble__PyLong_Copy__PyLong_FromByteArray__PyLong_New__PyLong_NumBits__PyLong_Sign__PyModule_Clear__PyOS_GetOpt__PyOS_optarg__PyOS_opterr__PyOS_optind__PyObject_Del__PyObject_Dump__PyObject_GC_Del__PyObject_GC_Malloc__PyObject_GC_New__PyObject_GC_NewVar__PyObject_GC_Resize__PyObject_GC_Track__PyObject_GC_UnTrack__PyObject_GetDictPtr__PyObject_New__PyObject_NewVar__PyObject_SlotCompare__PyParser_Grammar__PyParser_TokenNames__PySequence_IterSearch__PyString_Eq__PyString_FormatLong__PyString_Join__PyString_Resize__PySys_Init__PyThreadState_Current__PyThreadState_GetFrame__PyThread_Started__PyTrash_delete_later__PyTrash_delete_nesting__PyTrash_deposit_object__PyTrash_destroy_chain__PyTuple_Resize__PyType_Lookup__PyUnicodeUCS4_AsDefaultEncodedString__PyUnicodeUCS4_Fini__PyUnicodeUCS4_Init__PyUnicodeUCS4_IsAlpha__PyUnicodeUCS4_IsDecimalDigit__PyUnicodeUCS4_IsDigit__PyUnicodeUCS4_IsLinebreak__PyUnicodeUCS4_IsLowercase__PyUnicodeUCS4_IsNumeric__PyUnicodeUCS4_IsTitlecase__PyUnicodeUCS4_IsUppercase__PyUnicodeUCS4_IsWhitespace__PyUnicodeUCS4_ToDecimalDigit__PyUnicodeUCS4_ToDigit__PyUnicodeUCS4_ToLowercase__PyUnicodeUCS4_ToNumeric__PyUnicodeUCS4_ToTitlecase__PyUnicodeUCS4_ToUppercase__PyUnicode_TypeRecords__PyUnicode_XStrip__PyWeakref_CallableProxyType__PyWeakref_ClearRef__PyWeakref_GetWeakrefCount__PyWeakref_ProxyType__PyWeakref_RefType__Py_CheckInterval__Py_EllipsisObject__Py_HashDouble__Py_HashPointer__Py_Mangle__Py_NoneStruct__Py_NotImplementedStruct__Py_PackageContext__Py_QnewFlag__Py_ReadyTypes__Py_ReleaseInternedStrings__Py_Ticker__Py_TrueStruct__Py_ZeroStruct__Py_abstract_hack__Py_c_diff__Py_c_neg__Py_c_pow__Py_c_prod__Py_c_quot__Py_c_sum__Py_cobject_hack___darwin_gcc3_preregister_frame_info___progname__cplus_init__mh_execute_header__objcInit_catch_exception_raise_catch_exception_raise_state_catch_exception_raise_state_identity_clock_alarm_reply_do_mach_notify_dead_name_do_mach_notify_no_senders_do_mach_notify_port_deleted_do_mach_notify_send_once_do_seqnos_mach_notify_dead_name_do_seqnos_mach_notify_no_senders_do_seqnos_mach_notify_port_deleted_do_seqnos_mach_notify_send_once_environ_init_codecs_init_sre_init_symtable_initerrno_initgc_initimp_initposix_initsignal_initthread_initxxsubtype_initzipimport_main_receive_samplesstartdyld__mh_bundle_headerdyld_lazy_symbol_binding_entry_pointdyld_func_lookup_pointer/mnt/gmirror/ports/devel/py-cheetah/work/Cheetah-2.0/src/_namemapper.cgcc2_compiled._kwlist.0_kwlist.1_kwlist.2_kwlist.3_namemapper_methods_namemapper_valueForKey_namemapper_valueForName_namemapper_valueFromSearchList_namemapper_valueFromFrame_namemapper_valueFromFrameOrSearchList_NotFound_TooManyPeriods_pprintMod_pformatinit_namemapper:F(0,1)=(0,1)void:t(0,1)m:r(0,2)=*(0,3)=(0,4)=xs_object:PyObject:t(0,3)_object:T(0,4)=s8ob_refcnt:(0,5)=r(0,5);-2147483648;2147483647;,0,32;ob_type:(0,6)=*(0,7)=xs_typeobject:,32,32;;int:t(0,5)_typeobject:T(0,7)=s192ob_refcnt:(0,5),0,32;ob_type:(0,6),32,32;ob_size:(0,5),64,32;tp_name:(0,8)=*(0,9)=r(0,9);0;127;,96,32;tp_basicsize:(0,5),128,32;tp_itemsize:(0,5),160,32;tp_dealloc:(0,10)=(0,11)=*(0,12)=f(0,1),192,32;tp_print:(0,13)=(0,14)=*(0,15)=f(0,5),224,32;tp_getattr:(0,16)=(0,17)=*(0,18)=f(0,2),256,32;tp_setattr:(0,19)=(0,20)=*(0,21)=f(0,5),288,32;tp_compare:(0,22)=(0,23)=*(0,24)=f(0,5),320,32;tp_repr:(0,25)=(0,26)=*(0,27)=f(0,2),352,32;tp_as_number:(0,28)=*(0,29)=(0,30)=s152nb_add:(0,31)=(0,32)=*(0,33)=f(0,2),0,32;nb_subtract:(0,31),32,32;nb_multiply:(0,31),64,32;nb_divide:(0,31),96,32;nb_remainder:(0,31),128,32;nb_divmod:(0,31),160,32;nb_power:(0,34)=(0,35)=*(0,36)=f(0,2),192,32;nb_negative:(0,37)=(0,26),224,32;nb_positive:(0,37),256,32;nb_absolute:(0,37),288,32;nb_nonzero:(0,38)=(0,39)=*(0,40)=f(0,5),320,32;nb_invert:(0,37),352,32;nb_lshift:(0,31),384,32;nb_rshift:(0,31),416,32;nb_and:(0,31),448,32;nb_xor:(0,31),480,32;nb_or:(0,31),512,32;nb_coerce:(0,41)=(0,42)=*(0,43)=f(0,5),544,32;nb_int:(0,37),576,32;nb_long:(0,37),608,32;nb_float:(0,37),640,32;nb_oct:(0,37),672,32;nb_hex:(0,37),704,32;nb_inplace_add:(0,31),736,32;nb_inplace_subtract:(0,31),768,32;nb_inplace_multiply:(0,31),800,32;nb_inplace_divide:(0,31),832,32;nb_inplace_remainder:(0,31),864,32;nb_inplace_power:(0,34),896,32;nb_inplace_lshift:(0,31),928,32;nb_inplace_rshift:(0,31),960,32;nb_inplace_and:(0,31),992,32;nb_inplace_xor:(0,31),1024,32;nb_inplace_or:(0,31),1056,32;nb_floor_divide:(0,31),1088,32;nb_true_divide:(0,31),1120,32;nb_inplace_floor_divide:(0,31),1152,32;nb_inplace_true_divide:(0,31),1184,32;;,384,32;tp_as_sequence:(0,44)=*(0,45)=(0,46)=s40sq_length:(0,38),0,32;sq_concat:(0,31),32,32;sq_repeat:(0,47)=(0,48)=*(0,49)=f(0,2),64,32;sq_item:(0,47),96,32;sq_slice:(0,50)=(0,51)=*(0,52)=f(0,2),128,32;sq_ass_item:(0,53)=(0,54)=*(0,55)=f(0,5),160,32;sq_ass_slice:(0,56)=(0,57)=*(0,58)=f(0,5),192,32;sq_contains:(0,59)=(0,23),224,32;sq_inplace_concat:(0,31),256,32;sq_inplace_repeat:(0,47),288,32;;,416,32;tp_as_mapping:(0,60)=*(0,61)=(0,62)=s12mp_length:(0,38),0,32;mp_subscript:(0,31),32,32;mp_ass_subscript:(0,63)=(0,64)=*(0,65)=f(0,5),64,32;;,448,32;tp_hash:(0,66)=(0,67)=*(0,68)=f(0,69)=r(0,69);-2147483648;2147483647;,480,32;tp_call:(0,34),512,32;tp_str:(0,25),544,32;tp_getattro:(0,70)=(0,32),576,32;tp_setattro:(0,71)=(0,64),608,32;tp_as_buffer:(0,72)=*(0,73)=(0,74)=s16bf_getreadbuffer:(0,75)=(0,76)=*(0,77)=f(0,5),0,32;bf_getwritebuffer:(0,78)=(0,76),32,32;bf_getsegcount:(0,79)=(0,80)=*(0,81)=f(0,5),64,32;bf_getcharbuffer:(0,82)=(0,83)=*(0,84)=f(0,5),96,32;;,640,32;tp_flags:(0,69),672,32;tp_doc:(0,8),704,32;tp_traverse:(0,85)=(0,86)=*(0,87)=f(0,5),736,32;tp_clear:(0,38),768,32;tp_richcompare:(0,88)=(0,89)=*(0,90)=f(0,2),800,32;tp_weaklistoffset:(0,69),832,32;tp_iter:(0,91)=(0,26),864,32;tp_iternext:(0,92)=(0,26),896,32;tp_methods:(0,93)=*(0,94)=xsPyMethodDef:,928,32;tp_members:(0,95)=*(0,96)=xsPyMemberDef:,960,32;tp_getset:(0,97)=*(0,98)=xsPyGetSetDef:,992,32;tp_base:(0,6),1024,32;tp_dict:(0,2),1056,32;tp_descr_get:(0,99)=(0,35),1088,32;tp_descr_set:(0,100)=(0,64),1120,32;tp_dictoffset:(0,69),1152,32;tp_init:(0,101)=(0,64),1184,32;tp_alloc:(0,102)=(0,103)=*(0,104)=f(0,2),1216,32;tp_new:(0,105)=(0,106)=*(0,107)=f(0,2),1248,32;tp_free:(0,108)=(0,109)=*(0,110)=f(0,1),1280,32;tp_is_gc:(0,38),1312,32;tp_bases:(0,2),1344,32;tp_mro:(0,2),1376,32;tp_cache:(0,2),1408,32;tp_subclasses:(0,2),1440,32;tp_weaklist:(0,2),1472,32;tp_del:(0,10),1504,32;;char:t(0,9)destructor:t(0,10)printfunc:t(0,13)getattrfunc:t(0,16)setattrfunc:t(0,19)cmpfunc:t(0,22)reprfunc:t(0,25)PyNumberMethods:t(0,29)binaryfunc:t(0,31)ternaryfunc:t(0,34)unaryfunc:t(0,37)inquiry:t(0,38)coercion:t(0,41)PySequenceMethods:t(0,45)intargfunc:t(0,47)intintargfunc:t(0,50)intobjargproc:t(0,53)intintobjargproc:t(0,56)objobjproc:t(0,59)PyMappingMethods:t(0,61)objobjargproc:t(0,63)hashfunc:t(0,66)long int:t(0,69)getattrofunc:t(0,70)setattrofunc:t(0,71)PyBufferProcs:t(0,73)getreadbufferproc:t(0,75)getwritebufferproc:t(0,78)getsegcountproc:t(0,79)getcharbufferproc:t(0,82)traverseproc:t(0,85)richcmpfunc:t(0,88)getiterfunc:t(0,91)iternextfunc:t(0,92)PyMethodDef:T(0,94)=s16ml_name:(0,8),0,32;ml_meth:(0,111)=(0,32),32,32;ml_flags:(0,5),64,32;ml_doc:(0,8),96,32;;PyGetSetDef:T(0,98)=s20name:(0,8),0,32;get:(0,112)=(0,113)=*(0,114)=f(0,2),32,32;set:(0,115)=(0,116)=*(0,117)=f(0,5),64,32;doc:(0,8),96,32;closure:(0,118)=*(0,1),128,32;;descrgetfunc:t(0,99)descrsetfunc:t(0,100)initproc:t(0,101)allocfunc:t(0,102)newfunc:t(0,105)freefunc:t(0,108)PyCFunction:t(0,111)getter:t(0,112)setter:t(0,115)d:r(0,2)pprintMod:r(0,2)_PyNamemapper_valueForKeynamemapper_valueForKey:f(0,2)self:p(0,2)args:p(0,2)args:r(0,2)obj:(0,2)key:(0,8)_getNameChunks_PyNamemapper_valueForName_wrapInternalNotFoundExceptionnamemapper_valueForName:f(0,2)self:p(0,2)args:p(0,2)keywds:p(0,2)args:r(0,2)keywds:r(0,2)obj:(0,2)name:(0,8)executeCallables:(0,5)nameCopy:r(0,8)tmpPntr1:r(0,8)tmpPntr2:r(0,8)nameChunks:(0,119)=ar(0,120)=r(0,120);0000000000000;0037777777777;;0;14;(0,8)long unsigned int:t(0,121)=r(0,121);0000000000000;0037777777777;numChunks:r(0,5)theValue:r(0,2)kwlist:V(0,122)=ar(0,120);0;3;(0,8)obj:(0,2)name:(0,8)executeCallables:(0,5)nameCopy:r(0,8)tmpPntr1:r(0,8)tmpPntr2:r(0,8)nameChunks:(0,119)numChunks:r(0,5)theValue:r(0,2)kwlist:V(0,122)namemapper_valueFromSearchList:f(0,2)self:p(0,2)args:p(0,2)keywds:p(0,2)args:r(0,2)keywds:r(0,2)searchList:(0,2)name:(0,8)executeCallables:(0,5)nameCopy:(0,8)tmpPntr1:r(0,8)tmpPntr2:r(0,8)nameChunks:(0,119)numChunks:(0,5)nameSpace:r(0,2)theValue:(0,2)iterator:(0,2)kwlist:V(0,123)=ar(0,120);0;3;(0,8)key:r(0,8)searchList:(0,2)name:(0,8)executeCallables:(0,5)nameCopy:(0,8)tmpPntr1:r(0,8)tmpPntr2:r(0,8)nameChunks:(0,119)numChunks:(0,5)nameSpace:r(0,2)theValue:(0,2)iterator:(0,2)kwlist:V(0,123)key:r(0,8)exceptionStr:(0,2)exceptionStr:(0,2)namemapper_valueFromFrameOrSearchList:f(0,2)self:p(0,2)args:p(0,2)keywds:p(0,2)args:r(0,2)keywds:r(0,2)name:(0,8)executeCallables:(0,5)searchList:(0,2)nameCopy:(0,8)tmpPntr1:r(0,8)tmpPntr2:r(0,8)nameChunks:(0,119)numChunks:(0,5)nameSpace:r(0,2)theValue:(0,2)excString:(0,2)iterator:(0,2)kwlist:V(0,124)=ar(0,120);0;3;(0,8)key:r(0,8)key:r(0,8)name:(0,8)executeCallables:(0,5)searchList:(0,2)nameCopy:(0,8)tmpPntr1:r(0,8)tmpPntr2:r(0,8)nameChunks:(0,119)numChunks:(0,5)nameSpace:r(0,2)theValue:(0,2)excString:(0,2)iterator:(0,2)kwlist:V(0,124)key:r(0,8)key:r(0,8)key:r(0,8)key:r(0,8)key:r(0,8)key:r(0,8)exceptionStr:(0,2)key:r(0,8)exceptionStr:(0,2)key:r(0,8)exceptionStr:(0,2)namemapper_valueFromFrame:f(0,2)self:p(0,2)args:p(0,2)keywds:p(0,2)args:r(0,2)keywds:r(0,2)name:(0,8)executeCallables:(0,5)tmpPntr1:r(0,8)tmpPntr2:r(0,8)nameCopy:(0,8)nameChunks:(0,119)numChunks:(0,5)nameSpace:r(0,2)theValue:(0,2)excString:(0,2)kwlist:V(0,125)=ar(0,120);0;2;(0,8)key:r(0,8)key:r(0,8)name:(0,8)executeCallables:(0,5)tmpPntr1:r(0,8)tmpPntr2:r(0,8)nameCopy:(0,8)nameChunks:(0,119)numChunks:(0,5)nameSpace:r(0,2)theValue:(0,2)excString:(0,2)kwlist:V(0,125)key:r(0,8)key:r(0,8)key:r(0,8)key:r(0,8)key:r(0,8)exceptionStr:(0,2)key:r(0,8)exceptionStr:(0,2)key:r(0,8)exceptionStr:(0,2)wrapInternalNotFoundException:f(0,5)fullName:p(0,8)namespace:p(0,2)excType:(0,2)excValue:(0,2)excTraceback:(0,2)isAlreadyWrapped:r(0,2)getNameChunks:f(0,5)nameChunks:p(0,126)=*(0,8)name:p(0,8)nameCopy:p(0,8)name:r(0,8)nameCopy:r(0,8)c:r(0,9)currChunk:r(0,8)currChunkNum:r(0,5)PyNamemapper_valueForKey:f(0,2)obj:p(0,2)key:p(0,8)key:r(0,8)theValue:(0,2)theValue:(0,2)exceptionStr:(0,2)PyNamemapper_valueForName:f(0,2)obj:p(0,2)nameChunks:p(0,126)numChunks:p(0,5)executeCallables:p(0,5)i:(0,5)currentKey:r(0,8)currentVal:r(0,2)nextVal:r(0,2)exceptionStr:(0,2)exceptionStr:(0,2)NotFound:S(0,2)TooManyPeriods:S(0,2)pprintMod_pformat:S(0,2)namemapper_methods:S(0,127)=ar(0,120);0;5;(0,94)PKܡ(8,,Cheetah/Template.pyc; Gc@sdZdZddd!ZdkZdkZdkZdkZdkZdk Z dk l Z dk Z dk Z dkZdkZdkZdkZdkZdklZlZydklZWn%ej oeieifZnXyd klZeZWnej o eZnXyd klZWn&ej od fd YZnXd klZl Z dkl!Z!dk"l#Z#dk$l%Z%l&Z&dk'l(Z(l)Z)dk*l+Z+dk*l,Z,dk-l.Z.dk/l0Z0dk1l2Z2dk3l4Z4dk5l6Z6l7Z7dk8l9Z9l:Z:dk;l<Z<dk=l>Z>l?Z?l@Z@dkAlBZBdeCfdYZDdeDfd YZEd!ZFd"ZGd#ZHeIaJd$ZKd%ZLd&fd'YZMd(fd)YZNd*e#fd+YZOeOZPd,ZQdS(-sProvides the core API for Cheetah. See the docstring in the Template class and the Users' Guide for more information Meta-Data ================================================================================ Author: Tavis Rudd License: This software is released for unlimited distribution under the terms of the MIT license. See the LICENSE file. Version: $Revision: 1.185 $ Start Date: 2001/03/30 Last Revision Date: $Date: 2007/10/02 01:36:26 $ s!Tavis Rudd s$Revision: 1.185 $i iN(s randrange(s StringTypes ClassType(s StringTypes(s BooleanType(sLocksLockcBstZdZdZRS(NcCsdS(N((sself((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/Template.pysacquire2scCsdS(N((sself((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/Template.pysrelease3s(s__name__s __module__sacquiresrelease(((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/Template.pysLock1s (sconvertVersionStringToTuplesMinCompatibleVersionTuple(sMinCompatibleVersion(sServlet(s ParseErrors SourceReader(sCompilersDEFAULT_COMPILER_SETTINGS(s ErrorCatchers(sFilters(sconvertTmplPathToModuleName(s VerifyType(s checkKeywords(sIndenter(sNotFoundsvalueFromSearchList(sMemoryCacheStoresMemcachedCacheStore(s CacheRegion(s _Converters_lookupsNonNumericInputError(s UnspecifiedsErrorcBstZRS(N(s__name__s __module__(((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/Template.pysErrorJssPreprocessErrorcBstZRS(N(s__name__s __module__(((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/Template.pysPreprocessErrorKscCsxg}x[|D]S}t|tot|}n!t|tot|}n|i|q Wt t |SdS(N( s hashedListslsvs isinstancesdictshashDictslistshashListsappendshashstuple(sls hashedListsv((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/Template.pyshashListMscCs|i}|ig}xg|D]_\}}t|tot|}n!t|t ot |}n|i ||fq#Wt t |SdS(N(sdsitemsssorts hashedListsksvs isinstancesdictshashDictslistshashListsappendshashstuple(sdsitemssks hashedListsv((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/Template.pyshashDictWs   cCs\|tijo |}n;d|ttiiddttddf}|SdS(s=The calling code is responsible for concurrency locking. scheetah_%s_%s_%ss.s_i'iN(sbaseModuleNamessyssmoduless finalNamesstrstimesreplaces randrange(sbaseModuleNames finalName((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/Template.pys_genUniqueModuleNamefs  :cCs|tj o|Sn|SdS(N(svals Unspecifiedsdefault(svalsdefault((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/Template.pys valOrDefaultvs cCsPdk}t|}ti}|i}|}||||f|i |ed4Z?e?Z@eeeeeeed5ZAd6ZBd7ZCeed&e1eeed8ZDeee)eed9ZEed:ed;ZFd<ZGfd=d>d?d@d?d@edAZHRS(BsRThis class provides a) methods used by templates at runtime and b) methods for compiling Cheetah source code into template classes. This documentation assumes you already know Python and the basics of object oriented programming. If you don't know Python, see the sections of the Cheetah Users' Guide for non-programmers. It also assumes you have read about Cheetah's syntax in the Users' Guide. The following explains how to use Cheetah from within Python programs or via the interpreter. If you statically compile your templates on the command line using the 'cheetah' script, this is not relevant to you. Statically compiled Cheetah template modules/classes (e.g. myTemplate.py: MyTemplateClasss) are just like any other Python module or class. Also note, most Python web frameworks (Webware, Aquarium, mod_python, Turbogears, CherryPy, Quixote, etc.) provide plugins that handle Cheetah compilation for you. There are several possible usage patterns: 1) tclass = Template.compile(src) t1 = tclass() # or tclass(namespaces=[namespace,...]) t2 = tclass() # or tclass(namespaces=[namespace2,...]) outputStr = str(t1) # or outputStr = t1.aMethodYouDefined() Template.compile provides a rich and very flexible API via its optional arguments so there are many possible variations of this pattern. One example is: tclass = Template.compile('hello $name from $caller', baseclass=dict) print tclass(name='world', caller='me') See the Template.compile() docstring for more details. 2) tmplInstance = Template(src) # or Template(src, namespaces=[namespace,...]) outputStr = str(tmplInstance) # or outputStr = tmplInstance.aMethodYouDefined(...args...) Notes on the usage patterns: usage pattern 1) This is the most flexible, but it is slightly more verbose unless you write a wrapper function to hide the plumbing. Under the hood, all other usage patterns are based on this approach. Templates compiled this way can #extend (subclass) any Python baseclass: old-style or new-style (based on object or a builtin type). usage pattern 2) This was Cheetah's original usage pattern. It returns an instance, but you can still access the generated class via tmplInstance.__class__. If you want to use several different namespace 'searchLists' with a single template source definition, you're better off with Template.compile (1). Limitations (use pattern 1 instead): - Templates compiled this way can only #extend subclasses of the new-style 'object' baseclass. Cheetah.Template is a subclass of 'object'. You also can not #extend dict, list, or other builtin types. - If your template baseclass' __init__ constructor expects args there is currently no way to pass them in. If you need to subclass a dynamically compiled Cheetah class, do something like this: from Cheetah.Template import Template T1 = Template.compile('$meth1 #def meth1: this is meth1 in T1') T2 = Template.compile('#implements meth1 this is meth1 redefined in T2', baseclass=T1) print T1, T1() print T2, T2() Note about class and instance attribute names: Attributes used by Cheetah have a special prefix to avoid confusion with the attributes of the templates themselves or those of template baseclasses. Class attributes which are used in class methods look like this: klass._CHEETAH_useCompilationCache (_CHEETAH_xxx) Instance attributes look like this: klass._CHEETAH__globalSetVars (_CHEETAH__xxx with 2 underscores) s_initCheetahInstances searchLists errorCatchersgetVars varExistssgetFileContentssi18nsrunAsMainProgramsrespondsshutdownswebInputsserverSidePathsgeneratedClassCodesgeneratedModuleCodes_getCacheStores_getCacheStoreIdPrefixs_createCacheRegionsgetCacheRegionsgetCacheRegionss refreshCaches_handleCheetahIncludes2_getTemplateAPIClassForIncludeDirectiveCompilationssubclassscacheRegionClasss cacheStorescacheStoreIdPrefixscacheStoreClasss"DynamicallyCompiledCheetahTemplatecCs |iSdS(N(sklasss_CHEETAH_compilerClass(sklassssourcesfile((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/Template.pys_getCompilerClass?scCs |iSdS(N(sklasss_CHEETAH_compilerSettings(sklassssourcesfile((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/Template.pys_getCompilerSettingsCsc2 Bsy<ei}ei}ei}#ei}$ei }%ei }ei }ei}ei}"ei}*eo ei}n||d|#|$|%gd||d|#|$|%|gde| |i} e| eo | i } n|| d|#|$|e!gde| |i#} eo|| d|*|gdne| |i%} eo|| d|*|gdne||i'||ph}||d |gd e||i)||}e| |i+} e||i-}eo|| d|*|gdn||d |#|$gde/}!| o=|oe!|e1joe2|}|}!qe|i3}ne||i5}||d |#|$gd|p|}e||i7}||d |#|$gde| |i9} e||i;}eo||d|*|gdne||i=}||d|#|$gdWn!e>j o},e>|,nX| o%|}0|iA||| \}}ne/}/e/}1| oQe!| e1jo | }1qe!| ee!fjod| iD}1| }/qne/}e/}|pe|eGeHfoe/}|oeJ|}ne/}(| oeJ| }(ne/}|o,eGeM|eGeNiOiP|}nypdiQgiR}eM|||||eM|eM| ||(eM|g D]}|eG|q~}Wq q Xn| o|o ||iUjo|iU|}|iV}-nK|||d |d|d|1d |d|ph})|)iY|)iZ}-| o|-Sn|oe\i\|_]|iSnz|i^i_e`|}.|.d} |oeNiOic| oedd|neNiOiQ|| } yee| dif|-Wqnegj oehiidejikqnXnelim|.}| o1x.| ioD]\}+}eq||+|qWn| |_b|!oeNiOic|!o |!|_0n| o|/oeq||1|/ny!eY|-| d}||isUWnetj o[}&yev|||-d|&}Wn-ehiiex| |-|-|&_W|&qX|n/edj o"}&ex| |-|-|&_WnX|ejiy|.||d(if module, must contain subclasses of Cheetah.Filters.Filter)s errorCatchersstring, class or NonesB(if class, must be subclass of Cheetah.ErrorCatchers.ErrorCatcher)scompilerSettingss dictionarys-you must supply either a source string or thes& 'file' keyword argument, but not boths_CHEETAH_versionTupleslThis template was compiled with Cheetah version %s. Templates compiled before version %s must be recompiled.s searchLists namespacess_globalSetVarss_preBuiltSearchListN(<stypess StringTypesSs UnicodeTypesUsListTypesLs TupleTypesTsDictTypesDsFileTypesFs ClassTypesCs ModuleTypesMsNoneTypesNs VerifyTypesvtsVerifyTypeClasssvtcssourcesfilesfilterstypesFilterssFilters filtersLibs errorCatchers ErrorCatcherss ErrorCatcherscompilerSettingss Unspecifieds TypeErrorsreasonsNonesServlets__init__sselfshasattrssyssmoduless __class__s __module__smods__CHEETAH_version__scompiledVersionsconvertVersionStringToTuplescompiledVersionTuplesMinCompatibleVersionTuplesAssertionErrorsMinCompatibleVersions_initCheetahInstances searchLists namespacess_globalSetVarss_preBuiltSearchLists_compile(sselfssources namespacess searchListsfilesfilters filtersLibs errorCatcherscompilerSettingss_globalSetVarss_preBuiltSearchListsvtscompiledVersionTuplesvtcscompiledVersionsCsDsFsMsLsNsSsTsmodsreasonsU((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/Template.pys__init__sXx          cCs |iSdS(seReturn the module code the compiler generated, or None if no compilation took place. N(sselfs_CHEETAH_generatedModuleCode(sself((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/Template.pysgeneratedModuleCodescCs*|i|iid|iid!SdS(sdReturn the class code the compiler generated, or None if no compilation took place. s class s ## END CLASS DEFINITIONN(sselfs_CHEETAH_generatedModuleCodesfind(sself((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/Template.pysgeneratedClassCodescCs |iSdS(s-Return a reference to the searchlist N(sselfs_CHEETAH__searchList(sself((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/Template.pys searchListscCs |iSdS(s7Return a reference to the current errorCatcher N(sselfs_CHEETAH__errorCatcher(sself((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/Template.pys errorCatcherscCsI|i o3|itj o|i|_q>|i|_n|iSdS(N(sselfs_CHEETAH__cacheStores_CHEETAH_cacheStoresNones_CHEETAH_cacheStoreClass(sself((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/Template.pys_getCacheStores  cCs/|itj o |iSntt|SdS(N(sselfs_CHEETAH_cacheStoreIdPrefixsNonesstrsid(sself((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/Template.pys_getCacheStoreIdPrefixs cCs,|id|d|id|iSdS(NsregionIDstemplateCacheIdPrefixs cacheStore(sselfs_CHEETAH_cacheRegionClasssregionIDs_getCacheStoreIdPrefixs_getCacheStore(sselfsregionID((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/Template.pys_createCacheRegions  cCsI|ii|}| o|o |i|}||i| tags. ** KLUDGE: 'debug' is supposed to insert into the template output, but it wasn't working so I changed it to a'print' statement. So the debugging output will appear wherever standard output is pointed, whether at the terminal, in a Webware log file, or whatever. *** Since we didn't specify any coversions, the value is a string. It's a 'single' value because we specified it in 'names' rather than 'namesMulti'. Single values work like this: * If one value is found, take it. * If several values are found, choose one arbitrarily and ignore the rest. * If no values are found, use or raise the appropriate 'default*' value. Multi values work like this: * If one value is found, put it in a list. * If several values are found, leave them in a list. * If no values are found, use the empty list ([]). The 'default*' arguments are *not* consulted in this case. Example: assume 'days' came from a set of checkboxes or a multiple combo box on a form, and the user chose'Monday', 'Tuesday' and 'Thursday'. #silent $webInput([], ['days']) The days you chose are: #slurp #for $day in $days $day #slurp #end for dic = self.webInput([], ['days']) write('The days you chose are: ') for day in dic['days']: write(day + ' ') Both these examples print: 'The days you chose are: Monday Tuesday Thursday'. By default, missing strings are replaced by '' and missing/bad numbers by zero. (A'bad number' means the converter raised an exception for it, usually because of non-numeric characters in the value.) This mimics Perl/PHP behavior, and simplifies coding for many applications where missing/bad values *should* be blank/zero. In those relatively few cases where you must distinguish between empty-string/zero on the one hand and missing/bad on the other, change the appropriate 'default*' and 'bad*' arguments to something like: * None * another constant value * $NonNumericInputError/self.NonNumericInputError * $ValueError/ValueError (NonNumericInputError is defined in this class and is useful for distinguishing between bad input vs a TypeError/ValueError thrown for some other rason.) Here's an example using multiple values to schedule newspaper deliveries. 'checkboxes' comes from a form with checkboxes for all the days of the week. The days the user previously chose are preselected. The user checks/unchecks boxes as desired and presses Submit. The value of 'checkboxes' is a list of checkboxes that were checked when Submit was pressed. Our task now is to turn on the days the user checked, turn off the days he unchecked, and leave on or off the days he didn't change. dic = self.webInput([], ['dayCheckboxes']) wantedDays = dic['dayCheckboxes'] # The days the user checked. for day, on in self.getAllValues(): if not on and wantedDays.has_key(day): self.TurnOn(day) # ... Set a flag or insert a database record ... elif on and not wantedDays.has_key(day): self.TurnOff(day) # ... Unset a flag or delete a database record ... 'source' allows you to look up the variables from a number of different sources: 'f' fields (CGI GET/POST parameters) 'c' cookies 's' session variables 'v' 'values', meaning fields or cookies In many forms, you're dealing only with strings, which is why the 'default' argument is third and the numeric arguments are banished to the end. But sometimes you want automatic number conversion, so that you can do numeric comparisions in your templates without having to write a bunch of conversion/exception handling code. Example: #silent $webInput(['name', 'height:int']) $name is $height cm tall. #if $height >= 300 Wow, you're tall! #else Pshaw, you're short. #end if dic = self.webInput(['name', 'height:int']) name = dic[name] height = dic[height] write('%s is %s cm tall.' % (name, height)) if height > 300: write('Wow, you're tall!') else: write('Pshaw, you're short.') To convert a value to a number, suffix ':int' or ':float' to the name. The method will search first for a 'height:int' variable and then for a 'height' variable. (It will be called 'height' in the final dictionary.) If a numeric conversion fails, use or raise 'badInt' or 'badFloat'. Missing values work the same way as for strings, except the default is 'defaultInt' or 'defaultFloat' instead of 'default'. If a name represents an uploaded file, the entire file will be read into memory. For more sophistocated file-upload handling, leave that name out of the list and do your own handling, or wait for Cheetah.Utils.UploadFileMixin. This only in a subclass that also inherits from Webware's Servlet or HTTPServlet. Otherwise you'll get an AttributeError on 'self.request'. EXCEPTIONS: ValueError if 'source' is not one of the stated characters. TypeError if a conversion suffix is not ':int' or ':float'. FUTURE EXPANSION: a future version of this method may allow source cascading; e.g., 'vs' would look first in 'values' and then in session variables. Meta-Data ================================================================================ Author: Mike Orr License: This software is released for unlimited distribution under the terms of the MIT license. See the LICENSE file. Version: $Revision: 1.185 $ Start Date: 2002/03/17 Last Revision Date: $Date: 2007/10/02 01:36:26 $ sfsvsfieldscs#can't get cookies from a CGI scriptsss-can't get session variables from a CGI scriptsvaluessessionscookiesarg 'src' invalidssstringsintsfloats
    s	
    
    iN(+ssrcslowersselfs_CHEETAH__isControlledByWebKitsisCgis_formUsedByWebInputsNonescgis FieldStoragesgetvaluessourcesfuncs RuntimeErrorsrequestsvaluessessionsfieldscookies TypeErrorssourcess _Convertersdefaultsints defaultIntsbadIntsfloats defaultFloatsbadFloats converterssdicsnamessnames_lookupsFalsesksvs namesMultisTruesdebugspprintspformats searchListsinsert(sselfsnamess namesMultisdefaultssrcs defaultInts defaultFloatsbadIntsbadFloatsdebugssourcesssources converterssisCgisfuncsnamesksdicsv((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/Template.pyswebInput sP   %    %  N(Is__name__s __module__s__doc__s_CHEETAH_requiredCheetahMethodss$_CHEETAH_requiredCheetahClassMethodss'_CHEETAH_requiredCheetahClassAttributessFalses&_CHEETAH_cacheModuleFilesForTracebackssNones_CHEETAH_cacheDirForModuleFilessdicts_CHEETAH_compileCachesLocks_CHEETAH_compileLocks_CHEETAH_defaultMainMethodNames_CHEETAH_compilerSettingssCompilers_CHEETAH_compilerClasssTrues _CHEETAH_cacheCompilationResultss_CHEETAH_useCompilationCaches_CHEETAH_keepRefToGeneratedCodes%_CHEETAH_defaultBaseclassForTemplatess%_CHEETAH_defaultClassNameForTemplatess*_CHEETAH_defaultMainMethodNameForTemplatess&_CHEETAH_defaultModuleNameForTemplatess)_CHEETAH_defaultModuleGlobalsForTemplatess_CHEETAH_preprocessorssTemplatePreprocessors!_CHEETAH_defaultPreprocessorClasss_CHEETAH_generatedModuleCodesNonNumericInputErrors CacheRegions_CHEETAH_cacheRegionClasssMemoryCacheStores_CHEETAH_cacheStoreClasss_CHEETAH_cacheStores_CHEETAH_cacheStoreIdPrefixs_getCompilerClasss classmethods_getCompilerSettingss Unspecifiedscompilessubclasss_preprocessSources_normalizePreprocessorArgs_normalizePreprocessorSettingss#_updateSettingsWithPreprocessTokenss_addCheetahPlumbingCodeToClasssFilterss__init__sgeneratedModuleCodesgeneratedClassCodes searchLists errorCatchers_getCacheStores_getCacheStoreIdPrefixs_createCacheRegionsgetCacheRegionsgetCacheRegionss refreshCachesshutdownsgetVars varExistsshasVarsi18nsgetFileContentssrunAsMainPrograms_initCheetahInstances_compiles_handleCheetahIncludes2_getTemplateAPIClassForIncludeDirectiveCompilationswebInput(((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/Template.pysTemplates MH     9      6    1 '        ! P!, cCs`t|ttfo|pt}ti} ti d| | i }t |do |i}n"ttid|id}|i}g} xPtddD]?}||djoPn| i|d||||fqWg} xStddD]B}||t|j oPn| i|||||fqW| id}|d7}x@| o8| i} |dhd | d<d | d<7}qgWt |d o$|d d |i!pdd7}nx@| o8| i} |dhd | d<d | d<7}qWddddt|d|ddg}tid|} | o;t| id}t| id}|idnt}t}tiddi%|t&|dd} | oHt| id}t| id}|id|idndi%|}t'|d|}t*||d|d|SdS(Nislinenos[ ]*File.*line (\d+)iisLine|Python Code sC----|------------------------------------------------------------- s%(row)-4d|%(line)s srowslinesoffsets is^ sCError in the Python code which Cheetah generated for this template:s=iPssline (\d+), col (\d+)is) Here is the corresponding Cheetah code: s s( Here is the corresponding Cheetah code.sM** I had to guess the line & column numbers, so they are probably incorrect: sfilenamescol(+s isinstancesfilesstrsunicodesNonesfilenamesStringIOssios tracebacks print_excsgetvalues formatedExcshasattrs exceptionslinenospyLinenosintsressearchsgroupsgeneratedPyCodes splitlinessliness prevLinessrangesisappends nextLinesslensreversesreportspopslineInfosoffsetsmessagescheetahPosMatchscolsjoinsmaxs SourceReaderssourcesreaders ParseError(ssourcesfilesgeneratedPyCodes exceptionsmessagesfilenameslinenosreaderspyLinenossios nextLinesslineInfoscheetahPosMatchs prevLinessreportsisliness formatedExcscol((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/Template.pys!genParserErrorFromPythonExceptionsf#   ! '#   -$ -)  # (Rs__doc__s __author__s __revision__ssyssresnewsstringsos.pathsosstimesrandoms randrangesimpsinspectsStringIOs tracebackspprintscgistypess StringTypes ClassTypes StringTypess ImportErrors UnicodeTypes BooleanTypesTruesboolTypeAvailablesFalses threadingsLocksCheetah.VersionsconvertVersionStringToTuplesMinCompatibleVersionTuplesMinCompatibleVersionsCheetah.ServletsServletsCheetah.Parsers ParseErrors SourceReadersCheetah.CompilersCompilersDEFAULT_COMPILER_SETTINGSsCheetahs ErrorCatcherssFilterss#Cheetah.convertTmplPathToModuleNamesconvertTmplPathToModuleNames Cheetah.Utilss VerifyTypesCheetah.Utils.Miscs checkKeywordssCheetah.Utils.IndentersIndentersCheetah.NameMappersNotFoundsvalueFromSearchListsCheetah.CacheStoresMemoryCacheStoresMemcachedCacheStoresCheetah.CacheRegions CacheRegionsCheetah.Utils.WebInputMixins _Converters_lookupsNonNumericInputErrorsCheetah.Unspecifieds Unspecifieds ExceptionsErrorsPreprocessErrorshashListshashDicts_genUniqueModuleNamesNones_formUsedByWebInputs valOrDefaultsupdateLinecachesCompileCacheItemsTemplatePreprocessorsTemplatesTs!genParserErrorFromPythonException(9shashListsboolTypeAvailablesconvertTmplPathToModuleNames randrangesServlets _ConvertersMemcachedCacheStoresMinCompatibleVersions valOrDefaultsTemplates BooleanTypesFilterssMemoryCacheStoresPreprocessErrors StringTypes __revision__s_lookupsresvalueFromSearchListspprints ErrorCatcherssimps UnspecifiedsLocks StringTypessMinCompatibleVersionTuplesCompilerscgisstringsNotFoundsinspects __author__ssyssIndenters SourceReadersErrorsnewshashDicts CacheRegions ParseErrorstypess_genUniqueModuleNamesconvertVersionStringToTuplesCompileCacheItemsStringIOs ClassTypesupdateLinecaches tracebacks!genParserErrorFromPythonExceptions VerifyTypesTemplatePreprocessors checkKeywordssDEFAULT_COMPILER_SETTINGSstimesNonNumericInputErrorsossT((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/Template.pys?s                                )HPKݡ(8ThCheetah/Version.pyc; Gc@sQdZdddddfZdZdddddfZdZedjoeZed GHed GHed GHedGHed GHed edjptededjpteded jpted edjpteded jptededjpted ed jpteded jpteded jpteded jpteded jpteded jptededjpted ed jptndS(s2.0iisfinals2.0rc6s candidateicCsHdddg}d}d}|iddjo|id\}}d}nq|iddjo|id\}}d}n<|iddjo|id\}}d }n|}|id }x.tt|D]}t |||| Version: $Revision: 1.13 $ Start Date: 2001/08/30 Last Revision Date: $Date: 2005/11/13 01:12:13 $ s!Tavis Rudd s$Revision: 1.13 $i icCsdS(N((((s=build/bdist.darwin-8.0.1-i386/egg/Cheetah/DummyTransaction.pysflushss DummyResponsecBs tZdZdZdZRS(sA dummy Response class is used by Cheetah in place of real Webware Response objects when the Template obj is not used directly as a Webware servlet. csTg|_}|i|_|d}||_d}||_t|_dS(NcCsdi|SdS(Ns(sjoins outputChunks(s outputChunks((s=build/bdist.darwin-8.0.1-i386/egg/Cheetah/DummyTransaction.pysgetvaluescs|ddS(Ns (swritestxt(stxt(swrite(s=build/bdist.darwin-8.0.1-i386/egg/Cheetah/DummyTransaction.pyswriteln#s (sselfs _outputChunkss outputChunkssappendswritesgetvalueswritelnsflush(sselfswritelns outputChunkssgetvalueswrite((swrites=build/bdist.darwin-8.0.1-i386/egg/Cheetah/DummyTransaction.pys__init__s     cGs2gi}|D]}||i|q~dS(N(sappends_[1]slinesslnsselfswriteln(sselfsliness_[1]sln((s=build/bdist.darwin-8.0.1-i386/egg/Cheetah/DummyTransaction.pys writelines)s(s__name__s __module__s__doc__s__init__s writelines(((s=build/bdist.darwin-8.0.1-i386/egg/Cheetah/DummyTransaction.pys DummyResponses  sDummyTransactioncBstZdZedZRS(sA dummy Transaction class is used by Cheetah in place of real Webware transactions when the Template obj is not used directly as a Webware servlet. It only provides a response object and method. All other methods and attributes make no sense in this context. cCs|d}||_dS(NcCs|SdS(N(sresp(sresp((s=build/bdist.darwin-8.0.1-i386/egg/Cheetah/DummyTransaction.pysresponse8s(s DummyResponsesresponsesself(sselfs DummyResponsesresponse((s=build/bdist.darwin-8.0.1-i386/egg/Cheetah/DummyTransaction.pys__init__7s(s__name__s __module__s__doc__s DummyResponses__init__(((s=build/bdist.darwin-8.0.1-i386/egg/Cheetah/DummyTransaction.pysDummyTransaction-s N(s__doc__s __author__s __revision__sflushs DummyResponsesDummyTransaction(s DummyResponsesDummyTransactions __revision__sflushs __author__((s=build/bdist.darwin-8.0.1-i386/egg/Cheetah/DummyTransaction.pys?s   PK ;4  Cheetah/CacheStore.py"""Provides several CacheStore backends for Cheetah's caching framework. The methods provided by these classes have the same semantics as those in the python-memcached API, except for their return values: set(key, val, time=0) set the value unconditionally add(key, val, time=0) set only if the server doesn't already have this key replace(key, val, time=0) set only if the server already have this key get(key, val) returns val or raises a KeyError delete(key) deletes or raises a KeyError """ from time import time as currentTime from Cheetah.Utils.memcache import Client as MemcachedClient class Error(Exception): pass class AbstractCacheStore(object): def set(self, key, val, time=None): raise NotImplementedError def add(self, key, val, time=None): raise NotImplementedError def replace(self, key, val, time=None): raise NotImplementedError def delete(self, key): raise NotImplementedError def get(self, key): raise NotImplementedError class MemoryCacheStore(AbstractCacheStore): def __init__(self): self._data = {} def set(self, key, val, time=0): self._data[key] = (val, time) def add(self, key, val, time=0): if self._data.has_key(key): raise Error('a value for key %r is already in the cache'%key) self._data[key] = (val, time) def replace(self, key, val, time=0): if self._data.has_key(key): raise Error('a value for key %r is already in the cache'%key) self._data[key] = (val, time) def delete(self, key): del self._data[key] def get(self, key): (val, exptime) = self._data[key] if exptime and currentTime() > exptime: del self._data[key] raise KeyError(key) else: return val def clear(self): self._data.clear() class MemcachedCacheStore(AbstractCacheStore): servers = ('127.0.0.1:11211') def __init__(self, servers=None, debug=False): if servers is None: servers = self.servers self._client = MemcachedClient(servers, debug) def set(self, key, val, time=0): self._client.set(key, val, time) def add(self, key, val, time=0): res = self._client.add(key, val, time) if not res: raise Error('a value for key %r is already in the cache'%key) self._data[key] = (val, time) def replace(self, key, val, time=0): res = self._client.replace(key, val, time) if not res: raise Error('a value for key %r is already in the cache'%key) self._data[key] = (val, time) def delete(self, key): res = self._client.delete(key, time=0) if not res: raise KeyError(key) def get(self, key): val = self._client.get(key) if val is None: raise KeyError(key) else: return val def clear(self): self._client.flush_all() PK(8CCCheetah/FileUtils.pyc; License: This software is released for unlimited distribution under the terms of the MIT license. See the LICENSE file. Version: $Revision: 1.12 $ Start Date: 2001/09/26 Last Revision Date: $Date: 2005/11/02 22:26:07 $ s!Tavis Rudd s$Revision: 1.12 $i i(sglobN(slistdir(s StringType(smktemps ([\$\^\*\+\.\?\{\}\[\]\(\)\|\\])cCs|id|SdS(Ns\\\1(sescapeREssubstxt(stxtsescapeRE((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pys_escapeRegexCharsscOst||iSdS(sRecursively find all the files matching a glob pattern. This function is a wrapper around the FileFinder class. See its docstring for details about the accepted arguments, etc.N(s FileFindersargsskwsfiles(sargsskw((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pys findFilesscCs&t|}t|||iSdS(s/Replace all instances of 'theStr' with 'repl' for each file in the 'files' list. Returns a dictionary with data about the matches found. This is like string.replace() on a multi-file basis. This function is a wrapper around the FindAndReplace class. See its docstring for more details.N(s_escapeRegexCharsstheStrspatternsFindAndReplacesfilessreplsresults(sfilesstheStrsreplspattern((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pysreplaceStrInFiles&s cCst|||iSdS(s,Replace all instances of regex 'pattern' with 'repl' for each file in the 'files' list. Returns a dictionary with data about the matches found. This is like re.sub on a multi-file basis. This function is a wrapper around the FindAndReplace class. See its docstring for more details.N(sFindAndReplacesfilesspatternsreplsresults(sfilesspatternsrepl((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pysreplaceRegexInFiles3ss FileFindercBsktZdZdfddffdZdeieiieiidZ dZ e dZ d Z RS( sgTraverses a directory tree and finds all files in it that match one of the specified glob patterns.s*sCVSs.svncCs>||_||_||_||_g|_ |i |dS(N( srootPathsselfs _rootPaths globPatternss _globPatternssignoreBasenamess_ignoreBasenamess ignoreDirss _ignoreDirss_filess walkDirTree(sselfsrootPaths globPatternssignoreBasenamess ignoreDirs((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pys__init__Hs      s.c Cs|i}|i} |g}|i}|i}xt|ol|}||xR||D]D} ||| } || o"| | | o|| qqWqWWq0WdS(sBRecursively walk through a directory tree and find matching files.N(sselfs processDirs filterDirsdirs pendingDirssappendsaddDirspopsgetDirslistdirsbaseNamesjoinsfullPathsisdir( sselfsdirslistdirsisdirsjoinsgetDirs pendingDirss processDirsaddDirsfullPathsbaseNames filterDir((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pys walkDirTreeVs          cCs"||ijp ||ij SdS(s'A hook for filtering out certain dirs. N(sbaseNamesselfs_ignoreBasenamessfullPaths _ignoreDirs(sselfsbaseNamesfullPath((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pys filterDirqscCsC|ii}x0|iD]%}||tii||qWdS(N( sselfs_filessextends _globPatternsspatternsglobsosspathsjoinsdir(sselfsdirsglobsextendspattern((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pys processDirxs  cCs |iSdS(N(sselfs_files(sself((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pysfiles}s(s__name__s __module__s__doc__s__init__sosslistdirspathsisdirsjoins walkDirTrees filterDirsglobs processDirsfiles(((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pys FileFinderCs $  s_GenSubberFunccBstZdZeidZeidZdZdZdZ dZ dZ dd Z e d Zd Zd Zd ZdZdZdZdZdZdZdZdZdZRS(sConverts a 'sub' string in the form that one feeds to re.sub (backrefs, groups, etc.) into a function that can be used to do the substitutions in the FindAndReplace class.s\\([1-9][0-9]*)s\\g<([a-zA-Z_][a-zA-Z_]*)>cCs)||_d|_g|_|idS(Ni(s replaceStrsselfs_srcs_poss _codeChunkssparse(sselfs replaceStr((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pys__init__s   cCs |iSdS(N(sselfs_src(sself((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pyssrcscCs |iSdS(N(sselfs_pos(sself((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pysposscCs ||_dS(N(spossselfs_pos(sselfspos((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pyssetPosscCs|it|ijSdS(N(sselfs_posslens_src(sself((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pysatEndsicCs|i|7_dS(N(sselfs_possoffset(sselfsoffset((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pysadvancescCsQ|tjo |i}n||_|io|i|Sn|i||!SdS(N(sstartsNonesselfs_posstosatEnds_src(sselfstosstart((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pysreadTos     cCs#|ii|i|iSdS(N(sselfs backrefREsmatchssrcspos(sself((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pys matchBackrefscCs0|i}|i|i|idSdS(Ni(sselfs matchBackrefsmssetPossendsgroup(sselfsm((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pys getBackrefs cCs#|ii|i|iSdS(N(sselfsgroupREsmatchssrcspos(sself((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pys matchGroupscCs0|i}|i|i|idSdS(Ni(sselfs matchGroupsmssetPossendsgroup(sselfsm((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pysgetGroups cCsZxS|i oD|io|iq|io|iq|iqWdS(N(sselfsatEnds matchBackrefs eatBackrefs matchGroupseatGroups eatStrConst(sself((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pysparses  cCs}|i}x<|i o-|ip |ioPq|iqW|i|id|}|i t |dS(Nsstart( sselfspossstartPossatEnds matchBackrefs matchGroupsadvancesreadTosstrConstsaddChunksrepr(sselfsstartPossstrConst((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pys eatStrConsts cCs|id|iddS(Nsm.group(s)(sselfsaddChunks getBackref(sself((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pys eatBackrefscCs|id|iddS(Ns m.group("s")(sselfsaddChunksgetGroup(sself((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pyseatGroupscCs|ii|dS(N(sselfs _codeChunkssappendschunk(sselfschunk((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pysaddChunkscCsdi|iSdS(Ns, (sjoinsselfs _codeChunks(sself((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pyscodeBodyscCsd|iSdS(Ns%def subber(m): return ''.join([%s]) (sselfscodeBody(sself((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pyscodescBs|idUeSdS(N(sselfscodessubber(sself((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pys subberFuncs(s__name__s __module__s__doc__srescompiles backrefREsgroupREs__init__ssrcsposssetPossatEndsadvancesNonesreadTos matchBackrefs getBackrefs matchGroupsgetGroupsparses eatStrConsts eatBackrefseatGroupsaddChunkscodeBodyscodes subberFunc(((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pys_GenSubberFuncs,                sFindAndReplacecBs5tZdZedZdZdZdZRS(s`Find and replace all instances of 'patternOrRE' with 'replacement' for each file in the 'files' list. This is a multi-file version of re.sub(). 'patternOrRE' can be a raw regex pattern or a regex object as generated by the re module. 'replacement' can be any string that would work with patternOrRE.sub(replacement, fileContents). cCs3t|tjoti||_n ||_t|tjot|i |_ n ||_ |ii |_ }||_h|_||_t|_tiddiidodt}t|didtid|d|di o t|_nti|n|idS(NspgrepisUsage:sws#spgrep "s" (stypes patternOrREs StringTypesrescompilesselfs_regexs replacements_GenSubberFuncs subberFuncs_subberspatterns_patternsfiless_filess_resultss recordResultss_recordResultssFalses _usePgrepsosspopen3sreads startswithsmktempstmpFilesopenswritesTruesremoves_run(sselfsfiless patternOrREs replacements recordResultsstmpFilespattern((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pys__init__s$      # ' cCs |iSdS(N(sselfs_results(sself((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pysresults sc CsC|i}|i}|i}|i}x|i D] }t i i | oq.n||_t}tido~n|io0t id|d|io t}qn-t|i}|i|o t}n|oVtid ot|i}n|i||}t|di|q.q.WdS(Nsorigspgrep "s" sw(sselfs_regexsregexs_subDispatcherssubbers _usePgrepsusePgreps_patternspatterns_filessfilesosspathsisfiles _currFilesFalsesfoundslocalsshas_keysorigspopensreadsTruesopenssearchssubsnewswrite( sselfsregexspatternssubbersusePgrepsfilesnewsfoundsorig((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pys_runs.       " cCs|io|ii|i o,h}|i|i}||d7}||d7}||d7}||d7}q+Whd|<d|<d|<d|<}|SdS(Nis codeLiness blankLiness commentLiness totalLines( s codeLiness blankLiness commentLiness totalLinessselfsrawStatssvaluess fileStatssstats(sselfs totalLinessstatss blankLiness commentLiness codeLiness fileStats((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pyssummaryJs*cCsdS(N((sself((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pys printStats\sc Csd}d}d}tid}tid}t|i i }t |}xT|D]L} |i| o|d7}q[|i| o|d7}q[|d7}q[Whd|<d|<d|<d|<} | SdS( Nis\s#.*$s\s$is codeLiness blankLiness commentLiness totalLines(s codeLiness blankLiness commentLinessrescompiles commentLineRes blankLineResopensfileNamesreads splitlinesslinesslens totalLinesslinesmatchsstats( sselfsfileNames totalLiness blankLineRes blankLiness commentLineRes commentLinessliness codeLinessstatssline((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pys getFileStats_s  *( s__name__s __module__s__doc__sNones _fileStatss__init__srawStatsssummarys printStatss getFileStats(((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pysSourceFileStats;s     (s__doc__s __author__s __revision__sglobsosslistdirsos.pathsrestypess StringTypestempfilesmktempscompiles_escapeRegexCharss findFilessreplaceStrInFilessreplaceRegexInFiless FileFinders_GenSubberFuncsFindAndReplacesSourceFileStats(smktemps StringTypeslistdirs __revision__sSourceFileStatss_GenSubberFuncsglobs __author__sresFindAndReplaces_escapeRegexCharss FileFindersreplaceStrInFilessreplaceRegexInFilessoss findFiles((s6build/bdist.darwin-8.0.1-i386/egg/Cheetah/FileUtils.pys? s"          =dWPKn38&Cheetah/convertTmplPathToModuleName.pyimport os.path import string l = ['_'] * 256 for c in string.digits + string.letters: l[ord(c)] = c _pathNameTransChars = string.join(l, '') del l, c def convertTmplPathToModuleName(tmplPath, _pathNameTransChars=_pathNameTransChars, splitdrive=os.path.splitdrive, translate=string.translate, ): return translate(splitdrive(tmplPath)[1], _pathNameTransChars) PKzL7CSCheetah/Version.pyVersion = '2.0' VersionTuple = (2,0,0,'final',0) MinCompatibleVersion = '2.0rc6' MinCompatibleVersionTuple = (2,0,0,'candidate',6) #### def convertVersionStringToTuple(s): versionNum = [0,0,0] releaseType = 'final' releaseTypeSubNum = 0 if s.find('a')!=-1: num, releaseTypeSubNum = s.split('a') releaseType = 'alpha' elif s.find('b')!=-1: num, releaseTypeSubNum = s.split('b') releaseType = 'beta' elif s.find('rc')!=-1: num, releaseTypeSubNum = s.split('rc') releaseType = 'candidate' else: num = s num = num.split('.') for i in range(len(num)): versionNum[i] = int(num[i]) if len(versionNum)<3: versionNum += [0] releaseTypeSubNum = int(releaseTypeSubNum) return tuple(versionNum+[releaseType,releaseTypeSubNum]) if __name__ == '__main__': c = convertVersionStringToTuple print c('2.0a1') print c('2.0b1') print c('2.0rc1') print c('2.0') print c('2.0.2') assert c('0.9.19b1') < c('0.9.19') assert c('0.9b1') < c('0.9.19') assert c('2.0a2') > c('2.0a1') assert c('2.0b1') > c('2.0a2') assert c('2.0b2') > c('2.0b1') assert c('2.0b2') == c('2.0b2') assert c('2.0rc1') > c('2.0b1') assert c('2.0rc2') > c('2.0rc1') assert c('2.0rc2') > c('2.0b1') assert c('2.0') > c('2.0a1') assert c('2.0') > c('2.0b1') assert c('2.0') > c('2.0rc1') assert c('2.0.1') > c('2.0') assert c('2.0rc1') > c('2.0b1') PK(8N Cheetah/CacheRegion.pyc; Cc@sydZdZddd!ZdkZdklZdklZdfd YZd fd YZ d fd YZ dS(seCache holder classes for Cheetah: Cache regions are defined using the #cache Cheetah directive. Each cache region can be viewed as a dictionary (keyed by cacheRegionID) handling at least one cache item (the default one). It's possible to add cacheItems in a region by using the `varyBy` #cache directive parameter as in the following example:: #def getArticle this is the article content. #end def #cache varyBy=$getArticleID() $getArticle($getArticleID()) #end cache The code above will generate a CacheRegion and add new cacheItem for each value of $getArticleID(). Meta-Data ================================================================================ Author: Tavis Rudd and Philippe Normand Version: $Revision: 1.3 $ Start Date: 2005/06/20 Last Revision Date: $Date: 2006/01/28 04:19:30 $ sJTavis Rudd and Philippe Normand s$Revision: 1.3 $i iN(stime(sMemoryCacheStores CacheItemcBs_tZdZdZdZdZdZdZdZdZ dZ d Z RS( sA CacheItem is a container storing: - cacheID (string) - refreshTime (timestamp or None) : last time the cache was refreshed - data (string) : the content of the cache cCs(||_||_t|_d|_dS(Ni(s cacheItemIDsselfs _cacheItemIDs cacheStores _cacheStoresNones _refreshTimes _expiryTime(sselfs cacheItemIDs cacheStore((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheRegion.pys__init__*s   cCs|iot|ijSdS(N(sselfs _expiryTimes currentTime(sself((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheRegion.pys hasExpired0scCs ||_dS(N(stimesselfs _expiryTime(sselfstime((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheRegion.pys setExpiryTime3scCs |iSdS(N(sselfs _expiryTime(sself((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheRegion.pys getExpiryTime6scCs,t|_|ii|i||idS(N(s currentTimesselfs _refreshTimes _cacheStoressets _cacheItemIDsdatas _expiryTime(sselfsdata((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheRegion.pyssetData9s cCs |iSdS(N(sselfs _refreshTime(sself((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheRegion.pysgetRefreshTime=scCs(|ipt|ii|iSdS(N(sselfs _refreshTimesAssertionErrors _cacheStoresgets _cacheItemID(sself((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheRegion.pysgetData@scCs|ipdSdS(s+Can be overridden to implement edge-cachingsN(sselfsgetData(sself((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheRegion.pys renderOutputDscCs |ii|it|_dS(N(sselfs _cacheStoresdeletes _cacheItemIDsNones _refreshTime(sself((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheRegion.pysclearHs( s__name__s __module__s__doc__s__init__s hasExpireds setExpiryTimes getExpiryTimessetDatasgetRefreshTimesgetDatas renderOutputsclear(((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheRegion.pys CacheItem"s         s_CacheDataStoreWrappercBs/tZdZdZdZddZRS(NcCs||_||_dS(N(s dataStoresselfs _dataStores keyPrefixs _keyPrefix(sselfs dataStores keyPrefix((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheRegion.pys__init__Ms cCs|ii|i|SdS(N(sselfs _dataStoresgets _keyPrefixskey(sselfskey((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheRegion.pysgetQscCs|ii|i|dS(N(sselfs _dataStoresdeletes _keyPrefixskey(sselfskey((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheRegion.pysdeleteTsicCs$|ii|i||d|dS(Nstime(sselfs _dataStoressets _keyPrefixskeysvalstime(sselfskeysvalstime((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheRegion.pyssetWs(s__name__s __module__s__init__sgetsdeletesset(((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheRegion.pys_CacheDataStoreWrapperLs   s CacheRegioncBs>tZdZeZdedZdZdZdZ RS(s A `CacheRegion` stores some `CacheItem` instances. This implementation stores the data in the memory of the current process. If you need a more advanced data store, create a cacheStore class that works with Cheetah's CacheStore protocol and provide it as the cacheStore argument to __init__. For example you could use Cheetah.CacheStore.MemcachedCacheStore, a wrapper around the Python memcached API (http://www.danga.com/memcached). scCsgt|_||_||_| o t}n||_ t |d|d|d|_ h|_ dS(Ns keyPrefixs:( sTruesselfs_isNewsregionIDs _regionIDstemplateCacheIdPrefixs_templateCacheIdPrefixs cacheStoresMemoryCacheStores _cacheStores_CacheDataStoreWrappers_wrappedCacheDataStores _cacheItems(sselfsregionIDstemplateCacheIdPrefixs cacheStore((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheRegion.pys__init__fs     !cCs |iSdS(N(sselfs_isNew(sself((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheRegion.pysisNewqscCs?x8|iiD]'}|i|}|i|i|=qWdS(s1 drop all the caches stored in this cache region N(sselfs _cacheItemsskeyss cacheItemIds cacheItemsclear(sselfs cacheItems cacheItemId((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheRegion.pysclearts   cCsstit|i}|ii| o5|id|d|i }||i| Version: $Revision: 1.134 $ Start Date: 2001/08/01 Last Revision Date: $Date: 2007/04/04 00:28:50 $ """ __author__ = "Tavis Rudd " __revision__ = "$Revision: 1.134 $"[11:-2] import os import sys import re from re import DOTALL, MULTILINE from types import StringType, ListType, TupleType, ClassType, TypeType import time from tokenize import pseudoprog import inspect import new import traceback from Cheetah.SourceReader import SourceReader from Cheetah import Filters from Cheetah import ErrorCatchers from Cheetah.Unspecified import Unspecified # re tools _regexCache = {} def cachedRegex(pattern): if pattern not in _regexCache: _regexCache[pattern] = re.compile(pattern) return _regexCache[pattern] def escapeRegexChars(txt, escapeRE=re.compile(r'([\$\^\*\+\.\?\{\}\[\]\(\)\|\\])')): """Return a txt with all special regular expressions chars escaped.""" return escapeRE.sub(r'\\\1' , txt) def group(*choices): return '(' + '|'.join(choices) + ')' def nongroup(*choices): return '(?:' + '|'.join(choices) + ')' def namedGroup(name, *choices): return '(P:<' + name +'>' + '|'.join(choices) + ')' def any(*choices): return apply(group, choices) + '*' def maybe(*choices): return apply(group, choices) + '?' ################################################## ## CONSTANTS & GLOBALS ## NO_CACHE = 0 STATIC_CACHE = 1 REFRESH_CACHE = 2 SET_LOCAL = 0 SET_GLOBAL = 1 SET_MODULE = 2 ################################################## ## Tokens for the parser ## #generic identchars = "abcdefghijklmnopqrstuvwxyz" \ "ABCDEFGHIJKLMNOPQRSTUVWXYZ_" namechars = identchars + "0123456789" #operators powerOp = '**' unaryArithOps = ('+', '-', '~') binaryArithOps = ('+', '-', '/', '//','%') shiftOps = ('>>','<<') bitwiseOps = ('&','|','^') assignOp = '=' augAssignOps = ('+=','-=','/=','*=', '**=','^=','%=', '>>=','<<=','&=','|=', ) assignmentOps = (assignOp,) + augAssignOps compOps = ('<','>','==','!=','<=','>=', '<>', 'is', 'in',) booleanOps = ('and','or','not') operators = (powerOp,) + unaryArithOps + binaryArithOps \ + shiftOps + bitwiseOps + assignmentOps \ + compOps + booleanOps delimeters = ('(',')','{','}','[',']', ',','.',':',';','=','`') + augAssignOps keywords = ('and', 'del', 'for', 'is', 'raise', 'assert', 'elif', 'from', 'lambda', 'return', 'break', 'else', 'global', 'not', 'try', 'class', 'except', 'if', 'or', 'while', 'continue', 'exec', 'import', 'pass', 'def', 'finally', 'in', 'print', ) single3 = "'''" double3 = '"""' tripleQuotedStringStarts = ("'''", '"""', "r'''", 'r"""', "R'''", 'R"""', "u'''", 'u"""', "U'''", 'U"""', "ur'''", 'ur"""', "Ur'''", 'Ur"""', "uR'''", 'uR"""', "UR'''", 'UR"""') tripleQuotedStringPairs = {"'''": single3, '"""': double3, "r'''": single3, 'r"""': double3, "u'''": single3, 'u"""': double3, "ur'''": single3, 'ur"""': double3, "R'''": single3, 'R"""': double3, "U'''": single3, 'U"""': double3, "uR'''": single3, 'uR"""': double3, "Ur'''": single3, 'Ur"""': double3, "UR'''": single3, 'UR"""': double3, } closurePairs= {')':'(',']':'[','}':'{'} closurePairsRev= {'(':')','[':']','{':'}'} ################################################## ## Regex chunks for the parser ## tripleQuotedStringREs = {} def makeTripleQuoteRe(start, end): start = escapeRegexChars(start) end = escapeRegexChars(end) return re.compile(r'(?:' + start + r').*?' + r'(?:' + end + r')', re.DOTALL) for start, end in tripleQuotedStringPairs.items(): tripleQuotedStringREs[start] = makeTripleQuoteRe(start, end) WS = r'[ \f\t]*' EOL = r'\r\n|\n|\r' EOLZ = EOL + r'|\Z' escCharLookBehind = nongroup(r'(?<=\A)',r'(?= len(stream): stream.setPos(len(stream) -1) self.msg = msg self.extMsg = extMsg self.lineno = lineno self.col = col def __str__(self): return self.report() def report(self): stream = self.stream if stream.filename(): f = " in file %s" % stream.filename() else: f = '' report = '' if self.lineno: lineno = self.lineno row, col, line = (lineno, (self.col or 0), self.stream.splitlines()[lineno-1]) else: row, col, line = self.stream.getRowColLine() ## get the surrounding lines lines = stream.splitlines() prevLines = [] # (rowNum, content) for i in range(1,4): if row-1-i <=0: break prevLines.append( (row-i,lines[row-1-i]) ) nextLines = [] # (rowNum, content) for i in range(1,4): if not row-1+i < len(lines): break nextLines.append( (row+i,lines[row-1+i]) ) nextLines.reverse() ## print the main message report += "\n\n%s\n" %self.msg report += "Line %i, column %i%s\n\n" % (row, col, f) report += 'Line|Cheetah Code\n' report += '----|-------------------------------------------------------------\n' while prevLines: lineInfo = prevLines.pop() report += "%(row)-4d|%(line)s\n"% {'row':lineInfo[0], 'line':lineInfo[1]} report += "%(row)-4d|%(line)s\n"% {'row':row, 'line':line} report += ' '*5 +' '*(col-1) + "^\n" while nextLines: lineInfo = nextLines.pop() report += "%(row)-4d|%(line)s\n"% {'row':lineInfo[0], 'line':lineInfo[1]} ## add the extra msg if self.extMsg: report += self.extMsg + '\n' return report class ForbiddenSyntax(ParseError): pass class ForbiddenExpression(ForbiddenSyntax): pass class ForbiddenDirective(ForbiddenSyntax): pass class CheetahVariable: def __init__(self, nameChunks, useNameMapper=True, cacheToken=None, rawSource=None): self.nameChunks = nameChunks self.useNameMapper = useNameMapper self.cacheToken = cacheToken self.rawSource = rawSource class Placeholder(CheetahVariable): pass class ArgList: """Used by _LowLevelParser.getArgList()""" def __init__(self): self.argNames = [] self.defVals = [] self.i = 0 def addArgName(self, name): self.argNames.append( name ) self.defVals.append( None ) def next(self): self.i += 1 def addToDefVal(self, token): i = self.i if self.defVals[i] == None: self.defVals[i] = '' self.defVals[i] += token def merge(self): defVals = self.defVals for i in range(len(defVals)): if type(defVals[i]) == StringType: defVals[i] = defVals[i].strip() return map(None, [i.strip() for i in self.argNames], defVals) def __str__(self): return str(self.merge()) class _LowLevelParser(SourceReader): """This class implements the methods to match or extract ('get*') the basic elements of Cheetah's grammar. It does NOT handle any code generation or state management. """ _settingsManager = None def setSettingsManager(self, settingsManager): self._settingsManager = settingsManager def setting(self, key, default=Unspecified): if default is Unspecified: return self._settingsManager.setting(key) else: return self._settingsManager.setting(key, default=default) def setSetting(self, key, val): self._settingsManager.setSetting(key, val) def settings(self): return self._settingsManager.settings() def updateSettings(self, settings): self._settingsManager.updateSettings(settings) def _initializeSettings(self): self._settingsManager._initializeSettings() def configureParser(self): """Is called by the Compiler instance after the parser has had a settingsManager assigned with self.setSettingsManager() """ self._makeCheetahVarREs() self._makeCommentREs() self._makeDirectiveREs() self._makePspREs() self._possibleNonStrConstantChars = ( self.setting('commentStartToken')[0] + self.setting('multiLineCommentStartToken')[0] + self.setting('cheetahVarStartToken')[0] + self.setting('directiveStartToken')[0] + self.setting('PSPStartToken')[0]) self._nonStrConstMatchers = [ self.matchCommentStartToken, self.matchMultiLineCommentStartToken, self.matchVariablePlaceholderStart, self.matchExpressionPlaceholderStart, self.matchDirective, self.matchPSPStartToken, self.matchEOLSlurpToken, ] ## regex setup ## def _makeCheetahVarREs(self): """Setup the regexs for Cheetah $var parsing.""" num = r'[0-9\.]+' interval = (r'(?P' + num + r's|' + num + r'm|' + num + r'h|' + num + r'd|' + num + r'w|' + num + ')' ) cacheToken = (r'(?:' + r'(?P\*' + interval + '\*)'+ '|' + r'(?P\*)' + '|' + r'(?P)' + ')') self.cacheTokenRE = cachedRegex(cacheToken) silentPlaceholderToken = (r'(?:' + r'(?P' +escapeRegexChars('!')+')'+ '|' + r'(?P)' + ')') self.silentPlaceholderTokenRE = cachedRegex(silentPlaceholderToken) self.cheetahVarStartRE = cachedRegex( escCharLookBehind + r'(?P'+escapeRegexChars(self.setting('cheetahVarStartToken'))+')'+ r'(?P'+silentPlaceholderToken+')'+ r'(?P'+cacheToken+')'+ r'(?P|(?:(?:\{|\(|\[)[ \t\f]*))' + # allow WS after enclosure r'(?=[A-Za-z_])') validCharsLookAhead = r'(?=[A-Za-z_\*!\{\(\[])' self.cheetahVarStartToken = self.setting('cheetahVarStartToken') self.cheetahVarStartTokenRE = cachedRegex( escCharLookBehind + escapeRegexChars(self.setting('cheetahVarStartToken')) +validCharsLookAhead ) self.cheetahVarInExpressionStartTokenRE = cachedRegex( escapeRegexChars(self.setting('cheetahVarStartToken')) +r'(?=[A-Za-z_])' ) self.expressionPlaceholderStartRE = cachedRegex( escCharLookBehind + r'(?P' + escapeRegexChars(self.setting('cheetahVarStartToken')) + ')' + r'(?P' + cacheToken + ')' + #r'\[[ \t\f]*' r'(?:\{|\(|\[)[ \t\f]*' + r'(?=[^\)\}\]])' ) if self.setting('EOLSlurpToken'): self.EOLSlurpRE = cachedRegex( escapeRegexChars(self.setting('EOLSlurpToken')) + r'[ \t\f]*' + r'(?:'+EOL+')' ) else: self.EOLSlurpRE = None def _makeCommentREs(self): """Construct the regex bits that are used in comment parsing.""" startTokenEsc = escapeRegexChars(self.setting('commentStartToken')) self.commentStartTokenRE = cachedRegex(escCharLookBehind + startTokenEsc) del startTokenEsc startTokenEsc = escapeRegexChars( self.setting('multiLineCommentStartToken')) endTokenEsc = escapeRegexChars( self.setting('multiLineCommentEndToken')) self.multiLineCommentTokenStartRE = cachedRegex(escCharLookBehind + startTokenEsc) self.multiLineCommentEndTokenRE = cachedRegex(escCharLookBehind + endTokenEsc) def _makeDirectiveREs(self): """Construct the regexs that are used in directive parsing.""" startToken = self.setting('directiveStartToken') endToken = self.setting('directiveEndToken') startTokenEsc = escapeRegexChars(startToken) endTokenEsc = escapeRegexChars(endToken) validSecondCharsLookAhead = r'(?=[A-Za-z_@])' reParts = [escCharLookBehind, startTokenEsc] if self.setting('allowWhitespaceAfterDirectiveStartToken'): reParts.append('[ \t]*') reParts.append(validSecondCharsLookAhead) self.directiveStartTokenRE = cachedRegex(''.join(reParts)) self.directiveEndTokenRE = cachedRegex(escCharLookBehind + endTokenEsc) def _makePspREs(self): """Setup the regexs for PSP parsing.""" startToken = self.setting('PSPStartToken') startTokenEsc = escapeRegexChars(startToken) self.PSPStartTokenRE = cachedRegex(escCharLookBehind + startTokenEsc) endToken = self.setting('PSPEndToken') endTokenEsc = escapeRegexChars(endToken) self.PSPEndTokenRE = cachedRegex(escCharLookBehind + endTokenEsc) def isLineClearToStartToken(self, pos=None): return self.isLineClearToPos(pos) def matchTopLevelToken(self): """Returns the first match found from the following methods: self.matchCommentStartToken self.matchMultiLineCommentStartToken self.matchVariablePlaceholderStart self.matchExpressionPlaceholderStart self.matchDirective self.matchPSPStartToken self.matchEOLSlurpToken Returns None if no match. """ match = None if self.peek() in self._possibleNonStrConstantChars: for matcher in self._nonStrConstMatchers: match = matcher() if match: break return match def matchPyToken(self): match = pseudoprog.match(self.src(), self.pos()) if match and match.group() in tripleQuotedStringStarts: TQSmatch = tripleQuotedStringREs[match.group()].match(self.src(), self.pos()) if TQSmatch: return TQSmatch return match def getPyToken(self): match = self.matchPyToken() if match is None: raise ParseError(self) elif match.group() in tripleQuotedStringStarts: raise ParseError(self, msg='Malformed triple-quoted string') return self.readTo(match.end()) def matchEOLSlurpToken(self): if self.EOLSlurpRE: return self.EOLSlurpRE.match(self.src(), self.pos()) def getEOLSlurpToken(self): match = self.matchEOLSlurpToken() if not match: raise ParseError(self, msg='Invalid EOL slurp token') return self.readTo(match.end()) def matchCommentStartToken(self): return self.commentStartTokenRE.match(self.src(), self.pos()) def getCommentStartToken(self): match = self.matchCommentStartToken() if not match: raise ParseError(self, msg='Invalid single-line comment start token') return self.readTo(match.end()) def matchMultiLineCommentStartToken(self): return self.multiLineCommentTokenStartRE.match(self.src(), self.pos()) def getMultiLineCommentStartToken(self): match = self.matchMultiLineCommentStartToken() if not match: raise ParseError(self, msg='Invalid multi-line comment start token') return self.readTo(match.end()) def matchMultiLineCommentEndToken(self): return self.multiLineCommentEndTokenRE.match(self.src(), self.pos()) def getMultiLineCommentEndToken(self): match = self.matchMultiLineCommentEndToken() if not match: raise ParseError(self, msg='Invalid multi-line comment end token') return self.readTo(match.end()) def getDottedName(self): srcLen = len(self) nameChunks = [] if not self.peek() in identchars: raise ParseError(self) while self.pos() < srcLen: c = self.peek() if c in namechars: nameChunk = self.getIdentifier() nameChunks.append(nameChunk) elif c == '.': if self.pos()+1 endOfFirstLine): self._compiler.handleWSBeforeDirective() self._compiler.addComment(comm) def eatPlaceholder(self): (expr, rawPlaceholder, lineCol, cacheTokenParts, filterArgs, isSilentPlaceholder) = self.getPlaceholder( allowCacheTokens=True, returnEverything=True) self._compiler.addPlaceholder( expr, filterArgs=filterArgs, rawPlaceholder=rawPlaceholder, cacheTokenParts=cacheTokenParts, lineCol=lineCol, silentMode=isSilentPlaceholder) return def eatPSP(self): # filtered self._filterDisabledDirectives(directiveName='psp') self.getPSPStartToken() endToken = self.setting('PSPEndToken') startPos = self.pos() while not self.atEnd(): if self.peek() == endToken[0]: if self.matchPSPEndToken(): break self.advance() pspString = self.readTo(self.pos(), start=startPos).strip() pspString = self._applyExpressionFilters(pspString, 'psp', startPos=startPos) self._compiler.addPSP(pspString) self.getPSPEndToken() ## generic directive eat methods _simpleIndentingDirectives = ''' else elif for while repeat unless try except finally'''.split() _simpleExprDirectives = ''' pass continue stop return yield break del assert raise silent echo import from'''.split() _directiveHandlerNames = {'import':'addImportStatement', 'from':'addImportStatement', } def eatDirective(self): directiveName = self.matchDirective() self._filterDisabledDirectives(directiveName) for callback in self.setting('preparseDirectiveHooks'): callback(parser=self, directiveName=directiveName) # subclasses can override the default behaviours here by providing an # eater method in self._directiveNamesAndParsers[directiveName] directiveParser = self._directiveNamesAndParsers.get(directiveName) if directiveParser: directiveParser() elif directiveName in self._simpleIndentingDirectives: handlerName = self._directiveHandlerNames.get(directiveName) if not handlerName: handlerName = 'add'+directiveName.capitalize() handler = getattr(self._compiler, handlerName) self.eatSimpleIndentingDirective(directiveName, callback=handler) elif directiveName in self._simpleExprDirectives: handlerName = self._directiveHandlerNames.get(directiveName) if not handlerName: handlerName = 'add'+directiveName.capitalize() handler = getattr(self._compiler, handlerName) if directiveName in ('silent', 'echo'): includeDirectiveNameInExpr = False else: includeDirectiveNameInExpr = True expr = self.eatSimpleExprDirective( directiveName, includeDirectiveNameInExpr=includeDirectiveNameInExpr) handler(expr) ## for callback in self.setting('postparseDirectiveHooks'): callback(parser=self, directiveName=directiveName) def _eatRestOfDirectiveTag(self, isLineClearToStartToken, endOfFirstLinePos): foundComment = False if self.matchCommentStartToken(): pos = self.pos() self.advance() if not self.matchDirective(): self.setPos(pos) foundComment = True self.eatComment() # this won't gobble the EOL else: self.setPos(pos) if not foundComment and self.matchDirectiveEndToken(): self.getDirectiveEndToken() elif isLineClearToStartToken and (not self.atEnd()) and self.peek() in '\r\n': # still gobble the EOL if a comment was found. self.readToEOL(gobble=True) if isLineClearToStartToken and (self.atEnd() or self.pos() > endOfFirstLinePos): self._compiler.handleWSBeforeDirective() def _eatToThisEndDirective(self, directiveName): finalPos = endRawPos = startPos = self.pos() directiveChar = self.setting('directiveStartToken')[0] isLineClearToStartToken = False while not self.atEnd(): if self.peek() == directiveChar: if self.matchDirective() == 'end': endRawPos = self.pos() self.getDirectiveStartToken() self.advance(len('end')) self.getWhiteSpace() if self.startswith(directiveName): if self.isLineClearToStartToken(endRawPos): isLineClearToStartToken = True endRawPos = self.findBOL(endRawPos) self.advance(len(directiveName)) # to end of directiveName self.getWhiteSpace() finalPos = self.pos() break self.advance() finalPos = endRawPos = self.pos() textEaten = self.readTo(endRawPos, start=startPos) self.setPos(finalPos) endOfFirstLinePos = self.findEOL() if self.matchDirectiveEndToken(): self.getDirectiveEndToken() elif isLineClearToStartToken and (not self.atEnd()) and self.peek() in '\r\n': self.readToEOL(gobble=True) if isLineClearToStartToken and self.pos() > endOfFirstLinePos: self._compiler.handleWSBeforeDirective() return textEaten def eatSimpleExprDirective(self, directiveName, includeDirectiveNameInExpr=True): # filtered isLineClearToStartToken = self.isLineClearToStartToken() endOfFirstLine = self.findEOL() self.getDirectiveStartToken() if not includeDirectiveNameInExpr: self.advance(len(directiveName)) startPos = self.pos() expr = self.getExpression().strip() directiveName = expr.split()[0] expr = self._applyExpressionFilters(expr, directiveName, startPos=startPos) if directiveName in self._closeableDirectives: self.pushToOpenDirectivesStack(directiveName) self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLine) return expr def eatSimpleIndentingDirective(self, directiveName, callback, includeDirectiveNameInExpr=False): # filtered isLineClearToStartToken = self.isLineClearToStartToken() endOfFirstLinePos = self.findEOL() lineCol = self.getRowCol() self.getDirectiveStartToken() if directiveName not in 'else elif for while try except finally'.split(): self.advance(len(directiveName)) startPos = self.pos() self.getWhiteSpace() expr = self.getExpression(pyTokensToBreakAt=[':']) expr = self._applyExpressionFilters(expr, directiveName, startPos=startPos) if self.matchColonForSingleLineShortFormDirective(): self.advance() # skip over : if directiveName in 'else elif except finally'.split(): callback(expr, dedent=False, lineCol=lineCol) else: callback(expr, lineCol=lineCol) self.getWhiteSpace(max=1) self.parse(breakPoint=self.findEOL(gobble=True)) self._compiler.commitStrConst() self._compiler.dedent() else: if self.peek()==':': self.advance() self.getWhiteSpace() self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLinePos) if directiveName in self._closeableDirectives: self.pushToOpenDirectivesStack(directiveName) callback(expr, lineCol=lineCol) def eatEndDirective(self): isLineClearToStartToken = self.isLineClearToStartToken() self.getDirectiveStartToken() self.advance(3) # to end of 'end' self.getWhiteSpace() pos = self.pos() directiveName = False for key in self._endDirectiveNamesAndHandlers.keys(): if self.find(key, pos) == pos: directiveName = key break if not directiveName: raise ParseError(self, msg='Invalid end directive') endOfFirstLinePos = self.findEOL() self.getExpression() # eat in any extra comment-like crap self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLinePos) if directiveName in self._closeableDirectives: self.popFromOpenDirectivesStack(directiveName) # subclasses can override the default behaviours here by providing an # end-directive handler in self._endDirectiveNamesAndHandlers[directiveName] if self._endDirectiveNamesAndHandlers.get(directiveName): handler = self._endDirectiveNamesAndHandlers[directiveName] handler() elif directiveName in 'block capture cache call filter errorCatcher'.split(): if key == 'block': self._compiler.closeBlock() elif key == 'capture': self._compiler.endCaptureRegion() elif key == 'cache': self._compiler.endCacheRegion() elif key == 'call': self._compiler.endCallRegion() elif key == 'filter': self._compiler.closeFilterBlock() elif key == 'errorCatcher': self._compiler.turnErrorCatcherOff() elif directiveName in 'while for if try repeat unless'.split(): self._compiler.commitStrConst() self._compiler.dedent() elif directiveName=='closure': self._compiler.commitStrConst() self._compiler.dedent() # @@TR: temporary hack of useSearchList self.setSetting('useSearchList', self._useSearchList_orig) ## specific directive eat methods def eatBreakPoint(self): """Tells the parser to stop parsing at this point and completely ignore everything else. This is a debugging tool. """ self.setBreakPoint(self.pos()) def eatShbang(self): # filtered self.getDirectiveStartToken() self.advance(len('shBang')) self.getWhiteSpace() startPos = self.pos() shBang = self.readToEOL() shBang = self._applyExpressionFilters(shBang, 'shbang', startPos=startPos) self._compiler.setShBang(shBang.strip()) def eatEncoding(self): # filtered self.getDirectiveStartToken() self.advance(len('encoding')) self.getWhiteSpace() startPos = self.pos() encoding = self.readToEOL() encoding = self._applyExpressionFilters(encoding, 'encoding', startPos=startPos) self._compiler.setModuleEncoding(encoding.strip()) def eatCompiler(self): # filtered isLineClearToStartToken = self.isLineClearToStartToken() endOfFirstLine = self.findEOL() startPos = self.pos() self.getDirectiveStartToken() self.advance(len('compiler')) # to end of 'compiler' self.getWhiteSpace() startPos = self.pos() settingName = self.getIdentifier() if settingName.lower() == 'reset': self.getExpression() # gobble whitespace & junk self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLine) self._initializeSettings() self.configureParser() return self.getWhiteSpace() if self.peek() == '=': self.advance() else: raise ParseError(self) valueExpr = self.getExpression() endPos = self.pos() # @@TR: it's unlikely that anyone apply filters would have left this # directive enabled: # @@TR: fix up filtering, regardless self._applyExpressionFilters('%s=%r'%(settingName, valueExpr), 'compiler', startPos=startPos) self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLine) try: self._compiler.setCompilerSetting(settingName, valueExpr) except: out = sys.stderr print >> out, 'An error occurred while processing the following #compiler directive.' print >> out, '-'*80 print >> out, self[startPos:endPos] print >> out, '-'*80 print >> out, 'Please check the syntax of these settings.' print >> out, 'A full Python exception traceback follows.' raise def eatCompilerSettings(self): # filtered isLineClearToStartToken = self.isLineClearToStartToken() endOfFirstLine = self.findEOL() self.getDirectiveStartToken() self.advance(len('compiler-settings')) # to end of 'settings' keywords = self.getTargetVarsList() self.getExpression() # gobble any garbage self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLine) if 'reset' in keywords: self._compiler._initializeSettings() self.configureParser() # @@TR: this implies a single-line #compiler-settings directive, and # thus we should parse forward for an end directive. # Subject to change in the future return startPos = self.pos() settingsStr = self._eatToThisEndDirective('compiler-settings') settingsStr = self._applyExpressionFilters(settingsStr, 'compilerSettings', startPos=startPos) try: self._compiler.setCompilerSettings(keywords=keywords, settingsStr=settingsStr) except: out = sys.stderr print >> out, 'An error occurred while processing the following compiler settings.' print >> out, '-'*80 print >> out, settingsStr.strip() print >> out, '-'*80 print >> out, 'Please check the syntax of these settings.' print >> out, 'A full Python exception traceback follows.' raise def eatAttr(self): # filtered isLineClearToStartToken = self.isLineClearToStartToken() endOfFirstLinePos = self.findEOL() startPos = self.pos() self.getDirectiveStartToken() self.advance(len('attr')) self.getWhiteSpace() startPos = self.pos() if self.matchCheetahVarStart(): self.getCheetahVarStartToken() attribName = self.getIdentifier() self.getWhiteSpace() self.getAssignmentOperator() expr = self.getExpression() expr = self._applyExpressionFilters(expr, 'attr', startPos=startPos) self._compiler.addAttribute(attribName, expr) self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLinePos) def eatDecorator(self): isLineClearToStartToken = self.isLineClearToStartToken() endOfFirstLinePos = self.findEOL() startPos = self.pos() self.getDirectiveStartToken() #self.advance() # eat @ startPos = self.pos() decoratorExpr = self.getExpression() decoratorExpr = self._applyExpressionFilters(decoratorExpr, 'decorator', startPos=startPos) self._compiler.addDecorator(decoratorExpr) self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLinePos) self.getWhiteSpace() directiveName = self.matchDirective() if not directiveName or directiveName not in ('def', 'block', 'closure'): raise ParseError(self, msg='Expected #def, #block or #closure') self.eatDirective() def eatDef(self): # filtered self._eatDefOrBlock('def') def eatBlock(self): # filtered startPos = self.pos() methodName, rawSignature = self._eatDefOrBlock('block') self._compiler._blockMetaData[methodName] = { 'raw':rawSignature, 'lineCol':self.getRowCol(startPos), } def eatClosure(self): # filtered self._eatDefOrBlock('closure') def _eatDefOrBlock(self, directiveName): # filtered assert directiveName in ('def','block','closure') isLineClearToStartToken = self.isLineClearToStartToken() endOfFirstLinePos = self.findEOL() startPos = self.pos() self.getDirectiveStartToken() self.advance(len(directiveName)) self.getWhiteSpace() if self.matchCheetahVarStart(): self.getCheetahVarStartToken() methodName = self.getIdentifier() self.getWhiteSpace() if self.peek() == '(': argsList = self.getDefArgList() self.advance() # past the closing ')' if argsList and argsList[0][0] == 'self': del argsList[0] else: argsList=[] def includeBlockMarkers(): if self.setting('includeBlockMarkers'): startMarker = self.setting('blockMarkerStart') self._compiler.addStrConst(startMarker[0] + methodName + startMarker[1]) # @@TR: fix up filtering self._applyExpressionFilters(self[startPos:self.pos()], 'def', startPos=startPos) if self.matchColonForSingleLineShortFormDirective(): isNestedDef = (self.setting('allowNestedDefScopes') and [name for name in self._openDirectivesStack if name=='def']) self.getc() rawSignature = self[startPos:endOfFirstLinePos] self._eatSingleLineDef(directiveName=directiveName, methodName=methodName, argsList=argsList, startPos=startPos, endPos=endOfFirstLinePos) if directiveName == 'def' and not isNestedDef: #@@TR: must come before _eatRestOfDirectiveTag ... for some reason self._compiler.closeDef() elif directiveName == 'block': includeBlockMarkers() self._compiler.closeBlock() elif directiveName == 'closure' or isNestedDef: self._compiler.dedent() self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLinePos) else: if self.peek()==':': self.getc() self.pushToOpenDirectivesStack(directiveName) rawSignature = self[startPos:self.pos()] self._eatMultiLineDef(directiveName=directiveName, methodName=methodName, argsList=argsList, startPos=startPos, isLineClearToStartToken=isLineClearToStartToken) if directiveName == 'block': includeBlockMarkers() return methodName, rawSignature def _eatMultiLineDef(self, directiveName, methodName, argsList, startPos, isLineClearToStartToken=False): # filtered in calling method self.getExpression() # slurp up any garbage left at the end signature = self[startPos:self.pos()] endOfFirstLinePos = self.findEOL() self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLinePos) parserComment = ('## CHEETAH: generated from ' + signature + ' at line %s, col %s' % self.getRowCol(startPos) + '.') isNestedDef = (self.setting('allowNestedDefScopes') and len([name for name in self._openDirectivesStack if name=='def'])>1) if directiveName=='block' or (directiveName=='def' and not isNestedDef): self._compiler.startMethodDef(methodName, argsList, parserComment) else: #closure self._useSearchList_orig = self.setting('useSearchList') self.setSetting('useSearchList', False) self._compiler.addClosure(methodName, argsList, parserComment) return methodName def _eatSingleLineDef(self, directiveName, methodName, argsList, startPos, endPos): # filtered in calling method fullSignature = self[startPos:endPos] parserComment = ('## Generated from ' + fullSignature + ' at line %s, col %s' % self.getRowCol(startPos) + '.') isNestedDef = (self.setting('allowNestedDefScopes') and [name for name in self._openDirectivesStack if name=='def']) if directiveName=='block' or (directiveName=='def' and not isNestedDef): self._compiler.startMethodDef(methodName, argsList, parserComment) else: #closure # @@TR: temporary hack of useSearchList useSearchList_orig = self.setting('useSearchList') self.setSetting('useSearchList', False) self._compiler.addClosure(methodName, argsList, parserComment) self.getWhiteSpace(max=1) self.parse(breakPoint=endPos) if directiveName=='closure' or isNestedDef: # @@TR: temporary hack of useSearchList self.setSetting('useSearchList', useSearchList_orig) def eatExtends(self): # filtered isLineClearToStartToken = self.isLineClearToStartToken() endOfFirstLine = self.findEOL() self.getDirectiveStartToken() self.advance(len('extends')) self.getWhiteSpace() startPos = self.pos() if self.setting('allowExpressionsInExtendsDirective'): baseName = self.getExpression() else: baseName = self.getDottedName() baseName = self._applyExpressionFilters(baseName, 'extends', startPos=startPos) self._compiler.setBaseClass(baseName) # in compiler self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLine) def eatImplements(self): # filtered isLineClearToStartToken = self.isLineClearToStartToken() endOfFirstLine = self.findEOL() self.getDirectiveStartToken() self.advance(len('implements')) self.getWhiteSpace() startPos = self.pos() methodName = self.getIdentifier() if not self.atEnd() and self.peek() == '(': argsList = self.getDefArgList() self.advance() # past the closing ')' if argsList and argsList[0][0] == 'self': del argsList[0] else: argsList=[] # @@TR: need to split up filtering of the methodname and the args #methodName = self._applyExpressionFilters(methodName, 'implements', startPos=startPos) self._applyExpressionFilters(self[startPos:self.pos()], 'implements', startPos=startPos) self._compiler.setMainMethodName(methodName) self._compiler.setMainMethodArgs(argsList) self.getExpression() # throw away and unwanted crap that got added in self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLine) def eatSuper(self): # filtered isLineClearToStartToken = self.isLineClearToStartToken() endOfFirstLine = self.findEOL() self.getDirectiveStartToken() self.advance(len('super')) self.getWhiteSpace() startPos = self.pos() if not self.atEnd() and self.peek() == '(': argsList = self.getDefArgList() self.advance() # past the closing ')' if argsList and argsList[0][0] == 'self': del argsList[0] else: argsList=[] self._applyExpressionFilters(self[startPos:self.pos()], 'super', startPos=startPos) #parserComment = ('## CHEETAH: generated from ' + signature + # ' at line %s, col %s' % self.getRowCol(startPos) # + '.') self.getExpression() # throw away and unwanted crap that got added in self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLine) self._compiler.addSuper(argsList) def eatSet(self): # filtered isLineClearToStartToken = self.isLineClearToStartToken() endOfFirstLine = self.findEOL() self.getDirectiveStartToken() self.advance(3) self.getWhiteSpace() style = SET_LOCAL if self.startswith('local'): self.getIdentifier() self.getWhiteSpace() elif self.startswith('global'): self.getIdentifier() self.getWhiteSpace() style = SET_GLOBAL elif self.startswith('module'): self.getIdentifier() self.getWhiteSpace() style = SET_MODULE startsWithDollar = self.matchCheetahVarStart() startPos = self.pos() LVALUE = self.getExpression(pyTokensToBreakAt=assignmentOps, useNameMapper=False).strip() OP = self.getAssignmentOperator() RVALUE = self.getExpression() expr = LVALUE + ' ' + OP + ' ' + RVALUE.strip() expr = self._applyExpressionFilters(expr, 'set', startPos=startPos) self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLine) class Components: pass # used for 'set global' exprComponents = Components() exprComponents.LVALUE = LVALUE exprComponents.OP = OP exprComponents.RVALUE = RVALUE self._compiler.addSet(expr, exprComponents, style) def eatSlurp(self): if self.isLineClearToStartToken(): self._compiler.handleWSBeforeDirective() self._compiler.commitStrConst() self.readToEOL(gobble=True) def eatEOLSlurpToken(self): if self.isLineClearToStartToken(): self._compiler.handleWSBeforeDirective() self._compiler.commitStrConst() self.readToEOL(gobble=True) def eatRaw(self): isLineClearToStartToken = self.isLineClearToStartToken() endOfFirstLinePos = self.findEOL() self.getDirectiveStartToken() self.advance(len('raw')) self.getWhiteSpace() if self.matchColonForSingleLineShortFormDirective(): self.advance() # skip over : self.getWhiteSpace(max=1) rawBlock = self.readToEOL(gobble=False) else: if self.peek()==':': self.advance() self.getWhiteSpace() self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLinePos) rawBlock = self._eatToThisEndDirective('raw') self._compiler.addRawText(rawBlock) def eatInclude(self): # filtered isLineClearToStartToken = self.isLineClearToStartToken() endOfFirstLinePos = self.findEOL() self.getDirectiveStartToken() self.advance(len('include')) self.getWhiteSpace() includeFrom = 'file' isRaw = False if self.startswith('raw'): self.advance(3) isRaw=True self.getWhiteSpace() if self.startswith('source'): self.advance(len('source')) includeFrom = 'str' self.getWhiteSpace() if not self.peek() == '=': raise ParseError(self) self.advance() startPos = self.pos() sourceExpr = self.getExpression() sourceExpr = self._applyExpressionFilters(sourceExpr, 'include', startPos=startPos) self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLinePos) self._compiler.addInclude(sourceExpr, includeFrom, isRaw) def eatDefMacro(self): # @@TR: not filtered yet isLineClearToStartToken = self.isLineClearToStartToken() endOfFirstLinePos = self.findEOL() self.getDirectiveStartToken() self.advance(len('defmacro')) self.getWhiteSpace() if self.matchCheetahVarStart(): self.getCheetahVarStartToken() macroName = self.getIdentifier() self.getWhiteSpace() if self.peek() == '(': argsList = self.getDefArgList(useNameMapper=False) self.advance() # past the closing ')' if argsList and argsList[0][0] == 'self': del argsList[0] else: argsList=[] assert not self._directiveNamesAndParsers.has_key(macroName) argsList.insert(0, ('src',None)) argsList.append(('parser','None')) argsList.append(('macros','None')) argsList.append(('compilerSettings','None')) argsList.append(('isShortForm','None')) argsList.append(('EOLCharsInShortForm','None')) argsList.append(('startPos','None')) argsList.append(('endPos','None')) if self.matchColonForSingleLineShortFormDirective(): self.advance() # skip over : self.getWhiteSpace(max=1) macroSrc = self.readToEOL(gobble=False) self.readToEOL(gobble=True) else: if self.peek()==':': self.advance() self.getWhiteSpace() self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLinePos) macroSrc = self._eatToThisEndDirective('defmacro') #print argsList normalizedMacroSrc = ''.join( ['%def callMacro('+','.join([defv and '%s=%s'%(n,defv) or n for n,defv in argsList]) +')\n', macroSrc, '%end def']) from Cheetah.Template import Template templateAPIClass = self.setting('templateAPIClassForDefMacro', default=Template) compilerSettings = self.setting('compilerSettingsForDefMacro', default={}) searchListForMacros = self.setting('searchListForDefMacro', default=[]) searchListForMacros = list(searchListForMacros) # copy to avoid mutation bugs searchListForMacros.append({'macros':self._macros, 'parser':self, 'compilerSettings':self.settings(), }) templateAPIClass._updateSettingsWithPreprocessTokens( compilerSettings, placeholderToken='@', directiveToken='%') macroTemplateClass = templateAPIClass.compile(source=normalizedMacroSrc, compilerSettings=compilerSettings) #print normalizedMacroSrc #t = macroTemplateClass() #print t.callMacro('src') #print t.generatedClassCode() class MacroDetails: pass macroDetails = MacroDetails() macroDetails.macroSrc = macroSrc macroDetails.argsList = argsList macroDetails.template = macroTemplateClass(searchList=searchListForMacros) self._macroDetails[macroName] = macroDetails self._macros[macroName] = macroDetails.template.callMacro self._directiveNamesAndParsers[macroName] = self.eatMacroCall def eatMacroCall(self): isLineClearToStartToken = self.isLineClearToStartToken() endOfFirstLinePos = self.findEOL() startPos = self.pos() self.getDirectiveStartToken() macroName = self.getIdentifier() macro = self._macros[macroName] if hasattr(macro, 'parse'): return macro.parse(parser=self, startPos=startPos) if hasattr(macro, 'parseArgs'): args = macro.parseArgs(parser=self, startPos=startPos) else: self.getWhiteSpace() args = self.getExpression(useNameMapper=False, pyTokensToBreakAt=[':']).strip() if self.matchColonForSingleLineShortFormDirective(): isShortForm = True self.advance() # skip over : self.getWhiteSpace(max=1) srcBlock = self.readToEOL(gobble=False) EOLCharsInShortForm = self.readToEOL(gobble=True) #self.readToEOL(gobble=False) else: isShortForm = False if self.peek()==':': self.advance() self.getWhiteSpace() self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLinePos) srcBlock = self._eatToThisEndDirective(macroName) if hasattr(macro, 'convertArgStrToDict'): kwArgs = macro.convertArgStrToDict(args, parser=self, startPos=startPos) else: def getArgs(*pargs, **kws): return pargs, kws exec 'positionalArgs, kwArgs = getArgs(%(args)s)'%locals() assert not kwArgs.has_key('src') kwArgs['src'] = srcBlock if type(macro)==new.instancemethod: co = macro.im_func.func_code elif (hasattr(macro, '__call__') and hasattr(macro.__call__, 'im_func')): co = macro.__call__.im_func.func_code else: co = macro.func_code availableKwArgs = inspect.getargs(co)[0] if 'parser' in availableKwArgs: kwArgs['parser'] = self if 'macros' in availableKwArgs: kwArgs['macros'] = self._macros if 'compilerSettings' in availableKwArgs: kwArgs['compilerSettings'] = self.settings() if 'isShortForm' in availableKwArgs: kwArgs['isShortForm'] = isShortForm if isShortForm and 'EOLCharsInShortForm' in availableKwArgs: kwArgs['EOLCharsInShortForm'] = EOLCharsInShortForm if 'startPos' in availableKwArgs: kwArgs['startPos'] = startPos if 'endPos' in availableKwArgs: kwArgs['endPos'] = self.pos() srcFromMacroOutput = macro(**kwArgs) origParseSrc = self._src origBreakPoint = self.breakPoint() origPos = self.pos() # add a comment to the output about the macro src that is being parsed # or add a comment prefix to all the comments added by the compiler self._src = srcFromMacroOutput self.setPos(0) self.setBreakPoint(len(srcFromMacroOutput)) self.parse(assertEmptyStack=False) self._src = origParseSrc self.setBreakPoint(origBreakPoint) self.setPos(origPos) #self._compiler.addRawText('end') def eatCache(self): isLineClearToStartToken = self.isLineClearToStartToken() endOfFirstLinePos = self.findEOL() lineCol = self.getRowCol() self.getDirectiveStartToken() self.advance(len('cache')) startPos = self.pos() argList = self.getDefArgList(useNameMapper=True) argList = self._applyExpressionFilters(argList, 'cache', startPos=startPos) def startCache(): cacheInfo = self._compiler.genCacheInfoFromArgList(argList) self._compiler.startCacheRegion(cacheInfo, lineCol) if self.matchColonForSingleLineShortFormDirective(): self.advance() # skip over : self.getWhiteSpace(max=1) startCache() self.parse(breakPoint=self.findEOL(gobble=True)) self._compiler.endCacheRegion() else: if self.peek()==':': self.advance() self.getWhiteSpace() self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLinePos) self.pushToOpenDirectivesStack('cache') startCache() def eatCall(self): # @@TR: need to enable single line version of this isLineClearToStartToken = self.isLineClearToStartToken() endOfFirstLinePos = self.findEOL() lineCol = self.getRowCol() self.getDirectiveStartToken() self.advance(len('call')) startPos = self.pos() useAutocallingOrig = self.setting('useAutocalling') self.setSetting('useAutocalling', False) self.getWhiteSpace() if self.matchCheetahVarStart(): functionName = self.getCheetahVar() else: functionName = self.getCheetahVar(plain=True, skipStartToken=True) self.setSetting('useAutocalling', useAutocallingOrig) # @@TR: fix up filtering self._applyExpressionFilters(self[startPos:self.pos()], 'call', startPos=startPos) self.getWhiteSpace() args = self.getExpression(pyTokensToBreakAt=[':']).strip() if self.matchColonForSingleLineShortFormDirective(): self.advance() # skip over : self._compiler.startCallRegion(functionName, args, lineCol) self.getWhiteSpace(max=1) self.parse(breakPoint=self.findEOL(gobble=False)) self._compiler.endCallRegion() else: if self.peek()==':': self.advance() self.getWhiteSpace() self.pushToOpenDirectivesStack("call") self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLinePos) self._compiler.startCallRegion(functionName, args, lineCol) def eatCallArg(self): isLineClearToStartToken = self.isLineClearToStartToken() endOfFirstLinePos = self.findEOL() lineCol = self.getRowCol() self.getDirectiveStartToken() self.advance(len('arg')) startPos = self.pos() self.getWhiteSpace() argName = self.getIdentifier() self.getWhiteSpace() argName = self._applyExpressionFilters(argName, 'arg', startPos=startPos) self._compiler.setCallArg(argName, lineCol) if self.peek() == ':': self.getc() else: self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLinePos) def eatFilter(self): isLineClearToStartToken = self.isLineClearToStartToken() endOfFirstLinePos = self.findEOL() self.getDirectiveStartToken() self.advance(len('filter')) self.getWhiteSpace() startPos = self.pos() if self.matchCheetahVarStart(): isKlass = True theFilter = self.getExpression(pyTokensToBreakAt=[':']) else: isKlass = False theFilter = self.getIdentifier() self.getWhiteSpace() theFilter = self._applyExpressionFilters(theFilter, 'filter', startPos=startPos) if self.matchColonForSingleLineShortFormDirective(): self.advance() # skip over : self.getWhiteSpace(max=1) self._compiler.setFilter(theFilter, isKlass) self.parse(breakPoint=self.findEOL(gobble=False)) self._compiler.closeFilterBlock() else: if self.peek()==':': self.advance() self.getWhiteSpace() self.pushToOpenDirectivesStack("filter") self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLinePos) self._compiler.setFilter(theFilter, isKlass) def eatErrorCatcher(self): isLineClearToStartToken = self.isLineClearToStartToken() endOfFirstLinePos = self.findEOL() self.getDirectiveStartToken() self.advance(len('errorCatcher')) self.getWhiteSpace() startPos = self.pos() errorCatcherName = self.getIdentifier() errorCatcherName = self._applyExpressionFilters( errorCatcherName, 'errorcatcher', startPos=startPos) self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLinePos) self._compiler.setErrorCatcher(errorCatcherName) def eatCapture(self): # @@TR: this could be refactored to use the code in eatSimpleIndentingDirective # filtered isLineClearToStartToken = self.isLineClearToStartToken() endOfFirstLinePos = self.findEOL() lineCol = self.getRowCol() self.getDirectiveStartToken() self.advance(len('capture')) startPos = self.pos() self.getWhiteSpace() expr = self.getExpression(pyTokensToBreakAt=[':']) expr = self._applyExpressionFilters(expr, 'capture', startPos=startPos) if self.matchColonForSingleLineShortFormDirective(): self.advance() # skip over : self._compiler.startCaptureRegion(assignTo=expr, lineCol=lineCol) self.getWhiteSpace(max=1) self.parse(breakPoint=self.findEOL(gobble=False)) self._compiler.endCaptureRegion() else: if self.peek()==':': self.advance() self.getWhiteSpace() self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLinePos) self.pushToOpenDirectivesStack("capture") self._compiler.startCaptureRegion(assignTo=expr, lineCol=lineCol) def eatIf(self): # filtered isLineClearToStartToken = self.isLineClearToStartToken() endOfFirstLine = self.findEOL() lineCol = self.getRowCol() self.getDirectiveStartToken() startPos = self.pos() expressionParts = self.getExpressionParts(pyTokensToBreakAt=[':']) expr = ''.join(expressionParts).strip() expr = self._applyExpressionFilters(expr, 'if', startPos=startPos) isTernaryExpr = ('then' in expressionParts and 'else' in expressionParts) if isTernaryExpr: conditionExpr = [] trueExpr = [] falseExpr = [] currentExpr = conditionExpr for part in expressionParts: if part.strip()=='then': currentExpr = trueExpr elif part.strip()=='else': currentExpr = falseExpr else: currentExpr.append(part) conditionExpr = ''.join(conditionExpr) trueExpr = ''.join(trueExpr) falseExpr = ''.join(falseExpr) self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLine) self._compiler.addTernaryExpr(conditionExpr, trueExpr, falseExpr, lineCol=lineCol) elif self.matchColonForSingleLineShortFormDirective(): self.advance() # skip over : self._compiler.addIf(expr, lineCol=lineCol) self.getWhiteSpace(max=1) self.parse(breakPoint=self.findEOL(gobble=True)) self._compiler.commitStrConst() self._compiler.dedent() else: if self.peek()==':': self.advance() self.getWhiteSpace() self._eatRestOfDirectiveTag(isLineClearToStartToken, endOfFirstLine) self.pushToOpenDirectivesStack('if') self._compiler.addIf(expr, lineCol=lineCol) ## end directive handlers def handleEndDef(self): isNestedDef = (self.setting('allowNestedDefScopes') and [name for name in self._openDirectivesStack if name=='def']) if not isNestedDef: self._compiler.closeDef() else: # @@TR: temporary hack of useSearchList self.setSetting('useSearchList', self._useSearchList_orig) self._compiler.commitStrConst() self._compiler.dedent() ### def pushToOpenDirectivesStack(self, directiveName): assert directiveName in self._closeableDirectives self._openDirectivesStack.append(directiveName) def popFromOpenDirectivesStack(self, directiveName): if not self._openDirectivesStack: raise ParseError(self, msg="#end found, but nothing to end") if self._openDirectivesStack[-1] == directiveName: del self._openDirectivesStack[-1] else: raise ParseError(self, msg="#end %s found, expected #end %s" %( directiveName, self._openDirectivesStack[-1])) def assertEmptyOpenDirectivesStack(self): if self._openDirectivesStack: errorMsg = ( "Some #directives are missing their corresponding #end ___ tag: %s" %( ', '.join(self._openDirectivesStack))) raise ParseError(self, msg=errorMsg) ################################################## ## Make an alias to export Parser = _HighLevelParser PKCb3[,,Cheetah/FileUtils.py#!/usr/bin/env python # $Id: FileUtils.py,v 1.12 2005/11/02 22:26:07 tavis_rudd Exp $ """File utitilies for Python: Meta-Data ================================================================================ Author: Tavis Rudd License: This software is released for unlimited distribution under the terms of the MIT license. See the LICENSE file. Version: $Revision: 1.12 $ Start Date: 2001/09/26 Last Revision Date: $Date: 2005/11/02 22:26:07 $ """ __author__ = "Tavis Rudd " __revision__ = "$Revision: 1.12 $"[11:-2] from glob import glob import os from os import listdir import os.path import re from types import StringType from tempfile import mktemp def _escapeRegexChars(txt, escapeRE=re.compile(r'([\$\^\*\+\.\?\{\}\[\]\(\)\|\\])')): return escapeRE.sub(r'\\\1' , txt) def findFiles(*args, **kw): """Recursively find all the files matching a glob pattern. This function is a wrapper around the FileFinder class. See its docstring for details about the accepted arguments, etc.""" return FileFinder(*args, **kw).files() def replaceStrInFiles(files, theStr, repl): """Replace all instances of 'theStr' with 'repl' for each file in the 'files' list. Returns a dictionary with data about the matches found. This is like string.replace() on a multi-file basis. This function is a wrapper around the FindAndReplace class. See its docstring for more details.""" pattern = _escapeRegexChars(theStr) return FindAndReplace(files, pattern, repl).results() def replaceRegexInFiles(files, pattern, repl): """Replace all instances of regex 'pattern' with 'repl' for each file in the 'files' list. Returns a dictionary with data about the matches found. This is like re.sub on a multi-file basis. This function is a wrapper around the FindAndReplace class. See its docstring for more details.""" return FindAndReplace(files, pattern, repl).results() ################################################## ## CLASSES class FileFinder: """Traverses a directory tree and finds all files in it that match one of the specified glob patterns.""" def __init__(self, rootPath, globPatterns=('*',), ignoreBasenames=('CVS','.svn'), ignoreDirs=(), ): self._rootPath = rootPath self._globPatterns = globPatterns self._ignoreBasenames = ignoreBasenames self._ignoreDirs = ignoreDirs self._files = [] self.walkDirTree(rootPath) def walkDirTree(self, dir='.', listdir=os.listdir, isdir=os.path.isdir, join=os.path.join, ): """Recursively walk through a directory tree and find matching files.""" processDir = self.processDir filterDir = self.filterDir pendingDirs = [dir] addDir = pendingDirs.append getDir = pendingDirs.pop while pendingDirs: dir = getDir() ## process this dir processDir(dir) ## and add sub-dirs for baseName in listdir(dir): fullPath = join(dir, baseName) if isdir(fullPath): if filterDir(baseName, fullPath): addDir( fullPath ) def filterDir(self, baseName, fullPath): """A hook for filtering out certain dirs. """ return not (baseName in self._ignoreBasenames or fullPath in self._ignoreDirs) def processDir(self, dir, glob=glob): extend = self._files.extend for pattern in self._globPatterns: extend( glob(os.path.join(dir, pattern)) ) def files(self): return self._files class _GenSubberFunc: """Converts a 'sub' string in the form that one feeds to re.sub (backrefs, groups, etc.) into a function that can be used to do the substitutions in the FindAndReplace class.""" backrefRE = re.compile(r'\\([1-9][0-9]*)') groupRE = re.compile(r'\\g<([a-zA-Z_][a-zA-Z_]*)>') def __init__(self, replaceStr): self._src = replaceStr self._pos = 0 self._codeChunks = [] self.parse() def src(self): return self._src def pos(self): return self._pos def setPos(self, pos): self._pos = pos def atEnd(self): return self._pos >= len(self._src) def advance(self, offset=1): self._pos += offset def readTo(self, to, start=None): if start == None: start = self._pos self._pos = to if self.atEnd(): return self._src[start:] else: return self._src[start:to] ## match and get methods def matchBackref(self): return self.backrefRE.match(self.src(), self.pos()) def getBackref(self): m = self.matchBackref() self.setPos(m.end()) return m.group(1) def matchGroup(self): return self.groupRE.match(self.src(), self.pos()) def getGroup(self): m = self.matchGroup() self.setPos(m.end()) return m.group(1) ## main parse loop and the eat methods def parse(self): while not self.atEnd(): if self.matchBackref(): self.eatBackref() elif self.matchGroup(): self.eatGroup() else: self.eatStrConst() def eatStrConst(self): startPos = self.pos() while not self.atEnd(): if self.matchBackref() or self.matchGroup(): break else: self.advance() strConst = self.readTo(self.pos(), start=startPos) self.addChunk(repr(strConst)) def eatBackref(self): self.addChunk( 'm.group(' + self.getBackref() + ')' ) def eatGroup(self): self.addChunk( 'm.group("' + self.getGroup() + '")' ) def addChunk(self, chunk): self._codeChunks.append(chunk) ## code wrapping methods def codeBody(self): return ', '.join(self._codeChunks) def code(self): return "def subber(m):\n\treturn ''.join([%s])\n" % (self.codeBody()) def subberFunc(self): exec self.code() return subber class FindAndReplace: """Find and replace all instances of 'patternOrRE' with 'replacement' for each file in the 'files' list. This is a multi-file version of re.sub(). 'patternOrRE' can be a raw regex pattern or a regex object as generated by the re module. 'replacement' can be any string that would work with patternOrRE.sub(replacement, fileContents). """ def __init__(self, files, patternOrRE, replacement, recordResults=True): if type(patternOrRE) == StringType: self._regex = re.compile(patternOrRE) else: self._regex = patternOrRE if type(replacement) == StringType: self._subber = _GenSubberFunc(replacement).subberFunc() else: self._subber = replacement self._pattern = pattern = self._regex.pattern self._files = files self._results = {} self._recordResults = recordResults ## see if we should use pgrep to do the file matching self._usePgrep = False if (os.popen3('pgrep')[2].read()).startswith('Usage:'): ## now check to make sure pgrep understands the pattern tmpFile = mktemp() open(tmpFile, 'w').write('#') if not (os.popen3('pgrep "' + pattern + '" ' + tmpFile)[2].read()): # it didn't print an error msg so we're ok self._usePgrep = True os.remove(tmpFile) self._run() def results(self): return self._results def _run(self): regex = self._regex subber = self._subDispatcher usePgrep = self._usePgrep pattern = self._pattern for file in self._files: if not os.path.isfile(file): continue # skip dirs etc. self._currFile = file found = False if locals().has_key('orig'): del orig if self._usePgrep: if os.popen('pgrep "' + pattern + '" ' + file ).read(): found = True else: orig = open(file).read() if regex.search(orig): found = True if found: if not locals().has_key('orig'): orig = open(file).read() new = regex.sub(subber, orig) open(file, 'w').write(new) def _subDispatcher(self, match): if self._recordResults: if not self._results.has_key(self._currFile): res = self._results[self._currFile] = {} res['count'] = 0 res['matches'] = [] else: res = self._results[self._currFile] res['count'] += 1 res['matches'].append({'contents':match.group(), 'start':match.start(), 'end':match.end(), } ) return self._subber(match) class SourceFileStats: """ """ _fileStats = None def __init__(self, files): self._fileStats = stats = {} for file in files: stats[file] = self.getFileStats(file) def rawStats(self): return self._fileStats def summary(self): codeLines = 0 blankLines = 0 commentLines = 0 totalLines = 0 for fileStats in self.rawStats().values(): codeLines += fileStats['codeLines'] blankLines += fileStats['blankLines'] commentLines += fileStats['commentLines'] totalLines += fileStats['totalLines'] stats = {'codeLines':codeLines, 'blankLines':blankLines, 'commentLines':commentLines, 'totalLines':totalLines, } return stats def printStats(self): pass def getFileStats(self, fileName): codeLines = 0 blankLines = 0 commentLines = 0 commentLineRe = re.compile(r'\s#.*$') blankLineRe = re.compile('\s$') lines = open(fileName).read().splitlines() totalLines = len(lines) for line in lines: if commentLineRe.match(line): commentLines += 1 elif blankLineRe.match(line): blankLines += 1 else: codeLines += 1 stats = {'codeLines':codeLines, 'blankLines':blankLines, 'commentLines':commentLines, 'totalLines':totalLines, } return stats PKcw#22TU`Cheetah/ErrorCatchers.py#!/usr/bin/env python # $Id: ErrorCatchers.py,v 1.7 2005/01/03 19:59:07 tavis_rudd Exp $ """ErrorCatcher class for Cheetah Templates Meta-Data ================================================================================ Author: Tavis Rudd Version: $Revision: 1.7 $ Start Date: 2001/08/01 Last Revision Date: $Date: 2005/01/03 19:59:07 $ """ __author__ = "Tavis Rudd " __revision__ = "$Revision: 1.7 $"[11:-2] import time from Cheetah.NameMapper import NotFound class Error(Exception): pass class ErrorCatcher: _exceptionsToCatch = (NotFound,) def __init__(self, templateObj): pass def exceptions(self): return self._exceptionsToCatch def warn(self, exc_val, code, rawCode, lineCol): return rawCode ## make an alias Echo = ErrorCatcher class BigEcho(ErrorCatcher): def warn(self, exc_val, code, rawCode, lineCol): return "="*15 + "<" + rawCode + " could not be found>" + "="*15 class KeyError(ErrorCatcher): def warn(self, exc_val, code, rawCode, lineCol): raise KeyError("no '%s' in this Template Object's Search List" % rawCode) class ListErrors(ErrorCatcher): """Accumulate a list of errors.""" _timeFormat = "%c" def __init__(self, templateObj): ErrorCatcher.__init__(self, templateObj) self._errors = [] def warn(self, exc_val, code, rawCode, lineCol): dict = locals().copy() del dict['self'] dict['time'] = time.strftime(self._timeFormat, time.localtime(time.time())) self._errors.append(dict) return rawCode def listErrors(self): """Return the list of errors.""" return self._errors PKݡ(8h)hhCheetah/SettingsManager.pyc; Fc@s^dZdZddd!ZdkZdkZdkZdklZdk Z dk l Z l Z l Z dkTdkZdkZdkZdkZd klZdkZydkZd klZWnd fd YZnXd fdYZyeefWn1ej o%ddjddjf\ZZnXe ie Ze ide de dZeeee e!e"e#fZ$eedZ%dZ&dZ'dZ(dZ)e ie)dZ*dZ+e ie)e+dZ,dZ-defdYZ.dfdYZ/d efd!YZ0d"fd#YZ1d$fd%YZ2d&e2fd'YZ3dS((sProvides a mixin/base class for collecting and managing application settings Meta-Data ========== Author: Tavis Rudd Version: $Revision: 1.29 $ Start Date: 2001/05/30 Last Revision Date: $Date: 2007/04/03 02:03:26 $ s!Tavis Rudd s$Revision: 1.29 $i iN(s ConfigParser(s Intnumbers FloatnumbersNumber(s*(sStringIO(sLocksLockcBstZdZdZRS(NcCsdS(N((sself((s<build/bdist.darwin-8.0.1-i386/egg/Cheetah/SettingsManager.pysacquire)scCsdS(N((sself((s<build/bdist.darwin-8.0.1-i386/egg/Cheetah/SettingsManager.pysrelease+s(s__name__s __module__sacquiresrelease(((s<build/bdist.darwin-8.0.1-i386/egg/Cheetah/SettingsManager.pysLock(s sBaseErrorClasscBstZRS(N(s__name__s __module__(((s<build/bdist.darwin-8.0.1-i386/egg/Cheetah/SettingsManager.pysBaseErrorClass.siis[\(]*s[ \t]*\+[ \t]*s[\)]*cCs|oti|}n|oti|}nx|iD]q\}}|i|o-t |t i jot ||t i jot |||||\s*)(?P[_a-zA-Z][_a-zA-Z0-9]*)s\s*:sM(?P\(\s*([_a-zA-Z][_a-zA-Z0-9]*\s*(,\s*[_a-zA-Z][_a-zA-Z0-9]*\s*)*)\))cCsg}x|iD]}ti|o)|iiddddddfjotid|}n>t i|o|ii d ot id|}n|i |qW|di d d jo d }nd }|d i|d SdS(s9Compiles a config file in the custom class-based SettingsContainer syntax to Vanilla Python # WebKit.config Applications: MyApp: Dirs: ROOT = '/home/www/Home' Products = '/home/www/Products' becomes: # WebKit.config from Cheetah.SettingsManager import SettingsContainer class Applications(SettingsContainer): class MyApp(SettingsContainer): class Dirs(SettingsContainer): ROOT = '/home/www/Home' Products = '/home/www/Products' s:iselsestrysexceptsfinallys-\gclass \g(SettingsContainer):s#\gclass \g\g:sclass isKfrom Cheetah.SettingsManager import SettingsContainer; True, False = 1, 0; sJfrom Cheetah.SettingsManager import SettingsContainer; True, False = 1, 0 s N(s outputLinesssrcs splitlinesslines customClassResmatchsstripssplitssubscustomClassWithBasesRes startswithsappendsfindsinitLinesjoin(ssrcs outputLinessinitLinesline((s<build/bdist.darwin-8.0.1-i386/egg/Cheetah/SettingsManager.pystranslateClassBasedConfigSyntax|s <' sErrorcBstZRS(N(s__name__s __module__(((s<build/bdist.darwin-8.0.1-i386/egg/Cheetah/SettingsManager.pysErrorss NoDefaultcBstZRS(N(s__name__s __module__(((s<build/bdist.darwin-8.0.1-i386/egg/Cheetah/SettingsManager.pys NoDefaultssConfigParserCaseSensitivecBstZdZdZRS(s=A case sensitive version of the standard Python ConfigParser.cCs|SdS(s>Don't change the case as is done in the default implemenation.N(s optionstr(sselfs optionstr((s<build/bdist.darwin-8.0.1-i386/egg/Cheetah/SettingsManager.pys optionxforms(s__name__s __module__s__doc__s optionxform(((s<build/bdist.darwin-8.0.1-i386/egg/Cheetah/SettingsManager.pysConfigParserCaseSensitives sSettingsContainercBstZdZRS(sEAn abstract base class for 'classes' that are used to house settings.(s__name__s __module__s__doc__(((s<build/bdist.darwin-8.0.1-i386/egg/Cheetah/SettingsManager.pysSettingsContainers s_SettingsCollectorcBs}tZdZeZeZdZdZe dZ e Z dZ dZ dZdZe dZe d ZRS( sAn abstract base class that provides the methods SettingsManager uses to collect settings from config files and SettingsContainers. This class only collects settings it doesn't modify the _settings dictionary of SettingsManager instances in any way. SettingsCollector is designed to: - be able to read settings from Python src files (or strings) so that complex Python objects can be stored in the application's settings dictionary. For example, you might want to store references to various classes that are used by the application and plugins to the application might want to substitute one class for another. - be able to read/write .ini style config files (or strings) - allow sections in .ini config files to be extended by settings in Python src files - allow python literals to be used values in .ini config files - maintain the case of setting names, unlike the ConfigParser module cCsdS(N((sself((s<build/bdist.darwin-8.0.1-i386/egg/Cheetah/SettingsManager.pys__init__scCs tii|iddSdS(sqA hook for any neccessary path manipulations. For example, when this is used with WebKit servlets all relative paths must be converted so they are relative to the servlet's directory rather than relative to the program's current working dir. The default implementation just normalizes the path for the current operating system.s\s/N(sosspathsnormpathsreplace(sselfspath((s<build/bdist.darwin-8.0.1-i386/egg/Cheetah/SettingsManager.pys normalizePaths cCsh}t|tjot|}n|i|}xv|iD]h\}}|o |i dp |t joqEn|i|o|i|||See the docstring for .updateSettingsFromConfigFile() s [globals] sconvertsmerges mergeSettingsN( s configStrsStringIOsinFilesselfsreadSettingsFromConfigFileObjsconverts newSettingssupdateSettingssgetsmerge(sselfs configStrsconvertsmerges newSettingssinFile((s<build/bdist.darwin-8.0.1-i386/egg/Cheetah/SettingsManager.pysupdateSettingsFromConfigStr&s    c Cs|tjo t}nhdh<}|d}x|iiD]\} }t |t jo|||              cCs9|i|}t|d}|i||idS(s_Write all the settings that can be represented as strings to an .ini style config file.swN(sselfs normalizePathspathsopensfps_createConfigFilesclose(sselfspathsfp((s<build/bdist.darwin-8.0.1-i386/egg/Cheetah/SettingsManager.pyswriteConfigFile]s  cCs|iiSdS(s6Return a string with the settings in .ini file format.N(sselfs_createConfigFilesgetvalue(sself((s<build/bdist.darwin-8.0.1-i386/egg/Cheetah/SettingsManager.pysgetConfigStringgs(s__name__s __module__s__doc__s__init__s_defaultSettingss_initializeSettingss NoDefaultssettings hasSettings setSettingssettingss copySettingssdeepcopySettingssTruesupdateSettingssupdateSettingsFromPySrcStrsupdateSettingsFromPySrcFilesupdateSettingsFromConfigFilesupdateSettingsFromConfigFileObjsupdateSettingsFromConfigStrsNones_createConfigFileswriteConfigFilesgetConfigString(((s<build/bdist.darwin-8.0.1-i386/egg/Cheetah/SettingsManager.pysSettingsManagers&             ) (4s__doc__s __author__s __revision__ssyssos.pathsosscopys copyModules ConfigParsersrestokenizes Intnumbers FloatnumbersNumberstypessnewstempfilestimesStringIOsimps threadingsLocksBaseErrorClasssTruesFalses NameErrorscompilesnumberREscomplexNumberREs StringTypesIntTypes FloatTypesLongTypes ComplexTypesNoneTypes UnicodeTypesconvertableToStrTypessmergeNestedDictionariessstringIsNumbersconvStringToNumsidents firstChunks customClassRes baseClassesscustomClassWithBasesRestranslateClassBasedConfigSyntaxsErrors NoDefaultsConfigParserCaseSensitivesSettingsContainers_SettingsCollectorsSettingsManager('s FloatnumbersBaseErrorClassstranslateClassBasedConfigSyntaxsnumberREs Intnumbers_SettingsCollectors __revision__sConfigParserCaseSensitivesimpstempfilesmergeNestedDictionariessresstringIsNumbers firstChunksnewsTruescustomClassWithBasesResconvStringToNumsconvertableToStrTypess copyModules __author__ssyssSettingsContainersErrorstypess ConfigParsersidentsFalsesStringIOsLockscomplexNumberREsNumbers threadingsSettingsManagers customClassRes baseClassesstimes NoDefaultsos((s<build/bdist.darwin-8.0.1-i386/egg/Cheetah/SettingsManager.pys? sV             #   . PKo;4G߽Cheetah/CacheRegion.py# $Id: CacheRegion.py,v 1.3 2006/01/28 04:19:30 tavis_rudd Exp $ """Cache holder classes for Cheetah: Cache regions are defined using the #cache Cheetah directive. Each cache region can be viewed as a dictionary (keyed by cacheRegionID) handling at least one cache item (the default one). It's possible to add cacheItems in a region by using the `varyBy` #cache directive parameter as in the following example:: #def getArticle this is the article content. #end def #cache varyBy=$getArticleID() $getArticle($getArticleID()) #end cache The code above will generate a CacheRegion and add new cacheItem for each value of $getArticleID(). Meta-Data ================================================================================ Author: Tavis Rudd and Philippe Normand Version: $Revision: 1.3 $ Start Date: 2005/06/20 Last Revision Date: $Date: 2006/01/28 04:19:30 $ """ __author__ = "Tavis Rudd and Philippe Normand " __revision__ = "$Revision: 1.3 $"[11:-2] import md5 from time import time as currentTime from Cheetah.CacheStore import MemoryCacheStore class CacheItem: """A CacheItem is a container storing: - cacheID (string) - refreshTime (timestamp or None) : last time the cache was refreshed - data (string) : the content of the cache """ def __init__(self, cacheItemID, cacheStore): self._cacheItemID = cacheItemID self._cacheStore = cacheStore self._refreshTime = None self._expiryTime = 0 def hasExpired(self): return (self._expiryTime and currentTime() > self._expiryTime) def setExpiryTime(self, time): self._expiryTime = time def getExpiryTime(self): return self._expiryTime def setData(self, data): self._refreshTime = currentTime() self._cacheStore.set(self._cacheItemID, data, self._expiryTime) def getRefreshTime(self): return self._refreshTime def getData(self): assert self._refreshTime return self._cacheStore.get(self._cacheItemID) def renderOutput(self): """Can be overridden to implement edge-caching""" return self.getData() or "" def clear(self): self._cacheStore.delete(self._cacheItemID) self._refreshTime = None class _CacheDataStoreWrapper: def __init__(self, dataStore, keyPrefix): self._dataStore = dataStore self._keyPrefix = keyPrefix def get(self, key): return self._dataStore.get(self._keyPrefix+key) def delete(self, key): self._dataStore.delete(self._keyPrefix+key) def set(self, key, val, time=0): self._dataStore.set(self._keyPrefix+key, val, time=time) class CacheRegion: """ A `CacheRegion` stores some `CacheItem` instances. This implementation stores the data in the memory of the current process. If you need a more advanced data store, create a cacheStore class that works with Cheetah's CacheStore protocol and provide it as the cacheStore argument to __init__. For example you could use Cheetah.CacheStore.MemcachedCacheStore, a wrapper around the Python memcached API (http://www.danga.com/memcached). """ _cacheItemClass = CacheItem def __init__(self, regionID, templateCacheIdPrefix='', cacheStore=None): self._isNew = True self._regionID = regionID self._templateCacheIdPrefix = templateCacheIdPrefix if not cacheStore: cacheStore = MemoryCacheStore() self._cacheStore = cacheStore self._wrappedCacheDataStore = _CacheDataStoreWrapper( cacheStore, keyPrefix=templateCacheIdPrefix+':'+regionID+':') self._cacheItems = {} def isNew(self): return self._isNew def clear(self): " drop all the caches stored in this cache region " for cacheItemId in self._cacheItems.keys(): cacheItem = self._cacheItems[cacheItemId] cacheItem.clear() del self._cacheItems[cacheItemId] def getCacheItem(self, cacheItemID): """ Lazy access to a cacheItem Try to find a cache in the stored caches. If it doesn't exist, it's created. Returns a `CacheItem` instance. """ cacheItemID = md5.new(str(cacheItemID)).hexdigest() if not self._cacheItems.has_key(cacheItemID): cacheItem = self._cacheItemClass( cacheItemID=cacheItemID, cacheStore=self._wrappedCacheDataStore) self._cacheItems[cacheItemID] = cacheItem self._isNew = False return self._cacheItems[cacheItemID] PK5f4HCheetah/Unspecified.pytry: from ds.sys.Unspecified import Unspecified except ImportError: class _Unspecified: def __repr__(self): return 'Unspecified' def __str__(self): return 'Unspecified' Unspecified = _Unspecified() PK(8>>Cheetah/_namemapper.pyc;  Gc@sdatdS(cCsGdk}dk}dk}|itdabb|ittdS(Ns_namemapper.so( ssyss pkg_resourcessimpsresource_filenames__name__s__file__s __bootstrap__s __loader__s load_dynamic(s pkg_resourcesssyssimp((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/_namemapper.pys __bootstrap__s N(s __bootstrap__(((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/_namemapper.pys?s PK(8Cheetah/Parser.pyc; BFc@sdZdZddd!ZdkZdkZdkZdklZlZdkl Z l Z l Z l Z l Z dkZdklZdkZdkZdkZd klZd klZd klZd klZhZd ZeiddZdZdZ dZ!dZ"dZ#dZ$dZ%dZ&dZ'dZ(dZ)dZ*e*dZ+dZ,dddfZ-ddddd fZ.d!d"fZ/d#d$d%fZ0d&Z1d'd(d)d*d+d,d-d.d/d0d1f Z2e1fe2Z3d2d3d4d5d6d7d8d9d:f Z4d;d<d=fZ5e,fe-e.e/e0e3e4e5Z6d>d?d@dAdBdCdDdEdFdGd&dHf e2Z7d;dIdJd9dKdLdMdNdOdPdQdRdSd=dTdUdVdWd<dXdYdZd[d\d]d^d:d_fZ8d`Z9daZ:d`dadbdcdddedfdgdhdidjdkdldmdndodpdqfZ;hd`e9<dae:<dbe9<dce:<dfe9<dge:<dje9<dke:<dde9<dee:<dhe9<die:<dne9<doe:<dle9<dme:<dpe9<dqe:<dCdB<dAd@d?<dBdC<d@dAhZ?drZ@x-e<iAD]\ZBZCe@eBeCe?eB Version: $Revision: 1.134 $ Start Date: 2001/08/01 Last Revision Date: $Date: 2007/04/04 00:28:50 $ s!Tavis Rudd s$Revision: 1.134 $i iN(sDOTALLs MULTILINE(s StringTypesListTypes TupleTypes ClassTypesTypeType(s pseudoprog(s SourceReader(sFilters(s ErrorCatchers(s UnspecifiedcCs0|tjoti|t|s|s)(snamesjoinschoices(snameschoices((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys namedGroup5scGstt|dSdS(Ns*(sapplysgroupschoices(schoices((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysany6scGstt|dSdS(Ns?(sapplysgroupschoices(schoices((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysmaybe7siiis5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_s 0123456789s**s+s-s~s/s//s%s>>s<>=s<<=s&=s|=ss==s!=s<=s>=s<>sissinsandsorsnots(s)s{s}s[s]s,s.s:s;s`sdelsforsraisesassertselifsfromslambdasreturnsbreakselsesglobalstrysclasssexceptsifswhilescontinuesexecsimportspasssdefsfinallysprints'''s"""sr'''sr"""sR'''sR"""su'''su"""sU'''sU"""sur'''sur"""sUr'''sUr"""suR'''suR"""sUR'''sUR"""cCsCt|}t|}tid|dd|dtiSdS(Ns(?:s).*?s)(sescapeRegexCharssstartsendsrescompilesDOTALL(sstartsend((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysmakeTripleQuoteRes  s[ \f\t]*s \r\n|\n|\rs|\Zs(?<=\A)s(?s   (s__name__s __module__sTruesNones__init__(((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysCheetahVariable=ss PlaceholdercBstZRS(N(s__name__s __module__(((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys PlaceholderEssArgListcBsDtZdZdZdZdZdZdZdZRS(s$Used by _LowLevelParser.getArgList()cCsg|_g|_d|_dS(Ni(sselfsargNamessdefValssi(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys__init__Js  cCs$|ii||iitdS(N(sselfsargNamessappendsnamesdefValssNone(sselfsname((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys addArgNameOscCs|id7_dS(Ni(sselfsi(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysnextSscCsE|i}|i|tjod|i|e9eeed9Z?e9eeed:Z@d;ZAd<ZBe9e9e9d=ZCRS(>sThis class implements the methods to match or extract ('get*') the basic elements of Cheetah's grammar. It does NOT handle any code generation or state management. cCs ||_dS(N(ssettingsManagersselfs_settingsManager(sselfssettingsManager((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pyssetSettingsManageroscCs;|tjo|ii|Sn|ii|d|SdS(Nsdefault(sdefaults Unspecifiedsselfs_settingsManagerssettingskey(sselfskeysdefault((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pyssettingrs cCs|ii||dS(N(sselfs_settingsManagers setSettingskeysval(sselfskeysval((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys setSettingxscCs|iiSdS(N(sselfs_settingsManagerssettings(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pyssettings{scCs|ii|dS(N(sselfs_settingsManagersupdateSettingsssettings(sselfssettings((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysupdateSettings~scCs|iidS(N(sselfs_settingsManagers_initializeSettings(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys_initializeSettingsscCs|i|i|i|i|idd|idd|idd|idd|idd|_|i|i|i |i |i |i |i g|_dS(sIs called by the Compiler instance after the parser has had a settingsManager assigned with self.setSettingsManager() scommentStartTokenismultiLineCommentStartTokenscheetahVarStartTokensdirectiveStartTokens PSPStartTokenN(sselfs_makeCheetahVarREss_makeCommentREss_makeDirectiveREss _makePspREsssettings_possibleNonStrConstantCharssmatchCommentStartTokensmatchMultiLineCommentStartTokensmatchVariablePlaceholderStartsmatchExpressionPlaceholderStartsmatchDirectivesmatchPSPStartTokensmatchEOLSlurpTokens_nonStrConstMatchers(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysconfigureParsers    ZcCsd}d|d|d|d|d|d|d}d d |d d d d dd}t||_d dtddd dd}t||_tt dt|i ddd|dd|ddd|_ d}|i d|_ tt t|i d||_tt|i dd|_tt dt|i ddd|ddd|_|i do2tt|i ddd td|_n t|_dS(s*Setup the regexs for Cheetah $var parsing.s[0-9\.]+s (?Pss|sm|sh|sd|sw|s)s(?:s(?P\*s\*)s|s(?P\*)s(?P)s (?Ps!s(?P)s(?PscheetahVarStartTokens(?Ps(?Ps((?P|(?:(?:\{|\(|\[)[ \t\f]*))s (?=[A-Za-z_])s(?=[A-Za-z_\*!\{\(\[])s(?:\{|\(|\[)[ \t\f]*s (?=[^\)\}\]])s EOLSlurpTokens[ \t\f]*N(snumsintervals cacheTokens cachedRegexsselfs cacheTokenREsescapeRegexCharsssilentPlaceholderTokenssilentPlaceholderTokenREsescCharLookBehindssettingscheetahVarStartREsvalidCharsLookAheadscheetahVarStartTokenscheetahVarStartTokenREs"cheetahVarInExpressionStartTokenREsexpressionPlaceholderStartREsEOLs EOLSlurpREsNone(sselfsintervals cacheTokensnumsvalidCharsLookAheadssilentPlaceholderToken((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys_makeCheetahVarREss 6 &$J&"> 2cCst|id}tt||_~t|id}t|id}tt||_tt||_ dS(s:Construct the regex bits that are used in comment parsing.scommentStartTokensmultiLineCommentStartTokensmultiLineCommentEndTokenN( sescapeRegexCharssselfssettings startTokenEscs cachedRegexsescCharLookBehindscommentStartTokenREs endTokenEscsmultiLineCommentTokenStartREsmultiLineCommentEndTokenRE(sselfs startTokenEscs endTokenEsc((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys_makeCommentREsscCs|id}|id}t|}t|}d}t|g}|ido|i dn|i |t di ||_ t t||_dS(s8Construct the regexs that are used in directive parsing.sdirectiveStartTokensdirectiveEndTokens(?=[A-Za-z_@])s'allowWhitespaceAfterDirectiveStartTokens[ ]*sN(sselfssettings startTokensendTokensescapeRegexCharss startTokenEscs endTokenEscsvalidSecondCharsLookAheadsescCharLookBehindsrePartssappends cachedRegexsjoinsdirectiveStartTokenREsdirectiveEndTokenRE(sselfs startTokens startTokenEscsrePartss endTokenEscsvalidSecondCharsLookAheadsendToken((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys_makeDirectiveREss    cCs`|id}t|}tt||_|id}t|}tt||_ dS(s!Setup the regexs for PSP parsing.s PSPStartTokens PSPEndTokenN( sselfssettings startTokensescapeRegexCharss startTokenEscs cachedRegexsescCharLookBehindsPSPStartTokenREsendTokens endTokenEscs PSPEndTokenRE(sselfs startTokens startTokenEscs endTokenEscsendToken((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys _makePspREss  cCs|i|SdS(N(sselfsisLineClearToPosspos(sselfspos((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysisLineClearToStartToken scCsQt}|i|ijo-x*|iD]}|}|oPq&q&Wn|SdS(sReturns the first match found from the following methods: self.matchCommentStartToken self.matchMultiLineCommentStartToken self.matchVariablePlaceholderStart self.matchExpressionPlaceholderStart self.matchDirective self.matchPSPStartToken self.matchEOLSlurpToken Returns None if no match. N(sNonesmatchsselfspeeks_possibleNonStrConstantCharss_nonStrConstMatcherssmatcher(sselfsmatchersmatch((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysmatchTopLevelToken s    cCs{ti|i|i}|o|itjo;t|ii|i|i}|o|Sqsn|SdS(N( s pseudoprogsmatchsselfssrcspossgroupstripleQuotedStringStartsstripleQuotedStringREssTQSmatch(sselfsTQSmatchsmatch((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys matchPyToken!s ( cCsi|i}|tjot|n*|itjot|ddn|i|iSdS(NsmsgsMalformed triple-quoted string( sselfs matchPyTokensmatchsNones ParseErrorsgroupstripleQuotedStringStartssreadTosend(sselfsmatch((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys getPyToken*s   cCs1|io#|ii|i|iSndS(N(sselfs EOLSlurpREsmatchssrcspos(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysmatchEOLSlurpToken2s cCsA|i}| ot|ddn|i|iSdS(NsmsgsInvalid EOL slurp token(sselfsmatchEOLSlurpTokensmatchs ParseErrorsreadTosend(sselfsmatch((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysgetEOLSlurpToken6s cCs#|ii|i|iSdS(N(sselfscommentStartTokenREsmatchssrcspos(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysmatchCommentStartToken<scCsA|i}| ot|ddn|i|iSdS(Nsmsgs'Invalid single-line comment start token(sselfsmatchCommentStartTokensmatchs ParseErrorsreadTosend(sselfsmatch((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysgetCommentStartToken?s cCs#|ii|i|iSdS(N(sselfsmultiLineCommentTokenStartREsmatchssrcspos(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysmatchMultiLineCommentStartTokenEscCsA|i}| ot|ddn|i|iSdS(Nsmsgs&Invalid multi-line comment start token(sselfsmatchMultiLineCommentStartTokensmatchs ParseErrorsreadTosend(sselfsmatch((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysgetMultiLineCommentStartTokenHs cCs#|ii|i|iSdS(N(sselfsmultiLineCommentEndTokenREsmatchssrcspos(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysmatchMultiLineCommentEndTokenNscCsA|i}| ot|ddn|i|iSdS(Nsmsgs$Invalid multi-line comment end token(sselfsmatchMultiLineCommentEndTokensmatchs ParseErrorsreadTosend(sselfsmatch((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysgetMultiLineCommentEndTokenQs cCst|}g}|itj ot|nx|i|jo|i}|t jo|i }|i |q9|djoI|id|jo|idtjo|i |i qPq9Pq9Wdi|SdS(Ns.is(slensselfssrcLens nameChunksspeeks identcharss ParseErrorsposscs namecharss getIdentifiers nameChunksappendsgetcsjoin(sselfscs nameChunkss nameChunkssrcLen((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys getDottedNameWs      -cCs ti|i|iSdS(N(sidentREsmatchsselfssrcspos(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysmatchIdentifiermscCsA|i}| ot|ddn|i|iSdS(NsmsgsInvalid identifier(sselfsmatchIdentifiersmatchs ParseErrorsreadTosend(sselfsmatch((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys getIdentifierps cCs8|i}|o|itjo t}n|SdS(N(sselfs matchPyTokensmatchsgroups operatorssNone(sselfsmatch((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys matchOperatorvs  cCsA|i}| ot|ddn|i|iSdS(NsmsgsExpected operator(sselfs matchOperatorsmatchs ParseErrorsreadTosend(sselfsmatch((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys getOperator|s cCs8|i}|o|itjo t}n|SdS(N(sselfs matchPyTokensmatchsgroups assignmentOpssNone(sselfsmatch((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysmatchAssignmentOperators  cCsA|i}| ot|ddn|i|iSdS(NsmsgsExpected assignment operator(sselfsmatchAssignmentOperatorsmatchs ParseErrorsreadTosend(sselfsmatch((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysgetAssignmentOperators cCsM|i}|i otSn|i|i}|i||SdS(s<Returns False or the name of the directive matched. N( sselfspossstartPossmatchDirectiveStartTokensFalsesgetDirectiveStartTokensmatchDirectiveNames directiveNamessetPos(sselfsstartPoss directiveName((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysmatchDirectives    s 0123456789-@c Cs8|i}|ii}d}t}x|i o|i }||j oPn||7}|djo0|i o|i tjo d}nPngi}|D]$}|i|o||qq~}| oPq*||jo|i p|i |jo |}Pq*q*W|i||SdS(Nss@(sselfspossstartPoss_directiveNamesAndParsersskeysspossibleMatchessnamesNonesmatchsatEndsgetcscsdirectiveNameCharsspeeks identcharssappends_[1]sdns startswithssetPos( sselfsdirectiveNameCharssdnsnamespossibleMatchesscs_[1]sstartPossmatch((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysmatchDirectiveNames,    ! ;-  cCs#|ii|i|iSdS(N(sselfsdirectiveStartTokenREsmatchssrcspos(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysmatchDirectiveStartTokenscCsA|i}| ot|ddn|i|iSdS(NsmsgsInvalid directive start token(sselfsmatchDirectiveStartTokensmatchs ParseErrorsreadTosend(sselfsmatch((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysgetDirectiveStartTokens cCs#|ii|i|iSdS(N(sselfsdirectiveEndTokenREsmatchssrcspos(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysmatchDirectiveEndTokenscCsA|i}| ot|ddn|i|iSdS(NsmsgsInvalid directive end token(sselfsmatchDirectiveEndTokensmatchs ParseErrorsreadTosend(sselfsmatch((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysgetDirectiveEndTokens cCs|i o|idjo\||id|i!}|i}| otSq}|ii |otSq}t SntSdS(Ns:i( sselfsatEndspeekspossfindEOLs restOfLinesstripsFalsescommentStartTokenREsmatchsTrue(sselfs restOfLine((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys)matchColonForSingleLineShortFormDirectives! cCs#|ii|i|iSdS(N(sselfsPSPStartTokenREsmatchssrcspos(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysmatchPSPStartTokenscCs#|ii|i|iSdS(N(sselfs PSPEndTokenREsmatchssrcspos(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysmatchPSPEndTokenscCsA|i}| ot|ddn|i|iSdS(NsmsgsInvalid psp start token(sselfsmatchPSPStartTokensmatchs ParseErrorsreadTosend(sselfsmatch((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysgetPSPStartTokens cCsA|i}| ot|ddn|i|iSdS(NsmsgsInvalid psp end token(sselfsmatchPSPEndTokensmatchs ParseErrorsreadTosend(sselfsmatch((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysgetPSPEndTokens cCs#|ii|i|iSdS(s&includes the enclosure and cache tokenN(sselfscheetahVarStartREsmatchssrcspos(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysmatchCheetahVarStartscCs#|ii|i|iSdS(s&includes the enclosure and cache tokenN(sselfscheetahVarStartTokenREsmatchssrcspos(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysmatchCheetahVarStartTokenscCs#|ii|i|iSdS(s%no enclosures or cache tokens allowedN(sselfs"cheetahVarInExpressionStartTokenREsmatchssrcspos(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys%matchCheetahVarInExpressionStartTokenscCs#|ii|i|iSdS(s&includes the enclosure and cache tokenN(sselfscheetahVarStartREsmatchssrcspos(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysmatchVariablePlaceholderStartscCs#|ii|i|iSdS(s&includes the enclosure and cache tokenN(sselfsexpressionPlaceholderStartREsmatchssrcspos(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysmatchExpressionPlaceholderStartscCsA|i}| ot|ddn|i|iSdS(s6just the start token, not the enclosure or cache tokensmsgs!Expected Cheetah $var start tokenN(sselfsmatchCheetahVarStartTokensmatchs ParseErrorsreadTosend(sselfsmatch((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysgetCheetahVarStartTokens  cCsbyB|ii|i|i}|i|i|iSWnt |ddnXdS(NsmsgsExpected cache token( sselfs cacheTokenREsmatchssrcsposstokenssetPossendsgroups ParseError(sselfstoken((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys getCacheTokens !cCsbyB|ii|i|i}|i|i|iSWnt |ddnXdS(Nsmsgs!Expected silent placeholder token( sselfssilentPlaceholderTokenREsmatchssrcsposstokenssetPossendsgroups ParseError(sselfstoken((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysgetSilentPlaceholderTokens !cCsg}x|i o|idjo|iq |idjoPq |ido|iq |idp |idoPq |io5|i|i |i |i |i q |i o|i |i q Pq W|SdS(Ns s s,sin sin (svarnamessselfsatEndspeeks getWhiteSpaces startswithsadvances%matchCheetahVarInExpressionStartTokensgetCheetahVarStartTokensgetSilentPlaceholderTokens getCacheTokensappends getDottedNamesmatchIdentifier(sselfsvarnames((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysgetTargetVarsLists(      cCs>| o|in|i|i|id|SdS(sThis is called when parsing inside expressions. Cache tokens are only valid in placeholders so this method discards any cache tokens found. splainN(sskipStartTokensselfsgetCheetahVarStartTokensgetSilentPlaceholderTokens getCacheTokensgetCheetahVarBodysplain(sselfsplainsskipStartToken((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys getCheetahVar(s   cCs |ii|id|SdS(Nsplain(sselfs _compilers genCheetahVarsgetCheetahVarNameChunkssplain(sselfsplain((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysgetCheetahVarBody2scCsg}x|it|jood}t}|itdj oPnZ|idjoF|idt|jo|idtjo|i qPn|i }|i o|idjo|idjo|i }n|idt}t|idd}|o,|i|| |df||d}n|o|ddjo t}qwn|i|||fq W|SdS( s nameChunks = list of Cheetah $var subcomponents represented as tuples [ (namemapperPart,autoCall,restOfName), ] where: namemapperPart = the dottedName base autocall = where NameMapper should use autocalling on namemapperPart restOfName = any arglist, index, or slice If restOfName contains a call arglist (e.g. '(1234)') then autocall is False, otherwise it defaults to True. EXAMPLE ------------------------------------------------------------------------ if the raw CheetahVar is $a.b.c[1].d().x.y.z nameChunks is the list [ ('a.b.c',True,'[1]'), ('d',False,'()'), ('x.y.z',True,''), ] ss.is([s(senclosediN(schunkssselfsposslensrestsTruesautoCallspeeks identcharssadvances getDottedNames dottedNamesatEndsgetCallArgStrings getExpressionsmaxsrfindsperiodsappendsFalse(sselfsautoCalls dottedNamesperiodsrestschunks((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysgetCheetahVarNameChunks6s23 !cCs7|tj o#|id}|id|n|onP|idj ot|ddn|i } |i d| fg}dg}|i } xfno^|ioS|dd}t|} |i|ddt|dd| d |d n|i}|d jol| ot|n|i }t|}|dd|jo|i| d Pqt|q|d jo| |i q|io|i } |i} |i}|i o|idjok|i} | djo<|i }|i| |idt} |i|n| | || q| | |q|i o|i!q|i }|i}|dddfjo |i$|i%dt}n|i&||}| |qW|tj o|id|ndi'|SdS(sf Get a method/function call argument string. This method understands *arg, and **kw s useNameMappers(smsgs Expected '('iiis#EOF was reached before a matching 's' was found for the 's's)}]s)s s=splains{s[senclosedsN((s useNameMappers UnspecifiedsselfssettingsuseNameMapper_origs setSettings enclosuresspeeks ParseErrorspossstartPossgetcs argStringBitssappendsaddBitsatEndsopensclosurePairsRevsclosessetPosscs closurePairsspops%matchCheetahVarInExpressionStartTokens getCheetahVarscodeFor1stTokens getWhiteSpacesWSs getPyTokens nextTokensendPossTruesmatchCheetahVarStarts-_raiseErrorAboutInvalidCheetahVarSyntaxInExprsbeforeTokenPosstokensrevs getExpressionstransformTokensjoin(sselfs enclosuress useNameMappers argStringBitssbeforeTokenPossopenscsuseNameMapper_origsWSscodeFor1stTokensclosesstartPoss nextTokensaddBitstokensendPos((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysgetCallArgStringqst       &           !         c Cs'|idjo|in |i}t} t}|i d}|i d|xno|i ot|dddn|i|joPn|i}|djp |ioPq^|djoPq^|d jo&|o| i|n|iq^|d jot}|iq^|d jo| it}|iq^|i|io| o|it|iq^|io| o| i|iq^|o|io|i}n||io|ina|i}|i!}|d dd fjo |i"|i#dt}n|i$||}| i|q^|djo| or|i%}|idjo||i%7}n|i ot|n||i7}| i|q^t|qeW|i d|| i'SdS(s, Get an argument list. Can be used for method/function definition argument lists or for #directive argument lists. Returns a list of tuples in the form (argName, defVal=None) with one tuple for each arg name. These defVals are always strings, so (argName, defVal=None) is safe even with a case like (arg1, arg2=None, arg3=1234*2), which would be returned as [('arg1', None), ('arg2', 'None'), ('arg3', '1234*2'), ] This method understands *arg, and **kw s(s useNameMapperismsgs%EOF was reached before a matching ')'s was found for the '('s)s:s s=s,s{s[sencloseds*N((sselfspeeksadvancesfindEOLsexitPossArgListsargListsFalsesonDefValssettingsuseNameMapper_origs setSettings useNameMappersatEnds ParseErrorsposscsmatchDirectiveEndTokens addToDefValsTruesnexts startswithscheetahVarStartTokenslensmatchIdentifiers addArgNames getIdentifiers%matchCheetahVarInExpressionStartTokens getCheetahVarstokensmatchCheetahVarStarts-_raiseErrorAboutInvalidCheetahVarSyntaxInExprsbeforeTokenPoss getPyTokensrevs getExpressionstransformTokensgetcsvarNamesmerge( sselfsexitPoss useNameMappersbeforeTokenPosscsonDefValstokensuseNameMapper_origsvarNamesargList((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys getDefArgListsr               cCs||tj o#|id} |id|n|tjo g}nt|} g}xno|i o_|oS|dd}t |}|i|ddt|dd|d|dqPn|i} | d jo4|i| |i| |if|iq\|o| oPq\| d jo| ot|nt| }|dd|jo|i|i| n|dd}t |}|i\}}|i|ddt|dd | d t|d t|d|d|d|iq\| djo|i|iq\|io| oPq\| djo|id| joati |i!|id}| o |it|ddn|i|i#q\| djo|o|iqNPq\|i$o|i%}|i|q\|i'o|i(q\|i} |i*} | o|o | |jo|i| Pn|i-| | } |i| t.i | o| djo,|i/dt0ddg}|i|qN|i|i|i o|idjo|i|i1qNq\qcW|tj o|id| n|SdS(s Get a Cheetah expression that includes $CheetahVars and break at directive end tokens, the end of an enclosure, or at a specified pyToken. s useNameMapperiiismsgs#EOF was reached before a matching 's' was found for the 's's{([s])}sA 's' was found at line s, col s before a matching 's' was found for the 's s\sLine ending expecteds sforspyTokensToBreakAtsins(N(2s useNameMappers UnspecifiedsselfssettingsuseNameMapper_origs setSettings enclosuressNoneslenssrcLensexprBitssatEndsopensclosurePairsRevsclosessetPoss ParseErrorspeekscsappendspossadvancesencloseds closurePairsspops getRowColsrowscolsstrs getWhiteSpacesmatchDirectiveEndTokensEOLresmatchssrcseolMatchsends%matchCheetahVarInExpressionStartTokens getCheetahVarsexprsmatchCheetahVarStarts-_raiseErrorAboutInvalidCheetahVarSyntaxInExprsbeforeTokenPoss getPyTokenstokenspyTokensToBreakAtstransformTokensidentREs getExpressionsFalsesgetCallArgString(sselfsencloseds enclosuresspyTokensToBreakAts useNameMappersclosesopensrowsexprBitsstokensuseNameMapper_origssrcLensbeforeTokenPosscseolMatchsexprscol((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysgetExpressionPartss       &       F $"          !  c Cs/di|id|d|d|d|SdS(spReturns the output of self.getExpressionParts() as a concatenated string rather than as a list. ssencloseds enclosuresspyTokensToBreakAts useNameMapperN(sjoinsselfsgetExpressionPartssencloseds enclosuresspyTokensToBreakAts useNameMapper(sselfsencloseds enclosuresspyTokensToBreakAts useNameMapper((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys getExpressionsc Cs|djo|i o|idjoi|i}|i}t|}|i }| odSn|i t p |i t o d}nd}|i||dg}d}x|i ||jow|ip |ioI|o|it|d}n|i} |id| dq||i7}qW|i||o|it|nd d i|d }n|SdS( sTakes a token from the expression being parsed and performs and special transformations required by Cheetah. At the moment only Cheetah's c'$placeholder strings' are transformed. scs'"Niissstr(s)s ''.join([s,s])(stokensselfsatEndspeeks getPyTokens nextTokensuppersevalstheStrspossendPoss startswithssingle3sdouble3s startPosIdxssetPossbeforeTokenPoss outputExprssstrConstsmatchCheetahVarStartsmatchExpressionPlaceholderStartsappendsreprsgetPlaceholdersplaceholderExprsgetcsjoin( sselfstokensbeforeTokenPosstheStrsstrConsts outputExprssendPoss startPosIdxs nextTokensplaceholderExpr((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pystransformTokens8.         cCsz|i}|i}|idot|ddn9|idot|ddnt|dddS(Ns cacheTokensmsgsXCache tokens are not valid inside expressions. Use them in top-level $placeholders only.s enclosuresxLong-form placeholders - ${}, $(), $[], etc. are not valid inside expressions. Use them in top-level $placeholders only.s3This form of $placeholder syntax is not valid here.(sselfsmatchCheetahVarStartsmatchs groupdictsgets ParseError(sselfs groupdictsmatch((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys-_raiseErrorAboutInvalidCheetahVarSyntaxInExprs  cCsx$|idD]}|d|qW|i}|i|}|i} |i }|o t } nt } |o(|i}|ii|i}nh}|idjo5|i}|i}||fg} |ing} t}|io |i} |ii | d|}t}| o|i}||7}|ido|idjo|i%d| dd !}q|it&|jo|iq|i'd t d| }|d t&|jo|d }n||7}n|||i!} nO|i'd t d| }|d t&|jo|d }n|||i!} |i)|d d | d |}x$|idD]}|d|qW|o|| |||| fSn|SdS(NspreparsePlaceholderHookssparsers({[splainsallowPlaceholderFilterArgss,s enclosuresiisencloseds placeholdersrawExprsstartPosspostparsePlaceholderHooks(+sselfssettingscallbackspossstartPoss getRowColslineColsgetCheetahVarStartTokens startTokensgetSilentPlaceholderTokenssilentPlaceholderTokensTruesisSilentPlaceholdersFalsesallowCacheTokenss getCacheTokens cacheTokens cacheTokenREsmatchs groupdictscacheTokenPartsspeeksgetcsenclosureOpenChars enclosuress getWhiteSpacesNones filterArgssmatchIdentifiersgetCheetahVarNameChunkss nameChunkss _compilers genCheetahVarsplainsexprs restOfExprsWSsgetCallArgStringsclosurePairsRevs getExpressionsrawPlaceholders_applyExpressionFilterssreturnEverything(sselfsallowCacheTokenssplainsreturnEverythingslineColsposs cacheTokensWSsstartPoss startTokensisSilentPlaceholdersrawPlaceholders enclosuress nameChunksssilentPlaceholderTokenscacheTokenPartssenclosureOpenChars filterArgssexprs restOfExprscallback((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysgetPlaceholdersb           # (Ds__name__s __module__s__doc__sNones_settingsManagerssetSettingsManagers Unspecifiedssettings setSettingssettingssupdateSettingss_initializeSettingssconfigureParsers_makeCheetahVarREss_makeCommentREss_makeDirectiveREss _makePspREssisLineClearToStartTokensmatchTopLevelTokens matchPyTokens getPyTokensmatchEOLSlurpTokensgetEOLSlurpTokensmatchCommentStartTokensgetCommentStartTokensmatchMultiLineCommentStartTokensgetMultiLineCommentStartTokensmatchMultiLineCommentEndTokensgetMultiLineCommentEndTokens getDottedNamesmatchIdentifiers getIdentifiers matchOperators getOperatorsmatchAssignmentOperatorsgetAssignmentOperatorsmatchDirectives identcharssmatchDirectiveNamesmatchDirectiveStartTokensgetDirectiveStartTokensmatchDirectiveEndTokensgetDirectiveEndTokens)matchColonForSingleLineShortFormDirectivesmatchPSPStartTokensmatchPSPEndTokensgetPSPStartTokensgetPSPEndTokensmatchCheetahVarStartsmatchCheetahVarStartTokens%matchCheetahVarInExpressionStartTokensmatchVariablePlaceholderStartsmatchExpressionPlaceholderStartsgetCheetahVarStartTokens getCacheTokensgetSilentPlaceholderTokensgetTargetVarsListsFalses getCheetahVarsgetCheetahVarBodysgetCheetahVarNameChunkssgetCallArgStrings getDefArgListsgetExpressionPartss getExpressionstransformTokens-_raiseErrorAboutInvalidCheetahVarSyntaxInExprsgetPlaceholder(((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys_LowLevelParsergs|         E                                       ;SWj ' s_HighLevelParsercBs9tZdZeeedZdZdZdZdZeedZ dZ ee dZ d Z d Zd Zd Zd ZdiZdiZhdd<ddRS(;sThis class is a StateMachine for parsing Cheetah source and sending state dependent code generation commands to Cheetah.Compiler.Compiler. cCsJti||d|d||i|||_|i |i dS(Nsfilenames breakPoint( s_LowLevelParsers__init__sselfssrcsfilenames breakPointssetSettingsManagerscompilers _compilers setupStatesconfigureParser(sselfssrcsfilenames breakPointscompiler((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys__init__s    cCsh|_h|_g|_dS(N(sselfs_macross _macroDetailss_openDirectivesStack(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys setupStates  cCsQ|iix0|iiD]\}}|ii|`qW|iidS(s8Cleanup to remove any possible reference cycles N( sselfs_macrossclears _macroDetailssitemss macronames macroDetailsstemplatesshutdown(sselfs macronames macroDetails((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pyscleanup!s    cCsti||idS(N(s_LowLevelParsersconfigureParsersselfs_initDirectives(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysconfigureParser*s csd} | } ti}idh}|i|t i}idh}|i|h_xG|i D]9\}|tdfjoqn| |i|idD]-}|d|d|d|d|d|}qW|SdS(s=Pipes cheetah expressions through a set of optional filter hooks. The filters are functions which may modify the expressions or raise a ForbiddenExpression exception if the expression is not allowed. They are defined in the compiler setting 'expressionFilterHooks'. Some intended use cases: - to implement 'restricted execution' safeguards in cases where you can't trust the author of the template. - to enforce style guidelines filter call signature: (parser, expr, exprType, rawExpr=None, startPos=None) - parser is the Cheetah parser - expr is the expression to filter. In some cases the parser will have already modified it from the original source code form. For example, placeholders will have been translated into namemapper calls. If you need to work with the original source, see rawExpr. - exprType is the name of the directive, 'psp', or 'placeholder'. All lowercase. @@TR: These will eventually be replaced with a set of constants. - rawExpr is the original source string that Cheetah parsed. This might be None in some cases. - startPos is the character position in the source string/file where the parser started parsing the current expression. @@TR: I realize this use of the term 'expression' is a bit wonky as many of the 'expressions' are actually statements, but I haven't thought of a better name yet. Suggestions? sexpressionFilterHookssparsersexprsexprTypesrawExprsstartPosN(sselfssettingscallbacksexprsexprTypesrawExprsstartPos(sselfsexprsexprTypesrawExprsstartPosscallback((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys_applyExpressionFiltersls cCs|i}||idjp#|ido||idjoGx*|idD]}|d|d|qXWt|dd|ndS(NsdisabledDirectivessenabledDirectivessdisabledDirectiveHookssparsers directiveNamesmsgsThis %r directive is disabled(s directiveNameslowersselfssettingscallbacksForbiddenDirective(sselfs directiveNamescallback((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys_filterDisabledDirectivess  <cCs8|o#|i}|i|t}nx|i o|io|iq-|i o|i q-|i o|i q-|i o|i q-|io|iq-|io|iq-|io|iq-|iq-W|o|in|o|i|ndS(N(s breakPointsselfsorigBPs setBreakPointsFalsesassertEmptyStacksatEndsmatchCommentStartTokens eatCommentsmatchMultiLineCommentStartTokenseatMultiLineCommentsmatchVariablePlaceholderStartseatPlaceholdersmatchExpressionPlaceholderStartsmatchDirectives eatDirectivesmatchPSPStartTokenseatPSPsmatchEOLSlurpTokenseatEOLSlurpTokens eatPlainTextsassertEmptyOpenDirectivesStack(sselfs breakPointsassertEmptyStacksorigBP((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pysparses2          cCs}|i}t}x5|i o&|i}|oPq|iqW|i|id|}|i i ||SdS(Nsstart( sselfspossstartPossNonesmatchsatEndsmatchTopLevelTokensadvancesreadTosstrConsts _compilers addStrConst(sselfsstrConstsstartPossmatch((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys eatPlainTexts  cCsT|i}|o|iin|i|id|}|ii|dS(Nsgobble(sselfsisLineClearToStartTokens _compilershandleWSBeforeDirectivesgetCommentStartTokens readToEOLscomms addComment(sselfscommsisLineClearToStartToken((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys eatComments   cCs|i}|i}|i|i}}d}xno|i}|i oPn|i o|i|d7}n&|i o|i |d8}n| oPn|i qBW|i|d|}|i o|i n|i o |idow||i|i!}|i o|id|n|o|i p|i|jo|iiqn|ii|dS(Nisstarts'gobbleWhitespaceAroundMultiLineCommentssgobble(sselfsisLineClearToStartTokensfindEOLsendOfFirstLinesgetMultiLineCommentStartTokenspossendPossstartPosslevelsatEndsmatchMultiLineCommentStartTokensmatchMultiLineCommentEndTokensgetMultiLineCommentEndTokensadvancesreadToscommssettings restOfLinesstrips readToEOLs _compilershandleWSBeforeDirectives addComment(sselfsisLineClearToStartTokenslevelscommsendPossstartPossendOfFirstLines restOfLine((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pyseatMultiLineComments:         'c Cs`|idtdt\}}}}}}|i i |d|d|d|d|d|dSdS(NsallowCacheTokenssreturnEverythings filterArgssrawPlaceholderscacheTokenPartsslineCols silentMode( sselfsgetPlaceholdersTruesexprsrawPlaceholderslineColscacheTokenPartss filterArgssisSilentPlaceholders _compilersaddPlaceholder(sselfslineColsexprscacheTokenPartssisSilentPlaceholders filterArgssrawPlaceholder((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pyseatPlaceholders*  cCs|idd|i|id}|i}xJ|i o;|i|djo|i oPqsn|i q8W|i |id|i }|i|dd|}|ii||idS(Ns directiveNamespsps PSPEndTokenisstartsstartPos(sselfs_filterDisabledDirectivessgetPSPStartTokenssettingsendTokenspossstartPossatEndspeeksmatchPSPEndTokensadvancesreadTosstrips pspStrings_applyExpressionFilterss _compilersaddPSPsgetPSPEndToken(sselfs pspStringsstartPossendToken((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pyseatPSPs    !s9 else elif for while repeat unless try except finallysc pass continue stop return yield break del assert raise silent echo import fromsimportsaddImportStatementsfromcCs|i}|i|x*|idD]}|d|d|q)W|ii|}|o |n||i joW|i i|}| od|i }nt |i|}|i|d|n||ijo|i i|}| od|i }nt |i|}|ddfjo t}nt}|i|d|}||nx*|id D]}|d|d|qwWdS( NspreparseDirectiveHookssparsers directiveNamesaddscallbackssilentsechosincludeDirectiveNameInExprspostparseDirectiveHooks(sselfsmatchDirectives directiveNames_filterDisabledDirectivesssettingscallbacks_directiveNamesAndParserssgetsdirectiveParsers_simpleIndentingDirectivess_directiveHandlerNamess handlerNames capitalizesgetattrs _compilershandlerseatSimpleIndentingDirectives_simpleExprDirectivessFalsesincludeDirectiveNameInExprsTrueseatSimpleExprDirectivesexpr(sselfsincludeDirectiveNameInExprsexprscallbackshandlers handlerNames directiveNamesdirectiveParser((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys eatDirectives8      cCst}|ioV|i}|i|i o!|i|t}|i qi|i|n| o |i o|i n=|o|i o|idjo|idtn|o|i p|i|jo|iindS(Ns sgobble(sFalses foundCommentsselfsmatchCommentStartTokenspossadvancesmatchDirectivessetPossTrues eatCommentsmatchDirectiveEndTokensgetDirectiveEndTokensisLineClearToStartTokensatEndspeeks readToEOLsendOfFirstLinePoss _compilershandleWSBeforeDirective(sselfsisLineClearToStartTokensendOfFirstLinePossposs foundComment((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys_eatRestOfDirectiveTag>s    ('c Cs|i}}}|idd}t}x|i o|i |jo|i djo|i}|i |i td|i|i|oW|i|ot}|i|}n|i t||i|i}Pqqn|i |i}}q0W|i|d|}|i||i}|io|in=|o|i o|i djo|idtn|o|i|jo|iin|SdS(NsdirectiveStartTokenisendsstarts sgobble(sselfspossfinalPoss endRawPossstartPosssettings directiveCharsFalsesisLineClearToStartTokensatEndspeeksmatchDirectivesgetDirectiveStartTokensadvanceslens getWhiteSpaces startswiths directiveNamesTruesfindBOLsreadTos textEatenssetPossfindEOLsendOfFirstLinePossmatchDirectiveEndTokensgetDirectiveEndTokens readToEOLs _compilershandleWSBeforeDirective( sselfs directiveNamesisLineClearToStartTokens endRawPossendOfFirstLinePossfinalPossstartPoss directiveChars textEaten((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys_eatToThisEndDirectiveSs>          (cCs|i}|i}|i| o|it|n|i }|i i }|id}|i||d|}||ijo|i|n|i|||SdS(NisstartPos(sselfsisLineClearToStartTokensfindEOLsendOfFirstLinesgetDirectiveStartTokensincludeDirectiveNameInExprsadvanceslens directiveNamespossstartPoss getExpressionsstripsexprssplits_applyExpressionFilterss_closeableDirectivesspushToOpenDirectivesStacks_eatRestOfDirectiveTag(sselfs directiveNamesincludeDirectiveNameInExprsisLineClearToStartTokensexprsstartPossendOfFirstLine((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pyseatSimpleExprDirectivexs    c Cs|i}|i}|i}|i|dijo|i t |n|i }|i |iddg}|i||d|}|io|i |dijo||dtd|n||d||i dd |id |id t|ii|iinm|idjo|i n|i |i||||ijo|i|n||d|dS( Ns&else elif for while try except finallyspyTokensToBreakAts:sstartPosselse elif except finallysdedentslineColsmaxis breakPointsgobble(sselfsisLineClearToStartTokensfindEOLsendOfFirstLinePoss getRowColslineColsgetDirectiveStartTokens directiveNamessplitsadvanceslenspossstartPoss getWhiteSpaces getExpressionsexprs_applyExpressionFilterss)matchColonForSingleLineShortFormDirectivescallbacksFalsesparsesTrues _compilerscommitStrConstsdedentspeeks_eatRestOfDirectiveTags_closeableDirectivesspushToOpenDirectivesStack( sselfs directiveNamescallbacksincludeDirectiveNameInExprsisLineClearToStartTokenslineColsexprsendOfFirstLinePossstartPos((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pyseatSimpleIndentingDirectives4          cCsK|i}|i|id|i|i}t}x;|ii D]*}|i |||jo |}PqOqOW| ot |ddn|i }|i|i||||ijo|i|n|ii|o|i|}|n;|dijo|djo|iiqG|djo|iiqG|djo|iiqG|djo|iiqG|d jo|iiqG|d jo|iiqGnp|d ijo|ii|iin?|d jo1|ii|ii|id |i ndS(NismsgsInvalid end directives,block capture cache call filter errorCatchersblockscapturescachescallsfilters errorCatcherswhile for if try repeat unlesssclosures useSearchList(!sselfsisLineClearToStartTokensgetDirectiveStartTokensadvances getWhiteSpacespossFalses directiveNames_endDirectiveNamesAndHandlersskeysskeysfinds ParseErrorsfindEOLsendOfFirstLinePoss getExpressions_eatRestOfDirectiveTags_closeableDirectivesspopFromOpenDirectivesStacksgetshandlerssplits _compilers closeBlocksendCaptureRegionsendCacheRegions endCallRegionscloseFilterBlocksturnErrorCatcherOffscommitStrConstsdedents setSettings_useSearchList_orig(sselfsisLineClearToStartTokenshandlerspossendOfFirstLinePosskeys directiveName((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pyseatEndDirectivesR                    cCs|i|idS(sTells the parser to stop parsing at this point and completely ignore everything else. This is a debugging tool. N(sselfs setBreakPointspos(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys eatBreakPointscCsq|i|itd|i|i}|i}|i |dd|}|i i |i dS(NsshBangsshbangsstartPos( sselfsgetDirectiveStartTokensadvanceslens getWhiteSpacespossstartPoss readToEOLsshBangs_applyExpressionFilterss _compilers setShBangsstrip(sselfsshBangsstartPos((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys eatShbangs    cCsq|i|itd|i|i}|i}|i |dd|}|i i |i dS(NsencodingsstartPos( sselfsgetDirectiveStartTokensadvanceslens getWhiteSpacespossstartPoss readToEOLsencodings_applyExpressionFilterss _compilerssetModuleEncodingsstrip(sselfsstartPossencoding((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys eatEncodings    c Cs|i}|i}|i}|i|itd|i |i}|i }|i djo6|i |i|||i|idSn|i |idjo|in t||i }|i}|id||fdd||i||y|ii||Wn^ti}|dIJ|ddIJ||||!IJ|ddIJ|d IJ|d IJnXdS( Nscompilersresets=s%s=%rsstartPossEAn error occurred while processing the following #compiler directive.s-iPs*Please check the syntax of these settings.s*A full Python exception traceback follows.(sselfsisLineClearToStartTokensfindEOLsendOfFirstLinespossstartPossgetDirectiveStartTokensadvanceslens getWhiteSpaces getIdentifiers settingNameslowers getExpressions_eatRestOfDirectiveTags_initializeSettingssconfigureParserspeeks ParseErrors valueExprsendPoss_applyExpressionFilterss _compilerssetCompilerSettingssyssstderrsout(sselfsisLineClearToStartTokensendPoss settingNamesstartPossoutsendOfFirstLines valueExpr((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys eatCompilersD                   c Cs;|i}|i}|i|itd|i}|i |i ||d|jo|i i |i dSn|i}|id}|i|dd|}y|i id|d|Wn]ti}|dIJ|dd IJ||iIJ|dd IJ|d IJ|d IJnXdS( Nscompiler-settingssresetscompilerSettingssstartPosskeywordss settingsStrsCAn error occurred while processing the following compiler settings.s-iPs*Please check the syntax of these settings.s*A full Python exception traceback follows.(sselfsisLineClearToStartTokensfindEOLsendOfFirstLinesgetDirectiveStartTokensadvanceslensgetTargetVarsListskeywordss getExpressions_eatRestOfDirectiveTags _compilers_initializeSettingssconfigureParserspossstartPoss_eatToThisEndDirectives settingsStrs_applyExpressionFiltersssetCompilerSettingsssyssstderrsoutsstrip(sselfsisLineClearToStartTokens settingsStrskeywordssstartPossendOfFirstLinesout((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pyseatCompilerSettings's4               cCs|i}|i}|i}|i|itd|i |i}|i o|i n|i }|i |i|i}|i|dd|}|ii|||i||dS(NsattrsstartPos(sselfsisLineClearToStartTokensfindEOLsendOfFirstLinePosspossstartPossgetDirectiveStartTokensadvanceslens getWhiteSpacesmatchCheetahVarStartsgetCheetahVarStartTokens getIdentifiers attribNamesgetAssignmentOperators getExpressionsexprs_applyExpressionFilterss _compilers addAttributes_eatRestOfDirectiveTag(sselfsisLineClearToStartTokensexprs attribNamesendOfFirstLinePossstartPos((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pyseatAttrJs            cCs|i}|i}|i}|i|i}|i}|i |dd|}|i i ||i |||i |i}| p|dddfjot|ddn|idS(Ns decoratorsstartPossdefsblocksclosuresmsgs!Expected #def, #block or #closure(sselfsisLineClearToStartTokensfindEOLsendOfFirstLinePosspossstartPossgetDirectiveStartTokens getExpressions decoratorExprs_applyExpressionFilterss _compilers addDecorators_eatRestOfDirectiveTags getWhiteSpacesmatchDirectives directiveNames ParseErrors eatDirective(sselfsisLineClearToStartTokens decoratorExprsendOfFirstLinePoss directiveNamesstartPos((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys eatDecorator]s        cCs|iddS(Nsdef(sselfs_eatDefOrBlock(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pyseatDefoscCsP|i}|id\}}hd|<d|i|<|ii|                    cCs?|io|iin|ii|idtdS(Nsgobble(sselfsisLineClearToStartTokens _compilershandleWSBeforeDirectivescommitStrConsts readToEOLsTrue(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pyseatSlurpVs  cCs?|io|iin|ii|idtdS(Nsgobble(sselfsisLineClearToStartTokens _compilershandleWSBeforeDirectivescommitStrConsts readToEOLsTrue(sself((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pyseatEOLSlurpToken\s  cCs|i}|i}|i|itd|i|io0|i|idd|i dt }nK|i djo|in|i|i |||id}|ii|dS(Nsrawsmaxisgobbles:(sselfsisLineClearToStartTokensfindEOLsendOfFirstLinePossgetDirectiveStartTokensadvanceslens getWhiteSpaces)matchColonForSingleLineShortFormDirectives readToEOLsFalsesrawBlockspeeks_eatRestOfDirectiveTags_eatToThisEndDirectives _compilers addRawText(sselfsisLineClearToStartTokensendOfFirstLinePossrawBlock((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pyseatRawbs       cCs;|i}|i}|i|itd|id}t }|i do|idt }n|i|i doU|itdd}|i|i dj ot|n|in|i}|i}|i|dd|}|i|||ii|||dS( Nsincludesfilesrawissourcesstrs=sstartPos(sselfsisLineClearToStartTokensfindEOLsendOfFirstLinePossgetDirectiveStartTokensadvanceslens getWhiteSpaces includeFromsFalsesisRaws startswithsTruespeeks ParseErrorspossstartPoss getExpressions sourceExprs_applyExpressionFilterss_eatRestOfDirectiveTags _compilers addInclude(sselfsisLineClearToStartTokensisRaws sourceExprsendOfFirstLinePossstartPoss includeFrom((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys eatIncludets.          c Cs|i} |i}|i|itd|i|io|i n|i }|i|i djoG|i dt}|i|o|dddjo |d=qng}|ii| pt|iddtf|iddf|id df|id df|id df|id df|id df|iddf|io@|i|idd|idt} |idtnK|i djo|in|i|i| ||id} diddigi} |D].\}}| |od||fp|q:~ d| dg} dk!l"}|i#dd|}|i#ddh}|i#ddg}t'|}|ihd |i(<d|<d |i)<|i*|ddd d!|i+d"| d |} d#fd$Y}|}| |_||_| d%||_/||i0|<|i/i1|i(|<|i2|i|%   #     #  %  # 1  / #     @      %     P X  $    /  (]s__doc__s __author__s __revision__sosssyssresDOTALLs MULTILINEstypess StringTypesListTypes TupleTypes ClassTypesTypeTypestimestokenizes pseudoprogsinspectsnews tracebacksCheetah.SourceReaders SourceReadersCheetahsFilterss ErrorCatcherssCheetah.Unspecifieds Unspecifieds _regexCaches cachedRegexscompilesescapeRegexCharssgroupsnongroups namedGroupsanysmaybesNO_CACHEs STATIC_CACHEs REFRESH_CACHEs SET_LOCALs SET_GLOBALs SET_MODULEs identcharss namecharsspowerOps unaryArithOpssbinaryArithOpssshiftOpss bitwiseOpssassignOps augAssignOpss assignmentOpsscompOpss booleanOpss operatorss delimetersskeywordsssingle3sdouble3stripleQuotedStringStartsstripleQuotedStringPairss closurePairssclosurePairsRevstripleQuotedStringREssmakeTripleQuoteResitemssstartsendsWSsEOLsEOLZsescCharLookBehindsnameCharLookAheadsidentREsEOLres specialVarREsunicodeDirectiveREsencodingDirectiveREsescapedNewlineREsNonesdirectiveNamesAndParserssendDirectiveNamesAndHandlerss ValueErrors ParseErrorsForbiddenSyntaxsForbiddenExpressionsForbiddenDirectivesCheetahVariables PlaceholdersArgLists_LowLevelParsers_HighLevelParsersParser(SsassignOpsParsers unaryArithOpss closurePairssTypeTypes SET_LOCALsescCharLookBehinds booleanOpss SourceReadersbinaryArithOpssListTypessingle3sEOLsmakeTripleQuoteResescapeRegexCharssForbiddenSyntaxs assignmentOpss specialVarREsanys REFRESH_CACHEsDOTALLs StringTypes __revision__sgroupspowerOpsendDirectiveNamesAndHandlerssstartsForbiddenDirectivestripleQuotedStringREssescapedNewlineREs ErrorCatcherss bitwiseOpssArgListsresForbiddenExpressionskeywordss _regexCaches_HighLevelParsers SET_GLOBALsnews cachedRegexsshiftOpssdouble3sunicodeDirectiveREsencodingDirectiveREs_LowLevelParsersnongroupscompOpss operatorssinspects SET_MODULEs __author__ssyssidentREs MULTILINEs UnspecifiedsNO_CACHEs STATIC_CACHEs pseudoprogsendsnameCharLookAheads TupleTypes augAssignOpss identcharsstripleQuotedStringStartssEOLresmaybes delimeterss namecharss ClassTypes tracebacksdirectiveNamesAndParserss namedGroupstripleQuotedStringPairssclosurePairsRevs PlaceholdersFiltersstimesWSsEOLZs ParseErrorsossCheetahVariable((s3build/bdist.darwin-8.0.1-i386/egg/Cheetah/Parser.pys?s    %                 ' !%.Z< !!   G> PKݡ(8,j'Cheetah/convertTmplPathToModuleName.pyc; Cc@sdkZdkZdgdZx(eieiD]Zeeee and Mike Orr > Version: $Revision: 1.26 $ Start Date: 2001/03/30 Last Revision Date: $Date: 2007/10/02 01:22:04 $ """ __author__ = "Tavis Rudd and Mike Orr " __revision__ = "$Revision: 1.26 $"[11:-2] import getopt, glob, os, pprint, re, shutil, sys import cPickle as pickle 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]*$" ) def fprintfMessage(stream, format, *args): if format[-1:] == '^': format = format[:-1] else: format += '\n' if args: message = format % args else: message = format stream.write(message) class Error(Exception): pass class Bundle: """Wrap the source, destination and backup paths in one neat little class. Used by CheetahWrapper.getBundles(). """ def __init__(self, **kw): self.__dict__.update(kw) def __repr__(self): return "" % 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 def usage(usageMessage, errorMessage="", out=sys.stderr): """Write help text, an optional error message, and abort the program. """ out.write(WRAPPER_TOP) out.write(usageMessage) exitStatus = 0 if errorMessage: out.write('\n') out.write("*** USAGE ERROR ***: %s\n" % errorMessage) exitStatus = 1 sys.exit(exitStatus) WRAPPER_TOP = """\ __ ____________ __ \ \/ \/ / \/ * * \/ CHEETAH %(Version)s Command-Line Tool \ | / \ ==----== / by Tavis Rudd \__________/ and Mike Orr """ % globals() HELP_PAGE1 = """\ USAGE: ------ cheetah compile [options] [FILES ...] : Compile template definitions cheetah fill [options] [FILES ...] : Fill template definitions cheetah help : Print this help message cheetah options : Print options help message cheetah test [options] : Run Cheetah's regression tests : (same as for unittest) cheetah version : Print Cheetah version number You may abbreviate the command to the first letter; e.g., 'h' == 'help'. If FILES is a single "-", read standard input and write standard output. 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 Run "cheetah help" for the main help screen. """ ################################################## ## CheetahWrapper CLASS class CheetahWrapper: MAKE_BACKUPS = True BACKUP_SUFFIX = ".bak" _templateClass = None _compilerSettings = None def __init__(self): self.progName = None self.command = None self.opts = None self.pathArgs = None self.sourceFiles = [] self.searchList = [] ################################################## ## MAIN ROUTINE def main(self, argv=None): """The main program controller.""" if argv is None: argv = sys.argv # Step 1: Determine the command and arguments. try: self.progName = progName = os.path.basename(argv[0]) self.command = command = optionDashesRE.sub("", argv[1]) if command == 'test': self.testOpts = argv[2:] else: self.parseOpts(argv[2:]) except IndexError: usage(HELP_PAGE1, "not enough command-line arguments") # Step 2: Call the command meths = (self.compile, self.fill, self.help, self.options, self.test, self.version) for meth in meths: methName = meth.__name__ # Or meth.im_func.func_name # Or meth.func_name (Python >= 2.1 only, sometimes works on 2.0) methInitial = methName[0] if command in (methName, methInitial): sys.argv[0] += (" " + methName) # @@MO: I don't necessarily agree sys.argv[0] should be # modified. meth() return # If none of the commands matched. usage(HELP_PAGE1, "unknown command '%s'" % command) 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) self.opts, self.pathArgs = opts, files = parser.parse_args(args) D("""\ cheetah compile %s Options are %s Files are %s""", args, pprint.pformat(vars(opts)), files) #cleanup trailing path separators seps = [sep for sep in [os.sep, os.altsep] if sep] for attr in ['idir', 'odir']: for sep in seps: path = getattr(opts, attr, None) if path and path.endswith(sep): path = path[:-len(sep)] setattr(opts, attr, path) break self._fixExts() if opts.env: self.searchList.insert(0, os.environ) if opts.pickle: f = open(opts.pickle, 'rb') unpickled = pickle.load(f) f.close() self.searchList.insert(0, unpickled) opts.verbose = not opts.stdout ################################################## ## COMMAND METHODS def compile(self): self._compileOrFill() def fill(self): from Cheetah.ImportHooks import install install() self._compileOrFill() def help(self): usage(HELP_PAGE1, "", sys.stdout) def options(self): usage(HELP_PAGE2, "", sys.stdout) def test(self): # @@MO: Ugly kludge. TEST_WRITE_FILENAME = 'cheetah_test_file_creation_ability.tmp' try: f = open(TEST_WRITE_FILENAME, 'w') except: sys.exit("""\ Cannot run the tests because you don't have write permission in the current directory. The tests need to create temporary files. Change to a directory you do have write permission to and re-run the tests.""") else: f.close() os.remove(TEST_WRITE_FILENAME) # @@MO: End ugly kludge. from Cheetah.Tests import Test import Cheetah.Tests.unittest_local_copy as unittest del sys.argv[1:] # Prevent unittest from misinterpreting options. sys.argv.extend(self.testOpts) #unittest.main(testSuite=Test.testSuite) #unittest.main(testSuite=Test.testSuite) unittest.main(module=Test) def version(self): print Version # If you add a command, also add it to the 'meths' variable in main(). ################################################## ## LOGGING METHODS def chatter(self, format, *args): """Print a verbose message to stdout. But don't if .opts.stdout is true or .opts.verbose is false. """ if self.opts.stdout or not self.opts.verbose: return fprintfMessage(sys.stdout, format, *args) def debug(self, format, *args): """Print a debugging message to stderr, but don't if .debug is false. """ if self.opts.debug: fprintfMessage(sys.stderr, format, *args) def warn(self, format, *args): """Always print a warning message to stderr. """ fprintfMessage(sys.stderr, format, *args) def error(self, format, *args): """Always print a warning message to stderr and exit with an error code. """ fprintfMessage(sys.stderr, format, *args) sys.exit(1) ################################################## ## HELPER METHODS def _fixExts(self): assert self.opts.oext, "oext is empty!" iext, oext = self.opts.iext, self.opts.oext if iext and not iext.startswith("."): self.opts.iext = "." + iext if oext and not oext.startswith("."): self.opts.oext = "." + oext def _compileOrFill(self): C, D, W = self.chatter, self.debug, self.warn opts, files = self.opts, self.pathArgs if files == ["-"]: self._compileOrFillStdin() return elif not files and opts.recurse: which = opts.idir and "idir" or "current" C("Drilling down recursively from %s directory.", which) sourceFiles = [] dir = os.path.join(self.opts.idir, os.curdir) os.path.walk(dir, self._expandSourceFilesWalk, sourceFiles) elif not files: usage(HELP_PAGE1, "Neither files nor -R specified!") else: sourceFiles = self._expandSourceFiles(files, opts.recurse, True) sourceFiles = [os.path.normpath(x) for x in sourceFiles] D("All source files found: %s", sourceFiles) bundles = self._getBundles(sourceFiles) D("All bundles: %s", pprint.pformat(bundles)) if self.opts.flat: self._checkForCollisions(bundles) for b in bundles: self._compileOrFillBundle(b) def _checkForCollisions(self, bundles): """Check for multiple source paths writing to the same destination path. """ C, D, W = self.chatter, self.debug, self.warn isError = False dstSources = {} for b in bundles: if dstSources.has_key(b.dst): dstSources[b.dst].append(b.src) else: dstSources[b.dst] = [b.src] keys = dstSources.keys() keys.sort() for dst in keys: sources = dstSources[dst] if len(sources) > 1: isError = True sources.sort() fmt = "Collision: multiple source files %s map to one destination file %s" W(fmt, sources, dst) if isError: what = self.isCompile and "Compilation" or "Filling" sys.exit("%s aborted due to collisions" % what) def _expandSourceFilesWalk(self, arg, dir, files): """Recursion extension for .expandSourceFiles(). This method is a callback for os.path.walk(). 'arg' is a list to which successful paths will be appended. """ iext = self.opts.iext for f in files: path = os.path.join(dir, f) if path.endswith(iext) and os.path.isfile(path): arg.append(path) elif os.path.islink(path) and os.path.isdir(path): os.path.walk(path, self._expandSourceFilesWalk, arg) # If is directory, do nothing; 'walk' will eventually get it. def _expandSourceFiles(self, files, recurse, addIextIfMissing): """Calculate source paths from 'files' by applying the command-line options. """ C, D, W = self.chatter, self.debug, self.warn idir = self.opts.idir iext = self.opts.iext files = [] for f in self.pathArgs: oldFilesLen = len(files) D("Expanding %s", f) path = os.path.join(idir, f) pathWithExt = path + iext # May or may not be valid. if os.path.isdir(path): if recurse: os.path.walk(path, self._expandSourceFilesWalk, files) else: raise Error("source file '%s' is a directory" % path) elif os.path.isfile(path): files.append(path) elif (addIextIfMissing and not path.endswith(iext) and os.path.isfile(pathWithExt)): files.append(pathWithExt) # Do not recurse directories discovered by iext appending. elif os.path.exists(path): W("Skipping source file '%s', not a plain file.", path) else: W("Skipping source file '%s', not found.", path) if len(files) > oldFilesLen: D(" ... found %s", files[oldFilesLen:]) return files def _getBundles(self, sourceFiles): flat = self.opts.flat idir = self.opts.idir iext = self.opts.iext nobackup = self.opts.nobackup odir = self.opts.odir oext = self.opts.oext idirSlash = idir + os.sep bundles = [] for src in sourceFiles: # 'base' is the subdirectory plus basename. base = src if idir and src.startswith(idirSlash): base = src[len(idirSlash):] if iext and base.endswith(iext): base = base[:-len(iext)] basename = os.path.basename(base) if flat: dst = os.path.join(odir, basename + oext) else: dbn = basename if odir and base.startswith(os.sep): odd = odir while odd != '': idx = base.find(odd) if idx == 0: dbn = base[len(odd):] if dbn[0] == '/': dbn = dbn[1:] break odd = os.path.dirname(odd) if odd == '/': break dst = os.path.join(odir, dbn + oext) else: dst = os.path.join(odir, base + oext) bak = dst + self.BACKUP_SUFFIX b = Bundle(src=src, dst=dst, bak=bak, base=base, basename=basename) bundles.append(b) return bundles def _getTemplateClass(self): C, D, W = self.chatter, self.debug, self.warn modname = None if self._templateClass: return self._templateClass modname = self.opts.templateClassName if not modname: return Template p = modname.rfind('.') if ':' not in modname: self.error('The value of option --templateAPIClass is invalid\n' 'It must be in the form "module:class", ' 'e.g. "Cheetah.Template:Template"') modname, classname = modname.split(':') C('using --templateAPIClass=%s:%s'%(modname, classname)) if p >= 0: mod = getattr(__import__(modname[:p], {}, {}, [modname[p+1:]]), modname[p+1:]) else: mod = __import__(modname, {}, {}, []) klass = getattr(mod, classname, None) if klass: self._templateClass = klass return klass else: self.error('**Template class specified in option --templateAPIClass not found\n' '**Falling back on Cheetah.Template:Template') def _getCompilerSettings(self): if self._compilerSettings: return self._compilerSettings def getkws(**kws): return kws if self.opts.compilerSettingsString: try: exec 'settings = getkws(%s)'%self.opts.compilerSettingsString except: self.error("There's an error in your --settings option." "It must be valid Python syntax.\n" +" --settings='%s'\n"%self.opts.compilerSettingsString +" %s: %s"%sys.exc_info()[:2] ) validKeys = DEFAULT_COMPILER_SETTINGS.keys() if [k for k in settings.keys() if k not in validKeys]: self.error( 'The --setting "%s" is not a valid compiler setting name.'%k) self._compilerSettings = settings return settings else: return {} def _compileOrFillStdin(self): TemplateClass = self._getTemplateClass() compilerSettings = self._getCompilerSettings() if self.isCompile: pysrc = TemplateClass.compile(file=sys.stdin, compilerSettings=compilerSettings, returnAClass=False) output = pysrc else: output = str(TemplateClass(file=sys.stdin, compilerSettings=compilerSettings)) sys.stdout.write(output) def _compileOrFillBundle(self, b): C, D, W = self.chatter, self.debug, self.warn TemplateClass = self._getTemplateClass() compilerSettings = self._getCompilerSettings() src = b.src dst = b.dst base = b.base basename = b.basename dstDir = os.path.dirname(dst) what = self.isCompile and "Compiling" or "Filling" C("%s %s -> %s^", what, src, dst) # No trailing newline. if os.path.exists(dst) and not self.opts.nobackup: bak = b.bak C(" (backup %s)", bak) # On same line as previous message. else: bak = None C("") if self.isCompile: if not moduleNameRE.match(basename): tup = basename, src raise Error("""\ %s: base name %s contains invalid characters. It must be named according to the same rules as Python modules.""" % tup) pysrc = TemplateClass.compile(file=src, returnAClass=False, moduleName=basename, className=basename, compilerSettings=compilerSettings) output = pysrc else: #output = str(TemplateClass(file=src, searchList=self.searchList)) tclass = TemplateClass.compile(file=src, compilerSettings=compilerSettings) output = str(tclass(searchList=self.searchList)) if bak: shutil.copyfile(dst, bak) if dstDir and not os.path.exists(dstDir): if self.isCompile: mkdirsWithPyInitFiles(dstDir) else: os.makedirs(dstDir) if self.opts.stdout: sys.stdout.write(output) else: f = open(dst, 'w') f.write(output) f.close() ################################################## ## if run from the command line if __name__ == '__main__': CheetahWrapper().main() # vim: shiftwidth=4 tabstop=4 expandtab PK(8SCheetah/Unspecified.pyc;  Dc@sGydklZWn/ej o#dfdYZeZnXdS((s Unspecifieds _UnspecifiedcBstZdZdZRS(NcCsdSdS(Ns Unspecified((sself((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/Unspecified.pys__repr__scCsdSdS(Ns Unspecified((sself((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/Unspecified.pys__str__s(s__name__s __module__s__repr__s__str__(((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/Unspecified.pys _Unspecifieds N(sds.sys.Unspecifieds Unspecifieds ImportErrors _Unspecified(s _Unspecifieds Unspecified((s8build/bdist.darwin-8.0.1-i386/egg/Cheetah/Unspecified.pys?sPKݡ(8 OCheetah/CacheStore.pyc; Cc@s|dZdklZdklZdefdYZdefdYZ de fdYZ d e fd YZ d S( sProvides several CacheStore backends for Cheetah's caching framework. The methods provided by these classes have the same semantics as those in the python-memcached API, except for their return values: set(key, val, time=0) set the value unconditionally add(key, val, time=0) set only if the server doesn't already have this key replace(key, val, time=0) set only if the server already have this key get(key, val) returns val or raises a KeyError delete(key) deletes or raises a KeyError (stime(sClientsErrorcBstZRS(N(s__name__s __module__(((s7build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheStore.pysErrorssAbstractCacheStorecBs>tZedZedZedZdZdZRS(NcCs tdS(N(sNotImplementedError(sselfskeysvalstime((s7build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheStore.pyssetscCs tdS(N(sNotImplementedError(sselfskeysvalstime((s7build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheStore.pysaddscCs tdS(N(sNotImplementedError(sselfskeysvalstime((s7build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheStore.pysreplace scCs tdS(N(sNotImplementedError(sselfskey((s7build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheStore.pysdelete#scCs tdS(N(sNotImplementedError(sselfskey((s7build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheStore.pysget&s(s__name__s __module__sNonessetsaddsreplacesdeletesget(((s7build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheStore.pysAbstractCacheStores     sMemoryCacheStorecBsPtZdZddZddZddZdZdZdZRS( NcCs h|_dS(N(sselfs_data(sself((s7build/bdist.darwin-8.0.1-i386/egg/Cheetah/CacheStore.pys__init__*sicCs||f|i||ii|otd|n||f|i||ii|otd|n||f|i| Version: $Revision: 1.32 $ Start Date: 2001/08/01 Last Revision Date: $Date: 2007/03/29 19:31:15 $ s!Tavis Rudd s$Revision: 1.32 $i is s s"s"sErrorcBstZRS(N(s__name__s __module__(((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Filters.pysErrorssFiltercBs)tZdZedZeedZRS(s$A baseclass for the Cheetah Filters.cCs ||_dS(sSetup a reference to the template that is using the filter instance. This reference isn't used by any of the standard filters, but is available to Filter subclasses, should they need it. Subclasses should call this method. N(stemplatesself(sselfstemplate((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Filters.pys__init__scKs_t|to$|o|i|}qW|}n$|tjo d}n ||}|SdS(sRPass Unicode strings through unmolested, unless an encoding is specified. sN(s isinstancesvalsunicodesencodingsencodesfilteredsNonesstr(sselfsvalsencodingsstrskwsfiltered((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Filters.pysfilter%s    (s__name__s __module__s__doc__sNones__init__sstrsfilter(((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Filters.pysFilters  s EncodeUnicodecBstZdedZRS(Nsutf8cKsNt|to|i|}n$|tjo d}n ||}|SdS(s0Encode Unicode strings, by default in UTF-8. >>> import Cheetah.Template >>> t = Cheetah.Template.Template(''' ... $myvar ... ${myvar, encoding='utf16'} ... ''', searchList=[{'myvar': u'Asnires'}], ... filter='EncodeUnicode') >>> print t sN(s isinstancesvalsunicodesencodesencodingsfilteredsNonesstr(sselfsvalsencodingsstrskwsfiltered((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Filters.pysfilter=s    (s__name__s __module__sstrsfilter(((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Filters.pys EncodeUnicode<ssMaxLencBstZdZRS(NcKsZtt|i||}|idot||djo||d Sn|SdS(s+Replace None with '' and cut off at maxlen.smaxlenN( ssupersMaxLensselfsfiltersvalskwsoutputshas_keyslen(sselfsvalskwsoutput((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Filters.pysfilterTs '(s__name__s __module__sfilter(((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Filters.pysMaxLenSssWebSafecBstZdZdZRS(s+Escape HTML entities in $placeholders. cKstt|i||}|idd}|idd}|idd}|idoe|d}t }xR|D]F}|i|o||}ndt|}|i||}qxWn|SdS( Ns&s&ss>salsos&#%s;(ssupersWebSafesselfsfiltersvalskwsssreplaceshas_keysalsoswebSafeEntitiessentitiessksvsord(sselfsvalskwsentitiessvsalsosssk((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Filters.pysfilter_s (s__name__s __module__s__doc__sfilter(((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Filters.pysWebSafe\s sStripcBstZdZdZRS(sStrip leading/trailing whitespace but preserve newlines. This filter goes through the value line by line, removing leading and trailing whitespace on each line. It does not strip newlines, so every input line corresponds to one output line, with its trailing newline intact. We do not use val.split(' ') because that would squeeze out consecutive blank lines. Instead, we search for each newline individually. This makes us unable to use the fast C .split method, but it makes the filter much more widely useful. This filter is intended to be usable both with the #filter directive and with the proposed #sed directive (which has not been ratified yet.) cKstt|i||}g}d}xgno_|i d|}|djoPn|||!i }|i ||i d|d}q1W||i }|i |di|SdS(Niis is(ssupersStripsselfsfiltersvalskwsssresultsstartsfindsendsstripschunksappendsjoin(sselfsvalskwsendsstartsssresultschunk((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Filters.pysfilters    (s__name__s __module__s__doc__sfilter(((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Filters.pysStripss s StripSqueezecBstZdZdZRS(sCanonicalizes every chunk of whitespace to a single space. Strips leading/trailing whitespace. Removes all newlines, so multi-line input is joined into one ling line with NO trailing newline. cKs8tt|i||}|i}di|SdS(Ns ( ssupers StripSqueezesselfsfiltersvalskwssssplitsjoin(sselfsvalskwss((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Filters.pysfilters (s__name__s __module__s__doc__sfilter(((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Filters.pys StripSqueezes cCs}d}d}dG| GHdGti| GHHdG| GHdGti| GHdGti| GHdGtid  GHdS( Ns abc <=> &s asdf 1 2 3 sWebSafe INPUT:s WebSafe:s Strip INPUT:s Strip:s StripSqueeze:sUnicode:u aoeu12345ሴ(ss1ss2sWebSafesfiltersStrips StripSqueezes EncodeUnicode(ss2ss1((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Filters.pystests  s__main__N(s__doc__s __author__s __revision__swebSafeEntitiess ExceptionsErrorsobjectsFiltersRawOrEncodedUnicodes EncodeUnicodesMaxLensWebSafesStrips StripSqueezestests__name__( sStrips __revision__s EncodeUnicodeswebSafeEntitiessRawOrEncodedUnicodes __author__sFiltersMaxLens StripSqueezesWebSafesErrorstest((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Filters.pys? s    PKݡ(8**Cheetah/Servlet.pyc; Fc@sdZdZddd!ZdkZdkZeZyfydkl Z Wndk l Z nXe Ze e e o#de efdYZeZ nWnd efd YZ nXd e fd YZ dS( sProvides an abstract Servlet baseclass for Cheetah's Template class Meta-Data ================================================================================ Author: Tavis Rudd License: This software is released for unlimited distribution under the terms of the MIT license. See the LICENSE file. Version: $Revision: 1.41 $ Start Date: 2001/10/03 Last Revision Date: $Date: 2007/04/04 00:55:27 $ s!Tavis Rudd s$Revision: 1.41 $i iN(sServletsNewStyleBaseServletcBstZRS(N(s__name__s __module__(((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Servlet.pysNewStyleBaseServletss BaseServletcBs8tZdZdZdZdZdZdZRS(NiicCsdS(N((sself((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Servlet.pys__init__$scCsdS(N((sselfs transaction((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Servlet.pysawake'scCsdS(N((sselfs transaction((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Servlet.pyssleep*scCsdS(N((sself((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Servlet.pysshutdown-s(s__name__s __module__s _reusables _threadSafes__init__sawakessleepsshutdown(((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Servlet.pys BaseServlet s    sServletcBsttZdZeZeZeZeZdZdZ edZ dZ dZ ee iie iidZRS(sThis class is an abstract baseclass for Cheetah.Template.Template. It wraps WebKit.Servlet and provides a few extra convenience methods that are also found in WebKit.Page. It doesn't do any of the HTTP method resolution that is done in WebKit.HTTPServlet cCsti|t|_dS(N(s BaseServlets__init__sselfsFalses_CHEETAH__isControlledByWebKit(sself((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Servlet.pys__init__As cCslti||t|_||_|i|_}|i|_|i|_|i |_ |i |_ dS(N( s BaseServletsawakesselfs transactionsTrues_CHEETAH__isControlledByWebKitsresponsesrequests_requestssessionswrite(sselfs transactionsresponse((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Servlet.pysawakeIs    cCstddS(Nscouldn't find the template's main method. If you are using #extends without #implements, try adding '#implements respond' to your template definition.(sNotImplementedError(sselfstrans((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Servlet.pysrespond_scCsAti||t|_t|_t|_t|_t|_dS(N( s BaseServletssleepsselfs transactionsNonessessionsrequests_requestsresponse(sselfs transaction((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Servlet.pyssleepes     cCsdS(N((sself((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Servlet.pysshutdownmscCs~|ioti||Sn]|o |||iddSn6t|do|i o|||i Snt SdS(Ns\s/s _filePath( sselfs_CHEETAH__isControlledByWebKits BaseServletsserverSidePathspathsnormpathsabspathsreplaceshasattrs _filePathsNone(sselfspathsnormpathsabspath((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Servlet.pysserverSidePathps  (s__name__s __module__s__doc__sNones transactions applicationsrequestssessions__init__sawakesrespondssleepsshutdownsosspathsnormpathsabspathsserverSidePath(((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Servlet.pysServlet3s      (s__doc__s __author__s __revision__ssyssos.pathsossFalsesisWebwareInstalledsds.appserver.ServletsServlets BaseServletsWebKit.ServletsTrues issubclasssobjectsNewStyleBaseServlet(s BaseServlets __revision__sServlets __author__ssyssisWebwareInstalledsossNewStyleBaseServlet((s4build/bdist.darwin-8.0.1-i386/egg/Cheetah/Servlet.pys? s"   PK56J}%}%Cheetah/SourceReader.py#!/usr/bin/env python # $Id: SourceReader.py,v 1.15 2007/04/03 01:57:42 tavis_rudd Exp $ """SourceReader class for Cheetah's Parser and CodeGenerator Meta-Data ================================================================================ Author: Tavis Rudd License: This software is released for unlimited distribution under the terms of the MIT license. See the LICENSE file. Version: $Revision: 1.15 $ Start Date: 2001/09/19 Last Revision Date: $Date: 2007/04/03 01:57:42 $ """ __author__ = "Tavis Rudd " __revision__ = "$Revision: 1.15 $"[11:-2] import re import sys EOLre = re.compile(r'[ \f\t]*(?:\r\n|\r|\n)') EOLZre = re.compile(r'(?:\r\n|\r|\n|\Z)') ENCODINGsearch = re.compile("coding[=:]\s*([-\w.]+)").search class Error(Exception): pass class SourceReader: def __init__(self, src, filename=None, breakPoint=None, encoding=None): ## @@TR 2005-01-17: the following comes from a patch Terrel Shumway ## contributed to add unicode support to the reading of Cheetah source ## files with dynamically compiled templates. All the existing unit ## tests pass but, it needs more testing and some test cases of its ## own. My instinct is to move this up into the code that passes in the ## src string rather than leaving it here. As implemented here it ## forces all src strings to unicode, which IMO is not what we want. # if encoding is None: # # peek at the encoding in the first two lines # m = EOLZre.search(src) # pos = m.end() # if pos= self._BOLs[i] and pos <= self._EOLs[i]: return i def getRowCol(self, pos=None): if pos == None: pos = self._pos lineNum = self.lineNum(pos) BOL, EOL = self._BOLs[lineNum], self._EOLs[lineNum] return lineNum+1, pos-BOL+1 def getRowColLine(self, pos=None): if pos == None: pos = self._pos row, col = self.getRowCol(pos) return row, col, self.splitlines()[row-1] def getLine(self, pos): if pos == None: pos = self._pos lineNum = self.lineNum(pos) return self.splitlines()[lineNum] def pos(self): return self._pos def setPos(self, pos): self.checkPos(pos) self._pos = pos def validPos(self, pos): return pos <= self._breakPoint and pos >=0 def checkPos(self, pos): if not pos <= self._breakPoint: raise Error("pos (" + str(pos) + ") is invalid: beyond the stream's end (" + str(self._breakPoint-1) + ")" ) elif not pos >=0: raise Error("pos (" + str(pos) + ") is invalid: less than 0" ) def breakPoint(self): return self._breakPoint def setBreakPoint(self, pos): if pos > self._srcLen: raise Error("New breakpoint (" + str(pos) + ") is invalid: beyond the end of stream's source string (" + str(self._srcLen) + ")" ) elif not pos >= 0: raise Error("New breakpoint (" + str(pos) + ") is invalid: less than 0" ) self._breakPoint = pos def setBookmark(self, name): self._bookmarks[name] = self._pos self._posTobookmarkMap[self._pos] = name def hasBookmark(self, name): return self._bookmarks.has_key(name) def gotoBookmark(self, name): if not self.hasBookmark(name): raise Error("Invalid bookmark (" + name + ") is invalid: does not exist") pos = self._bookmarks[name] if not self.validPos(pos): raise Error("Invalid bookmark (" + name + ', '+ str(pos) + ") is invalid: pos is out of range" ) self._pos = pos def atEnd(self): return self._pos >= self._breakPoint def atStart(self): return self._pos == 0 def peek(self, offset=0): self.checkPos(self._pos+offset) pos = self._pos + offset return self._src[pos] def getc(self): pos = self._pos if self.validPos(pos+1): self._pos += 1 return self._src[pos] def ungetc(self, c=None): if not self.atStart(): raise Error('Already at beginning of stream') self._pos -= 1 if not c==None: self._src[self._pos] = c def advance(self, offset=1): self.checkPos(self._pos + offset) self._pos += offset def rev(self, offset=1): self.checkPos(self._pos - offset) self._pos -= offset def read(self, offset): self.checkPos(self._pos + offset) start = self._pos self._pos += offset return self._src[start:self._pos] def readTo(self, to, start=None): self.checkPos(to) if start == None: start = self._pos self._pos = to return self._src[start:to] def readToEOL(self, start=None, gobble=True): EOLmatch = EOLZre.search(self.src(), self.pos()) if gobble: pos = EOLmatch.end() else: pos = EOLmatch.start() return self.readTo(to=pos, start=start) def find(self, it, pos=None): if pos == None: pos = self._pos return self._src.find(it, pos ) def startswith(self, it, pos=None): if self.find(it, pos) == self.pos(): return True else: return False def rfind(self, it, pos): if pos == None: pos = self._pos return self._src.rfind(it, pos) def findBOL(self, pos=None): if pos == None: pos = self._pos src = self.src() return max(src.rfind('\n',0,pos)+1, src.rfind('\r',0,pos)+1, 0) def findEOL(self, pos=None, gobble=False): if pos == None: pos = self._pos match = EOLZre.search(self.src(), pos) if gobble: return match.end() else: return match.start() def isLineClearToPos(self, pos=None): if pos == None: pos = self.pos() self.checkPos(pos) src = self.src() BOL = self.findBOL() return BOL == pos or src[BOL:pos].isspace() def matches(self, strOrRE): if isinstance(strOrRE, (str, unicode)): return self.startswith(strOrRE, pos=self.pos()) else: # assume an re object return strOrRE.match(self.src(), self.pos()) def matchWhiteSpace(self, WSchars=' \f\t'): return (not self.atEnd()) and self.peek() in WSchars def getWhiteSpace(self, max=None, WSchars=' \f\t'): if not self.matchWhiteSpace(WSchars): return '' start = self.pos() breakPoint = self.breakPoint() if max is not None: breakPoint = min(breakPoint, self.pos()+max) while self.pos() < breakPoint: self.advance() if not self.matchWhiteSpace(WSchars): break return self.src()[start:self.pos()] def matchNonWhiteSpace(self, WSchars=' \f\t\n\r'): return self.atEnd() or not self.peek() in WSchars def getNonWhiteSpace(self, WSchars=' \f\t\n\r'): if not self.matchNonWhiteSpace(WSchars): return '' start = self.pos() while self.pos() < self.breakPoint(): self.advance() if not self.matchNonWhiteSpace(WSchars): break return self.src()[start:self.pos()] PK 6 ɁFFCheetah/ImportManager.py#!/usr/bin/env python # $Id: ImportManager.py,v 1.6 2007/04/03 01:56:24 tavis_rudd Exp $ """Provides an emulator/replacement for Python's standard import system. @@TR: Be warned that Import Hooks are in the deepest, darkest corner of Python's jungle. If you need to start hacking with this, be prepared to get lost for a while. Also note, this module predates the newstyle import hooks in Python 2.3 http://www.python.org/peps/pep-0302.html. This is a hacked/documented version of Gordon McMillan's iu.py. I have: - made it a little less terse - added docstrings and explanatations - standardized the variable naming scheme - reorganized the code layout to enhance readability Meta-Data ================================================================================ Author: Tavis Rudd based on Gordon McMillan's iu.py License: This software is released for unlimited distribution under the terms of the MIT license. See the LICENSE file. Version: $Revision: 1.6 $ Start Date: 2001/03/30 Last Revision Date: $Date: 2007/04/03 01:56:24 $ """ __author__ = "Tavis Rudd " __revision__ = "$Revision: 1.6 $"[11:-2] ################################################## ## DEPENDENCIES import sys import imp import marshal ################################################## ## CONSTANTS & GLOBALS try: True,False except NameError: True, False = (1==1),(1==0) _installed = False STRINGTYPE = type('') # _globalOwnerTypes is defined at the bottom of this file _os_stat = _os_path_join = _os_getcwd = _os_path_dirname = None ################################################## ## FUNCTIONS def _os_bootstrap(): """Set up 'os' module replacement functions for use during import bootstrap.""" names = sys.builtin_module_names join = dirname = None if 'posix' in names: sep = '/' from posix import stat, getcwd elif 'nt' in names: sep = '\\' from nt import stat, getcwd elif 'dos' in names: sep = '\\' from dos import stat, getcwd elif 'os2' in names: sep = '\\' from os2 import stat, getcwd elif 'mac' in names: from mac import stat, getcwd def join(a, b): if a == '': return b if ':' not in a: a = ':' + a if a[-1:] != ':': a = a + ':' return a + b else: raise ImportError, 'no os specific module found' if join is None: def join(a, b, sep=sep): if a == '': return b lastchar = a[-1:] if lastchar == '/' or lastchar == sep: return a + b return a + sep + b if dirname is None: def dirname(a, sep=sep): for i in range(len(a)-1, -1, -1): c = a[i] if c == '/' or c == sep: return a[:i] return '' global _os_stat _os_stat = stat global _os_path_join _os_path_join = join global _os_path_dirname _os_path_dirname = dirname global _os_getcwd _os_getcwd = getcwd _os_bootstrap() def packageName(s): for i in range(len(s)-1, -1, -1): if s[i] == '.': break else: return '' return s[:i] def nameSplit(s): rslt = [] i = j = 0 for j in range(len(s)): if s[j] == '.': rslt.append(s[i:j]) i = j+1 if i < len(s): rslt.append(s[i:]) return rslt def getPathExt(fnm): for i in range(len(fnm)-1, -1, -1): if fnm[i] == '.': return fnm[i:] return '' def pathIsDir(pathname): "Local replacement for os.path.isdir()." try: s = _os_stat(pathname) except OSError: return None return (s[0] & 0170000) == 0040000 def getDescr(fnm): ext = getPathExt(fnm) for (suffix, mode, typ) in imp.get_suffixes(): if suffix == ext: return (suffix, mode, typ) ################################################## ## CLASSES class Owner: """An Owner does imports from a particular piece of turf That is, there's an Owner for each thing on sys.path There are owners for directories and .pyz files. There could be owners for zip files, or even URLs. A shadowpath (a dictionary mapping the names in sys.path to their owners) is used so that sys.path (or a package's __path__) is still a bunch of strings, """ def __init__(self, path): self.path = path def __str__(self): return self.path def getmod(self, nm): return None class DirOwner(Owner): def __init__(self, path): if path == '': path = _os_getcwd() if not pathIsDir(path): raise ValueError, "%s is not a directory" % path Owner.__init__(self, path) def getmod(self, nm, getsuffixes=imp.get_suffixes, loadco=marshal.loads, newmod=imp.new_module): pth = _os_path_join(self.path, nm) possibles = [(pth, 0, None)] if pathIsDir(pth): possibles.insert(0, (_os_path_join(pth, '__init__'), 1, pth)) py = pyc = None for pth, ispkg, pkgpth in possibles: for ext, mode, typ in getsuffixes(): attempt = pth+ext try: st = _os_stat(attempt) except: pass else: if typ == imp.C_EXTENSION: fp = open(attempt, 'rb') mod = imp.load_module(nm, fp, attempt, (ext, mode, typ)) mod.__file__ = attempt return mod elif typ == imp.PY_SOURCE: py = (attempt, st) else: pyc = (attempt, st) if py or pyc: break if py is None and pyc is None: return None while 1: if pyc is None or py and pyc[1][8] < py[1][8]: try: co = compile(open(py[0], 'r').read()+'\n', py[0], 'exec') break except SyntaxError, e: print "Invalid syntax in %s" % py[0] print e.args raise elif pyc: stuff = open(pyc[0], 'rb').read() try: co = loadco(stuff[8:]) break except (ValueError, EOFError): pyc = None else: return None mod = newmod(nm) mod.__file__ = co.co_filename if ispkg: mod.__path__ = [pkgpth] subimporter = PathImportDirector(mod.__path__) mod.__importsub__ = subimporter.getmod mod.__co__ = co return mod class ImportDirector(Owner): """ImportDirectors live on the metapath There's one for builtins, one for frozen modules, and one for sys.path Windows gets one for modules gotten from the Registry Mac would have them for PY_RESOURCE modules etc. A generalization of Owner - their concept of 'turf' is broader""" pass class BuiltinImportDirector(ImportDirector): """Directs imports of builtin modules""" def __init__(self): self.path = 'Builtins' def getmod(self, nm, isbuiltin=imp.is_builtin): if isbuiltin(nm): mod = imp.load_module(nm, None, nm, ('','',imp.C_BUILTIN)) return mod return None class FrozenImportDirector(ImportDirector): """Directs imports of frozen modules""" def __init__(self): self.path = 'FrozenModules' def getmod(self, nm, isFrozen=imp.is_frozen, loadMod=imp.load_module): if isFrozen(nm): mod = loadMod(nm, None, nm, ('','',imp.PY_FROZEN)) if hasattr(mod, '__path__'): mod.__importsub__ = lambda name, pname=nm, owner=self: owner.getmod(pname+'.'+name) return mod return None class RegistryImportDirector(ImportDirector): """Directs imports of modules stored in the Windows Registry""" def __init__(self): self.path = "WindowsRegistry" self.map = {} try: import win32api ## import win32con except ImportError: pass else: HKEY_CURRENT_USER = -2147483647 HKEY_LOCAL_MACHINE = -2147483646 KEY_ALL_ACCESS = 983103 subkey = r"Software\Python\PythonCore\%s\Modules" % sys.winver for root in (HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE): try: hkey = win32api.RegOpenKeyEx(root, subkey, 0, KEY_ALL_ACCESS) except: pass else: numsubkeys, numvalues, lastmodified = win32api.RegQueryInfoKey(hkey) for i in range(numsubkeys): subkeyname = win32api.RegEnumKey(hkey, i) hskey = win32api.RegOpenKeyEx(hkey, subkeyname, 0, KEY_ALL_ACCESS) val = win32api.RegQueryValueEx(hskey, '') desc = getDescr(val[0]) self.map[subkeyname] = (val[0], desc) hskey.Close() hkey.Close() break def getmod(self, nm): stuff = self.map.get(nm) if stuff: fnm, desc = stuff fp = open(fnm, 'rb') mod = imp.load_module(nm, fp, fnm, desc) mod.__file__ = fnm return mod return None class PathImportDirector(ImportDirector): """Directs imports of modules stored on the filesystem.""" def __init__(self, pathlist=None, importers=None, ownertypes=None): if pathlist is None: self.path = sys.path else: self.path = pathlist if ownertypes == None: self._ownertypes = _globalOwnerTypes else: self._ownertypes = ownertypes if importers: self._shadowPath = importers else: self._shadowPath = {} self._inMakeOwner = False self._building = {} def getmod(self, nm): mod = None for thing in self.path: if type(thing) is STRINGTYPE: owner = self._shadowPath.get(thing, -1) if owner == -1: owner = self._shadowPath[thing] = self._makeOwner(thing) if owner: mod = owner.getmod(nm) else: mod = thing.getmod(nm) if mod: break return mod def _makeOwner(self, path): if self._building.get(path): return None self._building[path] = 1 owner = None for klass in self._ownertypes: try: # this may cause an import, which may cause recursion # hence the protection owner = klass(path) except: pass else: break del self._building[path] return owner #=================ImportManager============================# # The one-and-only ImportManager # ie, the builtin import UNTRIED = -1 class ImportManager: # really the equivalent of builtin import def __init__(self): self.metapath = [ BuiltinImportDirector(), FrozenImportDirector(), RegistryImportDirector(), PathImportDirector() ] self.threaded = 0 self.rlock = None self.locker = None self.setThreaded() def setThreaded(self): thread = sys.modules.get('thread', None) if thread and not self.threaded: self.threaded = 1 self.rlock = thread.allocate_lock() self._get_ident = thread.get_ident def install(self): import __builtin__ __builtin__.__import__ = self.importHook __builtin__.reload = self.reloadHook def importHook(self, name, globals=None, locals=None, fromlist=None): # 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 contexts = [None] if globals: importernm = globals.get('__name__', '') if importernm: if hasattr(_sys_modules_get(importernm), '__path__'): contexts.insert(0,importernm) else: pkgnm = packageName(importernm) if pkgnm: contexts.insert(0,pkgnm) # so contexts is [pkgnm, None] or just [None] # now break the name being imported up so we get: # a.b.c -> [a, b, c] nmparts = nameSplit(name) _self_doimport = self.doimport threaded = self.threaded for context in contexts: ctx = context for i in range(len(nmparts)): nm = nmparts[i] #print " importHook trying %s in %s" % (nm, ctx) if ctx: fqname = ctx + '.' + nm else: fqname = nm if threaded: self._acquire() mod = _sys_modules_get(fqname, UNTRIED) if mod is UNTRIED: mod = _self_doimport(nm, ctx, fqname) if threaded: self._release() if mod: ctx = fqname else: break else: # no break, point i beyond end i = i + 1 if i: break if i= len(fromlist): break nm = fromlist[i] i = i + 1 if not hasattr(bottommod, nm): if self.threaded: self._acquire() mod = self.doimport(nm, ctx, ctx+'.'+nm) if self.threaded: self._release() if not mod: raise ImportError, "%s not found in %s" % (nm, ctx) #print "importHook done with %s %s %s (case 3)" % (name, globals['__name__'], fromlist) return bottommod def doimport(self, nm, parentnm, fqname): # Not that nm is NEVER a dotted name at this point #print "doimport(%s, %s, %s)" % (nm, parentnm, fqname) if parentnm: parent = sys.modules[parentnm] if hasattr(parent, '__path__'): importfunc = getattr(parent, '__importsub__', None) if not importfunc: subimporter = PathImportDirector(parent.__path__) importfunc = parent.__importsub__ = subimporter.getmod mod = importfunc(nm) if mod: setattr(parent, nm, mod) else: #print "..parent not a package" return None else: # now we're dealing with an absolute import for director in self.metapath: mod = director.getmod(nm) if mod: break if mod: mod.__name__ = fqname sys.modules[fqname] = mod if hasattr(mod, '__co__'): co = mod.__co__ del mod.__co__ exec co in mod.__dict__ if fqname == 'thread' and not self.threaded: ## print "thread detected!" self.setThreaded() else: sys.modules[fqname] = None #print "..found %s" % mod return mod def reloadHook(self, mod): fqnm = mod.__name__ nm = nameSplit(fqnm)[-1] parentnm = packageName(fqnm) newmod = self.doimport(nm, parentnm, fqnm) mod.__dict__.update(newmod.__dict__) ## return newmod def _acquire(self): if self.rlock.locked(): if self.locker == self._get_ident(): self.lockcount = self.lockcount + 1 ## print "_acquire incrementing lockcount to", self.lockcount return self.rlock.acquire() self.locker = self._get_ident() self.lockcount = 0 ## print "_acquire first time!" def _release(self): if self.lockcount: self.lockcount = self.lockcount - 1 ## print "_release decrementing lockcount to", self.lockcount else: self.rlock.release() ## print "_release releasing lock!" ################################################## ## MORE CONSTANTS & GLOBALS _globalOwnerTypes = [ DirOwner, Owner, ] PK(8ȫZCheetah/_namemapper.pydef __bootstrap__(): global __bootstrap__, __loader__, __file__ import sys, pkg_resources, imp __file__ = pkg_resources.resource_filename(__name__,'_namemapper.so') del __bootstrap__, __loader__ imp.load_dynamic(__name__,__file__) __bootstrap__() PKܡ(8DCheetah/__init__.pyc; Cc@s*dZdZddd!ZdklZdS(sZCheetah is an open source template engine and code generation tool. It can be used standalone or combined with other tools and frameworks. Web development is its principle use, but Cheetah is very flexible and is also being used to generate C++ game code, Java, sql, form emails and even Python code. Homepage ================================================================================ http://www.CheetahTemplate.org/ Documentation ================================================================================ For a high-level introduction to Cheetah please refer to the User's Guide at http://cheetahtemplate.org/learn.html Mailing list ================================================================================ cheetahtemplate-discuss@lists.sourceforge.net Subscribe at http://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss s!Tavis Rudd s$Revision: 1.10 $i i(sVersionN(s__doc__s __author__s __revision__sVersion(s __revision__sVersions __author__((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/__init__.pys?s PK(8;^::Cheetah/SourceReader.pyc; Fc@sdZdZddd!ZdkZdkZeidZeidZeidiZ d e fd YZ d fd YZ dS( sSourceReader class for Cheetah's Parser and CodeGenerator Meta-Data ================================================================================ Author: Tavis Rudd License: This software is released for unlimited distribution under the terms of the MIT license. See the LICENSE file. Version: $Revision: 1.15 $ Start Date: 2001/09/19 Last Revision Date: $Date: 2007/04/03 01:57:42 $ s!Tavis Rudd s$Revision: 1.15 $i iNs[ \f\t]*(?:\r\n|\r|\n)s(?:\r\n|\r|\n|\Z)scoding[=:]\s*([-\w.]+)sErrorcBstZRS(N(s__name__s __module__(((s9build/bdist.darwin-8.0.1-i386/egg/Cheetah/SourceReader.pysErrorss SourceReadercBstZeeedZdZdZdZdZdZdZ edZ ed Z ed Z d Z d Zd ZdZdZdZdZdZdZdZdZdZddZdZedZddZddZdZedZee d Z!ed!Z"ed"Z#d#Z$ed$Z%ee&d%Z'ed&Z(d'Z)d(d)Z*ed(d*Z+d+d,Z,d+d-Z-RS(.NcCs||_||_t||_|tjo|i|_ n|i |d|_ h|_ h|_ g|_d}xL|t|jo8ti||}|ii|i|i}qxWg|_x0|iD]%}|i|}|ii|qWdS(Ni(ssrcsselfs_srcsfilenames _filenameslens_srcLens breakPointsNones _breakPoints setBreakPoints_poss _bookmarkss_posTobookmarkMaps_EOLsspossEOLZressearchsEOLmatchsappendsstartsends_BOLssfindBOLsBOLpos(sselfssrcsfilenames breakPointsencodingsBOLpossEOLmatchspos((s9build/bdist.darwin-8.0.1-i386/egg/Cheetah/SourceReader.pys__init__s*          cCs |iSdS(N(sselfs_src(sself((s9build/bdist.darwin-8.0.1-i386/egg/Cheetah/SourceReader.pyssrcOscCs |iSdS(N(sselfs _filename(sself((s9build/bdist.darwin-8.0.1-i386/egg/Cheetah/SourceReader.pysfilenameRscCs |iSdS(N(sselfs _breakPoint(sself((s9build/bdist.darwin-8.0.1-i386/egg/Cheetah/SourceReader.pys__len__UscCs|i||i|SdS(N(sselfscheckPossis_src(sselfsi((s9build/bdist.darwin-8.0.1-i386/egg/Cheetah/SourceReader.pys __getitem__Xs cCs0t|d}t|d}|i||!SdS(Ni(smaxsisjsselfs_src(sselfsisj((s9build/bdist.darwin-8.0.1-i386/egg/Cheetah/SourceReader.pys __getslice__\scCs2t|d o|ii|_n|iSdS(Ns _srcLines(shasattrsselfs_srcs splitliness _srcLines(sself((s9build/bdist.darwin-8.0.1-i386/egg/Cheetah/SourceReader.pys splitlines`scCsn|tjo |i}nxMtt|iD]6}||i|jo||i|jo|Sq0q0WdS(N( spossNonesselfs_possrangeslens_BOLssis_EOLs(sselfspossi((s9build/bdist.darwin-8.0.1-i386/egg/Cheetah/SourceReader.pyslineNumes   (cCsc|tjo |i}n|i|}|i||i|f\}}|d||dfSdS(Ni( spossNonesselfs_posslineNums_BOLss_EOLssBOLsEOL(sselfspossEOLslineNumsBOL((s9build/bdist.darwin-8.0.1-i386/egg/Cheetah/SourceReader.pys getRowColms    cCsN|tjo |i}n|i|\}}|||i|dfSdS(Ni(spossNonesselfs_poss getRowColsrowscols splitlines(sselfsposscolsrow((s9build/bdist.darwin-8.0.1-i386/egg/Cheetah/SourceReader.pys getRowColLinets  cCs;|tjo |i}n|i|}|i|SdS(N(spossNonesselfs_posslineNums splitlines(sselfsposslineNum((s9build/bdist.darwin-8.0.1-i386/egg/Cheetah/SourceReader.pysgetLinezs  cCs |iSdS(N(sselfs_pos(sself((s9build/bdist.darwin-8.0.1-i386/egg/Cheetah/SourceReader.pysposscCs|i|||_dS(N(sselfscheckPossposs_pos(sselfspos((s9build/bdist.darwin-8.0.1-i386/egg/Cheetah/SourceReader.pyssetPoss cCs||ijo |djSdS(Ni(spossselfs _breakPoint(sselfspos((s9build/bdist.darwin-8.0.1-i386/egg/Cheetah/SourceReader.pysvalidPosscCst||ij o3tdt|dt|iddn-|dj otdt|dndS(Nspos (s') is invalid: beyond the stream's end (is)is) is invalid: less than 0(spossselfs _breakPointsErrorsstr(sselfspos((s9build/bdist.darwin-8.0.1-i386/egg/Cheetah/SourceReader.pyscheckPoss3cCs |iSdS(N(sselfs _breakPoint(sself((s9build/bdist.darwin-8.0.1-i386/egg/Cheetah/SourceReader.pys breakPointscCsx||ijo/tdt|dt|idn-|dj otdt|dn||_dS(NsNew breakpoint (s8) is invalid: beyond the end of stream's source string (s)is) is invalid: less than 0(spossselfs_srcLensErrorsstrs _breakPoint(sselfspos((s9build/bdist.darwin-8.0.1-i386/egg/Cheetah/SourceReader.pys setBreakPoints /cCs$|i|i|<||i|i|i|ijo$|i|i| oPq(q(W|i||i!SdS(Ns(sselfsmatchNonWhiteSpacesWScharsspossstarts breakPointsadvancessrc(sselfsWScharssstart((s9build/bdist.darwin-8.0.1-i386/egg/Cheetah/SourceReader.pysgetNonWhiteSpace(s   (.s__name__s __module__sNones__init__ssrcsfilenames__len__s __getitem__s __getslice__s splitlinesslineNums getRowCols getRowColLinesgetLinesposssetPossvalidPosscheckPoss breakPoints setBreakPoints setBookmarks hasBookmarks gotoBookmarksatEndsatStartspeeksgetcsungetcsadvancesrevsreadsreadTosTrues readToEOLsfinds startswithsrfindsfindBOLsFalsesfindEOLsisLineClearToPossmatchessmatchWhiteSpaces getWhiteSpacesmatchNonWhiteSpacesgetNonWhiteSpace(((s9build/bdist.darwin-8.0.1-i386/egg/Cheetah/SourceReader.pys SourceReadersR3                                  ( s__doc__s __author__s __revision__sressysscompilesEOLresEOLZressearchsENCODINGsearchs ExceptionsErrors SourceReader( sEOLres __revision__s SourceReaders __author__ssyssresENCODINGsearchsErrorsEOLZre((s9build/bdist.darwin-8.0.1-i386/egg/Cheetah/SourceReader.pys? s   PKܡ(8(ammCheetah/Compiler.pyc; 3Fc@s dZdZddd!ZdkZdkZdkZdklZlZdkZdk Z dk Z dk Z dk Z dk Z dkZdklZlZdklZd klZd klZd klZd klZlZlZlZlZlZl Z l!Z!l"Z"l#Z#l$Z$d k%l&Z&l'Z'l(Z(l)Z)e)Z*e(Z+e'Z,e i Z-de.fdYZ/hde0<de0<de0<de0<de0<de1<de0<de0<de0<de1<de0<dd<de0<de1<dd d!f<d"d#d!f<d$d%<d&e1<d'd(<d)d*<d+d,d-<d.d/<d0e1<d1e0<d2e0<d3e0<d4e2<d5g<d6g<d7g<d8g<d9g<d:g<d;g<d<g<d=e2<d>d?<d@dA<dBdC<dDdE<dFdG<dHe0<dIdJ<dKdJ<dLe1<dMdN<dOdP<dQdJ<dRdSdTdUg<dVe1<dWe1<dXe0<dYe0 Version: $Revision: 1.155 $ Start Date: 2001/09/19 Last Revision Date: $Date: 2007/04/04 00:28:35 $ s!Tavis Rudd s$Revision: 1.155 $i iN(sgetmtimesexists(sVersions VersionTuple(sSettingsManager(s indentize(s ErrorCatchers(s NameMapper( sParsers ParseErrors specialVarREs STATIC_CACHEs REFRESH_CACHEs SET_LOCALs SET_GLOBALs SET_MODULEsunicodeDirectiveREsencodingDirectiveREsescapedNewlineRE(sNotFounds valueForNamesvalueFromSearchListsvalueFromFrameOrSearchListsErrorcBstZRS(N(s__name__s __module__(((s5build/bdist.darwin-8.0.1-i386/egg/Cheetah/Compiler.pysError0ss useNameMappers useSearchListsallowSearchListAsMethArgsuseAutocallingsuseStackFramessuseErrorCatchersalwaysFilterNones useFilterssincludeRawExprInFilterArgss autoAssignDummyTransactionToSelfsuseKWsDictArgForPassingTranss commentOffsetisoutputRowColCommentssincludeBlockMarkerssblockMarkerStarts sblockMarkerEnds N(sstylesheetTagsTxtsselfs_stylesheetLibssitemsstitlessrcsstrs_stylesheetsOrders identifiers _stylesheetsshas_keyswarnings attribsDictscssCodes attribCodesksv( sselfsstylesheetTagsTxtssrcstitles attribCodeswarningscssCodesvs attribsDicts identifiersk((sDbuild/bdist.darwin-8.0.1-i386/egg/Cheetah/Templates/_SkeletonPage.pysstylesheetTagsIs4       &  cCsg}xy|iiD]h\}}t|titi fjod|g}n|dt |ddt |ddg7}qWxy|i iD]h\}}t|titi fjod|g}n|dt |ddt |ddg7}qWdi |Sd S( sReturn a formatted version of the javascriptTags and javascriptLibs dictionaries. Each value in javascriptTags should be a either a code string to include, or a list containing the JavaScript version number and the code string. The keys can be anything. The same applies for javascriptLibs, but the string should be the SRC filename rather than a code string.ss s" type="text/javascript" src="is" /> N( sjavascriptTagsTxtsselfs_javascriptTagssitemsskeysdetailsstypestypessListTypes TupleTypesstrs_javascriptLibssjoin(sselfsdetailsskeysjavascriptTagsTxt((sDbuild/bdist.darwin-8.0.1-i386/egg/Cheetah/Templates/_SkeletonPage.pysjavascriptTagsns 1 1cCs|id|iSdS(s>Create a body tag from the entries in the dict bodyTagAttribs.sbodyN(sselfs formHTMLTags_bodyTagAttribs(sself((sDbuild/bdist.darwin-8.0.1-i386/egg/Cheetah/Templates/_SkeletonPage.pysbodyTagsic Cs|i|}| p| oyRdk} | i|}|i\}}~| o |}n| o |}nWqyPt i d|i id\}}| o |}n| o |}nWqqXqXn|o|oDdid|dt|dt|d|d t|d g Sn|o8did|dt|d|d t|d g Snh|o8did|dt|d|d t|d g Sn)did|d|d t|d gSdS( sDynamically generate an image tag. Cheetah will try to convert the src argument to a WebKit serverSidePath relative to the servlet's location. If width and height aren't specified they are calculated using PIL or ImageMagick if available.Nsidentify -format "%w,%h" s,ss s
���(sselfs normalizePathssrcswidthsheightsImagesopensimssizes calcWidths calcHeightsosspopensreadssplitsjoinsstrsaltsborder( sselfssrcsaltswidthsheightsborders calcWidthsims calcHeightsImage((sDbuild/bdist.darwin-8.0.1-i386/egg/Cheetah/Templates/_SkeletonPage.pysimgTags8  (  D88cCs#tidtitiSdS(s,Return a string representing the current yr.s%YN(stimesstrftimes localtime(sself((sDbuild/bdist.darwin-8.0.1-i386/egg/Cheetah/Templates/_SkeletonPage.pys currentYrss %b %d, %YcCs#ti|titiSdS(s3Return a string representing the current localtime.N(stimesstrftimes formatStrings localtime(sselfs formatString((sDbuild/bdist.darwin-8.0.1-i386/egg/Cheetah/Templates/_SkeletonPage.pys currentDatesicCsdt|t|fSdS(Ns6(sstrswidthsheight(sselfswidthsheight((sDbuild/bdist.darwin-8.0.1-i386/egg/Cheetah/Templates/_SkeletonPage.pysspacerscCsrd|ig}x?|iD]1\}}|d|idt|dg7}qW|iddi |SdS(s*returns a string containing an HTML ssN( stagNameslowerstagTxts attributessitemssnamesvalsstrsappendsjoin(sselfstagNames attributessnamesvalstagTxt((sDbuild/bdist.darwin-8.0.1-i386/egg/Cheetah/Templates/_SkeletonPage.pys formHTMLTags ) cCsg}|idoJxG|diD]1\}}|dt|dt|dg7}q'Wn|idoJxG|diD]1\}}|dt|dt|dg7}qWndi|SdS( s9format a dict of metaTag definitions into an HTML versions HTTP-EQUIVs sNAMEs \n') _v = VFFSL(SL,"title",True) # '$title' on line 24, col 8 if _v is not None: write(_filter(_v, rawExpr='$title')) # from line 24, col 8. write('\n') _v = VFFSL(SL,"metaTags",True) # '$metaTags' on line 25, col 1 if _v is not None: write(_filter(_v, rawExpr='$metaTags')) # from line 25, col 1. write(' \n') _v = VFFSL(SL,"stylesheetTags",True) # '$stylesheetTags' on line 26, col 1 if _v is not None: write(_filter(_v, rawExpr='$stylesheetTags')) # from line 26, col 1. write(' \n') _v = VFFSL(SL,"javascriptTags",True) # '$javascriptTags' on line 27, col 1 if _v is not None: write(_filter(_v, rawExpr='$javascriptTags')) # from line 27, col 1. write('\n\n') ######################################## ## END - generated method body return _dummyTrans and trans.response().getvalue() or "" def writeBody(self, **KWS): ## CHEETAH: generated from #block writeBody at line 36, col 1. trans = KWS.get("trans") if (not trans and not self._CHEETAH__isBuffering and not callable(self.transaction)): trans = self.transaction # is None unless self.awake() was called if not trans: trans = DummyTransaction() _dummyTrans = True else: _dummyTrans = False write = trans.response().write SL = self._CHEETAH__searchList _filter = self._CHEETAH__currentFilter ######################################## ## START - generated method body write('This skeleton page has no flesh. Its body needs to be implemented.\n') ######################################## ## END - generated method body return _dummyTrans and trans.response().getvalue() or "" def respond(self, trans=None): ## CHEETAH: main method generated for this template if (not trans and not self._CHEETAH__isBuffering and not callable(self.transaction)): trans = self.transaction # is None unless self.awake() was called if not trans: trans = DummyTransaction() _dummyTrans = True else: _dummyTrans = False write = trans.response().write SL = self._CHEETAH__searchList _filter = self._CHEETAH__currentFilter ######################################## ## START - generated method body ## START CACHE REGION: ID=header. line 6, col 1 in the source. _RECACHE_header = False _cacheRegion_header = self.getCacheRegion(regionID='header', cacheInfo={'type': 2, 'id': 'header'}) if _cacheRegion_header.isNew(): _RECACHE_header = True _cacheItem_header = _cacheRegion_header.getCacheItem('header') if _cacheItem_header.hasExpired(): _RECACHE_header = True if (not _RECACHE_header) and _cacheItem_header.getRefreshTime(): try: _output = _cacheItem_header.renderOutput() except KeyError: _RECACHE_header = True else: write(_output) del _output if _RECACHE_header or not _cacheItem_header.getRefreshTime(): _orig_transheader = trans trans = _cacheCollector_header = DummyTransaction() write = _cacheCollector_header.response().write _v = VFFSL(SL,"docType",True) # '$docType' on line 7, col 1 if _v is not None: write(_filter(_v, rawExpr='$docType')) # from line 7, col 1. write('\n') _v = VFFSL(SL,"htmlTag",True) # '$htmlTag' on line 8, col 1 if _v is not None: write(_filter(_v, rawExpr='$htmlTag')) # from line 8, col 1. write(''' ''') self.writeHeadTag(trans=trans) write('\n') trans = _orig_transheader write = trans.response().write _cacheData = _cacheCollector_header.response().getvalue() _cacheItem_header.setData(_cacheData) write(_cacheData) del _cacheData del _cacheCollector_header del _orig_transheader ## END CACHE REGION: header write('\n') _v = VFFSL(SL,"bodyTag",True) # '$bodyTag' on line 34, col 1 if _v is not None: write(_filter(_v, rawExpr='$bodyTag')) # from line 34, col 1. write('\n\n') self.writeBody(trans=trans) write(''' ''') ######################################## ## END - generated method body return _dummyTrans and trans.response().getvalue() or "" ################################################## ## CHEETAH GENERATED ATTRIBUTES _CHEETAH__instanceInitialized = False _CHEETAH_version = __CHEETAH_version__ _CHEETAH_versionTuple = __CHEETAH_versionTuple__ _CHEETAH_genTime = __CHEETAH_genTime__ _CHEETAH_genTimestamp = __CHEETAH_genTimestamp__ _CHEETAH_src = __CHEETAH_src__ _CHEETAH_srcLastModified = __CHEETAH_srcLastModified__ _mainCheetahMethod_for_SkeletonPage= 'respond' ## END CLASS DEFINITION if not hasattr(SkeletonPage, '_initCheetahAttributes'): templateAPIClass = getattr(SkeletonPage, '_CHEETAH_templateClass', Template) templateAPIClass._addCheetahPlumbingCodeToClass(SkeletonPage) # CHEETAH was developed by Tavis Rudd and Mike Orr # with code, advice and input from many other volunteers. # For more information visit http://www.CheetahTemplate.org/ ################################################## ## if run from command line: if __name__ == '__main__': from Cheetah.TemplateCmdLineIface import CmdLineIface CmdLineIface(templateObj=SkeletonPage()).run() PKtG-U#Cheetah/Templates/SkeletonPage.tmpl##doc-module: A Skeleton HTML page template, that provides basic structure and utility methods. ################################################################################ #extends Cheetah.Templates._SkeletonPage #implements respond ################################################################################ #cache id='header' $docType $htmlTag #block writeHeadTag $title $metaTags $stylesheetTags $javascriptTags #end block writeHeadTag #end cache header ################# $bodyTag #block writeBody This skeleton page has no flesh. Its body needs to be implemented. #end block writeBody PKN'41`o"o""Cheetah/Templates/_SkeletonPage.py#!/usr/bin/env python # $Id: _SkeletonPage.py,v 1.13 2002/10/01 17:52:02 tavis_rudd Exp $ """A baseclass for the SkeletonPage template Meta-Data ========== Author: Tavis Rudd , Version: $Revision: 1.13 $ Start Date: 2001/04/05 Last Revision Date: $Date: 2002/10/01 17:52:02 $ """ __author__ = "Tavis Rudd " __revision__ = "$Revision: 1.13 $"[11:-2] ################################################## ## DEPENDENCIES ## import time, types, os, sys # intra-package imports ... from Cheetah.Template import Template ################################################## ## GLOBALS AND CONSTANTS ## True = (1==1) False = (0==1) ################################################## ## CLASSES ## class _SkeletonPage(Template): """A baseclass for the SkeletonPage template""" docType = '' # docType = '' title = '' siteDomainName = 'www.example.com' siteCredits = 'Designed & Implemented by Tavis Rudd' siteCopyrightName = "Tavis Rudd" htmlTag = '' def __init__(self, *args, **KWs): Template.__init__(self, *args, **KWs) self._metaTags = {'HTTP-EQUIV':{'keywords':'Cheetah', 'Content-Type':'text/html; charset=iso-8859-1', }, 'NAME':{'generator':'Cheetah: The Python-Powered Template Engine'} } # metaTags = {'HTTP_EQUIV':{'test':1234}, 'NAME':{'test':1234,'test2':1234} } self._stylesheets = {} # stylesheets = {'.cssClassName':'stylesheetCode'} self._stylesheetsOrder = [] # stylesheetsOrder = ['.cssClassName',] self._stylesheetLibs = {} # stylesheetLibs = {'libName':'libSrcPath'} self._javascriptLibs = {} self._javascriptTags = {} # self._javascriptLibs = {'libName':'libSrcPath'} self._bodyTagAttribs = {} def metaTags(self): """Return a formatted vesion of the self._metaTags dictionary, using the formatMetaTags function from Cheetah.Macros.HTML""" return self.formatMetaTags(self._metaTags) def stylesheetTags(self): """Return a formatted version of the self._stylesheetLibs and self._stylesheets dictionaries. The keys in self._stylesheets must be listed in the order that they should appear in the list self._stylesheetsOrder, to ensure that the style rules are defined in the correct order.""" stylesheetTagsTxt = '' for title, src in self._stylesheetLibs.items(): stylesheetTagsTxt += '\n' if not self._stylesheetsOrder: return stylesheetTagsTxt stylesheetTagsTxt += '\n' return stylesheetTagsTxt def javascriptTags(self): """Return a formatted version of the javascriptTags and javascriptLibs dictionaries. Each value in javascriptTags should be a either a code string to include, or a list containing the JavaScript version number and the code string. The keys can be anything. The same applies for javascriptLibs, but the string should be the SRC filename rather than a code string.""" javascriptTagsTxt = [] for key, details in self._javascriptTags.items(): if type(details) not in (types.ListType, types.TupleType): details = ['',details] javascriptTagsTxt += ['\n'] for key, details in self._javascriptLibs.items(): if type(details) not in (types.ListType, types.TupleType): details = ['',details] javascriptTagsTxt += ['