Skip to content
A CLI tool to search for Python code in a path using jQuery-like selectors.
Python
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
pyq
sizzle
testfiles
.gitignore
CHANGELOG.md
LICENSE
README.md
setup.py
test_cmd.py
test_pyq.py
test_sizzle.py

README.md

pyq

A command-line tool to search for Python code using jQuery-like selectors

PyPI version

Installation

pip install pyqtool

Notice: As the tool is still under heavy development, you may see that some features are not yet available in the version distributed over PyPI. If you want to have a fresh taste, you can get it directly from source:

pip install https://github.com/caioariede/pyq/archive/master.zip -U

Please report any possible issues, we expect the master branch to be stable.

Usage

Usage: pyq3 [OPTIONS] SELECTOR [PATH]...

Options:
-l / --files       Only print filenames containing matches.
--ignore-dir TEXT  Ignore directory.
-n / --no-recurse  No descending into subdirectories.
-e / --expand      Show multiple matches in the same line.
--help             Show this message and exit.

The executable name will vary depending on the Python version: pyq2 pyq3

Available selectors

Type selectors
Name Attributes Additional notes
class class name
def def name
import import name
import name as name
from from import name
It's also possible to match the full import using
the special attribute full
assign name [, name ...] = value
call name(arg, arg, ..., kwarg=, kwarg=, ...)
attr foo.name.name
ID/Name selector
Syntax Applied to
#name class, def, assign, call, attr

Attribute selectors

Syntax Description
[name=value] Attribute name is equal to value
[name!=value] Attribute name is not equal to value
[name*=value] Attribute name contains value
[name^=value] Attribute name starts with value
[name$=value] Attribute name endswith value

Pseudo selectors

Syntax Applies to Description
:extends(selector) class Selects classes that its bases matches selector
:has(selector) all Selects everything that its body match selector
:not(selector) all Selects everything that do not match selector

Combinators

Syntax Description
parent > child Select direct child from parent
parent descendant Selects all descendant from parent

Examples

Search for classes that extends the IntegerField class:

❯ pyq3 'class:extends(#IntegerField)' django/forms
django/forms/fields.py:278 class FloatField(IntegerField):
django/forms/fields.py:315 class DecimalField(IntegerField):

Search for classes with the name FloatField:

❯ pyq3 'class[name=FloatField]' django/forms
django/forms/fields.py:278 class FloatField(IntegerField):

Search for methods under the FloatField class:

❯ pyq3 'class[name=FloatField] > def' django/forms
django/forms/fields.py:283     def to_python(self, value):
django/forms/fields.py:299     def validate(self, value):
django/forms/fields.py:308     def widget_attrs(self, widget):

Search for methods whose name starts with to under the FloatField class:

❯ pyq3 'class[name=FloatField] > def[name^=to]' django/forms
django/forms/fields.py:283     def to_python(self, value):

Search for import statements importing Counter:

❯ pyq3 'import[from=collections][name=Counter]' django/
django/apps/registry.py:5 from collections import Counter, OrderedDict, defaultdict
django/template/utils.py:3 from collections import Counter, OrderedDict
django/test/testcases.py:14 from collections import Counter
...

Search for classes without methods:

❯ pyq3 'class:not(:has(> def))' django/core
django/core/exceptions.py:8 class FieldDoesNotExist(Exception):
django/core/exceptions.py:13 class DjangoRuntimeWarning(RuntimeWarning):
django/core/exceptions.py:17 class AppRegistryNotReady(Exception):
...
You can’t perform that action at this time.