xdev.cli package

Submodules

Module contents

class xdev.cli.AvailablePackageConfig(*args, **kwargs)[source]

Bases: DataConfig

Print a table of available versions of a python package on Pypi

Refactor of ~/local/tools/supported_python_versions_pip.py to report the available versions of a python package that meet some critera

Valid options: []

Parameters:
  • *args – positional arguments for this data config

  • **kwargs – keyword arguments for this data config

default = {'package_name': <Value(None)>, 'refresh': <Value(False)>, 'request_min': <Value(None)>}
class xdev.cli.DirectoryStatsCLI(*args, **kwargs)[source]

Bases: DataConfig

Analysis for code in a repository

CommandLine

python ~/code/xdev/xdev/cli/repo_stats.py .

Valid options: []

Parameters:
  • *args – positional arguments for this data config

  • **kwargs – keyword arguments for this data config

classmethod _register_main(func)[source]
default = {'block_dnames': <Value(None)>, 'block_fnames': <Value(None)>, 'dpath': <Value('.')>, 'ignore_dotprefix': <Value(True)>, 'include_dnames': <Value(None)>, 'include_fnames': <Value(None)>, 'max_display_depth': <Value(None)>, 'max_files': <Value(None)>, 'max_walk_depth': <Value(None)>, 'parse_content': <Value(True)>, 'python': <Value(False)>, 'verbose': <Value(0)>, 'version': <Value(False)>}
main(**kwargs)

Example

>>> # xdoctest: +SKIP
>>> cmdline = 0
>>> kwargs = dict(dpath='module:watch')
>>> main(cmdline=cmdline, **kwargs)
normalize()
class xdev.cli.DirectoryWalker(dpath, block_dnames=None, block_fnames=None, include_dnames=None, include_fnames=None, max_walk_depth=None, max_files=None, parse_content=False, show_progress=True, ignore_empty_dirs=False, **kwargs)[source]

Bases: object

Configurable directory walker that can explore a directory and report information about its contents in a concise manner.

Options will impact how long this process takes based on how much data / metadata we need to parse out of the filesystem.

Parameters:
  • dpath (str | PathLike) – the path to walk

  • block_dnames (Coercable[MultiPattern]) – blocks directory names matching this pattern

  • block_fnames (Coercable[MultiPattern]) – blocks file names matching this pattern

  • include_dnames (Coercable[MultiPattern]) – if specified, excludes directories that do NOT match this pattern.

  • include_fnames (Coercable[MultiPattern]) – if specified, excludes files that do NOT match this pattern.

  • max_files (None | int) – ignore all files in directories with more than this number.

  • max_walk_depth (None | int) – how far to recurse

  • parse_content (bool) – if True, include content analysis

  • **kwargs – passed to label options

write_network_text(**kwargs)[source]
write_report(**nxtxt_kwargs)[source]
build()[source]
_inplace_filter_dnames(dnames)[source]
_inplace_filter_fnames(fnames)[source]
_walk()[source]
property file_paths
property dir_paths
_accum_stats()[source]
_update_stats()[source]
_humanize_stats(stats, node_type, reduce_prefix=False)[source]
_find_duplicate_files()[source]
_update_path_metadata()[source]
_update_labels()[source]

Update how each node will be displayed

_sort()[source]
class xdev.cli.ExtendedStubGenerator[source]

Bases: object

_hack_for_info(info)[source]
visit_func_def(o: None, is_abstract: bool = False, is_overload: bool = False) None[source]
process_decorator(o) None[source]
visit_class_def(o) None[source]
class xdev.cli.PythonVersions[source]

Bases: object

Class that contains information about different Python versions

resolve_pyversion(pyver, maximize=False)[source]
class xdev.cli.ReqPythonVersionSpec(pattern)[source]

Bases: object

For python_version specs in requirements files

Example

>>> pattern = '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*'
>>> other = '3.7.2'
>>> reqspec = ReqPythonVersionSpec(pattern)
>>> reqspec.highest_explicit()
>>> reqspec.matches('2.6')
>>> reqspec.matches('2.7')

Example

>>> self = ReqPythonVersionSpec('~=3.2')
>>> self.highest_explicit()
highest_explicit()[source]
matches(other)[source]
class xdev.cli.XdevCLI(description='', sub_clis=None, version=None)[source]

Bases: ModalCLI

The XDEV CLI

A collection of excellent developer tools for excellent developers.

class InfoCLI(*args, **kwargs)[source]

Bases: DataConfig

Info about xdev

Valid options: []

Parameters:
  • *args – positional arguments for this data config

  • **kwargs – keyword arguments for this data config

classmethod main(cmdline=False, **kwargs)[source]
default = {}
class CodeblockCLI(*args, **kwargs)[source]

Bases: DataConfig

Remove indentation from text.

Useful for writing subscripts (e.g. python -c code) in shell files without having to resort to ugly indentation.

Valid options: []

Parameters:
  • *args – positional arguments for this data config

  • **kwargs – keyword arguments for this data config

classmethod main(cmdline=False, **kwargs)[source]

Example

>>> from xdev.cli.main import *  # NOQA
>>> CodeblockCLI.main(cmdline=0, text='foobar')
default = {'text': <Value('')>}
class SedCLI(*args, **kwargs)[source]

Bases: DataConfig

Search and replace text in files

Valid options: []

Parameters:
  • *args – positional arguments for this data config

  • **kwargs – keyword arguments for this data config

classmethod main(cmdline=False, **kwargs)[source]
default = {'dirblocklist': <Value(None)>, 'dpath': <Value(None)>, 'dry': <Value('ask')>, 'exclude': <Value(None)>, 'include': <Value(None)>, 'recursive': <Value(True)>, 'regexpr': <Value('')>, 'repl': <Value('')>, 'verbose': <Value(2)>}
class FindCLI(*args, **kwargs)[source]

Bases: DataConfig

Find matching files or paths in a directory.

This is similar to the GNU find program, but written in Python. Important differences are that this program is:

  • has pattern first argument and uses the cwd by default.

  • recursive by default

  • has explicit include / exclude options

Example

xdev find “*.py”

Valid options: []

Parameters:
  • *args – positional arguments for this data config

  • **kwargs – keyword arguments for this data config

classmethod main(cmdline=False, **kwargs)[source]
default = {'dirblocklist': <Value(None)>, 'dpath': <Value(None)>, 'exclude': <Value(None)>, 'followlinks': <Value(False)>, 'include': <Value(None)>, 'pattern': <Value('')>, 'recursive': <Value(True)>, 'type': <Value('f')>}
class TreeCLI(*args, **kwargs)[source]

Bases: DataConfig

List a directory like a tree

See also

The

Example

xdev tree

Valid options: []

Parameters:
  • *args – positional arguments for this data config

  • **kwargs – keyword arguments for this data config

classmethod main(cmdline=False, **kwargs)[source]
default = {'colors': <Value(False)>, 'cwd': <Value('.')>, 'dirblocklist': <Value(None)>, 'ignore_dotprefix': <Value(True)>, 'max_depth': <Value(None)>, 'max_files': <Value(100)>}
class PintCLI(*args, **kwargs)[source]

Bases: DataConfig

Converts one type of unit to another via the pint library.

Notes:

See also

The, in-bash, something, we, megabytes., Example, -------------, xdev

Valid options: []

Parameters:
  • *args – positional arguments for this data config

  • **kwargs – keyword arguments for this data config

classmethod main(cmdline=False, **kwargs)[source]
default = {'input_expr': <Value(None)>, 'output_unit': <Value(None)>, 'precision': <Value(0)>}
class PyfileCLI(*args, **kwargs)[source]

Bases: DataConfig

Prints the path corresponding to a Python module.

This uses the ubelt.modname_to_modpath mechanism that does not require importing of your package.

Alternatives

An alternative with no dependencies is to use the one-liner:

python -c “import <modname>; print(<modname>.__file__)”

Example Usage

xdev pyfile xdev xdev pyfile numpy

# Use this feature in scripts for developement to avoid referencing # machine-specific paths. MODPATH=$(xdev pyfile ubelt) echo “MODPATH = $MODPATH”

Valid options: []

Parameters:
  • *args – positional arguments for this data config

  • **kwargs – keyword arguments for this data config

classmethod main(cmdline=False, **kwargs)[source]
default = {'modname': <Value(None)>}
class PyVersionCLI(*args, **kwargs)[source]

Bases: DataConfig

Detect and print the version of a Python module or package.

Note

Different backends may produce different results, especially for packages that are in development and were installed in development mode.

An alternative with no dependencies is to use the one-liner:

python -c “import <modname>; print(<modname>.__version__)”

xdev pyversion xdev xdev pyversion numpy

# Both the module name and the package name can be used. xdev pyversion cv2 xdev pyversion opencv-python-headless

xdev pyversion xdev –backend=import xdev pyversion xdev –backend=pkg_resources

Valid options: []

Parameters:
  • *args – positional arguments for this data config

  • **kwargs – keyword arguments for this data config

classmethod main(cmdline=False, **kwargs)[source]
default = {'backend': <Value('auto')>, 'modname': <Value(None)>}
class EditfileCLI(*args, **kwargs)[source]

Bases: DataConfig

Opens a file in your visual editor determined by the VISUAL environment variable.

If VISUAL is unspecified it attempts to default to the first known existing editor.

Example Usage

xdev edit xdev xdev edit numpy

Valid options: []

Parameters:
  • *args – positional arguments for this data config

  • **kwargs – keyword arguments for this data config

classmethod main(cmdline=False, **kwargs)[source]
default = {'target': <Value(None)>}
class FormatQuotesCLI(*args, **kwargs)[source]

Bases: DataConfig

Use single quotes for code and double quotes for docs.

This is useful for “fixing” quotations after running a code formater like black on a module.

Valid options: []

Parameters:
  • *args – positional arguments for this data config

  • **kwargs – keyword arguments for this data config

classmethod main(cmdline=False, **kwargs)[source]
default = {'diff': <Value(True)>, 'path': <Value('')>, 'recursive': <Value(True)>, 'verbose': <Value(3)>, 'write': <Value(False)>}
class FreshPyenvCLI(*args, **kwargs)[source]

Bases: DataConfig

Create a fresh environment in a docker container to test a Python package.

SeeAlso

The generic freshpyenv.sh bash script also installed with this package.

Valid options: []

Parameters:
  • *args – positional arguments for this data config

  • **kwargs – keyword arguments for this data config

classmethod main(cmdline=False, **kwargs)[source]
default = {'image': <Value('__default__')>}
class DocstrStubgenCLI(*args, **kwargs)[source]

Bases: DataConfig

Generate Typed Stubs from Docstrings (experimental)

Note

This is an experimental command and currently requires a specialized patch to mypy to work correctly.

Valid options: []

Parameters:
  • *args – positional arguments for this data config

  • **kwargs – keyword arguments for this data config

classmethod main(cmdline=False, **kwargs)[source]
default = {'module': <Value(None)>}
class AvailablePackageCLI(*args, **kwargs)[source]

Bases: DataConfig

Print a table of available versions of a python package on Pypi

Refactor of ~/local/tools/supported_python_versions_pip.py to report the available versions of a python package that meet some critera

Valid options: []

Parameters:
  • *args – positional arguments for this data config

  • **kwargs – keyword arguments for this data config

classmethod main(cmdline=False, **kwargs)[source]
default = {'package_name': <Value(None)>, 'refresh': <Value(False)>, 'request_min': <Value(None)>}
class DirectoryStatsCLI(*args, **kwargs)

Bases: DataConfig

Analysis for code in a repository

CommandLine

python ~/code/xdev/xdev/cli/repo_stats.py .

Valid options: []

Parameters:
  • *args – positional arguments for this data config

  • **kwargs – keyword arguments for this data config

classmethod _register_main(func)
default = {'block_dnames': <Value(None)>, 'block_fnames': <Value(None)>, 'dpath': <Value('.')>, 'ignore_dotprefix': <Value(True)>, 'include_dnames': <Value(None)>, 'include_fnames': <Value(None)>, 'max_display_depth': <Value(None)>, 'max_files': <Value(None)>, 'max_walk_depth': <Value(None)>, 'parse_content': <Value(True)>, 'python': <Value(False)>, 'verbose': <Value(0)>, 'version': <Value(False)>}
main(**kwargs)

Example

>>> # xdoctest: +SKIP
>>> cmdline = 0
>>> kwargs = dict(dpath='module:watch')
>>> main(cmdline=cmdline, **kwargs)
normalize()
class RegexCLI(*args, **kwargs)[source]

Bases: DataConfig

Query the regex builder for help on the command line. By default prints useful regex constructs I have a hard time remembering.

Valid options: []

Parameters:
  • *args – positional arguments for this data config

  • **kwargs – keyword arguments for this data config

classmethod main(cmdline=False, **kwargs)[source]
default = {'backend': <Value('python')>}
xdev.cli.build_package_table(package_name, refresh=False)[source]
xdev.cli.byte_str(num, unit='auto', precision=2)[source]

Automatically chooses relevant unit (KB, MB, or GB) for displaying some number of bytes.

Parameters:
  • num (int) – number of bytes

  • unit (str) – which unit to use, can be auto, B, KB, MB, GB, or TB

References

Returns:

string representing the number of bytes with appropriate units

Return type:

str

Example

>>> import ubelt as ub
>>> num_list = [1, 100, 1024,  1048576, 1073741824, 1099511627776]
>>> result = ub.urepr(list(map(byte_str, num_list)), nl=0)
>>> print(result)
['0.00 KB', '0.10 KB', '1.00 KB', '1.00 MB', '1.00 GB', '1.00 TB']
>>> byte_str(10, unit='B')
'10.00 B'
xdev.cli.common_module_aliases()[source]
xdev.cli.common_module_names()[source]

fpath = ub.grabdata(’https://raw.githubusercontent.com/hugovk/top-pypi-packages/main/top-pypi-packages-30-days.json’, expires=86400) fpath = ub.Path(fpath) import json data = json.loads(fpath.read_text()) for item in data[‘rows’][0:300]:

pkg_name = item[‘project’] if ‘-’ not in pkg_name:

print(f’{pkg_name!r},’)

xdev.cli.common_unreferenced()[source]
xdev.cli.cp_sorter(v)[source]
xdev.cli.delete_unpaired_pyi_files(modpath)[source]

Cleanup pyi files corresponding to renamed or removed py files.

xdev.cli.demo()[source]
xdev.cli.generate_typed_stubs(modpath)[source]

Attempt to use google-style docstrings, xdoctest, and mypy to generate typed stub files.

Does not overwrite anything by itself.

Parameters:

modpath (PathLike) – path to the module to generate types for

Returns:

A dictionary mapping the path of each file to write to the text to be written.

Return type:

Dict[PathLike, str]

Notes

FIXME: This currently requires my hacked version of mypy

CommandLine

xdoctest -m /home/joncrall/code/xdev/xdev/cli/docstr_stubgen.py generate_typed_stubs --hacked

Example

>>> # xdoctest: +REQUIRES(module:mypy)
>>> # xdoctest: +REQUIRES(--hacked)
>>> from xdev.cli.docstr_stubgen import *  # NOQA
>>> import xdev
>>> import ubelt as ub
>>> from xdev.cli import docstr_stubgen
>>> modpath = ub.Path(docstr_stubgen.__file__)
>>> generated = generate_typed_stubs(modpath)
>>> text = generated[ub.peek(generated.keys())]
>>> assert 'PathLike' in text
>>> assert 'Dict' in text
>>> print(text)
xdev.cli.grab_pypi_items(package_name, refresh=False)[source]

Get all the information about a package from pypi

xdev.cli.hacked_typing_info(type_name)[source]
xdev.cli.minimum_cross_python_versions(package_name, request_min=None, refresh=False)[source]

package_name = ‘scipy’ request_min = None

package_name = ‘opencv-python-headless’

package_name = ‘numpy’ request_min = ‘1.21.0’

xdev.cli.modpath_coerce(modpath_coercable)[source]

if modpath_coercable is a name, statically converts it to a path

Parameters:

modpath_coercable (str | PathLike | ModuleType) – something we can extract a path to a module from.

Returns:

the coerced modpath

Return type:

str

Example

>>> # xdoctest: +SKIP
>>> from xdev.cli.docstr_stubgen import *  # NOQA
>>> import xdev
>>> modpath_coercable = xdev
>>> modpath = modpath_coerce(modpath_coercable)
>>> print(f'modpath={modpath}')
>>> assert modpath_coerce(modpath) == modpath
>>> assert modpath_coerce(xdev.__name__) == modpath
xdev.cli.parse_file_stats(fpath, parse_content=True)[source]

Get information about a file, including things like number of code lines / documentation lines, if that sort of information is available.

xdev.cli.parse_platform_tag(platform_tag)[source]

Parse finer grained information out of the package platform tag.

Example

>>> cases = [
>>>     'manylinux1_x86_64',
>>>     'macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64',
>>>     'manylinux1_i686',
>>>     'win32',
>>>     'win_amd64',
>>>     'macosx_10_9_x86_64',
>>>     'macosx_10_9_intel',
>>>     'macosx_10_6_intel',
>>>     'manylinux2010_i686',
>>>     'manylinux2010_x86_64',
>>>     'manylinux2014_aarch64',
>>>     'manylinux_2_12_i686.manylinux2010_i686',
>>>     'manylinux_2_12_x86_64.manylinux2010_x86_64',
>>>     'manylinux_2_17_aarch64.manylinux2014_aarch64',
>>>     'manylinux_2_5_i686.manylinux1_i686',
>>>     'manylinux_2_5_x86_64.manylinux1_x86_64',
>>>     'macosx_10_9_universal2',
>>>     'macosx_11_0_arm64',
>>>     'manylinux_2_17_x86_64.manylinux2014_x86_64',
>>>     'macosx_10_14_x86_64',
>>>     'macosx_10_15_x86_64',
>>>     'macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64']
>>> for platform_tag in cases:
>>>     plat_info = parse_platform_tag(platform_tag)
>>>     print(f'platform_tag={platform_tag}')
>>>     print('plat_info = {}'.format(ub.repr2(plat_info, nl=1)))
xdev.cli.parse_wheel_name(fname)[source]
xdev.cli.postprocess_hacks(text, mod)[source]
xdev.cli.remove_duplicate_imports(text)[source]
xdev.cli.rprint(*args)[source]
xdev.cli.stdlib_names()[source]
xdev.cli.strip_comments_and_newlines(source)[source]

Removes hashtag comments from underlying source

Parameters:

source (str | List[str])

Todo

would be better if this was some sort of configurable minify API

Example

>>> from xdev.cli.dirstats import strip_comments_and_newlines
>>> import ubelt as ub
>>> fmtkw = dict(sss=chr(39) * 3, ddd=chr(34) * 3)
>>> source = ub.codeblock(
>>>    '''
       # comment 1
       a = '# not a comment'  # comment 2

multiline_string = {ddd}

one

{ddd} b = [

1, # foo

# bar 3,

] c = 3 ‘’’).format(**fmtkw)

>>> non_comments = strip_comments_and_newlines(source)
>>> print(non_comments)
>>> assert non_comments.count(chr(10)) == 10
>>> assert non_comments.count('#') == 1
xdev.cli.strip_docstrings(tokens)[source]

Replace docstring tokens with NL tokens in a tokenize stream.

Any STRING token not part of an expression is deemed a docstring. Indented docstrings are not yet recognised.

xdev.cli.summarize_package_availability(package_name)[source]

Todo

for each released version of the package we want to know

  • For source distros:
    • Does it need to be compiled?

    • What are is the min (or max?) python version

  • For binaries:
    • What python version, arch, and os targets are available.

xdev.cli.vectorize(func)[source]