diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2970ac47..a760c761 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -159,9 +159,6 @@ jobs: fail-fast: false matrix: include: - - name: Test Linux py38 - os: ubuntu-latest - pyversion: '3.8' - name: Test Linux py39 os: ubuntu-latest pyversion: '3.9' diff --git a/codegen/tests/test_codegen_utils.py b/codegen/tests/test_codegen_utils.py index 288f2828..8e1de9c0 100644 --- a/codegen/tests/test_codegen_utils.py +++ b/codegen/tests/test_codegen_utils.py @@ -144,6 +144,34 @@ def foo(a1, a2, a3): # hi ha ho assert code3 == code2 +def test_format_code_return_type(): + code1 = """ + def foo() -> None: + pass + def foo( + a1, + a2, + a3, + ) -> None: + pass + """ + + code2 = """ + def foo() -> None: + pass + def foo(a1, a2, a3) -> None: + pass + """ + + code1 = dedent(code1).strip() + code2 = dedent(code2).strip() + + code3 = format_code(code1, True) + code3 = code3.replace("\n\n", "\n").replace("\n\n", "\n").strip() + + assert code3 == code2 + + def test_patcher(): code = """ class Foo1: diff --git a/codegen/utils.py b/codegen/utils.py index 1d1df8ff..5b3b2a7a 100644 --- a/codegen/utils.py +++ b/codegen/utils.py @@ -144,51 +144,102 @@ def format_code(src, singleline=False): # Make defs single-line. You'd think that setting the line length # to a very high number would do the trick, but it does not. if singleline: - lines1 = result.splitlines() - lines2 = [] - in_sig = False - comment = "" - for line in lines1: - if in_sig: - # Handle comment - line, _, c = line.partition("#") - line = line.rstrip() - c = c.strip() - if c: - comment += " " + c.strip() - # Detect end - if line.endswith("):"): - in_sig = False - # Compose line - current_line = lines2[-1] - if not current_line.endswith("("): - current_line += " " - current_line += line.lstrip() - # Finalize - if not in_sig: - # Remove trailing spaces and commas - current_line = current_line.replace(" ):", "):") - current_line = current_line.replace(",):", "):") - # Add comment - if comment: - current_line += " #" + comment - comment = "" - lines2[-1] = current_line - else: - lines2.append(line) - line_nc = line.split("#")[0].strip() - if ( - line_nc.startswith(("def ", "async def", "class ")) - and "(" in line_nc - ): - if not line_nc.endswith("):"): - in_sig = True - lines2.append("") - result = "\n".join(lines2) + result = _make_sigs_singline(result) return result +def _make_sigs_singline(code): + lines1 = code.splitlines() + lines2 = [] + + sig_state = 0 + sig_brace_depth = 0 + sig_line = "" + sig_comment = "" + + for line in lines1: + # Check to enter in signature-retrieval mode + if not sig_state: + if line.lstrip().startswith(("def ", "async def", "class ")): + sig_state = 1 + sig_line = "" + sig_comment = "" + sig_brace_depth = 0 + if line.lstrip().startswith("class ") and "(" not in line: + sig_state = 3 # search for closing colon directly + else: + lines2.append(line) + continue + + # If we get here, we're in a signature + + # Handle comment + line, _, c = line.partition("#") + line = line.rstrip() + c = c.strip() + if c: + sig_comment += " " + c.strip() + + if sig_state == 1: + # Find the first opening brace + i = line.find("(") + if i >= 0: + i += 1 + sig_brace_depth = 1 + sig_line += line[:i] + line = line[i:] + sig_state = 2 + + line = line.lstrip() + if sig_line.endswith(","): + line = " " + line + + if sig_state == 2: + # Resolve braces until we find the closing brace + while True: + i1 = line.find("(") + i2 = line.find(")") + if i1 >= 0 and i1 < i2: + i = i1 + 1 + sig_brace_depth += 1 + sig_line += line[:i] + line = line[i:] + elif i2 >= 0: + i = i2 + 1 + sig_brace_depth -= 1 + sig_line += line[:i] + line = line[i:] + else: + break + if sig_brace_depth == 0: + sig_state = 3 + break + + if sig_state == 3: + # Find the closing colon + i = line.find(":") + if i >= 0: + i += 1 + sig_line += line[:i] + line = line[i:] + # Finish the signature line + sig_line = sig_line.replace(", )", ")") + if sig_comment: + sig_line += " #" + sig_comment + lines2.append(sig_line) + if line.strip(): + lines2.append(" " * 12 + line.strip()) + # End the search + sig_state = 0 + line = "" + + sig_line += line + + lines2.append("") + return "\n".join(lines2) + + class Patcher: """Class to help patch a Python module. Supports iterating (over lines, classes, properties, methods), and applying diffs (replace, diff --git a/docs/start.rst b/docs/start.rst index dbd23e73..156f3759 100644 --- a/docs/start.rst +++ b/docs/start.rst @@ -7,7 +7,7 @@ Install with pip ---------------- You can install ``wgpu-py`` via pip. -Python 3.8 or higher is required. Pypy is supported. Only depends on ``cffi`` (installed automatically by pip). +Python 3.9 or higher is required. Pypy is supported. Only depends on ``cffi`` (installed automatically by pip). .. code-block:: bash diff --git a/pyproject.toml b/pyproject.toml index f98f6ed3..6e8a9345 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ readme = "README.md" license = { file = "LICENSE" } authors = [{ name = "Almar Klein" }, { name = "Korijn van Golen" }] keywords = ["webgpu", "wgpu", "vulkan", "metal", "DX12", "opengl"] -requires-python = ">= 3.8" +requires-python = ">= 3.9" dependencies = ["cffi>=1.15.0", "rubicon-objc>=0.4.1; sys_platform == 'darwin'"] [project.optional-dependencies] diff --git a/wgpu/backends/wgpu_native/_api.py b/wgpu/backends/wgpu_native/_api.py index 9bc3b8e4..01fc11f0 100644 --- a/wgpu/backends/wgpu_native/_api.py +++ b/wgpu/backends/wgpu_native/_api.py @@ -519,6 +519,8 @@ class GPUCanvasContext(classes.GPUCanvasContext): # we can give meaningful errors/warnings on invalid use, rather than # the more cryptic Rust panics. + _surface_id = ffi.NULL + def __init__(self, canvas): super().__init__(canvas)