diff --git a/.flake8 b/.flake8
new file mode 100644
index 0000000..091e39b
--- /dev/null
+++ b/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+exclude = setup.py, scripts, examples, tests, build, pcbflow/hershey.py
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 0000000..150b7f7
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,77 @@
+# This workflow will install Python dependencies, run tests and lint with a single version of Python
+# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
+
+name: pcbflow
+
+on:
+ push:
+ pull_request:
+ branches: [ "main" ]
+
+permissions:
+ contents: read
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ python-version: ["3.9", "3.10", "3.11", "3.12"]
+ steps:
+ - name: Set Swap Space
+ uses: pierotofy/set-swap-space@master
+ with:
+ swap-size-gb: 10
+ - uses: actions/checkout@v4
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v5
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install pytest skidl setuptools
+ if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
+ python setup.py install
+ - name: Test with pytest
+ run: |
+ pytest
+ lint:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Set up Python 3.10
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.10"
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install flake8 flake8-black
+ if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
+ - name: Lint with flake8 / flake8-black
+ run: |
+ # stop the build if there are Python syntax errors or undefined names
+ flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
+ # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
+ flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
+ examples:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Set up Python 3.10
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.10"
+ - name: Install dependencies
+ run: |
+ python setup.py install
+ - name: Run basic blank
+ run: |
+ python examples/basic/blank.py
+ - name: Run basic holes
+ run: |
+ python examples/basic/holes.py
+ # - name: Run sample
+ # run: |
+ # python examples/sample/sample.py
diff --git a/.gitignore b/.gitignore
index 97a4cd5..5b75a82 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,6 @@
+# test files
+skidl_test.*
+
# python intermediate files
*.py[cod]
diff --git a/README.md b/README.md
index 1df6de4..21b9049 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
# pcbflow - Python PCB layout and design (based on CuFlow)

-
+

[](https://codecov.io/gh/michaelgale/pcbflow)
@@ -29,14 +29,13 @@ This implementation is alpha and not fully documented.
## Requirements
-Since the initial release of `pcbflow`, some changes have been made to adapt with newer versions of python and library dependancies. In particular:
+Since the initial release of `pcbflow`, some changes have been made to adapt with newer versions of python and library dependancies. In particular:
+- Python 3.9+
- the initial versions of `pcbflow` used `shapely` v.1.6+. However `shapely` has changed the way geometries are iterated in v.2.0.1+; therefore `pcbflow` has been changed to support `shapley` versions 2.0.1+
->
-> `pcbflow` has been changed to support `shapley` versions 2.0.1+ ONLY.
-> Check your version with `pip list` and verify `shapley` is v.2.0.1+
->
+> [!IMPORTANT]
+> `pcbflow` has been changed to support `shapley` versions 2.0.1+ ONLY. Check your version with `pip list` and verify `shapley` is v.2.0.1+. If it's not, you can fix by running `pip install --upgrade shapely`
## Installation
@@ -177,7 +176,7 @@ The `side` argument can be specified as either `top` or `bottom`. This will mir
Arbitrary bitmap logos/annotations can be applied to the PCB as follows:
```python
-brd.add_bitmap((x, y), "logo.png",
+brd.add_bitmap((x, y), "logo.png",
scale=None,
side="top",
layer=None,
@@ -189,7 +188,7 @@ The bitmap should be a monochrome bitmap image with transparent background. It
## Named Polygons
-Arbitary polygon regions can be added to a copper layer with a name corresponding to its net name. For example, this can be used to apply different voltage "patches" under a part requiring several voltages, or to make a split plane of several voltages or GND references.
+Arbitary polygon regions can be added to a copper layer with a name corresponding to its net name. For example, this can be used to apply different voltage "patches" under a part requiring several voltages, or to make a split plane of several voltages or GND references.
```python
# add a polygon with a coordinate list
@@ -252,7 +251,7 @@ print(usb_con)
# 5: VUSB (17.00, 8.12)
# alternatively, we can reference the pad by name to do the same thing
-usb_con.pad("D-").turtle("r 90 f 5 l 90 f 10").wire(width=0.25)
+usb_con.pad("D-").turtle("r 90 f 5 l 90 f 10").wire(width=0.25)
```
## Saving Asset Files
@@ -269,7 +268,7 @@ usb_con.pad("D-").turtle("r 90 f 5 l 90 f 10").wire(width=0.25)
Outfiles can be created in the same folder as the script file or in a subfolder under the script (generated automatically). To generate asset files:
```python
-brd.save(basename, in_subdir=True,
+brd.save(basename, in_subdir=True,
gerber=True, pdf=True, bom=True, centroids=True, povray=False)
```
@@ -360,7 +359,7 @@ if __name__ == "__main__":
# Create a pcbflow Board instance
brd = Board((55, 30))
-
+
# add two inner copper layers (named GP2, GP3)
brd.add_inner_copper_layer(2)
# Place 2 mm mounting holes in the corners
@@ -394,14 +393,14 @@ if __name__ == "__main__":
sp.fanout(["GND"], relative_to="inside")
print(brd.parts_str())
-
+
# finish the PCB with an outline and poured copper layers
brd.add_outline()
brd.fill_layer("GTL", "GND")
brd.fill_layer("GBL", "GND")
brd.fill_layer("GP3", "GND")
- # Save the rendered PCB to asset files
+ # Save the rendered PCB to asset files
brd.save("%s" % (os.path.basename(__file__)[:-3]))
```
diff --git a/environment.yml b/environment.yml
index f757f33..3252130 100644
--- a/environment.yml
+++ b/environment.yml
@@ -3,7 +3,7 @@ channels:
- conda-forge
- defaults
dependencies:
- - python>=3.6
+ - python>=3.9
- ipython
- pyparsing
- sphinx=3.2.1
diff --git a/examples/sample/sample.py b/examples/sample/sample.py
index 0b02eed..7ec8d79 100644
--- a/examples/sample/sample.py
+++ b/examples/sample/sample.py
@@ -38,7 +38,7 @@
brd.add_part((35, 5), SOIC8, side="bottom")
usb_con = EaglePart(
brd.DC((50, 15)).right(180),
- libraryfile="sparkfun.lbr",
+ libraryfile="scripts/sparkfun.lbr",
partname="USB-B-SMT",
side="top",
)
diff --git a/pcbflow/hershey.py b/pcbflow/hershey.py
index 4cfdafb..e7d8dec 100644
--- a/pcbflow/hershey.py
+++ b/pcbflow/hershey.py
@@ -14,7 +14,7 @@ def char2val(c): # data is stored as signed bytes relative to ASCII R
def hersheyparse(dat):
- """ reads a line of Hershey font text """
+ """reads a line of Hershey font text"""
lines = []
@@ -22,7 +22,6 @@ def hersheyparse(dat):
# starting at col 11
for s in dat[10:].split(" R"):
-
# each line is a list of pairs of coordinates
# NB: origin is at centre(ish) of character
# Y coordinates **increase** downwards
@@ -46,7 +45,7 @@ def hersheyparse(dat):
def plline(l):
(ucode, h, _) = [int(i, 0) for i in l[:-1].split(",")]
- return (unichr(ucode), h)
+ return (chr(ucode), h)
# From http://paulbourke.net/dataformats/hershey/romans.hmp
@@ -71,11 +70,32 @@ def plline(l):
720,
]
+ list(range(700, 710))
- + [712, 713, 2241, 726, 2242, 715, 2273,]
+ + [
+ 712,
+ 713,
+ 2241,
+ 726,
+ 2242,
+ 715,
+ 2273,
+ ]
+ list(range(501, 527))
- + [2223, 804, 2224, 2262, 999, 730,]
+ + [
+ 2223,
+ 804,
+ 2224,
+ 2262,
+ 999,
+ 730,
+ ]
+ list(range(601, 627))
- + [2225, 723, 2226, 2246, 718,]
+ + [
+ 2225,
+ 723,
+ 2226,
+ 2246,
+ 718,
+ ]
)
diff --git a/pcbflow/sexp_parser.py b/pcbflow/sexp_parser.py
index 3f29dec..7146fc7 100644
--- a/pcbflow/sexp_parser.py
+++ b/pcbflow/sexp_parser.py
@@ -30,7 +30,7 @@
if PY3:
string_types = (str,)
else:
- string_types = (basestring,)
+ string_types = (str,)
logger = logging.getLogger(__name__)
diff --git a/setup.py b/setup.py
index adb62eb..0569c60 100644
--- a/setup.py
+++ b/setup.py
@@ -7,7 +7,7 @@
import setuptools
PACKAGE_NAME = "pcbflow"
-MINIMUM_PYTHON_VERSION = "3.6"
+MINIMUM_PYTHON_VERSION = "3.9"
loc = os.path.abspath(os.path.dirname(__file__))
@@ -38,19 +38,18 @@
def check_python_version():
"""Exit when the Python version is too low."""
-
+
# get the version number, remove any trailing text, split into numerical values.
# then compare these sequences of numbers to one another
- version = [int(v) for v in sys.version.split(' ')[0].split(".")]
- min_version = [int(v) for v in MINIMUM_PYTHON_VERSION.split(' ')[0].split(".")]
- for a,b in zip(version, min_version):
- if a>b:
+ version = [int(v) for v in sys.version.split(" ")[0].split(".")]
+ min_version = [int(v) for v in MINIMUM_PYTHON_VERSION.split(" ")[0].split(".")]
+ for a, b in zip(version, min_version):
+ if a > b:
break
- if a