Path finding algorithm using recursion in Python
What's in a name?

This code is pretty easy to follow, and I could mostly understand it on the first read through. However, we could do better. Let's take a look at possible_paths(). This function doesn't return paths - it returns neighbors. It returns all the adjacent squares. Moreover, what is path[0] and what is path[1]? Let's name these things too.

Point = collections.namedtuple('Point', 'x y')

def neighbors(maze, coor):
    adjacent = (Point(coor.x - 1, coor.y),
        Point(coor.x, coor.y-1),
        Point(coor.x, coor.y+1),
        Point(coor.x+1, coor.y)
    )

    for p in adjacent:
        if 0 &lt;= p.x &lt; len(maze[0]) and 0 &lt;= p.y &lt; len(maze):
            if maze[p.y][p.x]: # I don't understand this flipping
                yield p


Having x and y is easier to grok than path[0], which looks like a point in a path, rather than an individual coordinate of a point. You could split this up even more by putting the adjacent points in their own function:

def adjacent(coor):
    yield Point(coor.x - 1, coor.y)
    yield Point(coor.x, coor.y - 1)
    yield Point(coor.x, coor.y + 1)
    yield Point(coor.x + 1, coor.y)

def neighbors(maze, coor):
    for p in adjacent(coor):
        ...


That's nice and bite-size. This idea should get propagated through to solve() so instead of starting with paths = ... we call it next_nodes = ... (or next_neighbors or something equivalent suggesting that we're talking about single points, not paths).

Global Variables

Right now, your solver is a little hard to use. You have to call it, then separately, check some global variable to see the result. Global variables are bad for a lot of reasons that I won't get into here, but the important one here is: you want your solver to return the answer. So let's do that:

if pos == exit:
    # we made it!
    return current_path


Okay that part is easy. What do we do in the other cases? First, there's not really a special case for len(paths) == 1 if you think about it. There is a special case for 0 though. Did we hit a dead end? Let's quit. 

elif not next_nodes:
    # no path found
    return []


And for the rest, we just have to check the return of solve() every time. Note that there's no reason to copy the full list of current_path every time! That's expensive. You can just append to the end before the call to solve and pop afterwards:

else:
    for node in next_nodes:
        current_path.append(node)
        res = solve(maze, node, current_path)
        if res:
            return res
        current_path.pop()


Since current_path is what gets returned anyway, this can be simplified into just:

    for node in next_nodes:
        current_path.append(node)
        if solve(maze, node, current_path):
            return current_path:
        current_path.pop()


Now your usage is just:

&gt;&gt;&gt; print solve(maze, Point(0,0), Point(2,0), [Point(0,0)])
[Point(0,0), ...]


Default values

Be very wary of having default values that are mutable. The canonical counterexample is something like:

def foo(x = []):
    x.append(1)
    return x

&gt;&gt;&gt; foo()
[1]
&gt;&gt;&gt; foo()
[1,1]
&gt;&gt;&gt; foo()
[1,1,1]


Prefer to default to None. Then you can check it and assign it as appropriate:

def solve(maze, pos, exit, current_path = None):
    if current_path is None:
        current_path = [pos]

    next_nodes = [...]


What about other paths?

There may be more than one path. Let's return all of them. Or, rather than returning all of them, let's make this a generator. If the caller only wants one path, he can just take the first one!

def solve(maze, pos, exit, current_path = None):
    if current_path is None:
        current_path = [pos]
    if pos == exit:
        yield current_path # instead of return
    else:
        for node in neighbors(maze, pos):
            if node not in current_path:
                for result in solve(maze, node, exit, current_path + [node]):
                    yield result


A Path != Best Path

Depth-first search (what you're doing) will definitely find a path if it exists. But it won't necessary find the shortest one. Try out a few of the other path-finding algorithms. The direct corollary to DFS is Breadth-first search (which does exactly what it sounds like). And then there is a lot of room for optimization.