diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3f9f8e91..918c457e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -20,12 +20,12 @@ jobs: architecture: [x64, x86] python-version: - '3.9' - - '3.10' + - '3.12' julia-version: - '1.4' - - '1.6' - '1.7' - '1.8' + - '1.9' exclude: - os: ubuntu-latest architecture: x86 diff --git a/setup.py b/setup.py index 6a1870e7..3208dae2 100644 --- a/setup.py +++ b/setup.py @@ -67,6 +67,8 @@ def pyload(path): 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', ], url='http://julialang.org', project_urls={ diff --git a/src/julia/core.py b/src/julia/core.py index 183298c4..5120b28f 100644 --- a/src/julia/core.py +++ b/src/julia/core.py @@ -24,6 +24,8 @@ import textwrap import warnings from ctypes import c_char_p, c_void_p +from importlib.abc import Loader, MetaPathFinder +from importlib.machinery import ModuleSpec from logging import getLogger # see `.logger` from types import ModuleType # this is python 3.3 specific @@ -189,7 +191,7 @@ def __try_getattr(self, name): if self._julia.isamodule(jl_fullname): realname = self._julia.fullname(self._julia.eval(jl_fullname)) if self._julia.isdefined(realname): - return self.__loader__.load_module("julia." + realname) + return self.__loader__.create_module(_find_spec_from_fullname("julia." + realname)) # Otherwise, it may be, e.g., "Main.anonymous", created by # Module(). @@ -220,27 +222,31 @@ def __setattr__(self, name, value): # add custom import behavior for the julia "module" -class JuliaImporter(object): +class JuliaImporter(MetaPathFinder): - # find_module was deprecated in v3.4 - def find_module(self, fullname, path=None): - if fullname.startswith("julia."): - filename = fullname.split(".", 2)[1] - filepath = os.path.join(os.path.dirname(__file__), filename) - if os.path.isfile(filepath + ".py") or os.path.isdir(filepath): - return - return JuliaModuleLoader() + def find_spec(self, fullname, path=None, target=None): + return _find_spec_from_fullname(fullname) -class JuliaModuleLoader(object): +def _find_spec_from_fullname(fullname): + if fullname.startswith("julia."): + filename = fullname.split(".", 2)[1] + filepath = os.path.join(os.path.dirname(__file__), filename) + if os.path.isfile(filepath + ".py") or os.path.isdir(filepath): + return + return ModuleSpec(fullname, JuliaModuleLoader(), origin=filepath) +class JuliaModuleLoader(Loader): @property def julia(self): self.__class__.julia = julia = Julia() return julia - # load module was deprecated in v3.4 - def load_module(self, fullname): + def exec_module(self, module): + pass + + def create_module(self, spec): + fullname = spec.name juliapath = remove_prefix(fullname, "julia.") if juliapath == 'Main': return sys.modules.setdefault(fullname, diff --git a/src/julia/release.py b/src/julia/release.py index b91b9912..85a16f2c 100644 --- a/src/julia/release.py +++ b/src/julia/release.py @@ -1,5 +1,5 @@ # This file is executed via setup.py and imported via __init__.py -__version__ = "0.6.1" +__version__ = "0.6.2" # For Python versioning scheme, see: # https://www.python.org/dev/peps/pep-0440/#version-scheme