# PEP 810: Explicit lazy imports

**URL:** <https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131>\
**Category:** PEPs\
**Created:** [October 3, 2025, 11:50am UTC](https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131 "2025-10-03T11:50:19Z")\
**Posts on this page:** 20\
**Page:** 15

<div class="post-metadata">

**Author:** ![matthewyu0311](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/matthewyu0311/32/20118_2.png) [@matthewyu0311](https://discuss.python.org/u/matthewyu0311)\
**Post date:** [October 10, 2025, 12:04pm UTC](https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131/290 "2025-10-10T12:04:15Z")

</div>

> [@encukou](#):
>
> With the current PEP, you _can’t_ get this module’s ` __dict__ `

By the time someone asks for the ` __dict__ `, we’ve already done most of the legwork of running the module’s top-level code and populating its global namespace with classes, top-level functions, eager imports, lazy imports that have been successfully reified, etc. If reification fails for a few lazy items, can we just exclude them from the ` __dict__ `?

---

<div class="post-metadata">

**Author:** ![thomas](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/thomas/32/5492_2.png) [@thomas](https://discuss.python.org/u/thomas)\
**Post date:** [October 12, 2025, 1:10pm UTC](https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131/291 "2025-10-12T13:10:34Z")

</div>

> [@encukou](#):
>
> With the current PEP, you _can’t_ get this module’s ` __dict__ `. The failure cascades down to all the places where hiding lazy objects is meant to help introspection:
> 
> ```python
> >>> import foo
> >>> help(foo)
> No module named 'fast_foo'
> 
> ```

Hm. This is a very compelling argument. I do think we need to reconsider implicit reification for anything that isn’t getting a _specific_ name. So we’d keep reification for `LOAD_GLOBAL` and such, and also `module.attr`, but _not_ `module. __dict__ ` or `globals()` or other forms of inspecting modules/namespaces. That does make it slightly more likely for lazy objects to leak out and surprise code that wasn’t expecting them, but the fix isn’t particularly difficult: don’t use lazy imports, fixing the code doing the inspection, or reify _at any point before that code is called_. I think that gives us enough ways to sensibly work around dependencies that can’t deal with  
lazy imports yet.

Thinking through how we got to the proposal we made in the PEP, I think we got here because we relied too much on our practical experience with lazy imports, all of which is of course with the old lazy imports proposal (as mentioned before, Meta uses it extensively internally, as do some of the other folks who worked on this PEP). I think perhaps we’re working too hard to hide the new feature, instead of accepting that some old code won’t work well with the new feature and it’s on the programmers to make that consideration – while still giving them enough tools to be able to make things work.

This is where the rejection of `with` and `try/except` with lazy imports comes from as well. I think on balance, purely looking at uses of the new syntax, `try/except` is still too much of a footgun to allow lazy imports in. For `with`, I’m personally still lightly opposed to it, but I think the other PEP authors think we should allow it. The theoretical utility does seem to outweigh the risk of people writing code like:

```python
with MyGlobalLock:
    lazy import extension_that_requires_global_lock

```

… although it would be nice if this theoretical utility actually works out in practice 🙂

---

<div class="post-metadata">

**Author:** ![ncoghlan](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/ncoghlan/32/14266_2.png) [@ncoghlan](https://discuss.python.org/u/ncoghlan)\
**Post date:** [October 12, 2025, 2:58pm UTC](https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131/292 "2025-10-12T14:58:23Z")

</div>

> [@thomas](#):
>
> For `with`, I’m personally still lightly opposed to it, but I think the other PEP authors think we should allow it.

The externally locked example does make me wonder if we should offer an _eager_ import context manager in `importlib.util` that temporarily maps ` __lazy_import__ ` to ` __import__ `.

---

<div class="post-metadata">

**Author:** ![gerardw](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/gerardw/32/8739_2.png) [@gerardw](https://discuss.python.org/u/gerardw)\
**Post date:** [October 12, 2025, 10:12pm UTC](https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131/293 "2025-10-12T22:12:55Z")

</div>

> A module may contain a ` __lazy_modules__ ` attribute, which is a sequence of fully qualified module names (strings) to make _potentially lazy_ (as if the `lazy` keyword was used).

Does ` __lazy_imports__ ` have to be a sequence?  
The most straightforward way of reifying a module would be to “for real” import it, which could mean removing it.

The current proof of concept supports using a set, but I don’t know if that is part of the format specification.

```python
from typing import Sequence
import sys
print(isinstance(set,Sequence)) # False
__lazy_modules__ = set(("requests","json"))
import json
print('json' in sys.modules) # False
__lazy_modules__.discard("json")
import json
print('json' in sys.modules) # True

```

---

<div class="post-metadata">

**Author:** ![pganssle](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/pganssle/32/245_2.png) [@pganssle](https://discuss.python.org/u/pganssle)\
**Post date:** [October 13, 2025, 3:13am UTC](https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131/294 "2025-10-13T03:13:04Z")

</div>

Unless I misunderstand you, you don’t need a special context manager for that, you can just eagerly import it. The global flag situation is different but I think the plan with the global flag is that if you are going to change the behavior of all your libraries it is on you to make sure stuff doesn’t break (using filters or defensive coding or whatever).

---

<div class="post-metadata">

**Author:** ![ncoghlan](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/ncoghlan/32/14266_2.png) [@ncoghlan](https://discuss.python.org/u/ncoghlan)\
**Post date:** [October 13, 2025, 4:21am UTC](https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131/295 "2025-10-13T04:21:14Z")

</div>

Explicitly overriding the global flag is what I had in mind. Being able to say “_this_ import absolutely _must_ be complete after the statement has executed” allows for usage specific overrides that may reduce the need for name based filtering.

---

<div class="post-metadata">

**Author:** ![MegaIng](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/megaing/32/16162_2.png) [@MegaIng](https://discuss.python.org/u/MegaIng)\
**Post date:** [October 13, 2025, 5:47am UTC](https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131/296 "2025-10-13T05:47:56Z")

</div>

> [@ncoghlan](#):
>
> Being able to say “_this_ import absolutely _must_ be complete after the statement has executed” allows for usage specific overrides that may reduce the need for name based filtering.

I think if such a thing is not provided and lazy modules start to be used, patterns for this will emerge. For example `import foo; foo`.

Not sure if this is a good or bad thing, but I am certain that this will emerge for some libraries that get reports that it would be nice to support the globally lazy option. (No matter what’s inside the PEP or documentation, such reports are going to come, and some authors will not want to shut them down)

---

<div class="post-metadata">

**Author:** ![blhsing](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/blhsing/32/25812_2.png) [@blhsing](https://discuss.python.org/u/blhsing)\
**Post date:** [October 13, 2025, 7:45am UTC](https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131/297 "2025-10-13T07:45:39Z")

</div>

> [@ncoghlan](#):
>
> Explicitly overriding the global flag is what I had in mind. Being able to say “_this_ import absolutely _must_ be complete after the statement has executed” allows for usage specific overrides that may reduce the need for name based filtering.

> [@MegaIng](#):
>
> I think if such a thing is not provided and lazy modules start to be used, patterns for this will emerge. For example `import foo; foo`.

Yeah, we should acknowledge that a vast majority of modules _can_ be lazily imported, that for many code maintainers lazy imports are going to be the norm rather than the exception, and they will want to enable global lazy imports while being able to explicitly specify which select few imports are eager (usually those that install hooks as a side effect).

While a pattern like `import foo; foo` will work just fine, a dedicated syntax such as `eager import foo` or `not lazy import foo` would help express the intent much better.

---

<div class="post-metadata">

**Author:** ![pf\_moore](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/pf_moore/32/35_2.png) [@pf\_moore](https://discuss.python.org/u/pf_moore)\
**Post date:** [October 13, 2025, 9:53am UTC](https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131/298 "2025-10-13T09:53:23Z")

</div>

> [@blhsing](#):
>
> Yeah, we should acknowledge that a vast majority of modules _can_ be lazily imported, that for many code maintainers lazy imports are going to be the norm rather than the exception, and they will want to enable global lazy imports while being able to explicitly specify which select few imports are eager (usually those that install hooks as a side effect).

I think this is going to be a matter of debate for a _long_ time. As someone who has worked with Python for many years, I would expect imports to be eager by default. The idea of a statement that does nothing right now but triggers non-trivial work at some arbitrary later point in the program is unusual, and worthy of explicit note. I would personally insist that all lazy imports in programs that I maintain are explicitly marked with the `lazy` keyword, for maintainability.

I accept that not everyone would agree with my view, but I don’t think that “enabling global lazy imports” should be considered normal practice in the foreseeable future - after all, the rejection of PEP 690 explicitly confirmed the SC’s opposition to that practice.

---

<div class="post-metadata">

**Author:** ![pablogsal](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/pablogsal/32/32246_2.png) [@pablogsal](https://discuss.python.org/u/pablogsal)\
**Post date:** [October 13, 2025, 4:59pm UTC](https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131/299 "2025-10-13T16:59:39Z")

</div>

The global flag is still considered an advanced feature and our experience shows it needs to remain that way. As we mentioned a couple of times in the discussion we don’t want to push the PEP toward a world where _everything_ is lazy by default. The approach here is deliberately cautious and explicit. I know a lot of people think we should steer toward a future where lazy becomes the default and give even more emphasis to control that world, but at this time and for this PEP we strongly believe the main mechanism for laziness should remain the explicit `lazy` keyword (and related APIs). That makes intent clear, keeps semantics predictable, and avoids breaking code that relies on import-time side effects.

The flag absolutely has its users and it’s important for them (and that’s why we believe it’s crucial to have it) but we don’t want to expose everyone to its trade-offs automatically. We believe this is the right set of defaults: explicit laziness for predictability and safety, with a global control available for advanced users who know what they’re doing. We’ve spent a lot of time discussing this design, exploring alternatives, and weighing real deployment data across organizations using the feature.

So while the global switch will stay, it will remain an opt-in, advanced knob rather than a general setting where the **final user** that decides to opt-in into it it’s the one responsible for the consequences and the control, not the library developers or anyone else.

---

<div class="post-metadata">

**Author:** ![pablogsal](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/pablogsal/32/32246_2.png) [@pablogsal](https://discuss.python.org/u/pablogsal)\
**Post date:** [October 13, 2025, 5:21pm UTC](https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131/300 "2025-10-13T17:21:32Z")

</div>

We’ve updated the PEP with a lot of clarifications, small renames, and several explicitly documented rejected ideas (all based on the feedback here and from private discussions). Many of the comments in this thread helped us refine the explanations and make the document clearer and more precise so thanks a lot ❤

After discussing with the team extensively and reading through all the feedback, we’ve made a couple of updates based on what we’ve learned from the conversation:

**• Lazy imports inside `with` blocks**  
We’ve decided to _allow_ them. There are many legitimate use cases where `with` is used for managing lifetime or scoping behavior rather than just suppressing exceptions, and the syntax is explicit enough that users know what they’re doing. It fits Python’s “consenting adults” model as `with` carries broader semantics than just error handling. For the genuinely problematic cases (like `contextlib.suppress(ImportError)`), we think linters are the right abstraction to catch them rather than hard language restrictions.

**• ` __dict__ ` and reification**  
We’ve also pivoted to _not automatically reify_ on ` __dict__ ` access. This makes the model cleaner: ` __dict__ ` is already a low-level API, and introspection code generally shouldn’t trigger side effects implicitly. It’s a better mental model to ask users to reify explicitly when they need it, rather than forcing them into awkward patterns just to avoid automatic behavior. This decision also came out naturally when we had to make parts of the stdlib reason about this (for example, in the `traceback` module) as it quickly became clear that automatic reification was cumbersome and not the right thing to do. This also restores nice symmetry with `globals()`: both now expose the raw namespace view, and both are easy to explain and predict.

Thanks again to everyone who shared thoughts, questions, and concerns regarding this! All this feedback genuinely makes a difference and helps us refine the proposal into something better for everyone.

We will be updating the PEP shortly.

---

<div class="post-metadata">

**Author:** ![thomas](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/thomas/32/5492_2.png) [@thomas](https://discuss.python.org/u/thomas)\
**Post date:** [October 14, 2025, 7:32pm UTC](https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131/301 "2025-10-14T19:32:04Z")

</div>

FYI, the updated PEP was sent to the SC today:

> <https://github.com/python/steering-council/issues/314>
>
> After a lot of discussion we'd like to submit PEP 810 (Explicit lazy imports) fo…r your consideration. https://peps.python.org/pep-0810/
> 
> Although the volume of the discussion has been quite challenging, we're genuinely humbled by the reception this has gotten. We are confident this addresses a real and pressing need in the community, as evidenced by the strong support from major library maintainers (too many to put here, check the discussion itself), the Scientific Python community, several major companies (including Meta, Google, Bloomberg, HRT and more) who've shared detailed feedback from their production deployments and many community members including educators and users working in academia. The discussion has been open since October 3rd and has gotten over 300 substantive comments. After several iterations incorporating feedback, we feel confident the discussion has converged and the PEP reflects the best proposal we can offer. We've documented the design space extensively with a large Rejected Ideas section explaining our rationale, a Deferred Ideas section for things that are out of scope but could be future work, and a comprehensive FAQ covering the questions that came up during discussion.
> 
> We're available if you have specific questions or need clarification on anything. 
> 
> Thanks for your consideration!
> 
> The PEP 810 authors
> 
> \----
> 
> \* \[x\] The PEP has been discussed in threads listed in its \`Post-History\` header
>   
> \* \[x\] The PEP was announced on \[Discuss\](https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131/300) (link in \`Post-History\`)
> \* \[x\] The PEP includes all relevant \[Suggested Sections\](https://peps.python.org/pep-0012/#suggested-sections)
> \* \[x\] The PEP includes endorsements from the projects/groups/people it helps
>   
> \* \[x\] The PEP has a CODEOWNERS entry

---

<div class="post-metadata">

**Author:** ![notatallshaw](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/notatallshaw/32/10861_2.png) [@notatallshaw](https://discuss.python.org/u/notatallshaw)\
**Post date:** [October 14, 2025, 7:56pm UTC](https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131/302 "2025-10-14T19:56:43Z")

</div>

It’s probably too late now but I find the security implications section a little contradictory and unmotivated:

> There are no known security vulnerabilities introduced by lazy imports. Security-sensitive tools that need to ensure all imports are evaluated eagerly can use sys.set\_lazy\_imports() with “none” to force eager evaluation, or use sys.set\_lazy\_imports\_filter() for fine-grained control.

How can there be no know security vulnerabilities and something that security sensitive tools need to do? What is a security sensitive tool? A web server?

I would of preferred something like:

> Python package installers, and other similarly security sensitive tools, that need to eagerly import to avoid installed packages overriding their import namespace during installation can use `sys.set_lazy_imports()` with `"none"` to force eager evaluation, or use `sys.set_lazy_imports_filter()` for fine-grained control.

Apologies I hadn’t been keeping a close eye on if the text had been updated.

---

<div class="post-metadata">

**Author:** ![pablogsal](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/pablogsal/32/32246_2.png) [@pablogsal](https://discuss.python.org/u/pablogsal)\
**Post date:** [October 14, 2025, 8:45pm UTC](https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131/303 "2025-10-14T20:45:25Z")

</div>

> [@notatallshaw](#):
>
> How can there be no know security vulnerabilities and something that security sensitive tools need to do? What is a security sensitive tool? A web server?

This was based on a very particular request by someone before in the discussion regarding `pip` depending on importing something for side-effects to ensure that certain guarantees where being met (which you could argue is not good practice anyway) and we generalized it a bit. In this context a ‘security sensitive tool’ is defined as ‘any tool that for some reason cares about this’. But its true that most tools (even if security sensitive) should not care about this in most cases so we welcome any improvements to the language.

> [@notatallshaw](#):
>
> I would of preferred something like:

I think it sounds better. Would you like to make a PR? We can discuss the specifics there 🙂

---

<div class="post-metadata">

**Author:** ![notatallshaw](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/notatallshaw/32/10861_2.png) [@notatallshaw](https://discuss.python.org/u/notatallshaw)\
**Post date:** [October 14, 2025, 8:58pm UTC](https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131/304 "2025-10-14T20:58:13Z")

</div>

> [@pablogsal](#):
>
> This was based on a very particular request by someone before in the discussion regarding `pip`

That was me, I’m a maintainer of pip, which is why I’m familiar with the issue.

> [@pablogsal](#):
>
> I think it sounds better. Would you like to make a PR? We can discuss the specifics there 🙂

Yeah, I’ll try and make time to open a PR later today (will be my first time in the PEP repo so exciting!).

---

<div class="post-metadata">

**Author:** ![pablogsal](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/pablogsal/32/32246_2.png) [@pablogsal](https://discuss.python.org/u/pablogsal)\
**Post date:** [October 14, 2025, 8:59pm UTC](https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131/305 "2025-10-14T20:59:34Z")

</div>

> [@notatallshaw](#):
>
> (will be my first time in the PEP repo so exciting!).

Amazing! 🚀 Please CC me in the PR and I will ensusure to take a look asap 🙂

---

<div class="post-metadata">

**Author:** ![markshannon](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/markshannon/32/72_2.png) [@markshannon](https://discuss.python.org/u/markshannon)\
**Post date:** [October 14, 2025, 9:15pm UTC](https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131/306 "2025-10-14T21:15:08Z")

</div>

This feels a bit rushed. I was waiting for all the ~shouting~ discussion to subside and the design to stabilise before I did a proper analysis. Would you mind waiting a week or two?

---

<div class="post-metadata">

**Author:** ![pablogsal](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/pablogsal/32/32246_2.png) [@pablogsal](https://discuss.python.org/u/pablogsal)\
**Post date:** [October 14, 2025, 9:22pm UTC](https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131/307 "2025-10-14T21:22:19Z")

</div>

> [@markshannon](#):
>
> This feels a bit rushed.

I’m sorry you feel this way. After more than a week (which is what the SC recomends at least [when submitting a new PEP](https://raw.githubusercontent.com/python/steering-council/refs/heads/main/.github/ISSUE_TEMPLATE/pep-submission.md)) and almost 300 comments (which is more than what most PEPs get) and the discussion calming down as you mention, we certainly feel it has been discussed enough for us to feel confident on the design. You can surely disagree and that’s fine of course.

> [@markshannon](#):
>
> Would you mind waiting a week or two?

The SC is certainly not going to start reviewing this PEP this week or next week given the current queue, so don’t worry about that.

Edit/Update: I have requested in the submission post to not review this PEP before at least one or two weeks just to be sure Mark has time.

---

<div class="post-metadata">

**Author:** ![markshannon](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/markshannon/32/72_2.png) [@markshannon](https://discuss.python.org/u/markshannon)\
**Post date:** [October 14, 2025, 9:25pm UTC](https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131/308 "2025-10-14T21:25:02Z")

</div>

I didn’t mean that the design is rushed. Just the submission to the SC.  
I’ll try to get my review done within a week or so.

---

<div class="post-metadata">

**Author:** ![pablogsal](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/pablogsal/32/32246_2.png) [@pablogsal](https://discuss.python.org/u/pablogsal)\
**Post date:** [October 14, 2025, 9:25pm UTC](https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131/309 "2025-10-14T21:25:37Z")

</div>

> [@markshannon](#):
>
> I didn’t mean that the design is rushed. Just the submission to the SC.

I assumed you were referring to this but my previous comment still applies.

[Previous page](https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131.md?page=14)

[Next page](https://discuss.python.org/t/pep-810-explicit-lazy-imports/104131.md?page=16)
