summaryrefslogtreecommitdiff
path: root/www/cheps/2_import.rst
blob: 762d9b8ccf23eeafb12ce2bb2115320902e738a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
(#2) Conditionalized #import behavior
=====================================


:CHEP: 2
:Title: Conditionalized #import behavior
:Version: 1
:Author: R Tyler Ballance <tyler at slide.com>
:Status: Draft
:Type: Standards Track
:Content-Type: text/x-rst
:Created: 07-Jun-2009

----

Abstract
--------
This CHEP proposes an update to the way the #import and #from 
directives are handled such that locally scoped imports and 
module-level imports are handled appropriately.


Motivation
----------
Currently Cheetah (v2.2.1) provides two different, but mutually exclusive, 
means of importing Python modules with the #from/#import directives. The 
"traditional" handling for #from/#import (hereafter referred to as "module imports")
is that the generated import statements shall all be relocated to 
the top of the generated module's source code, i.e. ::

    #import cjson

    Hello $cjson.encode([1, 2, 3])
    

Will result in generated module code along the lines of::

    import cjson

    class Foo(Template):
        def writeBody(self):
            write('Hello ')
            write(cjson.encode([1, 2, 3]))


Also currently in Cheetah is the ability to switch off this 
behavior and enable location specific #from/#import handling
(hereafter referred to as "function imports") in the generated 
code, with this block of Cheetah for example::

    #def aFunction(arg)
        #try
            #from hashlib import md5
        #except ImportError
            #from md5 import md5
        #end try
        #return $md5.new(arg).hexdigest()
    #end def

Will result in code generated with everything in
place such that the Python looks something like::

    class Foo(Template):
        def aFunction(self, arg):
            try:
                from hashlib import md5
            except ImportError:
                from md5 import md5
            return md5.new(arg).hexdigest()


These two approaches to handling the #from/#import directives
are both beneficial for different situations but currently they
are handled in mutually exclusive code paths and in mutually 
exclusive fashions. 

Specification
-------------
The change in #from/#import behavior and how these directives 
are handled is all based on context of their use, making the 
#from/#import handling "intelligent". For module imports, the
"traditional" handling of the #from/#import directives will
still apply. Whereas function imports will result in inline 
generated import code.

The basic premise of the change proposed by this document is 
that all #from/#import directives contained within a #def/#end def
closure will result in import statements contained within that 
function block whereas everywhere else the statements will be relocated
to the top of the generated module code (i.e. the module import)


Rationale
---------

Backwards Compatibility
-----------------------

Reference Implementation
------------------------

Copyright
---------
This document has been placed in the public domain.