unbox
Finding imports in code
To install: pip install unbox
What's here
Lots of little goodies to help you analyze the imports of your, or others' code.
Getting a list of missing dependencies
>>> from unbox import print_missing_names
>>> import some_module # doctest: +SKIP
>>> print_missing_names(some_module) # doctest: +SKIP
SoundFile
i2
librosa
pyttsx3
slink
These are the names a package imports but doesn't declare. The declared names are
read from the package's pyproject.toml (PEP 621 [project] dependencies), falling
back to setup.cfg ([options] install_requires) for legacy projects:
>>> import unbox
>>> unbox.find_install_names(unbox) # doctest: +SKIP
['findimports', 'dol>=0.3.49', 'importlib_resources', 'config2py', 'py2store', 'xdol']
Use unbox.module_requirements_according_to_pyproject(pkg, extras=True) if you also
want the [project.optional-dependencies] groups.
Seeing what the dependencies of a package are, before installing it
Simply get a list of dependencies for a package from PyPI.
>>> import unbox
>>> unbox.dependencies_from_pypi('pandas')
['numpy', 'numpy', 'python-dateutil', 'pytz', 'tzdata']
But you have control over the requirements that are returned, and how they are returned:
>>> it = unbox.dependencies_from_pypi(
... 'pandas',
... requirement_filter=lambda x: True, # don't filter any requirements
... requirement_trans=lambda x: x, # as is
... egress = lambda x: x # just get the iterator as is
... )
>>> next(it)
'numpy>=1.22.4; python_version < "3.11"'
>>> list(it)[-1]
'zstandard>=0.17.0; extra == "all"'
A dict-like interface
The base of unbox is just the dol interface to findimports, which then allows us to offer a bunch of functionalities easily.
Say you wanted to know what dol was made of.
The dol way of doing this is to make a Mapping (i.e. a key-value dict-like interface),
and then do what you do with dicts...
>>> import dol
>>> import unbox
>>> s = unbox.ModuleNamesImportedByModule(dol) # make a store containing the modules of the `dol` package
>>> # Now wee how you can do things you do with dicts
>>> len(s)
15
>>> list(s)
['dol.__init__',
'dol.appendable',
'dol.base',
'dol.caching',
'dol.core',
'dol.dig',
'dol.errors',
'dol.filesys',
'dol.mixins',
'dol.naming',
'dol.paths',
'dol.signatures',
'dol.sources',
'dol.trans',
'dol.util']
>>> 'dol.appendable' in s
>>> # The values of `s` are sets of modules imported by a module.
>>> s['dol.appendable'] # what does dol.appendable import?
{'collections.abc', 'dol.trans', 'time', 'types', 'typing'}
Check out ModulesImportedByModule also, which gives you a Mapping with module objects
as keys, and findimports.ImportInfo instances as values.
imports_for
As an example of what you can do with this set up, have a look at imports_for.
Or don't have a look; just use it, since it's quite useful.
from unbox import imports_for
import wave
assert {"collections", "struct", "sys"}.issubset(imports_for(wave))
Note that we only check a subset here: what a stdlib module imports changes
between python versions (py3.10's wave imports audioop and chunk, both
removed in 3.13, while py3.12's imports uuid).
At it's base, imports_for gives you a generator of import names.
With the post argument (defaulted to set) you can specify a callable that can produce the output
you want; whether you want to filter the items, count them, order them, etc.
We curried a few common ones for you, for your convenience:
from unbox import imports_for
imports_for.counter # imported names and their counts
imports_for.most_common # imported names and their counts, ordered by most common
imports_for.first_level # set for imported first level names (e.g. 'os' instead of 'os.path.etc.)
imports_for.first_level_count # count of imported first level names (e.g. 'os' instead of 'os.path.etc.)
imports_for.third_party # imported (first level) names that are not builtin names (most probably third party packages)"
imports_for.runtime # like third_party, but ignoring the imports made only by the package's own tests
Test-only imports
By default imports_for scans every module under the root, so a package with an
in-package tests/ folder will list pytest (and friends) amongst its imports --
and print_missing_names will then report them as missing install requirements,
though they're only needed to develop the package, not to run it.
Scoping those out is opt-in (the default is unchanged):
imports_for.runtime(some_package) # third-party imports, minus the test-only ones
print_missing_names(some_package, exclude_tests=True)
What counts as a test module is unbox.DFLT_TEST_MODULE_PATTERNS -- fnmatch patterns
matched against each segment of the dotted module name. For anything else, pass your
own exclude (patterns and/or predicates on the full dotted name) to imports_for:
imports_for.third_party(
some_package, exclude=("tests", "scrap", lambda name: "examples" in name)
)
Collections of python names
Check out the contents of these collections:
from unbox import (
builtin_module_names,
scanned_standard_lib_names,
all_accessible_modules,
all_accessible_pkg_names,
all_accessible_non_pkg_module_names,
builtin_obj_names,
python_names,
)
For example, builtin_module_names will be a set of names that are
documented and importable on your system.
The scanned_standard_lib_names set is similar, but the names are obtained by scanning
the local standard library file names -- so include things like easter eggs (this, antigravity).
all_accessible_modules will be the list of all modules accessible in your python path.
And so on...
Metadata
Release files for unbox 0.1.13
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| unbox-0.1.13.tar.gz | 31.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| unbox-0.1.13-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 65.1 kB
Release files / unbox-0.1.13.tar.gz
| Download URL | unbox-0.1.13.tar.gz |
|---|---|
| Size | 31.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9f2459f87c7ff4601084a251078f7e1f159978dbe2654b1dedff11d7cefb7411
|
|
BLAKE2b-256 checksum How to use checksums |
543eecd563f558f6d2632340a35822f4ea046afa3bf97d349819c2a67af482f3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / unbox-0.1.13-py3-none-any.whl
| Download URL | unbox-0.1.13-py3-none-any.whl |
|---|---|
| Size | 33.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
313cd532b70430e2d10e67df11a1a00b35b87fc42e9e5010c5a8d11a24826184
|
|
BLAKE2b-256 checksum How to use checksums |
c64cc0c0c0e88002f32f08172ab5c37ae3826af26d9c2b3eb60ce383d4d56cc9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|