简体   繁体   English

python 如何从不在 sys.path 中的路径加载模块

[英]How does python load a module from a path which is not in sys.path

I was debugging a Python import issue where I can't load jinja2 properly while running my code using a pex file.我正在调试 Python 导入问题,在使用 pex 文件运行我的代码时我无法正确加载 jinja2。

Setup a breakpoint in my code, and found myself in a very interesting situation在我的代码中设置断点,发现自己处于一个非常有趣的境地

(Pdb) import jinja2
(Pdb) import jinja2.utils
(Pdb) jinja2.utils
*** AttributeError: 'module' object has no attribute 'utils'
(Pdb) sys.modules.get("jinja2")
<module 'jinja2' from '/home/xxx/.pex/install/Jinja2-2.10.3-py2.py3-none-any.whl.02f611acfe90225e024bd496a640e01844bf5a32/Jinja2-2.10.3-py2.py3-none-any.whl/jinja2/__init__.py'>
(Pdb) sys.modules.get("jinja2.utils")
<module 'jinja2.utils' from '/usr/local/lib/python2.7/dist-packages/jinja2/utils.pyc'>
(Pdb) [i for i in sys.path if "usr/local/lib/python2.7" in i]
[]

Before the breakpoint, jinja2 was already partially loaded because I set up the breakpoint inside jinja2's __init__.py , here is the stacktrace:在断点之前, jinja2已经部分加载,因为我在 jinja2 的__init__.py中设置了断点,这里是堆栈跟踪:

-> exec code in run_globals
  /home/xxx/.pex/code/e7fe7e585c258eb7224ec5030b9d53b74cdfb06f/application/app.py(2)<module>()
-> from flask import Flask, abort, request
  /home/xxx/.pex/install/Flask-1.0-py2.py3-none-any.whl.abe8dd5f49600e54576b3360b7622e1cc97e86fc/Flask-1.0-py2.py3-none-any.whl/flask/__init__.py(19)<module>()
-> from jinja2 import Markup, escape
> /home/xxx/.pex/install/Jinja2-2.10.3-py2.py3-none-any.whl.02f611acfe90225e024bd496a640e01844bf5a32/Jinja2-2.10.3-py2.py3-none-any.whl/jinja2/__init__.py(58)<module>()
-> print("aaaaaaaaa")

Questions are:问题是:

  1. How does python even load the jinja2.utils from /usr/local/lib/python2.7/dist-packages when it is not even not part of the sys.path?当 python 甚至不是 sys.path 的一部分时,它如何从/usr/local/lib/python2.7/dist-packages加载 jinja2.utils?
  2. Why python found jinja2's __init__.py path correctly but failed to find the utils.py which is under the same directory?为什么python正确找到了jinja2的__init__.py路径却找不到同一目录下的utils.py
~$ ls /home/xxx/.pex/install/Jinja2-2.10.3-py2.py3-none-any.whl.02f611acfe90225e024bd496a640e01844bf5a32/Jinja2-2.10.3-py2.py3-none-any.whl/jinja2/
asyncfilters.py  bccache.py  compiler.py   debug.py     environment.py  ext.py      _identifier.py  __init__.py  loaders.py  nativetypes.py  optimizer.py  runtime.py  tests.py  visitor.py
asyncsupport.py  _compat.py  constants.py  defaults.py  exceptions.py   filters.py  idtracking.py   lexer.py     meta.py     nodes.py        parser.py     sandbox.py  utils.py

Confirmed it is a pex issue.确认这是一个pex问题。

Pex loaded jinja2 in the beginning (which also included jinja2.utils ), then it removed the jinaj2 module and the path but failed to remove jinja2.utils . Pex 在开始时加载了jinja2 (其中还包括jinja2.utils ),然后它删除了jinaj2模块和路径,但未能删除jinja2.utils

The issue had been fixed with latest version of pex: https://github.com/pantsbuild/pex/commit/0f9bf622e1565dcdd27c3b79b788571c9608c272该问题已使用最新版本的 pex 修复: https://github.com/pantsbuild/pex/commit/0f9bf622e1565dcdd27c3b79b788571c9608c272

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM