diff --git a/docs/usage.rst b/docs/usage.rst index 5e67ab9..bc6b846 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -1,7 +1,10 @@ -Usage (Or: How To Get The List of Libraries) -============================================ +Usage +===== -The primary function that you'll care about in this package is ``stdlib_list.stdlib_list``. +Getting The List of Libraries +----------------------------- + +``stdlib_list.stdlib_list`` returns the list of libraries in stdlib for any given version (by default, current python version). In particular: @@ -15,5 +18,30 @@ In particular: Out[3]: ['__future__', '__main__', '_dummy_thread', '_thread', 'abc', 'aifc'] +Checking if a Module is part of stdlib +-------------------------------------- + +``stdlib_list.in_stdlib`` provides an efficient way to check if a module name is part of stdlib. +It relies on ``@lru_cache`` to cache the stdlib list and query results for similar calls. Therefore it is much more efficient than ``module_name in stdlib_list()`` especially if you wish to perform multiple checks. + +In particular: + +:: + + >>> from stdlib_list import in_stdlib + >>> in_stdlib('zipimport') # built in + True + >>> in_stdlib('math') # C-API stdlib module, but linked as extension (on my machine) + True + >>> in_stdlib('numpy') # C-API extension, not stdlib + False + >>> in_stdlib('sys') # built-in (and special) + True + >>> in_stdlib('os') # Python code in stdlib + True + >>> in_stdlib('requests') # Python code, not stdlib + False + + .. automodule:: stdlib_list - :members: stdlib_list + :members: stdlib_list, in_stdlib diff --git a/setup.py b/setup.py index fc6681c..f910d89 100644 --- a/setup.py +++ b/setup.py @@ -17,6 +17,7 @@ author_email='jackmaney@gmail.com', url='https://github.com/jackmaney/python-stdlib-list', version=versioneer.get_version(), + install_requires=['functools32;python_version<"3.2"'], extras_require={"develop": ["sphinx"]}, description='A list of Python Standard Libraries (2.6-7, 3.2-6).', long_description=long_description, diff --git a/stdlib_list/__init__.py b/stdlib_list/__init__.py index 549b317..d393949 100644 --- a/stdlib_list/__init__.py +++ b/stdlib_list/__init__.py @@ -3,4 +3,4 @@ del get_versions # Import all the things that used to be in here for backwards-compatibility reasons -from .base import stdlib_list, get_canonical_version, short_versions, long_versions, base_dir, list_dir +from .base import stdlib_list, in_stdlib, get_canonical_version, short_versions, long_versions, base_dir, list_dir diff --git a/stdlib_list/base.py b/stdlib_list/base.py index 1a11d83..7b5c540 100644 --- a/stdlib_list/base.py +++ b/stdlib_list/base.py @@ -3,6 +3,11 @@ import os import sys +try: + from functools import lru_cache +except ImportError: + from functools32 import lru_cache + base_dir = os.path.dirname(os.path.realpath(__file__)) list_dir = os.path.join(base_dir, "lists") @@ -45,3 +50,36 @@ def stdlib_list(version=None): result = [y for y in [x.strip() for x in f.readlines()] if y] return result + + +@lru_cache(maxsize=16) +def _stdlib_list_with_cache(version=None): + """Internal cached version of `stdlib_list`""" + return stdlib_list(version=version) + + +@lru_cache(maxsize=256) +def in_stdlib(module_name, version=None): + """ + Return a ``bool`` indicating if module ``module_name`` is in the list of stdlib + symbols for python version ``version``. If ``version`` is ``None`` (default), the + version of current python interpreter is used. + + Note that ``True`` will be returned for built-in modules too, since this project + considers they are part of stdlib. See :issue:21. + + It relies on ``@lru_cache`` to cache the stdlib list and query results for similar + calls. Therefore it is much more efficient than ``module_name in stdlib_list()`` + especially if you wish to perform multiple checks. + + :param str|None module_name: The module name (as a string) to query for. + :param str|None version: The version (as a string) whose list of libraries you want + (one of ``"2.6"``, ``"2.7"``, ``"3.2"``, ``"3.3"``, ``"3.4"``, or ``"3.5"``). + If not specified, the current version of Python will be used. + + :return: A bool indicating if the given module name is part of standard libraries + for the specified version of Python. + :rtype: list + """ + ref_list = _stdlib_list_with_cache(version=version) + return module_name in ref_list