Skip to content

Commit

Permalink
Revert "Account for GitHub changing .rst rendering."
Browse files Browse the repository at this point in the history
This reverts commit fb4faa0.
  • Loading branch information
Sachaa-Thanasius committed Sep 10, 2024
1 parent fb4faa0 commit 42f9fdf
Showing 1 changed file with 14 additions and 0 deletions.
14 changes: 14 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ defer-imports
:target: https://pypi.org/project/defer-imports
:alt: PyPI supported Python versions


A library that implements `PEP 690 <https://peps.python.org/pep-0690/>`_–esque lazy imports in pure Python, but at a user's behest within a context manager.

.. contents::
:local:
:depth: 2


Installation
============

Expand All @@ -31,6 +33,7 @@ This can be installed via pip::

It can also easily be vendored, as it has zero dependencies and has around 1,000 lines of code.


Usage
=====

Expand All @@ -47,6 +50,7 @@ Setup
import your_code
Example
-------

Expand All @@ -62,6 +66,7 @@ Assuming the path hook has been registered, you can use the ``defer_imports.unti
# inspect and Final won't be imported until referenced.
Use Cases
---------

Expand All @@ -71,6 +76,7 @@ Use Cases

- If expensive imports are only necessary for certain code paths that won't always be taken, e.g. in subcommands in CLI tools.


Extra: Console
--------------

Expand Down Expand Up @@ -132,13 +138,15 @@ Additionally, if you're using IPython in a terminal or Jupyter environment, ther
In [8]: print("numpy" in sys.modules)
True
Features
========

- Supports multiple Python runtimes/implementations.
- Supports all syntactically valid Python import statements.
- Doesn't break type-checkers like pyright and mypy.


Caveats
=======

Expand All @@ -147,6 +155,7 @@ Caveats
- Doesn't have an API for giving users a choice to automatically defer all imports on a module, library, or application scale.
- Has a relatively hefty one-time setup cost.


Why?
====

Expand All @@ -161,6 +170,7 @@ Lazy imports, in theory, alleviate several pain points that Python has currently

Then along came `slothy <https://github.com/bswck/slothy>`_, a library that seems to do it better, having been constructed with feedback from multiple CPython core developers as well as one of the minds behind PEP 690. It was the main inspiration for this project. However, the library (currently) limits itself to specific Python implementations by relying on the existence of frames that represent the call stack. For many use cases, that's perfectly fine; PEP 690's implementation was for CPython specifically, and to my knowledge, some of the most popular Python runtimes outside of CPython provide call stack access in some form. Still, I thought that there might be a way to do something similar while avoiding such implementation-specific APIs. After feedback and discussion, that thought crystalized into this library.


How?
====

Expand All @@ -174,6 +184,7 @@ The missing intermediate step is making sure these special proxies are stored wi

With this methodology, we can avoid using implementation-specific hacks like frame manipulation to modify the locals. We can even avoid changing the contract of ``builtins.__import__``, which specifically says it does not modify the global or local namespaces that are passed into it. We may modify and replace members of it, but at no point do we change its size while within ``__import__`` by removing or adding anything.


Quirks
======

Expand All @@ -191,6 +202,7 @@ This library tries to hide its implementation details to avoid changing the deve
print(dir()) # Output: [..., 'typing']
print(type(dir()[-1])) # Output: <class 'defer_imports._core.DeferredImportKey'>
- As far as I know, the only way to see a deferred import value without resolving it is by printing the namespace it resides within. The library's tests currently depend on this behavior to see what happens to the imports before and after they are referenced, but I'm open to other ideas:

.. code-block:: python
Expand All @@ -209,6 +221,7 @@ This library tries to hide its implementation details to avoid changing the deve
leak = next(name for name in dir() if nm == "typing")
print(leak, type(leak), sep=", ") # Output: 'typing', <class 'defer_imports._core.DeferredImportKey'>
Benchmarks
==========

Expand Down Expand Up @@ -252,6 +265,7 @@ A bit rough, but there are currently two ways of measuring activation and/or imp
- Substitute ``defer_imports`` with other modules, e.g. ``slothy``, to compare.
- This has great variance, so only value the resulting time relative to another import's time in the same process if possible.


Acknowledgements
================

Expand Down

0 comments on commit 42f9fdf

Please sign in to comment.