Robert Brewer avatar Robert Brewer committed db00faa

Fix for ticket #249 (ExposeAs recipe). The underscore hack is retained (and not reversed). %xx chars (ticket #104) were fixed in [561], so neither #104 nor #248 (firefox hack) apply anymore to #249.

Comments (0)

Files changed (3)

cherrypy/__init__.py

 __version__ = '2.1.0-beta'
 
 import datetime
+import sys
+import types
 
 from _cperror import *
 import config
 _sessionLockDict = {} # Needed for RAM sessions only
 _sessionLastCleanUpTime = datetime.datetime.now()
 
-# decorator function for exposing methods
-def expose(func):
-    func.exposed = True
-    return func
+def expose(func=None, alias=None):
+    """Expose the function, optionally providing an alias or set of aliases."""
+    
+    def expose_(func):
+        func.exposed = True
+        if alias is not None:
+            if isinstance(alias, basestring):
+                parentDict[alias] = func
+            else:
+                for a in alias:
+                    parentDict[a] = func
+        return func
+    
+    parentDict = sys._getframe(1).f_locals
+    if isinstance(func, (types.FunctionType, types.MethodType)):
+        # expose is being called directly, before the method has been bound
+        return expose_(func)
+    else:
+        # expose is being called as a decorator
+        if alias is None:
+            alias = func
+        return expose_
 
 def log(msg, context='', severity=0):
     """Syntactic sugar for writing to the (error) log."""

cherrypy/test/cp_decorator_tests.py

+
+import cherrypy
+class Exposing:
+    @cherrypy.expose("1")
+    def base(self):
+        return "expose works!"
+    cherrypy.expose(base, "2")
+
+class ExposingNewStyle(object):
+    @cherrypy.expose("1")
+    def base(self):
+        return "expose works!"
+    cherrypy.expose(base, "2")

cherrypy/test/test_objectmapping.py

 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 """
 
+import sys
+
 import cherrypy
 from cherrypy.lib import httptools
 
 setattr(Root, "Von B\xfclow", mapped_func)
 
 
+if sys.hexversion > 0x020400A2:
+    from cp_decorator_tests import Exposing, ExposingNewStyle
+else:
+    class Exposing:
+        def base(self):
+            return "expose works!"
+        cherrypy.expose(base, "1")
+        cherrypy.expose(base, "2")
+    
+    class ExposingNewStyle(object):
+        def base(self):
+            return "expose works!"
+        cherrypy.expose(base, "1")
+        cherrypy.expose(base, "2")
+
+
+
 class Dir1:
     def index(self):
         return "index for dir1"
         return "index for dir4, not exposed"
 
 cherrypy.root = Root()
+cherrypy.root.exposing = Exposing()
+cherrypy.root.exposingnew = ExposingNewStyle()
 cherrypy.root.dir1 = Dir1()
 cherrypy.root.dir1.dir2 = Dir2()
 cherrypy.root.dir1.dir2.dir3 = Dir3()
         # This should also test the %XX-unquoting of URL's.
         self.getPage("/Von%20B%fclow?ID=14")
         self.assertBody("ID is 14")
+    
+    def testExpose(self):
+        # Test the cherrypy.expose function/decorator
+        self.getPage("/exposing/1")
+        self.assertBody("expose works!")
+        
+        self.getPage("/exposing/2")
+        self.assertBody("expose works!")
+        
+        self.getPage("/exposingnew/1")
+        self.assertBody("expose works!")
+        
+        self.getPage("/exposingnew/2")
+        self.assertBody("expose works!")
+
 
 
 if __name__ == "__main__":
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.