2

Python has an opportunity to import zip module like this

import sys
sys.path.insert(0, "my_module.zip")

from my_module import my_function
my_function()

Is there a way to import this ZIP archive but from memory (bytes), not from filesystem? For example, like this

import sys
sys.path.insert(0, open("my_module.zip", "rb"))

from my_module import my_function
my_function()

Maybe there are some hooks or similar? I've found the similar question. But it's too old and doesn't work with Python 3.11 python load zip with modules from memory

EDIT:

my_module.py file

def my_function():
    print("This is my function")

Add the file in ZIP archive with name my_module.zip and delete my_module.py

Test 1

import sys

sys.path.insert(0, "my_module.zip")
import my_module

my_module.my_function()

Output:

This is my function

Test 2

#represents your bytes
mem = None
with open('my_module.zip', 'rb') as z:
    mem = z.read()


#actual script
from io import BytesIO
import sys

sys.path.insert(0, BytesIO(mem))
import my_module
my_module.my_function()

Output:

Traceback (most recent call last):
  File "........", line 12, in <module>
    import my_module
ModuleNotFoundError: No module named 'my_module'
Arty
  • 39
  • 1
  • 3
  • 1
    Can you give more details about the use case? Because copying to/importing from `/dev/shm` might count as importing from memory – Marat Aug 15 '23 at 15:18
  • Actually I need to transform ZIP archive before importing it. That's why I need to "tell" Python to import from "bytes" – Arty Aug 15 '23 at 15:53
  • As @Brian61354270 mentioned in comments: maybe you didn't delete the original `.py` file? – Arty Aug 15 '23 at 16:25
  • Yes, as a matter of fact, I did make that mistake. :D I'm surprised that `insert` did not complain, at all. In my defense, I didn't know you could do this, in the first place so, I wasn't prepared for tiny "gotchas". – OneMadGypsy Aug 15 '23 at 16:28
  • 1
    Some other related questions that might be helpful: [How to load compiled python modules from memory?](https://stackoverflow.com/q/1830727/11082165), [Import from instead of file](https://stackoverflow.com/q/61406657/11082165), [Python import from byte IO (or more generally from an object in memory)](https://stackoverflow.com/q/61175428/11082165) – Brian61354270 Aug 15 '23 at 16:31
  • 1
    Maybe a custom subclass of [`importlib.machinery.SourceFileLoader`](https://docs.python.org/3/library/importlib.html#importlib.machinery.SourceFileLoader) would work here. – Brian61354270 Aug 15 '23 at 16:33
  • @Brian61354270 you know, I tried something similar, but the fact is that SourceFileLoader works with files from filesystem, not with zip archive. Maybe there is some similar approach... – Arty Aug 15 '23 at 16:36
  • @Arty It's a real pity that `SourceFileLoader` uses `os` and string paths internally. If it just used `pathlib.Path`s, this might have been as simple as swapping in some `zipfile.Path`s :( – Brian61354270 Aug 15 '23 at 16:44

0 Answers0