On Sun, Nov 4, 2018 at 4:29 AM Stephen J. Turnbull email@example.com wrote:
Chris Angelico writes:
On Sat, Nov 3, 2018 at 4:49 AM Stephen J. Turnbull firstname.lastname@example.org wrote:
Andre Delfino writes:
Frequently, while globbing, one needs to work with multiple extensions. I’d like to propose for fnmatch.filter to handle a tuple of patterns (while preserving the single str argument functionality, alas str.endswith),
This is one of those famous 3-line functions, though:
import fnmatch def multifilter(names, *patterns): result =  for p in patterns: result.extend(fnmatch.filter(names, p)) return result
It's a 3-line function in 5 lines, OK, but still.
And like many "hey it's this easy" demonstrations, that isn't quite identical, as a single file can match multiple patterns
Sure. I would have written it with set.union() on general principles except I forgot how to say "union", didn't feel like looking it up, and wanted to keep the def as close to 3 lines as I could without being obfuscated (see below). I wonder how many people would fall into the trap I did. (I don't consider myself a great programmer, but maybe that's all the more reason for this? Not-so-great minds think alike? :-)
A very fair point; and still supporting the notion that "it's a 3-line function" doesn't instantly silence the need. TBH, it's the moments when we AREN'T great programmers that we need the language to help us out. Why is it that we love strong rules and tight exceptions? Because they tell us when we've done something stupid, and help us to fix that bug with a minimum of fuss :)
I was really more interested in the second question, though. Why invent yet another interface when we already have one that is well-known and more powerful?
That kind of globbing might also solve the use-cases, but I'm worried about backward compatibility. Creating more glob-special characters could potentially change the meaning of globs that are already in use. I don't personally glob files with braces in their names, but someone somewhere is doing it (and I do have a bunch of files with UUIDs in their names, mainly in Wine directories); adding a feature like that might break code, or alternatively, would have to be fnmatch_with_braces(). In contrast, accepting a tuple of strings can't possibly break any working code that uses individual strings.
P.S. I can't resist. This is horrible, but:
def multifilter(names, *patterns): return list(set().union(*[fnmatch.filter(names, p) for p in patterns]))
Who even needs a function? ;-)
I do want to make one small change to it, though: instead of list() at the end of the chain, I'd use sorted(). You're throwing away the original order of file names, so it'd look tidier to return them in order, rather than in whichever order iterating over the set gives them.
Also, I am a very very bad person for suggesting an 'improvement' to a function of that nature. That is... a piece of art. Modern art, the sort where you go "This is incomprehensible therefore it is beautiful". :)