最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

python - Why early imports to populate sys.module - Stack Overflow

programmeradmin2浏览0评论

.py

# We must import the app_info module early to populate it into
# `sys.modules`; otherwise doing `import stripe.app_info` will end up
# importing that module, and not the global `AppInfo` name from below.
import stripe.app_info
from stripe._app_info import AppInfo as AppInfo
from stripe._version import VERSION as VERSION

What is mean by stripe.app_info must be imported early to prevent AppInfo from being imported? AppInfo isnt even located in stripe.app_info but in stripe._app_info?

Tried ChatGPT, they say its something related to defensive programming to prevent bugs.

https://github.com/stripe/stripe-python/blob/master/stripe/__init__.py

# We must import the app_info module early to populate it into
# `sys.modules`; otherwise doing `import stripe.app_info` will end up
# importing that module, and not the global `AppInfo` name from below.
import stripe.app_info
from stripe._app_info import AppInfo as AppInfo
from stripe._version import VERSION as VERSION

What is mean by stripe.app_info must be imported early to prevent AppInfo from being imported? AppInfo isnt even located in stripe.app_info but in stripe._app_info?

Tried ChatGPT, they say its something related to defensive programming to prevent bugs.

Share Improve this question asked Feb 8 at 2:21 Pacific EastPacific East 111 bronze badge New contributor Pacific East is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct. 3
  • There's app_info.py file, and these shenanigans impact what import stripe.app_info does for an external user. I'd strongly recommend just never using this import dance unless you're trying to understand python imports in depth (and still never use this in production as confusing and error-prone). – STerliakov Commented Feb 8 at 3:01
  • Ah, well, they only do that for deprecation reasons, that's fine! – STerliakov Commented Feb 8 at 3:05
  • Relevant (good enough to let you understand the reasoning, but probably not similar enough to be a dupe target): stackoverflow.com/questions/54096838/… – STerliakov Commented Feb 8 at 3:23
Add a comment  | 

1 Answer 1

Reset to default 0

The comment is misleading. The first time stripe.app_info is imported, app_info.py is executed and its module is added to sys.modules as "stripe.app_info" and to the stripe namespace as app_info. A user would reference it as stripe.app_info. These are different namespaces, used in different contexts.

stripe/__init__.py is the package namespace and is the first thing executed when stripe is imported. At this point, its guaranteed that stripe.app_info has not been imported so the import happens and stripe.app_info references that module.

Now things get confusing. The authors decided to repurpose stripe.app_info to reference an optional dictionary that can reconfigure the package. This is also done in __init__.py, so when the package init is complete, stripe.app_info is a module in sys.modules and references None in the package namespace stripe.app_info. From the comment, the authors seem to think that stripe.app_info (the dictionary) shadows stripe.app_info (the module). But that's only partially true.

If you import stripe.app_info and then try my_info = stripe.app_info.AppInfo(...), you'll be disappointed. Python checked sys.modules for the import and since the module already exists, it didn't do anything. But when referencing in the second statement, that's the package namespace which has the None reference and AppInfo doesn't exist.

But if you from stripe.app_info import AppInfo, that's the module and you will get AppInfo. my_info = AppInfo(...) works. my_info = stripe.AppInfo(...) also works. That's because the real implementation of the class is in stripe._app_info and both app_info.py and __init__.py import from that same module.

Maybe there is some reason for this convoluted code, but personally I'd stay away from it.

发布评论

评论列表(0)

  1. 暂无评论