Hi, On Tue, 2010-08-17 at 09:14 -0400, Fred Drake wrote:
On Tue, Aug 17, 2010 at 9:03 AM, Antoine Pitrou <solipsis@pitrou.net> wrote:
IMO, fnmatch is the right place for such an enhancement. (and, as the doc states, “glob uses fnmatch() to match pathname segments”).
This is a good reason not to push the implementation down into glob, actually: the expansion may cross segment boundaries:
for{bar/turtle,car/monkey}_test.*
should expand to the two patterns:
foobar/turtle_test.* foocar/monkey_test.*
Then I have the correct behavior with the attached patch against the glob module. :) (I still have to write some proper unit tests for it, this is only a working proof of concept) Note that I wrote this patch against the Python trunk, and tested it on Python 2.5 (Windows XP) and Python 2.6 (Fedora 13). (I didn't have time to actually build the Python trunk and run the unit tests yet) To test it, I use the following dictionary where keys are the patterns I want to try and values are the corresponding expected output. d = { 'foo.txt': 'foo.txt', 'foo-{bar,baz}.txt': 'foo-bar.txt foo-baz.txt', 'foo-{bar,baz-{toto,plouf}}.txt': 'foo-bar.txt foo-baz-plouf.txt foo-baz-toto.txt', 'foo-{bar,baz}-{toto,plouf}.txt': 'foo-bar-plouf.txt foo-bar-toto.txt foo-baz-plouf.txt foo-baz-toto.txt', 'foo-{}.txt': 'foo-{}.txt', 'foo-{bar}.txt': 'foo-{bar}.txt', 'foo-{bar.txt': 'foo-{bar.txt', 'foo-bar}.txt': 'foo-bar}.txt', 'foo-{bar{baz,plouf}.txt': 'foo-{barbaz.txt foo-{barplouf.txt', 'foo-{bar,baz}-{toto}.txt': 'foo-bar-{toto}.txt foo-baz-{toto}.txt', 'foo-{bar,baz}-{toto.txt': 'foo-bar-{toto.txt foo-baz-{toto.txt', 'foo-{bar,baz}-toto}.txt': 'foo-bar-toto}.txt foo-baz-toto}.txt', 'tmp/foo.txt': 'tmp/foo.txt', 'tmp/foo-{bar,baz}.txt': 'tmp/foo-bar.txt tmp/foo-baz.txt', 'tmp/foo-{bar,baz-{toto,plouf}}.txt': 'tmp/foo-bar.txt tmp/foo-baz-plouf.txt tmp/foo-baz-toto.txt', 'tmp/foo-{bar,baz}-{toto,plouf}.txt': 'tmp/foo-bar-plouf.txt tmp/foo-bar-toto.txt tmp/foo-baz-plouf.txt tmp/foo-baz-toto.txt', 'tmp/foo-{}.txt': 'tmp/foo-{}.txt', 'tmp/foo-{bar}.txt': 'tmp/foo-{bar}.txt', 'tmp/foo-{bar.txt': 'tmp/foo-{bar.txt', 'tmp/foo-bar}.txt': 'tmp/foo-bar}.txt', 'tmp/foo-{bar{baz,plouf}.txt': 'tmp/foo-{barbaz.txt tmp/foo-{barplouf.txt', 'tmp/foo-{bar,baz}-{toto}.txt': 'tmp/foo-bar-{toto}.txt tmp/foo-baz-{toto}.txt', 'tmp/foo-{bar,baz}-{toto.txt': 'tmp/foo-bar-{toto.txt tmp/foo-baz-{toto.txt', 'tmp/foo-{bar,baz}-toto}.txt': 'tmp/foo-bar-toto}.txt tmp/foo-baz-toto}.txt', '{tmp,tmp2}/foo.txt': 'tmp2/foo.txt tmp/foo.txt', '{tmp,tmp2}/foo-{bar,baz}.txt': 'tmp2/foo-bar.txt tmp2/foo-baz.txt tmp/foo-bar.txt tmp/foo-baz.txt', '{tmp,tmp2}/foo-{bar,baz-{toto,plouf}}.txt': 'tmp2/foo-bar.txt tmp2/foo-baz-plouf.txt tmp2/foo-baz-toto.txt tmp/foo-bar.txt tmp/foo-baz-plouf.txt tmp/foo-baz-toto.txt', '{tmp,tmp2}/foo-{bar,baz}-{toto,plouf}.txt': 'tmp2/foo-bar-plouf.txt tmp2/foo-bar-toto.txt tmp2/foo-baz-plouf.txt tmp2/foo-baz-toto.txt tmp/foo-bar-plouf.txt tmp/foo-bar-toto.txt tmp/foo-baz-plouf.txt tmp/foo-baz-toto.txt', '{tmp,tmp2}/foo-{}.txt': 'tmp2/foo-{}.txt tmp/foo-{}.txt', '{tmp,tmp2}/foo-{bar}.txt': 'tmp2/foo-{bar}.txt tmp/foo-{bar}.txt', '{tmp,tmp2}/foo-{bar.txt': 'tmp2/foo-{bar.txt tmp/foo-{bar.txt', '{tmp,tmp2}/foo-bar}.txt': 'tmp2/foo-bar}.txt tmp/foo-bar}.txt', '{tmp,tmp2}/foo-{bar{baz,plouf}.txt': 'tmp2/foo-{barbaz.txt tmp2/foo-{barplouf.txt tmp/foo-{barbaz.txt tmp/foo-{barplouf.txt', '{tmp,tmp2}/foo-{bar,baz}-{toto}.txt': 'tmp2/foo-bar-{toto}.txt tmp2/foo-baz-{toto}.txt tmp/foo-bar-{toto}.txt tmp/foo-baz-{toto}.txt', '{tmp,tmp2}/foo-{bar,baz}-{toto.txt': 'tmp2/foo-bar-{toto.txt tmp2/foo-baz-{toto.txt tmp/foo-bar-{toto.txt tmp/foo-baz-{toto.txt', '{tmp,tmp2}/foo-{bar,baz}-toto}.txt': 'tmp2/foo-bar-toto}.txt tmp2/foo-baz-toto}.txt tmp/foo-bar-toto}.txt tmp/foo-baz-toto}.txt', 'tm{p/foo,p2/foo}.txt': 'tmp2/foo.txt tmp/foo.txt', 'foo-bar*{txt,xml}': 'foo-bar-plouf.txt foo-bar-toto.txt foo-bar-toto}.txt foo-bar-{toto.txt foo-bar-{toto}.txt foo-bar.txt foo-bar}.txt', 'foo?bar.{txt,xml}': 'foo-bar.txt', } (note that those actually correspond to files I have in the current folder so that they match) Anyone can think about other interesting patterns involving braces? Also, if the consensus is that glob is not the proper place, it would be pretty straight-forward to do it in a module that would expand the braces before calling glob on the resulting patterns. -- Mathieu