{"id":32136911,"url":"https://github.com/cpburnz/python-pathspec","last_synced_at":"2026-03-12T21:24:31.604Z","repository":{"id":12061955,"uuid":"14648551","full_name":"cpburnz/python-pathspec","owner":"cpburnz","description":"Utility library for gitignore style pattern matching of file paths.","archived":false,"fork":false,"pushed_at":"2025-09-21T03:47:42.000Z","size":320,"stargazers_count":199,"open_issues_count":9,"forks_count":46,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-10-20T04:43:23.143Z","etag":null,"topics":["gitignore-patterns","python","wildmatch"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cpburnz.png","metadata":{"files":{"readme":"README-dist.rst","changelog":"CHANGES.rst","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2013-11-23T19:06:13.000Z","updated_at":"2025-10-16T20:07:53.000Z","dependencies_parsed_at":"2024-06-18T13:58:07.179Z","dependency_job_id":"328bb061-d7e1-417b-b22b-97ca8eee54f8","html_url":"https://github.com/cpburnz/python-pathspec","commit_stats":{"total_commits":213,"total_committers":26,"mean_commits":8.192307692307692,"dds":"0.45070422535211263","last_synced_commit":"933dd7da982551300a584c98570993402a56bc27"},"previous_names":["cpburnz/python-path-specification"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/cpburnz/python-pathspec","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cpburnz%2Fpython-pathspec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cpburnz%2Fpython-pathspec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cpburnz%2Fpython-pathspec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cpburnz%2Fpython-pathspec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cpburnz","download_url":"https://codeload.github.com/cpburnz/python-pathspec/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cpburnz%2Fpython-pathspec/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280073292,"owners_count":26267110,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-20T02:00:06.978Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gitignore-patterns","python","wildmatch"],"created_at":"2025-10-21T04:50:21.166Z","updated_at":"2026-03-12T21:24:31.596Z","avatar_url":"https://github.com/cpburnz.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\nPathSpec\n========\n\n*pathspec* is a utility library for pattern matching of file paths. So far this\nonly includes Git's `gitignore`_ pattern matching.\n\n.. _`gitignore`: http://git-scm.com/docs/gitignore\n\n\nTutorial\n--------\n\nSay you have a \"Projects\" directory and you want to back it up, but only\ncertain files, and ignore others depending on certain conditions::\n\n\t\u003e\u003e\u003e from pathspec import PathSpec\n\t\u003e\u003e\u003e # The gitignore-style patterns for files to select, but we're including\n\t\u003e\u003e\u003e # instead of ignoring.\n\t\u003e\u003e\u003e spec_text = \"\"\"\n\t...\n\t... # This is a comment because the line begins with a hash: \"#\"\n\t...\n\t... # Include several project directories (and all descendants) relative to\n\t... # the current directory. To reference only a directory you must end with a\n\t... # slash: \"/\"\n\t... /project-a/\n\t... /project-b/\n\t... /project-c/\n\t...\n\t... # Patterns can be negated by prefixing with exclamation mark: \"!\"\n\t...\n\t... # Ignore temporary files beginning or ending with \"~\" and ending with\n\t... # \".swp\".\n\t... !~*\n\t... !*~\n\t... !*.swp\n\t...\n\t... # These are python projects so ignore compiled python files from\n\t... # testing.\n\t... !*.pyc\n\t...\n\t... # Ignore the build directories but only directly under the project\n\t... # directories.\n\t... !/*/build/\n\t...\n\t... \"\"\"\n\nThe ``PathSpec`` class provides an abstraction around pattern implementations,\nand we want to compile our patterns as \"gitignore\" patterns. You could call it a\nwrapper for a list of compiled patterns::\n\n\t\u003e\u003e\u003e spec = PathSpec.from_lines('gitignore', spec_text.splitlines())\n\nIf we wanted to manually compile the patterns, we can use the ``GitIgnoreBasicPattern``\nclass directly. It is used in the background for \"gitignore\" which internally\nconverts patterns to regular expressions::\n\n\t\u003e\u003e\u003e from pathspec.patterns.gitignore.basic import GitIgnoreBasicPattern\n\t\u003e\u003e\u003e patterns = map(GitIgnoreBasicPattern, spec_text.splitlines())\n\t\u003e\u003e\u003e spec = PathSpec(patterns)\n\n``PathSpec.from_lines()`` is a class method which simplifies that.\n\nIf you want to load the patterns from file, you can pass the file object\ndirectly as well::\n\n\t\u003e\u003e\u003e with open('patterns.list', 'r') as fh:\n\t\u003e\u003e\u003e     spec = PathSpec.from_lines('gitignore', fh)\n\nYou can perform matching on a whole directory tree with::\n\n\t\u003e\u003e\u003e matches = set(spec.match_tree_files('path/to/directory'))\n\nOr you can perform matching on a specific set of file paths with::\n\n\t\u003e\u003e\u003e matches = set(spec.match_files(file_paths))\n\nOr check to see if an individual file matches::\n\n\t\u003e\u003e\u003e is_matched = spec.match_file(file_path)\n\nThere's actually two implementations of \"gitignore\". The basic implementation is\nused by ``PathSpec`` and follows patterns as documented by `gitignore`_.\nHowever, Git's behavior differs from the documented patterns. There's some\nedge-cases, and in particular, Git allows including files from excluded\ndirectories which appears to contradict the documentation. ``GitIgnoreSpec``\nhandles these cases to more closely replicate Git's behavior::\n\n\t\u003e\u003e\u003e from pathspec import GitIgnoreSpec\n\t\u003e\u003e\u003e spec = GitIgnoreSpec.from_lines(spec_text.splitlines())\n\nYou do not specify the style of pattern for ``GitIgnoreSpec`` because it should\nalways use ``GitIgnoreSpecPattern`` internally.\n\n\nPerformance\n-----------\n\nRunning lots of regular expression matches against thousands of files in Python\nis slow. Alternate regular expression backends can be used to improve\nperformance. ``PathSpec`` and ``GitIgnoreSpec`` both accept a ``backend``\nparameter to control the backend. The default is \"best\" to automatically choose\nthe best available backend. There are currently 3 backends.\n\nThe \"simple\" backend is the default and it simply uses Python's ``re.Pattern``\nobjects that are normally created. This can be the fastest when there's only 1\nor 2 patterns.\n\nThe \"hyperscan\" backend uses the `hyperscan`_ library. Hyperscan tends to be at\nleast 2 times faster than \"simple\", and generally slower than \"re2\". This can be\nfaster than \"re2\" under the right conditions with pattern counts of 1-25.\n\nThe \"re2\" backend uses the `google-re2`_ library (not to be confused with the\n*re2* library on PyPI which is unrelated and abandoned). Google's re2 tends to\nbe significantly faster than \"simple\", and 3 times faster than \"hyperscan\" at\nhigh pattern counts.\n\nSee `benchmarks_backends.md`_ for comparisons between native Python regular\nexpressions and the optional backends.\n\n\n.. _`benchmarks_backends.md`: https://github.com/cpburnz/python-pathspec/blob/master/benchmarks_backends.md\n.. _`google-re2`: https://pypi.org/project/google-re2/\n.. _`hyperscan`: https://pypi.org/project/hyperscan/\n\n\nFAQ\n---\n\n\n1. How do I ignore files like *.gitignore*?\n+++++++++++++++++++++++++++++++++++++++++++\n\n``GitIgnoreSpec`` (and ``PathSpec``) positively match files by default. To find\nthe files to keep, and exclude files like *.gitignore*, you need to set\n``negate=True`` to flip the results::\n\n\t\u003e\u003e\u003e from pathspec import GitIgnoreSpec\n\t\u003e\u003e\u003e spec = GitIgnoreSpec.from_lines([...])\n\t\u003e\u003e\u003e keep_files = set(spec.match_tree_files('path/to/directory', negate=True))\n\t\u003e\u003e\u003e ignore_files = set(spec.match_tree_files('path/to/directory'))\n\n\nLicense\n-------\n\n*pathspec* is licensed under the `Mozilla Public License Version 2.0`_. See\n`LICENSE`_ or the `FAQ`_ for more information.\n\nIn summary, you may use *pathspec* with any closed or open source project\nwithout affecting the license of the larger work so long as you:\n\n- give credit where credit is due,\n\n- and release any custom changes made to *pathspec*.\n\n.. _`Mozilla Public License Version 2.0`: http://www.mozilla.org/MPL/2.0\n.. _`LICENSE`: LICENSE\n.. _`FAQ`: http://www.mozilla.org/MPL/2.0/FAQ.html\n\n\nSource\n------\n\nThe source code for *pathspec* is available from the GitHub repo\n`cpburnz/python-pathspec`_.\n\n.. _`cpburnz/python-pathspec`: https://github.com/cpburnz/python-pathspec\n\n\nInstallation\n------------\n\n*pathspec* is available for install through `PyPI`_::\n\n\tpip install pathspec\n\n*pathspec* can also be built from source. The following packages will be\nrequired:\n\n- `build`_ (\u003e=0.6.0)\n\n*pathspec* can then be built and installed with::\n\n\tpython -m build\n\tpip install dist/pathspec-*-py3-none-any.whl\n\nThe following optional dependencies can be installed:\n\n- `google-re2`_: Enables optional \"re2\" backend.\n- `hyperscan`_: Enables optional \"hyperscan\" backend.\n- `typing-extensions`_: Improves some type hints.\n\n.. _`PyPI`: http://pypi.python.org/pypi/pathspec\n.. _`build`: https://pypi.org/project/build/\n.. _`typing-extensions`: https://pypi.org/project/typing-extensions/\n\n\nDocumentation\n-------------\n\nDocumentation for *pathspec* is available on `Read the Docs`_.\n\nThe full change history can be found in `CHANGES.rst`_ and `Change History`_.\n\nAn upgrade guide is available in `UPGRADING.rst`_ and `Upgrade Guide`_.\n\n.. _`CHANGES.rst`: https://github.com/cpburnz/python-pathspec/blob/master/CHANGES.rst\n.. _`Change History`: https://python-path-specification.readthedocs.io/en/stable/changes.html\n.. _`Read the Docs`: https://python-path-specification.readthedocs.io\n.. _`UPGRADING.rst`: https://github.com/cpburnz/python-pathspec/blob/master/UPGRADING.rst\n.. _`Upgrade Guide`: https://python-path-specification.readthedocs.io/en/stable/upgrading.html\n\n\nOther Languages\n---------------\n\nThe related project `pathspec-ruby`_ (by *highb*) provides a similar library as\na `Ruby gem`_.\n\n.. _`pathspec-ruby`: https://github.com/highb/pathspec-ruby\n.. _`Ruby gem`: https://rubygems.org/gems/pathspec\n\n\nChange History\n==============\n\n\n1.0.4 (2026-01-26)\n------------------\n\n- `Issue #103`_: Using re2 fails if pyre2 is also installed.\n\n.. _`Issue #103`: https://github.com/cpburnz/python-pathspec/issues/103\n\n\n1.0.3 (2026-01-09)\n------------------\n\nBug fixes:\n\n- `Issue #101`_: pyright strict errors with pathspec \u003e= 1.0.0.\n- `Issue #102`_: No module named 'tomllib'.\n\n\n.. _`Issue #101`: https://github.com/cpburnz/python-pathspec/issues/101\n.. _`Issue #102`: https://github.com/cpburnz/python-pathspec/issues/102\n\n\n1.0.2 (2026-01-07)\n------------------\n\nBug fixes:\n\n- Type hint `collections.abc.Callable` does not properly replace `typing.Callable` until Python 3.9.2.\n\n\n1.0.1 (2026-01-06)\n------------------\n\nBug fixes:\n\n- `Issue #100`_: ValueError(f\"{patterns=!r} cannot be empty.\") when using black.\n\n\n.. _`Issue #100`: https://github.com/cpburnz/python-pathspec/issues/100\n\n\n1.0.0 (2026-01-05)\n------------------\n\nMajor changes:\n\n- `Issue #91`_: Dropped support of EoL Python 3.8.\n- Added concept of backends to allow for faster regular expression matching. The backend can be controlled using the `backend` argument to `PathSpec()`, `PathSpec.from_lines()`, `GitIgnoreSpec()`, and `GitIgnoreSpec.from_lines()`.\n- Renamed \"gitwildmatch\" pattern back to \"gitignore\". The \"gitignore\" pattern behaves slightly differently when used with `PathSpec` (*gitignore* as documented) than with `GitIgnoreSpec` (replicates *Git*'s edge cases).\n\nAPI changes:\n\n- Breaking: protected method `pathspec.pathspec.PathSpec._match_file()` (with a leading underscore) has been removed and replaced by backends. This does not affect normal usage of `PathSpec` or `GitIgnoreSpec`. Only custom subclasses will be affected. If this breaks your usage, let me know by `opening an issue \u003chttps://github.com/cpburnz/python-pathspec/issues\u003e`_.\n- Deprecated: \"gitwildmatch\" is now an alias for \"gitignore\".\n- Deprecated: `pathspec.patterns.GitWildMatchPattern` is now an alias for `pathspec.patterns.gitignore.spec.GitIgnoreSpecPattern`.\n- Deprecated: `pathspec.patterns.gitwildmatch` module has been replaced by the `pathspec.patterns.gitignore` package.\n- Deprecated: `pathspec.patterns.gitwildmatch.GitWildMatchPattern` is now an alias for `pathspec.patterns.gitignore.spec.GitIgnoreSpecPattern`.\n- Deprecated: `pathspec.patterns.gitwildmatch.GitWildMatchPatternError` is now an alias for `pathspec.patterns.gitignore.GitIgnorePatternError`.\n- Removed: `pathspec.patterns.gitwildmatch.GitIgnorePattern` has been deprecated since v0.4 (2016-07-15).\n- Signature of method `pathspec.pattern.RegexPattern.match_file()` has been changed from `def match_file(self, file: str) -\u003e RegexMatchResult | None` to `def match_file(self, file: AnyStr) -\u003e RegexMatchResult | None` to reflect usage.\n- Signature of class method `pathspec.pattern.RegexPattern.pattern_to_regex()` has been changed from `def pattern_to_regex(cls, pattern: str) -\u003e tuple[str, bool]` to `def pattern_to_regex(cls, pattern: AnyStr) -\u003e tuple[AnyStr | None, bool | None]` to reflect usage and documentation.\n\nNew features:\n\n- Added optional \"hyperscan\" backend using `hyperscan`_ library. It will automatically be used when installed. This dependency can be installed with ``pip install 'pathspec[hyperscan]'``.\n- Added optional \"re2\" backend using the `google-re2`_ library. It will automatically be used when installed. This dependency can be installed with ``pip install 'pathspec[re2]'``.\n- Added optional dependency on `typing-extensions`_ library to improve some type hints.\n\nBug fixes:\n\n- `Issue #93`_: Do not remove leading spaces.\n- `Issue #95`_: Matching for files inside folder does not seem to behave like .gitignore's.\n- `Issue #98`_: UnboundLocalError in RegexPattern when initialized with `pattern=None`.\n- Type hint on return value of `pathspec.pattern.RegexPattern.match_file()` to match documentation.\n\nImprovements:\n\n- Mark Python 3.13 and 3.14 as supported.\n- No-op patterns are now filtered out when matching files, slightly improving performance.\n- Fix performance regression in `iter_tree_files()` from v0.10.\n\n\n.. _`Issue #38`: https://github.com/cpburnz/python-pathspec/issues/38\n.. _`Issue #91`: https://github.com/cpburnz/python-pathspec/issues/91\n.. _`Issue #93`: https://github.com/cpburnz/python-pathspec/issues/93\n.. _`Issue #95`: https://github.com/cpburnz/python-pathspec/issues/95\n.. _`Issue #98`: https://github.com/cpburnz/python-pathspec/issues/98\n.. _`google-re2`: https://pypi.org/project/google-re2/\n.. _`hyperscan`: https://pypi.org/project/hyperscan/\n.. _`typing-extensions`: https://pypi.org/project/typing-extensions/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcpburnz%2Fpython-pathspec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcpburnz%2Fpython-pathspec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcpburnz%2Fpython-pathspec/lists"}