I figured out a simpler way to accomplish the same thing I wanted.

I built a stack inside my Java object that keeps track of function calls, and I simply pass the function name retrieved from the generator object:

self.arr.updateStack(curPos, stepList.gi_frame.f_code.co_name)

along with the current stack size that Jython is aware of, and it works like a charm.

my java code for this is:

    public void updateStack(int stackCount, String funcName) {
        while(!callStack.isEmpty() && stackCount < callStack.size()) {
        if(!callStack.isEmpty() && funcName.equals(callStack.peek())) {
            log.finer("*** Recursion Identified ***");
        String logStr = "Current Python Function Stack:\n";
        for(String item : callStack) {
            logStr += item + "\n";

I have some logging code in there which I used to help identify everything I needed. It all works nicely, and is a heck of a lot
less confusing that the previous attempt I was making doing a stack trace.

On Wed, Sep 2, 2009 at 10:28 AM, Jim Baker <jbaker@zyasoft.com> wrote:

Recursive generators currently require the loop syntax you mention. PEP 380, which is implemented in 2.7, supports an alternate (and more powerful) "yield from" construction.

- Jim

On Wed, Sep 2, 2009 at 9:59 AM, Cliff Hill <xlorep@darkhelm.org> wrote:
I'm hoping that this is pretty straight-forward. Here's to hoping.

I'm attempting to build a Java object that can see what Jython function called its method(s). In Jython, as in regular Python, I'd do this through the inspect module:

import inspect

def _code(num):
    return inspect.getouterframes(inspect.currentframe())[num + 2][0].f_code

def caller_name():
    return inspect.getouterframes(inspect.currentframe())[2][0].f_code.co_name

However, I'm not able to use a Jython call in this instance, due to performance constraints (the Google App Engine has a one minute requirement for all servlet calls to return, their "Hard Deadline", and when I built the object in Jython, it easily exceeded this hard deadline. So I built a Java object that relies on the magic metho/function names in Jython to "pretend" to be a Python object.

This all goes toward being able to write fairly clean, Pythonic code for sorting algorithms (for my showsort app), which will serve a couple purposes. First and foremost, actually running the sorts as it does, and second, I want to eventually have the actual code which is running in the sorting routines/algorithms be able to be displayed for the viewer. My trick is I'm storing the sorting algorithms in the Google Apps Engine DataStore (using some JDO trickery). I already have this functionality in place, and it works quite well, the source code for the sorting algorithms is stored in a Text field on the DataStore, and whenever a sort is requested, it loads the routine, compiles it, and then executes the routine. The "array" that the routine runs against is this Java object I've built, which relies on Jython special methods in order to produce a number of statistics during the sort: the number of comparisons that were done on the array's elements, the number of recursive calls done, the amount of memory which has been used by the sorting algorithm, and the number of moves (changes) to the array's elements that have been requested.

So far, this has been a piece of cake. I've built the sorting algorithms relying heavily on Jython generators for "lazy computing" of the sorts, which allows me to capture each and every change that the routine has done, like so:

def sort(arr):
    for i in range(len(arr), 0, -1):
        for j in range(1, i):
            if arr[j - 1] > arr[j]:
                yield arr.swap(j - 1, j)

That is my routine for a Bubble Sort. It should be fairly clear and clean, something even (I hope) non-Python people would be able to easily grasp. My goal is to make each and every routine look as much like pseudo-code as possible, which means I want to minimize the Python-specific syntax as possible. The yield lines in my code show where an update has taken place.

The difficulty I had was when I got to recursive algorithms, like Quicksort:

def sort(arr):
    def quick_sort(arr, left, right):
        l_hold, r_hold, pivot = left, right, arr[left]

        while left < right:
            while arr[right] >= pivot and left < right:
                right -= 1

            if left != right:
                yield arr.change(left, arr[right])
                left += 1

            while arr[left] <= pivot and left < right:
                left += 1

            if left != right:
                yield arr.change(right, arr[left])
                right -= 1

        yield arr.change(left, pivot)

        if l_hold < left:
            yield quick_sort(arr, l_hold, left - 1)

        if r_hold > left:
            yield quick_sort(arr, left + 1, r_hold)

What I built was a routine that when it processes the generator object, it looks for if the next element from the generator is, in fact, another generator object. If so, it identifies this as a recursive call, and recursively calls itself with the new generator object as a parameter:

    def process(self, stepList):
        Processes each generator that is created to build the list of updates
        to send back to the client app.
        recurseChecked = False
        log.debug3("Function caller: " + self.arr.getCallerName())
        for step in stepList:
            if recurseChecked == False and self.last_func != None and self.last_func == self.arr.getCallerName():
            recurseChecked = True
            self.last_func = self.arr.getCallerName()
            if type(step) is types.GeneratorType:

This worked great, until I built the Heapsort algorithm:

def sort(arr):
    def siftDown(arr, first, last):
        while 2 * first + 1 <= last:
            k = 2 * first + 1
            if k < last and arr[k] < arr[k + 1]:
                k += 1
            if arr[first] >= arr[k]:
            yield arr.swap(first, k)
            first = k

    first, last = 0, len(arr) - 1

    for i in range(int(last / 2), first - 1, -1):
        yield siftDown(arr, i, last)

    for i in range(last, first, -1):
        yield arr.swap(i, first)
        yield siftDown(arr, first, i - 1)

This is the code I'd like to run. However I'm finding it impossible, in this context, to properly identify a recursive call versus a regular function call. Now, I could write the "yield siftDown" lines in Heapsort as:

for upd in yield siftDown(arr, i, last): yield upd

Which fixes the problem of determining what is or isn't recursive. However it makes the code a little more ugly and hard to read, something that defeats one of my original purposes in all of this.

So, I have been trying to get my Java object (the arr object that the sort functions are using) to be able to track the name of the Jython function that called the swap() or change() methods. Then I could, in my process() method/function be able to determine what is or isn't a recursive call by simply comparing the function names between recursive calls to process(). That would make the syntax for both recursive and non-recursive function calls appear to be the same in my sorting algorithm code, and make the system be smart enough to tell the difference.

but I'm stuck at this point. So... any help would be appreciated.

"I'm not responcabel fer my computer's spleling errnors" - Xlorep DarkHelm
Website: http://darkhelm.org

Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
Jython-users mailing list

Jim Baker

"I'm not responcabel fer my computer's spleling errnors" - Xlorep DarkHelm
Website: http://darkhelm.org
Sent from Santa Maria, California, United States