findAllMatches with Python Tags

Another quick query - can I get findAllMatches to look for python tags?

Yes. From the NodePath documentation:

// There are also a number of NodePath methods for finding nodes deep
// within the tree by name or by type.  These take a path string,
// which at its simplest consists of a series of node names separated
// by slashes, like a directory pathname.
// Each component of the path string may optionally consist of one of
// the following special names, instead of a node name:
//   *          -- matches exactly one node, with any name.
//   **         -- matches any sequence of zero or more nodes.
//   +typename  -- matches any node that is or derives from the given type.
//   -typename  -- matches any node that is the given type exactly.
//   =tag       -- matches any node that has the indicated tag.
//   =tag=value -- matches any node whose tag matches the indicated value.
// Furthermore, a node name may itself contain standard filename
// globbing characters, like *, ?, and [a-z], that will be accepted as
// a partial match.  (In fact, the '*' special name may be seen as
// just a special case of this.)  The globbing characters may not be
// used with the typename matches or with tag matches, but they may
// be used to match a tag's value in the =tag=value syntax.
// The special characters "@@", appearing at the beginning of a node
// name, indicate a stashed node.  Normally, stashed nodes are not
// returned by a find (but see the special flags, below), but a
// stashed node may be found if it is explicitly named with its
// leading @@ characters.  By extension, "@@*" may be used to identify
// any stashed node.
// Examples:
// "room//graph" will look for a node named "graph", which is a child
// of an unnamed node, which is a child of a node named "room", which
// is a child of the starting path.
// "**/red*" will look for any node anywhere in the tree (below the
// starting path) with a name that begins with "red".
// "**/+PartBundleNode/**/head" will look for a node named "head",
// somewhere below a PartBundleNode anywhere in the tree.
// The search is always potentially ambiguous, even if the special
// wildcard operators are not used, because there may be multiple
// nodes in the tree with the same name.  In general, in the case of
// an ambiguity, the shortest path is preferred; when a method (such
// as extend_by) must choose only only one of several possible paths,
// it will choose the shortest available; on the other hand, when a
// method (such as find_all_matches) is to return all of the matching
// paths, it will sort them so that the shortest paths appear first in
// the output.
// Special flags.  The entire string may optionally be followed by the
// ";" character, followed by one or more of the following special
// control flags, with no intervening spaces or punctuation:
//    -h    Do not return hidden nodes.
//    +h    Do return hidden nodes.
//    -s    Do not return stashed nodes unless explicitly referenced with @@.
//    +s    Return stashed nodes even without any explicit @@ characters.
//    -i    Node name comparisons are not case insensitive: case must match
//          exactly.
//    +i    Node name comparisons are case insensitive: case is not important.
//          This affects matches against the node name only; node type
//          and tag strings are always case sensitive.
// The default flags are +h-s-i.

Thanks David. So searching with “tag=” should return NodePaths with both tags and python tags using that tag name?

I was about to reply yes, it certainly does; but then I took a look at the code and discovered to my surprise that it only checks the standard tags, not the Python tags. Oops.

So, with the current code as it is, the only way to search for a Python tag would be to write a recursive function to do it yourself.