Skip to content

Commit 7302ff1

Browse files
authored
Python 3.12 support / imp module deleted (AcademySoftwareFoundation#1669)
* Add python 3.12 to CI matrix Signed-off-by: Evan Blaudy <[email protected]> * Stop using imp module it's deprecated since python 3.4 and removed in python 3.12 Signed-off-by: Evan Blaudy <[email protected]> * Fix AttributeError: 'VendorImporter' object has no attribute '_path' in Python 3.12 for autogen_serialized_datamodel.py Signed-off-by: Evan Blaudy <[email protected]> * Update pybind11 submodule to latest tag (v2.11.1) Signed-off-by: Evan Blaudy <[email protected]> * Fix opentimelineio.url_utils.filepath_from_url for windows URL in python 3.12 Signed-off-by: Evan Blaudy <[email protected]> * In python-package.yml workflow upgrade pypa/cibuildwheel to v2.16.2 to support python 3.12 Signed-off-by: Evan Blaudy <[email protected]> --------- Signed-off-by: Evan Blaudy <[email protected]>
1 parent d98f657 commit 7302ff1

File tree

5 files changed

+28
-24
lines changed

5 files changed

+28
-24
lines changed

.github/workflows/python-package.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ jobs:
9393
strategy:
9494
matrix:
9595
os: [ubuntu-latest, windows-latest, macos-latest]
96-
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
96+
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12']
9797
include:
9898
- { os: ubuntu-latest, shell: bash }
9999
- { os: macos-latest, shell: bash }
@@ -163,12 +163,12 @@ jobs:
163163
strategy:
164164
matrix:
165165
os: [ubuntu-latest, windows-latest, macos-latest]
166-
python-build: ['cp37*', 'cp38*', 'cp39*', 'cp310*', 'cp311*']
166+
python-build: ['cp37*', 'cp38*', 'cp39*', 'cp310*', 'cp311*', 'cp312*']
167167
steps:
168168
- uses: actions/checkout@v3
169169

170170
- name: Build wheels (Python 3)
171-
uses: pypa/cibuildwheel@v2.11.1
171+
uses: pypa/cibuildwheel@v2.16.2
172172
with:
173173
output-dir: wheelhouse
174174
env:

src/deps/pybind11

Submodule pybind11 updated 75 files

src/py-opentimelineio/opentimelineio/console/autogen_serialized_datamodel.py

+1
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ def _generate_model_for_module(mod, classes, modules):
200200
if (
201201
inspect.ismodule(thing)
202202
and thing not in modules
203+
and "opentimelineio" in thing.__name__
203204
and all(not thing.__name__.startswith(t) for t in SKIP_MODULES)
204205
)
205206
),

src/py-opentimelineio/opentimelineio/plugins/python_plugin.py

+16-14
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
"""Base class for OTIO plugins that are exposed by manifests."""
55

66
import os
7-
import imp
87
import inspect
98
import collections
109
import copy
10+
import importlib.util
1111

1212
from .. import (
1313
core,
@@ -107,21 +107,23 @@ def module_abs_path(self):
107107
def _imported_module(self, namespace):
108108
"""Load the module this plugin points at."""
109109

110-
pyname = os.path.splitext(os.path.basename(self.module_abs_path()))[0]
111-
pydir = os.path.dirname(self.module_abs_path())
112-
113-
(file_obj, pathname, description) = imp.find_module(pyname, [pydir])
114-
115-
with file_obj:
116-
# this will reload the module if it has already been loaded.
117-
mod = imp.load_module(
118-
f"opentimelineio.{namespace}.{self.name}",
119-
file_obj,
120-
pathname,
121-
description
110+
module_name = f"opentimelineio.{namespace}.{self.name}"
111+
try:
112+
# Attempt to import the module using importlib first
113+
mod = importlib.import_module(module_name)
114+
except ImportError:
115+
# If the module couldn't be imported, import it manually
116+
pyname = os.path.splitext(os.path.basename(self.module_abs_path()))[0]
117+
pydir = os.path.dirname(self.module_abs_path())
118+
spec = importlib.util.spec_from_file_location(
119+
module_name,
120+
os.path.join(pydir, f"{pyname}.py"),
122121
)
123122

124-
return mod
123+
mod = importlib.util.module_from_spec(spec)
124+
spec.loader.exec_module(mod)
125+
126+
return mod
125127

126128
def module(self):
127129
"""Return the module object for this adapter. """

src/py-opentimelineio/opentimelineio/url_utils.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010
request
1111
)
1212
from pathlib import (
13-
Path,
14-
PureWindowsPath
13+
PurePath,
14+
PureWindowsPath,
15+
PurePosixPath
1516
)
1617

1718

@@ -21,7 +22,7 @@ def url_from_filepath(fpath):
2122
try:
2223
# appears to handle absolute windows paths better, which are absolute
2324
# and start with a drive letter.
24-
return urlparse.unquote(Path(fpath).as_uri())
25+
return urlparse.unquote(PurePath(fpath).as_uri())
2526
except ValueError:
2627
# scheme is "file" for absolute paths, else ""
2728
scheme = "file" if os.path.isabs(fpath) else ""
@@ -56,16 +57,16 @@ def filepath_from_url(urlstr):
5657
parsed_result = urlparse.urlparse(urlstr)
5758

5859
# Convert the parsed URL to a path
59-
filepath = Path(request.url2pathname(parsed_result.path))
60+
filepath = PurePath(request.url2pathname(parsed_result.path))
6061

6162
# If the network location is a window drive, reassemble the path
6263
if PureWindowsPath(parsed_result.netloc).drive:
63-
filepath = Path(parsed_result.netloc + parsed_result.path)
64+
filepath = PurePath(parsed_result.netloc + parsed_result.path)
6465

6566
# Otherwise check if the specified index is a windows drive, then offset the path
6667
elif PureWindowsPath(filepath.parts[1]).drive:
6768
# Remove leading "/" if/when `request.url2pathname` yields "/S:/path/file.ext"
68-
filepath = filepath.relative_to(filepath.root)
69+
filepath = PurePosixPath(*filepath.parts[1:])
6970

7071
# Convert "\" to "/" if needed
7172
return filepath.as_posix()

0 commit comments

Comments
 (0)