We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Importing shellcraft submodules doesn't work
```
$ python
>>> import pwnlib.shellcraft.arm
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named arm
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pwnlib/shellcraft/__init__.py`
Content:
```
1 from types import ModuleType
2 import sys, os, re
3 from . import internal
4 from ..context import context
5 
6 class module(ModuleType):
7     def __init__(self, name, directory):
8         super(module, self).__init__(name)
9 
10         # Insert nice properties
11         self.__dict__.update({
12             '__file__':    __file__,
13             '__package__': __package__,
14             '__path__':    __path__,
15         })
16 
17         # Save the shellcode directory
18         self._dir = directory
19 
20         # Find the absolute path of the directory
21         self._absdir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'templates', self._dir)
22 
23         # Get the docstring
24         with open(os.path.join(self._absdir, "__doc__")) as fd:
25             self.__doc__ = fd.read()
26 
27         # Insert into the module list
28         sys.modules[self.__name__] = self
29 
30     def __lazyinit__(self):
31 
32         # Create a dictionary of submodules
33         self._submodules = {}
34         self._shellcodes = {}
35         for name in os.listdir(self._absdir):
36             path = os.path.join(self._absdir, name)
37             if os.path.isdir(path):
38                 self._submodules[name] = module(self.__name__ + '.' + name, os.path.join(self._dir, name))
39             elif os.path.isfile(path) and name != '__doc__' and name[0] != '.':
40                 funcname, _ext = os.path.splitext(name)
41                 if not re.match('^[a-zA-Z][a-zA-Z0-9_]*$', funcname):
42                     raise ValueError("found illegal filename, %r" % name)
43                 self._shellcodes[funcname] = name
44 
45         # Put the submodules into toplevel
46         self.__dict__.update(self._submodules)
47 
48         # These are exported
49         self.__all__ = sorted(self._shellcodes.keys() + self._submodules.keys())
50 
51         # Make sure this is not called again
52         self.__lazyinit__ = None
53 
54     def __getattr__(self, key):
55         self.__lazyinit__ and self.__lazyinit__()
56 
57         # Maybe the lazyinit added it
58         if key in self.__dict__:
59             return self.__dict__[key]
60 
61         # This function lazy-loads the shellcodes
62         if key in self._shellcodes:
63             real = internal.make_function(key, self._shellcodes[key], self._dir)
64             setattr(self, key, real)
65             return real
66 
67         for m in self._context_modules():
68             try:
69                 return getattr(m, key)
70             except AttributeError:
71                 pass
72 
73         raise AttributeError("'module' object has no attribute '%s'" % key)
74 
75     def __dir__(self):
76         # This function lists the available submodules, available shellcodes
77         # and potentially shellcodes available in submodules that should be
78         # avilable because of the context
79         self.__lazyinit__ and self.__lazyinit__()
80 
81         result = list(self._submodules.keys())
82         result.extend(('__file__', '__package__', '__path__',
83                        '__all__',  '__name__'))
84         result.extend(self.__shellcodes__())
85 
86         return result
87 
88     def _context_modules(self):
89         self.__lazyinit__ and self.__lazyinit__()
90         for k, m in self._submodules.items():
91             if k in [context.arch, context.os]:
92                 yield m
93 
94     def __shellcodes__(self):
95         self.__lazyinit__ and self.__lazyinit__()
96         result = self._shellcodes.keys()
97         for m in self._context_modules():
98             result.extend(m.__shellcodes__())
99         return result
100 
101 # To prevent garbage collection
102 tether = sys.modules[__name__]
103 
104 # Create the module structure
105 module(__name__, '')
106
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pwnlib/shellcraft/__init__.py b/pwnlib/shellcraft/__init__.py
--- a/pwnlib/shellcraft/__init__.py
+++ b/pwnlib/shellcraft/__init__.py
@@ -102,4 +102,22 @@
 tether = sys.modules[__name__]
 
 # Create the module structure
-module(__name__, '')
+shellcraft = module(__name__, '')
+
+class LazyImporter:
+    def find_module(self, fullname, path):
+        if not fullname.startswith('pwnlib.shellcraft.'):
+            return None
+
+        parts = fullname.split('.')[2:]
+        cur = shellcraft
+        for part in parts:
+            cur = getattr(cur, part, None)
+            if not isinstance(cur, ModuleType):
+                return None
+
+        return self
+
+    def load_module(self, fullname):
+        return sys.modules[fullname]
+sys.meta_path.append(LazyImporter())

{"golden_diff": "diff --git a/pwnlib/shellcraft/__init__.py b/pwnlib/shellcraft/__init__.py\n--- a/pwnlib/shellcraft/__init__.py\n+++ b/pwnlib/shellcraft/__init__.py\n@@ -102,4 +102,22 @@\n tether = sys.modules[__name__]\n \n # Create the module structure\n-module(__name__, '')\n+shellcraft = module(__name__, '')\n+\n+class LazyImporter:\n+    def find_module(self, fullname, path):\n+        if not fullname.startswith('pwnlib.shellcraft.'):\n+            return None\n+\n+        parts = fullname.split('.')[2:]\n+        cur = shellcraft\n+        for part in parts:\n+            cur = getattr(cur, part, None)\n+            if not isinstance(cur, ModuleType):\n+                return None\n+\n+        return self\n+\n+    def load_module(self, fullname):\n+        return sys.modules[fullname]\n+sys.meta_path.append(LazyImporter())\n", "issue": "Importing shellcraft submodules doesn't work\n```\n$ python\n>>> import pwnlib.shellcraft.arm\nTraceback (most recent call last):\n  File \"<stdin>\", line 1, in <module>\nImportError: No module named arm\n```\n\n", "before_files": [{"content": "from types import ModuleType\nimport sys, os, re\nfrom . import internal\nfrom ..context import context\n\nclass module(ModuleType):\n    def __init__(self, name, directory):\n        super(module, self).__init__(name)\n\n        # Insert nice properties\n        self.__dict__.update({\n            '__file__':    __file__,\n            '__package__': __package__,\n            '__path__':    __path__,\n        })\n\n        # Save the shellcode directory\n        self._dir = directory\n\n        # Find the absolute path of the directory\n        self._absdir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'templates', self._dir)\n\n        # Get the docstring\n        with open(os.path.join(self._absdir, \"__doc__\")) as fd:\n            self.__doc__ = fd.read()\n\n        # Insert into the module list\n        sys.modules[self.__name__] = self\n\n    def __lazyinit__(self):\n\n        # Create a dictionary of submodules\n        self._submodules = {}\n        self._shellcodes = {}\n        for name in os.listdir(self._absdir):\n            path = os.path.join(self._absdir, name)\n            if os.path.isdir(path):\n                self._submodules[name] = module(self.__name__ + '.' + name, os.path.join(self._dir, name))\n            elif os.path.isfile(path) and name != '__doc__' and name[0] != '.':\n                funcname, _ext = os.path.splitext(name)\n                if not re.match('^[a-zA-Z][a-zA-Z0-9_]*$', funcname):\n                    raise ValueError(\"found illegal filename, %r\" % name)\n                self._shellcodes[funcname] = name\n\n        # Put the submodules into toplevel\n        self.__dict__.update(self._submodules)\n\n        # These are exported\n        self.__all__ = sorted(self._shellcodes.keys() + self._submodules.keys())\n\n        # Make sure this is not called again\n        self.__lazyinit__ = None\n\n    def __getattr__(self, key):\n        self.__lazyinit__ and self.__lazyinit__()\n\n        # Maybe the lazyinit added it\n        if key in self.__dict__:\n            return self.__dict__[key]\n\n        # This function lazy-loads the shellcodes\n        if key in self._shellcodes:\n            real = internal.make_function(key, self._shellcodes[key], self._dir)\n            setattr(self, key, real)\n            return real\n\n        for m in self._context_modules():\n            try:\n                return getattr(m, key)\n            except AttributeError:\n                pass\n\n        raise AttributeError(\"'module' object has no attribute '%s'\" % key)\n\n    def __dir__(self):\n        # This function lists the available submodules, available shellcodes\n        # and potentially shellcodes available in submodules that should be\n        # avilable because of the context\n        self.__lazyinit__ and self.__lazyinit__()\n\n        result = list(self._submodules.keys())\n        result.extend(('__file__', '__package__', '__path__',\n                       '__all__',  '__name__'))\n        result.extend(self.__shellcodes__())\n\n        return result\n\n    def _context_modules(self):\n        self.__lazyinit__ and self.__lazyinit__()\n        for k, m in self._submodules.items():\n            if k in [context.arch, context.os]:\n                yield m\n\n    def __shellcodes__(self):\n        self.__lazyinit__ and self.__lazyinit__()\n        result = self._shellcodes.keys()\n        for m in self._context_modules():\n            result.extend(m.__shellcodes__())\n        return result\n\n# To prevent garbage collection\ntether = sys.modules[__name__]\n\n# Create the module structure\nmodule(__name__, '')\n", "path": "pwnlib/shellcraft/__init__.py"}], "after_files": [{"content": "from types import ModuleType\nimport sys, os, re\nfrom . import internal\nfrom ..context import context\n\nclass module(ModuleType):\n    def __init__(self, name, directory):\n        super(module, self).__init__(name)\n\n        # Insert nice properties\n        self.__dict__.update({\n            '__file__':    __file__,\n            '__package__': __package__,\n            '__path__':    __path__,\n        })\n\n        # Save the shellcode directory\n        self._dir = directory\n\n        # Find the absolute path of the directory\n        self._absdir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'templates', self._dir)\n\n        # Get the docstring\n        with open(os.path.join(self._absdir, \"__doc__\")) as fd:\n            self.__doc__ = fd.read()\n\n        # Insert into the module list\n        sys.modules[self.__name__] = self\n\n    def __lazyinit__(self):\n\n        # Create a dictionary of submodules\n        self._submodules = {}\n        self._shellcodes = {}\n        for name in os.listdir(self._absdir):\n            path = os.path.join(self._absdir, name)\n            if os.path.isdir(path):\n                self._submodules[name] = module(self.__name__ + '.' + name, os.path.join(self._dir, name))\n            elif os.path.isfile(path) and name != '__doc__' and name[0] != '.':\n                funcname, _ext = os.path.splitext(name)\n                if not re.match('^[a-zA-Z][a-zA-Z0-9_]*$', funcname):\n                    raise ValueError(\"found illegal filename, %r\" % name)\n                self._shellcodes[funcname] = name\n\n        # Put the submodules into toplevel\n        self.__dict__.update(self._submodules)\n\n        # These are exported\n        self.__all__ = sorted(self._shellcodes.keys() + self._submodules.keys())\n\n        # Make sure this is not called again\n        self.__lazyinit__ = None\n\n    def __getattr__(self, key):\n        self.__lazyinit__ and self.__lazyinit__()\n\n        # Maybe the lazyinit added it\n        if key in self.__dict__:\n            return self.__dict__[key]\n\n        # This function lazy-loads the shellcodes\n        if key in self._shellcodes:\n            real = internal.make_function(key, self._shellcodes[key], self._dir)\n            setattr(self, key, real)\n            return real\n\n        for m in self._context_modules():\n            try:\n                return getattr(m, key)\n            except AttributeError:\n                pass\n\n        raise AttributeError(\"'module' object has no attribute '%s'\" % key)\n\n    def __dir__(self):\n        # This function lists the available submodules, available shellcodes\n        # and potentially shellcodes available in submodules that should be\n        # avilable because of the context\n        self.__lazyinit__ and self.__lazyinit__()\n\n        result = list(self._submodules.keys())\n        result.extend(('__file__', '__package__', '__path__',\n                       '__all__',  '__name__'))\n        result.extend(self.__shellcodes__())\n\n        return result\n\n    def _context_modules(self):\n        self.__lazyinit__ and self.__lazyinit__()\n        for k, m in self._submodules.items():\n            if k in [context.arch, context.os]:\n                yield m\n\n    def __shellcodes__(self):\n        self.__lazyinit__ and self.__lazyinit__()\n        result = self._shellcodes.keys()\n        for m in self._context_modules():\n            result.extend(m.__shellcodes__())\n        return result\n\n# To prevent garbage collection\ntether = sys.modules[__name__]\n\n# Create the module structure\nshellcraft = module(__name__, '')\n\nclass LazyImporter:\n    def find_module(self, fullname, path):\n        if not fullname.startswith('pwnlib.shellcraft.'):\n            return None\n\n        parts = fullname.split('.')[2:]\n        cur = shellcraft\n        for part in parts:\n            cur = getattr(cur, part, None)\n            if not isinstance(cur, ModuleType):\n                return None\n\n        return self\n\n    def load_module(self, fullname):\n        return sys.modules[fullname]\nsys.meta_path.append(LazyImporter())\n", "path": "pwnlib/shellcraft/__init__.py"}]}