YosysHQ / apicula

Project Apicula 🐝: bitstream documentation for Gowin FPGAs
MIT License
474 stars 66 forks source link

Incompatible with Python 3.8 #219

Closed nnn1590 closed 9 months ago

nnn1590 commented 9 months ago

Since commit 140c7b352f721ec01d3e95448805370757236779, TypeError occurs in Python 3.8 due to Type Hinting Generics in Standard Collections is a new feature in Python 3.9.(PEP 585)

Traceback ```console $ gowin_pack -d GW1N-9C -o fpga.fs fpga_pnr.json Traceback (most recent call last): File "/opt/oss-cad-suite-2023-12-29/libexec/gowin_pack", line 33, in sys.exit(load_entry_point('Apycula==0.10.1.dev4+g140c7b3', 'console_scripts', 'gowin_pack')()) File "/opt/oss-cad-suite-2023-12-29/libexec/gowin_pack", line 25, in importlib_load_entry_point return next(matches).load() File "/opt/oss-cad-suite-2023-12-29/lib/python3.8/importlib/metadata.py", line 77, in load module = import_module(match.group('module')) File "/opt/oss-cad-suite-2023-12-29/lib/python3.8/importlib/__init__.py", line 127, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "", line 1014, in _gcd_import File "", line 991, in _find_and_load File "", line 975, in _find_and_load_unlocked File "", line 655, in _load_unlocked File "", line 618, in _load_backward_compatible File "", line 259, in load_module File "/opt/oss-cad-suite-2023-12-29/lib/python3.8/site-packages/Apycula-0.10.1.dev4+g140c7b3-py3.8.egg/apycula/gowin_pack.py", line 15, in File "", line 991, in _find_and_load File "", line 975, in _find_and_load_unlocked File "", line 655, in _load_unlocked File "", line 618, in _load_backward_compatible File "", line 259, in load_module File "/opt/oss-cad-suite-2023-12-29/lib/python3.8/site-packages/Apycula-0.10.1.dev4+g140c7b3-py3.8.egg/apycula/chipdb.py", line 9, in File "", line 991, in _find_and_load File "", line 975, in _find_and_load_unlocked File "", line 655, in _load_unlocked File "", line 618, in _load_backward_compatible File "", line 259, in load_module File "/opt/oss-cad-suite-2023-12-29/lib/python3.8/site-packages/Apycula-0.10.1.dev4+g140c7b3-py3.8.egg/apycula/dat19.py", line 10, in File "/opt/oss-cad-suite-2023-12-29/lib/python3.8/site-packages/Apycula-0.10.1.dev4+g140c7b3-py3.8.egg/apycula/dat19.py", line 14, in Primitive TypeError: 'type' object is not subscriptable ```

I figured out three solutions:

A. Import List and Turple from typing

diff --git a/apycula/dat19.py b/apycula/dat19.py
index 74d5ae0..ccbb231 100644
--- a/apycula/dat19.py
+++ b/apycula/dat19.py
@@ -2,7 +2,7 @@ import sys
 import os
 from pathlib import Path
 from dataclasses import dataclass
-from typing import Any
+from typing import Any, List, Tuple

 @dataclass
@@ -10,8 +10,8 @@ class Primitive:
     name: str
     num: int
     num_ins: int
-    obj: list[int]
-    ins: list[list[int]]
+    obj: List[int]
+    ins: List[List[int]]

 @dataclass
@@ -20,7 +20,7 @@ class Grid:
     num_cols: int
     center_x: int
     center_y: int
-    rows: list[list[str]]
+    rows: List[List[str]]

 class Datfile:
@@ -33,7 +33,7 @@ class Datfile:
         self.compat_dict = self.read_portmap()
         self.compat_dict.update(self.read_io())
         self.compat_dict.update(self.read_something())
-        self.cmux_ins: dict[int, list[int]] = self.read_io()['CmuxIns']
+        self.cmux_ins: dict[int, List[int]] = self.read_io()['CmuxIns']

     def read_u8(self):
         v = self.data[self._cur]
@@ -71,31 +71,31 @@ class Datfile:
         self._cur += 8
         return v

-    def read_arr8(self, num: int) -> list[int]:
+    def read_arr8(self, num: int) -> List[int]:
         arr = [self.read_u8() for _ in range(num)]
         return arr

-    def read_arr16(self, num: int) -> list[int]:
+    def read_arr16(self, num: int) -> List[int]:
         arr = [self.read_i16() for _ in range(num)]
         return arr

-    def read_arr32(self, num: int) -> list[int]:
+    def read_arr32(self, num: int) -> List[int]:
         arr = [self.read_i32() for _ in range(num)]
         return arr

-    def read_arr8_with_padding(self, num: int, of_which_meaningful: int) -> list[int]:
+    def read_arr8_with_padding(self, num: int, of_which_meaningful: int) -> List[int]:
         arr = self.read_arr8(num)
         for i in range(of_which_meaningful, num):
             assert arr[i] == 0
         return arr[:of_which_meaningful]

-    def read_arr16_with_padding(self, num: int, of_which_meaningful: int) -> list[int]:
+    def read_arr16_with_padding(self, num: int, of_which_meaningful: int) -> List[int]:
         arr = self.read_arr16(num)
         for i in range(of_which_meaningful, num):
             assert arr[i] == -1
         return arr[:of_which_meaningful]

-    def read_arr32_with_padding(self, num: int, of_which_meaningful: int) -> list[int]:
+    def read_arr32_with_padding(self, num: int, of_which_meaningful: int) -> List[int]:
         arr = self.read_arr32(num)
         for i in range(of_which_meaningful, num):
             assert arr[i] == 0
@@ -110,7 +110,7 @@ class Datfile:
         obj = self.read_arr16(num)
         return Primitive(name, num, num_ins, obj, ins)

-    def read_primitives(self) -> list[Primitive]:
+    def read_primitives(self) -> List[Primitive]:
         self._cur = 0xC8
         ret = []
         primitives = [
@@ -169,7 +169,7 @@ class Datfile:
             rows.append(row)
         return Grid(grid_h, grid_w, cc_x, cc_y, rows)

-    def read_mult(self, num) -> list[tuple[int, int, int, int]]:
+    def read_mult(self, num) -> List[Tuple[int, int, int, int]]:
         ret = []
         for _ in range(num):
             a = self.read_i16()
@@ -179,7 +179,7 @@ class Datfile:
             ret.append((a, b, c, d))
         return ret

-    def read_outs(self, num) -> list[tuple[int, int]]:
+    def read_outs(self, num) -> List[Tuple[int, int]]:
         ret = []
         for _ in range(num):
             a = self.read_i16()
@@ -188,7 +188,7 @@ class Datfile:
             ret.append((a, b, c))
         return ret

-    def read_clkins(self, num) -> list[tuple[int, int]]:
+    def read_clkins(self, num) -> List[Tuple[int, int]]:
         ret = []
         for _ in range(num):
             a = self.read_i16()

B. Import annotations from __future__

diff --git a/apycula/dat19.py b/apycula/dat19.py
index 74d5ae0..a19dcb1 100644
--- a/apycula/dat19.py
+++ b/apycula/dat19.py
@@ -1,3 +1,4 @@
+from __future__ import annotations
 import sys
 import os
 from pathlib import Path

C. Require Python 3.9 or higher

diff --git a/readme.md b/readme.md
index c51e814..75e669b 100644
--- a/readme.md
+++ b/readme.md
@@ -8,7 +8,7 @@ This project is supported by our generous sponsors. Have a look at our [contribu

 ## Getting Started

-Install the latest git [yosys](https://github.com/yosyshq/yosys#setup), [nextpnr-gowin](https://github.com/YosysHQ/nextpnr#nextpnr-gowin), [openFPGALoader](https://github.com/trabucayre/openFPGALoader), and Python 3.8 or higher. [Yowasp](http://yowasp.org/) versions of Yosys and Nextpnr are also supported.
+Install the latest git [yosys](https://github.com/yosyshq/yosys#setup), [nextpnr-gowin](https://github.com/YosysHQ/nextpnr#nextpnr-gowin), [openFPGALoader](https://github.com/trabucayre/openFPGALoader), and Python 3.9 or higher. [Yowasp](http://yowasp.org/) versions of Yosys and Nextpnr are also supported.

 Currently supported boards are
  * Trenz TEC0117: GW1NR-UV9QN881C6/I5

I would suggest B to keep compatibility with 3.8 and because typing.List and .Tuple has been deprecated in 3.9.

From https://docs.python.org/3.9/library/typing.html#module-contents:

Note: This module defines several types that are subclasses of pre-existing standard library classes which also extend Generic to support type variables inside []. These types became redundant in Python 3.9 when the corresponding pre-existing classes were enhanced to support []. The redundant types are deprecated as of Python 3.9 but no deprecation warnings will be issued by the interpreter. It is expected that type checkers will flag the deprecated types when the checked program targets Python 3.9 or newer.

The deprecated types will be removed from the typing module in the first Python version released 5 years after the release of Python 3.9.0. See details in PEP 585Type Hinting Generics In Standard Collections.