{"id":1040,"library":"wcmatch","title":"Wcmatch - Wildcard/Glob File Name Matcher","description":"Wcmatch is a Python library that provides enhanced `fnmatch`, `glob`, and `pathlib` functionalities, closely following Bash-like wildcard and glob matching features. It includes support for recursive globs (`**`), Zsh-style symlink traversal (`***`), brace expansion, extended glob patterns, and more. The library is actively maintained with regular releases, often adding new features and dropping support for older Python versions.","status":"active","version":"10.1","language":"python","source_language":"en","source_url":"https://github.com/facelessuser/wcmatch","tags":["glob","wildcard","filesystem","path matching","fnmatch","pathlib","bash-like"],"install":[{"cmd":"pip install wcmatch","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Requires Python 3.9 or newer","package":"python","optional":false}],"imports":[{"note":"For filesystem globbing and path matching.","symbol":"glob","correct":"from wcmatch import glob"},{"note":"For string-based pattern matching.","symbol":"fnmatch","correct":"from wcmatch import fnmatch"},{"note":"Provides enhanced `pathlib.Path` subclasses with wcmatch's glob behavior.","symbol":"pathlib","correct":"from wcmatch import pathlib"},{"note":"The `wcmatch` submodule contains the `WcMatch` class for extendable file searches.","symbol":"WcMatch","correct":"from wcmatch import wcmatch"}],"quickstart":{"code":"import os\nimport shutil\nfrom wcmatch import glob, fnmatch\n\n# Create some dummy files/directories for the example\nos.makedirs('temp_dir/nested/.hidden', exist_ok=True)\nwith open('temp_dir/file.txt', 'w') as f: f.write('hi')\nwith open('temp_dir/nested/another.log', 'w') as f: f.write('hi')\nwith open('temp_dir/nested/.hidden/secret.dat', 'w') as f: f.write('hi')\n\nprint(\"Basic recursive glob (glob.GLOBSTAR):\")\n# By default, doesn't match hidden files or symlinks\n# Output may vary based on OS and actual symlinks\nresults_globstar = glob.glob('temp_dir/**/*.txt', flags=glob.GLOBSTAR)\nprint(f\"Found: {sorted(results_globstar)}\")\n# Expected: ['temp_dir/file.txt']\n\nprint(\"\\nRecursive glob including hidden files (GLOBSTAR | DOTGLOB):\")\nresults_hidden = glob.glob('temp_dir/**/*', flags=glob.GLOBSTAR | glob.DOTGLOB)\nprint(f\"Found: {sorted(results_hidden)}\")\n# Expected: Should include 'temp_dir/.hidden/secret.dat', 'temp_dir/file.txt', 'temp_dir/nested/another.log', etc.\n\nprint(\"\\nString matching with fnmatch:\")\nmatch_str = fnmatch.fnmatch('image.jpeg', '*.jp*g')\nprint(f\"'image.jpeg' matches '*.jp*g': {match_str}\")\n# Expected: True\n\n# Clean up\nshutil.rmtree('temp_dir')","lang":"python","description":"Demonstrates basic recursive globbing, including how to match hidden files, and a simple string match using `fnmatch`. This creates a temporary directory structure for the example."},"warnings":[{"fix":"Upgrade your Python environment to 3.9 or newer.","message":"Wcmatch has progressively dropped support for older Python versions. Version 10.1 dropped Python 3.8, Version 8.5 dropped Python 3.7, and Version 8.4 dropped Python 3.6. Ensure your environment uses Python 3.9 or newer.","severity":"breaking","affected_versions":"8.4, 8.5, 10.1"},{"fix":"Review your code for usage of `glob.raw_escape` and remove it, as its functionality is no longer available.","message":"The `glob.raw_escape` function was removed in version 9.0.","severity":"breaking","affected_versions":"9.0+"},{"fix":"Choose either the `exclude` parameter or the `NEGATE` flag with `!` prefix for exclusion patterns, but not both in the same call. The `exclude` parameter offers a cleaner separation.","message":"When using `glob` or `fnmatch` for exclusion, the `exclude` parameter (introduced in v8.4) is generally preferred over using the `NEGATE` flag with `!` prefixes in patterns. Do not use both simultaneously, as this can lead to unexpected behavior.","severity":"gotcha","affected_versions":"8.4+"},{"fix":"Add `flags=glob.GLOBSTAR | glob.FOLLOW` or `flags=glob.GLOBSTARLONG` to your `glob.glob` calls if symlink traversal is desired.","message":"By default, `GLOBSTAR` (`**`) in `wcmatch.glob` does not traverse symlinks. To include symlinks in recursive globbing, you must explicitly enable the `FOLLOW` or `GLOBSTARLONG` flag (the latter provides Zsh-style `***` behavior, introduced in 10.0).","severity":"gotcha","affected_versions":"10.0+"},{"fix":"Add `flags=glob.DOTGLOB` (or `glob.GLOBSTAR | glob.DOTGLOB` for recursive hidden files) to your `glob.glob` or `pathlib` calls.","message":"Wildcard characters like `*` do not match files or directories starting with a dot (`.`) by default. To include hidden files/directories in your glob results, enable the `DOTGLOB` flag.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Be mindful of complex brace expansions. Consider using extended glob patterns like `@(a|b|c)` or adjusting the `limit` parameter in `compile` or `glob` functions (set to `0` for no limit) if necessary.","message":"Large brace expansion patterns (e.g., `a{1..100000}`) can lead to a significant number of generated patterns, potentially impacting performance or exceeding the default pattern limit (1000).","severity":"gotcha","affected_versions":"6.0+"},{"fix":"Use raw strings for patterns with backslashes (e.g., `r'C:\\Users\\**'`) or use forward slashes for cross-platform compatibility.","message":"On Windows, backslashes in patterns must be escaped (e.g., `r'path\\\\to\\file'`) to match literal backslashes, as `wcmatch` allows escaped characters. Forward slashes (`/`) are normalized and will match both forward and backslashes.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-05-12T22:56:49.432Z","next_check":"2026-06-27T00:00:00.000Z","problems":[{"fix":"Import `wcmatch.glob` instead of the standard `glob` module: `from wcmatch import glob` then `glob.glob('**/*.txt', flags=glob.GLOBSTAR)`.","cause":"The user imported Python's standard `glob` module but attempted to use `wcmatch`-specific arguments like `flags` which are only available in `wcmatch.glob`.","error":"TypeError: glob.glob() got an unexpected keyword argument 'flags'"},{"fix":"Instantiate the `Path` class and call the method on the instance: `from wcmatch.path import Path` then `Path('.').walk()`.","cause":"In recent versions of `wcmatch` (v8.0+), path-related functions like `walk` are methods of the `wcmatch.path.Path` class, not direct functions of the module itself.","error":"AttributeError: module 'wcmatch.path' has no attribute 'walk'"},{"fix":"Install the library using pip: `pip install wcmatch`.","cause":"The `wcmatch` library has not been installed in the active Python environment, or the environment where it's installed is not the one being used.","error":"ModuleNotFoundError: No module named 'wcmatch'"},{"fix":"Upgrade Python to a supported version (e.g., Python 3.9 or newer for recent `wcmatch` versions) or explicitly install an older `wcmatch` version compatible with your current Python (e.g., `pip install wcmatch==7.0.2` for Python 3.7).","cause":"The Python version being used is no longer supported by the latest `wcmatch` releases, preventing `pip` from finding a compatible package.","error":"ERROR: No matching distribution found for wcmatch"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":null,"quickstart_tag":null,"pypi_latest":"10.1","cli_name":"","install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.2,"disk_size":"18.1M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":1.2,"disk_size":"18.1M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.5,"import_time_s":0.02,"mem_mb":1.2,"disk_size":"19M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.2,"disk_size":"19M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.09,"mem_mb":1.3,"disk_size":"20.1M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.1,"mem_mb":1.3,"disk_size":"20.1M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.6,"import_time_s":0.07,"mem_mb":1.3,"disk_size":"21M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.07,"mem_mb":1.3,"disk_size":"21M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.06,"mem_mb":1.1,"disk_size":"11.9M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.07,"mem_mb":1.1,"disk_size":"11.9M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.4,"import_time_s":0.06,"mem_mb":1.1,"disk_size":"12M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.07,"mem_mb":1.1,"disk_size":"12M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.05,"mem_mb":1.2,"disk_size":"11.7M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.06,"mem_mb":1.2,"disk_size":"11.6M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.5,"import_time_s":0.05,"mem_mb":1,"disk_size":"12M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.06,"mem_mb":1,"disk_size":"12M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.2,"disk_size":"17.6M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":1.2,"disk_size":"17.6M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.7,"import_time_s":0.03,"mem_mb":1.2,"disk_size":"18M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.2,"disk_size":"18M"}]},"quickstart_checks":{"last_tested":"2026-04-24","tag":null,"tag_description":null,"results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}