Skip to content

Commit

Permalink
Deal with a python 3.12 backwards compatibility break with meta_path …
Browse files Browse the repository at this point in the history
…loaders.

- also add python 3.12 to the testing framework
  • Loading branch information
CensoredUsername committed Apr 27, 2024
1 parent 6cc0633 commit f917112
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 3 deletions.
7 changes: 5 additions & 2 deletions .github/workflows/python-app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,18 @@ jobs:
tests-py3:
name: Runs tests
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.12"]

steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Set up Python 3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: "3.9"
python-version: ${{ matrix.python-version }}
- name: Test by decompiling a script and building un.rpyc
run: |
# test the command line tool
Expand Down
25 changes: 25 additions & 0 deletions decompiler/magic.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@
import pickle
import struct

try:
# only available (and needed) from 3.4 onwards.
from importlib.machinery import ModuleSpec
except:
pass

if PY3:
from io import BytesIO as StringIO
else:
Expand Down Expand Up @@ -402,19 +408,38 @@ class FakePackageLoader(object):
this ensures that any attempt to get a submodule from module *root*
results in a FakePackage, creating the illusion that *root* is an
actual package tree.
This class is both a `finder` and a `loader`
"""
def __init__(self, root):
self.root = root

# the old way of loading modules. find_module returns a loader for the
# given module. In this case, that is this object itself again.

def find_module(self, fullname, path=None):
if fullname == self.root or fullname.startswith(self.root + "."):
return self
else:
return None

# the new way of loading modules. It returns a ModuleSpec, that has
# the loader attribute set to this class.

def find_spec(self, fullname, path, target=None):
from importlib.machinery import ModuleSpec

This comment has been minimized.

Copy link
@madeddy

madeddy Apr 27, 2024

Contributor

Already imported in the file-head in L34 where it belongs. Or did i miss the reason for the double import?

This comment has been minimized.

Copy link
@CensoredUsername

CensoredUsername Apr 27, 2024

Author Owner

huh. I swear I removed that. I originally confined it to the method so it would only be called when ModuleSpec actually existed, but turns out that importing something during the importing code itself causes some recursive shenanigans so I had to import it globally.


if fullname == self.root or fullname.startswith(self.root + "."):
return ModuleSpec(fullname, self)
else:
return None

# loader methods. This loads the module.

def load_module(self, fullname):
return FakePackage(fullname)


# Fake unpickler implementation

class FakeUnpicklingError(pickle.UnpicklingError):
Expand Down
2 changes: 1 addition & 1 deletion un.rpyc/corrupy
Submodule corrupy updated 1 files
+39 −21 picklemagic.py

0 comments on commit f917112

Please sign in to comment.