GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — '*' matches entire path in fnmatch · Issue #72904 · python/cpython

'*' matches entire path in fnmatch #72904

New issue
Copy link
New issue
Copy link
Closed
Closed
'*' matches entire path in fnmatch#72904
Copy link
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancementA feature request or enhancement

Description

decibel
mannequin
opened on Nov 16, 2016
Issue body actions
BPO 28718
Nosy @serhiy-storchaka, @MojoVampire, @decibel, @Hooloovoo, @tovrstra

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = None
created_at = <Date 2016-11-16.20:12:07.121>
labels = ['library']
title = "'*' matches entire path in fnmatch"
updated_at = <Date 2019-03-31.12:59:09.371>
user = 'https://github.com/decibel'

bugs.python.org fields:

activity = <Date 2019-03-31.12:59:09.371>
actor = 'Toon Verstraelen'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Library (Lib)']
creation = <Date 2016-11-16.20:12:07.121>
creator = 'Jim Nasby'
dependencies = []
files = []
hgrepos = []
issue_num = 28718
keywords = []
message_count = 8.0
messages = ['280985', '281017', '281018', '288608', '290624', '307867', '339054', '339256']
nosy_count = 6.0
nosy_names = ['serhiy.storchaka', 'josh.r', 'Jim Nasby', 'Alberto Galera', 'aaron-whitehouse', 'Toon Verstraelen']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = None
url = 'https://bugs.python.org/issue28718'
versions = []

Linked PRs

  • GH-72904: Add glob.translate() function #106703
  • GH-72904: Simplify implementation of fnmatch.translate() #109879

Activity

Next
  1. decibel commented on Nov 16, 2016

    @decibel
    decibelmannequin
    on Nov 16, 2016
    MannequinAuthor
    More actions

    A '*' in fnmatch.translate is converted into '.*', which will greedily match directory separators. This doesn't match shell behavior, which is that * will only match file names:

    decibel@decina:[14:07]~$ls \~/tmp/*/1|head
    ls: /Users/decibel/tmp/*/1: No such file or directory
    decibel@decina:[14:07]~$ls \~/tmp/d*/base/1|head
    112
    

    From a posix standpoint, this would easily be fixed by using '[^/]*' instead of '.*'. I'm not sure how to make this work cross-platform though.

    It's worth noting that some programs (rsync, git) support **, which would correctly translate to '.*'.

  2. decibel
    added
    stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
    on Nov 16, 2016
  3. MojoVampire commented on Nov 17, 2016

    @MojoVampire
    MojoVampiremannequin
    on Nov 17, 2016
    Mannequin
    More actions

    Presumably something like:

    r'(?:' + r'|'.join({re.escape(os.path.sep), re.escape(os.path.altsep)}) + r')'

    would cover it completely. I switched to using non-capturing groups over a character class both to deal with the fact that escaping doesn't work the same way for character classes and to cover the possibility (no idea here) that some terrible OS might have a multicharacter path separator.

  4. MojoVampire commented on Nov 17, 2016

    @MojoVampire
    MojoVampiremannequin
    on Nov 17, 2016
    Mannequin
    More actions

    Oops, altsep is None, not the empty string when there is only one separator. And I didn't handle inverting the match. Sigh. You get the idea.

  5. Hooloovoo commented on Feb 26, 2017

    @Hooloovoo
    Hooloovoomannequin
    on Feb 26, 2017
    Mannequin
    More actions

    Note that somebody has forked the standard library to implement this:
    https://github.com/kianxineki/python-wildcard
    This shows that the actual changes would be pretty small (though pywildcard is based on 2.x code and does not handle the cross-platform slashes you have been discussing).

    It is also worth noting that the glob standard library:
    https://docs.python.org/3.7/library/glob.html
    implements a "recursive" option that has similar behaviour (* does not span path separators whereas ** does) and essentially builds this on top of fnmatch for the actual filename matching.

    I do not think we can change the default behaviour of fnmatch at this point, but I would like to see this behaviour triggered by an optional argument to the various functions, e.g.:
    fnmatch.fnmatch(filename, pattern, glob_asterisks=False)
    fnmatch.fnmatchcase(filename, pattern, glob_asterisks=False)
    fnmatch.filter(names, pattern, glob_asterisks=False)
    fnmatch.translate(pattern, glob_asterisks=False)

    In each case, if glob_asterisks (or whatever other name we came up with) is true, the behaviour would match the pywildcard behaviour, i.e.:
    ** matches everything
    * matches in one path level

    I look after the glob matching code in duplicity and would like to start using the standard library to do filename matching for us, but we need the above behaviour. I am happy to do the patching if there is a realistic chance of it being accepted.

  6. Hooloovoo
    changed the title [-]'*' matches entire path in fnmatch.translate[/-] [+]'*' matches entire path in fnmatch[/+] on Feb 26, 2017
  7. Hooloovoo commented on Mar 27, 2017

    @Hooloovoo
    Hooloovoomannequin
    on Mar 27, 2017
    Mannequin
    More actions

    Posted to the [Python-ideas] mailing list, as it is proposing a change to a standard library:
    https://mail.python.org/pipermail/python-ideas/2017-February/044880.html

    Nobody has responded so far, however. I take this as at least no vehement objection to the idea.

  8. AlbertoGalera commented on Dec 8, 2017

    @AlbertoGalera
    AlbertoGaleramannequin
    on Dec 8, 2017
    Mannequin
    More actions

    I see that they have commented on the lib that I made a few years ago (python-wildcard).

    The reason for the creation of that little fork started in this issue:

    https://bugs.python.org/issue25734

  9. tovrstra commented on Mar 28, 2019

    @tovrstra
    tovrstramannequin
    on Mar 28, 2019
    Mannequin
    More actions

    For consistency with the corresponding feature in the glob function since Python 3.5, I would suggest to add an extra optional argument 'recursive' instead of 'glob_asterisks'. With the default recursive=False, one gets the old behavior, with recursive=True, it can handle the '**' and '*' as in pywildcard.

    I realize that with recursive=False, the behavior is not exactly consistent with glob, but I'd still prefer the same name for the optional argument. It is the common terminology for this type of feature. See https://en.wikipedia.org/wiki/Matching_wildcards

  10. tovrstra commented on Mar 31, 2019

    @tovrstra
    tovrstramannequin
    on Mar 31, 2019
    Mannequin
    More actions

    Just for reference, here are a few more implementations of the same idea, next to pywildcard, sometimes combined with other useful features:

    • https://github.com/LawfulHacker/fnmatch2
    • https://github.com/demurgos/py-pathmatch
    • https://github.com/vidartf/globmatch
    • https://github.com/facelessuser/wcmatch

    The last one is rather active, with regular releases, last one on March 24, 2019.

    Reacted by Wim Jeantine-Glenn
  11. ezio-melotti
    transferred this issue fromon Apr 10, 2022
  12. serhiy-storchaka
    added this to Fnmatch and glob issueson May 19, 2022
  13. barneygale commented on Mar 15, 2023

    @barneygale
    barneygale
    on Mar 15, 2023
    Contributor
    More actions

    I have an implementation of this for pathlib:

    • GH-73435: Implement recursive wildcards in pathlib.PurePath.match() #101398

    It exploits a simple trick: swapping path separators and newlines, and then matching without setting re.DOTALL. This causes * (and other wildcards) to not match directory separators.

    If folks thought it was a good idea, we could instead put the implementation in an fnmatch.globmatch() or glob.match() function.

  14. barneygale commented on Jul 2, 2023

    @barneygale
    barneygale
    on Jul 2, 2023
    Contributor
    More actions

    Some other differences between fnmatch and glob:

    • **/ has a special meaning in glob.glob(). You might think it means "any number of characters, followed by one slash". In fact it means "any number of characters, as long as we terminate after a slash". Importantly, this means it can match nothing at all, and so a pattern like /etc/**/**/**/hosts will match /etc/hosts.
    • * as a standalone path segment also has a special meaning. You might think it means "any number of any non-slash characters". In fact it means "at least one non-slash character", i.e. it always consumes precisely one path component.
  15. barneygale
    added a commit that references this issue on Jul 12, 2023

    pythonGH-72904: Add optional *seps* argument to `fnmatch.translate()`

    bbfd404
  16. 3 remaining items

  17. barneygale
    added a commit that references this issue on Jul 19, 2023

    Merge branch 'main' into pythongh-72904-fnmatch-seps

    fbcf4e3
  18. barneygale commented on Aug 13, 2023

    @barneygale
    barneygale
    on Aug 13, 2023
    Contributor
    More actions

    I've posted about this on discuss.python.org: https://discuss.python.org/t/add-glob-translate-convert-path-with-shell-wildcards-to-regular-expression/31549

  19. barneygale
    added a commit that references this issue on Sep 23, 2023

    Merge branch 'main' into pythongh-72904-fnmatch-seps

    dd2d401
  20. wimglenn commented on Sep 25, 2023

    @wimglenn
    wimglenn
    on Sep 25, 2023
    Contributor
    More actions

    Adding to the helpful list from tovrstra, I can recommend pathspec.

  21. barneygale
    added 3 commits that reference this issue on Sep 26, 2023

    pythonGH-72904: Simplify implementation of `fnmatch.translate()`

    83accca

    Merge branch 'main' into pythongh-72904-fnmatch-seps

    5aae7a2

    Merge branch 'main' into pythongh-72904-fnmatch-seps

    9cb2952
  22. barneygale
    added a commit that references this issue on Oct 28, 2023

    Merge branch 'main' into pythongh-72904-fnmatch-seps

    1ad624d
  23. barneygale
    added a commit that references this issue on Nov 13, 2023

    GH-72904: Add `glob.translate()` function (#106703)

    cf67ebf
  24. barneygale commented on Nov 13, 2023

    @barneygale
    barneygale
    on Nov 13, 2023
    Contributor
    More actions

    Addressed in Python 3.13 / cf67ebf / #106703 -- we've added a new glob.translate() function that converts a glob expression into a regular expression.

    Reacted by Daniele
  25. barneygale
    closed this as completedon Nov 13, 2023
  26. github-project-automation
    moved this to Done in Fnmatch and glob issueson Nov 13, 2023
  27. aisk
    added a commit that references this issue on Feb 11, 2024

    pythonGH-72904: Add `glob.translate()` function (python#106703)

    610266f
  28. hauntsaninja commented on May 17, 2024

    @hauntsaninja
    hauntsaninja
    on May 17, 2024
    Contributor
    More actions

    @barneygale minor thing, I noticed that the pat argument is documented as pathname. Should we make the arg positional-only or rename the arg to match the documentation?

  29. Glyphack
    added a commit that references this issue on Sep 2, 2024

    pythonGH-72904: Add `glob.translate()` function (python#106703)

    ba33158
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancementA feature request or enhancement

    Projects

    • Fnmatch and glob issues
      Status
      Done
      Show more project fields

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402503 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.