diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..530504e7d80e9830fef5e947688735bee7235d21
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+*~
+/test/build
\ No newline at end of file
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..ac5755a61d2db376b634b405a962f397d22537dd
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,6 @@
+all:
+	$(MAKE) -C test --no-print-directory
+
+.PHONY: SRPM
+SRPM:
+	rpmbuild --define "_sourcedir $$(pwd)" -bs apa.spec
diff --git a/apa b/apa3
similarity index 84%
rename from apa
rename to apa3
index 78945153c9d7da2d3ccac70f4d65fc450fd66b9a..f9fcfa3a1741491807ceee1baa8c290989c7501b 100755
--- a/apa
+++ b/apa3
@@ -2,7 +2,7 @@
 """
 Anders Python Archiver
 
-Copyright (C) 2004-2019 Anders Blomdell <anders.blomdell@control.lth.se>
+Copyright (C) 2004-2023 Anders Blomdell <anders.blomdell@control.lth.se>
 
   A small utility program to join a number of python modules
   into a single executable python program.
@@ -139,37 +139,45 @@ To extract as individual files:
     print("}", file=apa)
     print("""
 
-class Importer:
-    \"\"\"Loads modules from local code dictionary
-    \"\"\"
-    def __init__(self, code):
-        self.code = code;
-        self.path = "<%s>" % str(self.__class__)
-        if not self.path in sys.path:
-            sys.path.insert(0, self.path)
+import sys
+import os
+import importlib.abc
+import importlib.util
+
+class Finder(importlib.abc.MetaPathFinder):
 
-    def __call__(self, path):
-        if path == self.path:
-            return self
+    def __init__(self, loader, code):
+        self.loader = loader
+        self.code = code
+        pass
+
+    def find_spec(self, fullname, path=None, target=None):
+        if fullname in self.code:
+            return importlib.util.spec_from_loader(fullname, self.loader)
         return None
+
+    pass
+
+class Loader(importlib.abc.Loader):
+
+    def __init__(self, code):
+        self.code = code;
+        self._path = "APA[%s]" % os.path.realpath(sys.argv[0])
+        pass
     
-    def find_module(self, fullname):
-        try:
-            self.code[fullname]
-            return self
-        except:
-            return None
-        
-    def load_module(self, fullname):
-        mod = sys.modules.setdefault(fullname, types.ModuleType(fullname))
-        (filename, src) = self.code[fullname]
+    def create_module(self, spec):
+        return None
+
+    def exec_module(self, module):
+        filename,src = self.code[module.__name__]
+        mod = sys.modules.setdefault(module.__name__, module)
         mod.__file__ = filename
         mod.__loader__ = self
-        mod.__path__ = [ self.path ]
+        mod.__path__ = [ self._path ]
         global BAD
         BAD = None
         try:
-            code = compile(src, "%s/%s" % (self.path, filename), 'exec')
+            code = compile(src, "%s/%s" % (self._path, filename), 'exec')
             exec(code, mod.__dict__)
         except SystemExit as e:
             # Silently propagate exit
@@ -182,7 +190,8 @@ class Importer:
 
     def is_package(self, fullname):
         (filename, src) = self.code[fullname]
-        return True
+        (name, extension) = os.path.splitext(os.path.basename(filename))
+        return name == '__init__'
 
     def get_code(self, fullname):
         (filename, src) = self.code[fullname]
@@ -192,11 +201,13 @@ class Importer:
     def get_source(self, fullname):
         (filename, src) = self.code[fullname]
         return src
-        
+
     def get_filename(self, fullname):
         (filename, src) = self.code[fullname]
         return filename
-   
+
+    pass
+
 def extract(dest='.'):
     \"\"\"Extracts archived files in dest directory ('.' is default)\"\"\"
     import os
@@ -215,12 +226,14 @@ def extract(dest='.'):
     
 if __name__ == '__main__':
     import sys
-    importer = Importer(code)
-    sys.path_hooks.append(importer)
-    import types
+    loader = Loader(code)
+    finder = Finder(loader, code)
+    sys.meta_path.append(finder)
     try:
         # This will start actual execution
-        importer.load_module("__main__")
+        spec = finder.find_spec("__main__")
+        m = importlib.util.module_from_spec(spec)
+        loader.exec_module(m)
     except SystemExit as e:
         raise e
     except:
diff --git a/test/Makefile b/test/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..8402b7679fce526e442b4aa4d9263e4272923a16
--- /dev/null
+++ b/test/Makefile
@@ -0,0 +1,20 @@
+all: TEST_TRACEBACK TEST_MODULE
+
+.PHONY: TEST_TRACEBACK
+TEST_TRACEBACK:
+	-mkdir -p build
+	../apa -o build/test_traceback test_traceback.py
+	./build/test_traceback \
+		&& echo "Expected failure not gotten, so BAD" && exit 1 \
+		|| echo "Expected failure gotten, so OK" 
+
+
+.PHONY: TEST_MODULE
+TEST_MODULE:
+	-mkdir -p build
+	../apa -o build/test_module \
+		test_module.py \
+		module/__init__.py \
+		module/a.py \
+		module/b.py
+	./build/test_module 
diff --git a/test/module/__init__.py b/test/module/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..d8bb652afdb296b175a2390336c910de7e8d64a6
--- /dev/null
+++ b/test/module/__init__.py
@@ -0,0 +1,3 @@
+print(__name__)
+
+from . import a
diff --git a/test/module/a.py b/test/module/a.py
new file mode 100644
index 0000000000000000000000000000000000000000..3f8ff89d3ad345e04ca065cebaf954c85d2cd1ed
--- /dev/null
+++ b/test/module/a.py
@@ -0,0 +1,2 @@
+print(__name__)
+from . import b
diff --git a/test/module/b.py b/test/module/b.py
new file mode 100644
index 0000000000000000000000000000000000000000..559a4c5a8675adb533493d0c4824e0378c04085b
--- /dev/null
+++ b/test/module/b.py
@@ -0,0 +1,2 @@
+print(__name__)
+from . import a
diff --git a/test/test_module.py b/test/test_module.py
new file mode 100644
index 0000000000000000000000000000000000000000..392b71878de772a5e22af49756b479507148c169
--- /dev/null
+++ b/test/test_module.py
@@ -0,0 +1,3 @@
+#!/usr/bin/python3
+
+import module
diff --git a/test/test_traceback.py b/test/test_traceback.py
new file mode 100755
index 0000000000000000000000000000000000000000..11906cdc6299d91d80a5e4df90801ced9f72531e
--- /dev/null
+++ b/test/test_traceback.py
@@ -0,0 +1,23 @@
+#!/usr/bin/python3
+
+MAX_DEPTH = 5
+
+def a(depth):
+    if depth > MAX_DEPTH:
+        raise Exception("Max depth exceeded")
+    b(depth+1)
+    pass
+
+def b(depth):
+    if depth > MAX_DEPTH:
+        raise Exception("Max depth exceeded")
+    c(depth+1)
+    pass
+
+def c(depth):
+    if depth > MAX_DEPTH:
+        raise Exception("Max depth exceeded")
+    a(depth+1)
+    pass
+
+a(1)