summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory P. Smith <greg@krypto.org>2021-12-15 06:16:27 -0800
committerGitHub <noreply@github.com>2021-12-15 15:16:27 +0100
commit665574122cb6302fa5342c6f3570c674fcaf0a44 (patch)
treefc7f4c3d17b74a69e7d2f54f4dbd2fde0f3b0563
parent8ce5987c88a578ab0f4f4a64aceff0577082f787 (diff)
downloadastroid-git-665574122cb6302fa5342c6f3570c674fcaf0a44.tar.gz
Prefer using the module loader to get source in builder. (#1207)
* Use loader.get_source() in builder.module_build() Otherwise we fail to get the module source code when running in an embedded hermetic interpreter environment where the source does not live on a filesystem. Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
-rw-r--r--ChangeLog6
-rw-r--r--astroid/builder.py10
2 files changed, 15 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index af8dad12..62ba3693 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,6 +12,12 @@ What's New in astroid 2.9.1?
============================
Release date: TBA
+* Prefer the module loader get_source() method in AstroidBuilder's
+ module_build() when possible to avoid assumptions about source
+ code being available on a filesystem. Otherwise the source cannot
+ be found and application behavior changes when running within an
+ embedded hermetic interpreter environment (pyoxidizer, etc.).
+
* Require Python 3.6.2 to use astroid.
* Fix ``deque.insert()`` signature in ``collections`` brain.
diff --git a/astroid/builder.py b/astroid/builder.py
index cfa8525e..b2c83262 100644
--- a/astroid/builder.py
+++ b/astroid/builder.py
@@ -87,7 +87,15 @@ class AstroidBuilder(raw_building.InspectBuilder):
"""Build an astroid from a living module instance."""
node = None
path = getattr(module, "__file__", None)
- if path is not None:
+ loader = getattr(module, "__loader__", None)
+ # Prefer the loader to get the source rather than assuming we have a
+ # filesystem to read the source file from ourselves.
+ if loader:
+ modname = modname or module.__name__
+ source = loader.get_source(modname)
+ if source:
+ node = self.string_build(source, modname, path=path)
+ if node is None and path is not None:
path_, ext = os.path.splitext(modutils._path_from_filename(path))
if ext in {".py", ".pyc", ".pyo"} and os.path.exists(path_ + ".py"):
node = self.file_build(path_ + ".py", modname)