Skip to content

Commit 9068c04

Browse files
committed
get cli running on monterey
1 parent 598f66a commit 9068c04

29 files changed

Lines changed: 188 additions & 169 deletions

app/Resources/English.lproj/PlotDeviceScript.xib

Lines changed: 45 additions & 45 deletions
Large diffs are not rendered by default.

app/deps/build.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def install_extensions(ext_root):
6363

6464
# Copy all build results to plotdevice/lib dir
6565
for extension in glob("%s/*/build/lib*"%DEPS):
66-
cmd = 'cp -R -p %s/* %s' % (extension, ext_root)
66+
cmd = 'cp -pR %s/* %s' % (extension, ext_root)
6767
result = call(cmd, shell=True)
6868
if result > 0:
6969
lib_name = dirname(dirname(extension))

app/deps/vendor/Makefile

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
# interpretter info gathered from $PYTHON environment variable
2-
PYTHON ?= /usr/bin/python
2+
PYTHON ?= python3
33
PY_VERSION = $(shell $(PYTHON) -c 'import sys; print("py%i%i"%sys.version_info[:2])')
44

55
# dependencies to be fetched
66
HTTP_MODULES = requests cachecontrol lockfile
77

8-
VENV_VERSION = 13.1.0
9-
VENV_SRC = virtualenv-$(VENV_VERSION).tar.gz
10-
VENV_URL = https://pypi.python.org/packages/source/v/virtualenv/$(VENV_SRC)
11-
12-
OBJC_VERSION = 3.0.4
8+
OBJC_VERSION = 8.5
139
OBJC_SRC = pyobjc-$(OBJC_VERSION)-$(PY_VERSION).tar.gz
1410
OBJC_URL = http://plotdevice.io/wheelhouse/$(OBJC_SRC)
1511

@@ -23,8 +19,8 @@ HTTP = $(DSTROOT)/$(firstword $(HTTP_MODULES))
2319

2420
# commands
2521
CURL = @curl -L --progress-bar -f
26-
VIRTUALENV = $(BUILD)/virtualenv-$(VENV_VERSION)/virtualenv.py
27-
PIP = $(ENV)/bin/pip --isolated -q install
22+
# VIRTUALENV = $(BUILD)/virtualenv-$(VENV_VERSION)/virtualenv.py
23+
PIP = $(ENV)/bin/pip3 --isolated
2824

2925
# ---------------------------------------------------------------------------------------- #
3026

@@ -52,37 +48,27 @@ wheels: clean $(ENV)
5248

5349
# ---------------------------------------------------------------------------------------- #
5450

55-
# fetch the current version of virtualenv (which we mostly use for its copy of pip)
56-
$(VENV_SRC):
57-
@echo $(VENV_URL)
58-
$(CURL) $(VENV_URL) -o $@
59-
6051
# fetch the cached wheelhouse archive from plotdevice.io (or build it if necessary)
6152
$(OBJC_SRC):
6253
@echo $(OBJC_URL)
6354
-$(CURL) $(OBJC_URL) -o $@ || $(MAKE) wheels
6455

65-
# unpack the virtualenv sdist in the build dir
66-
$(VIRTUALENV): $(VENV_SRC)
67-
@mkdir -p $(BUILD)
68-
tar xzf $(VENV_SRC) -C $(BUILD)
69-
touch $@
70-
7156
# unpack the archived wheels in the build dir
7257
$(WHEELHOUSE): $(OBJC_SRC)
7358
@mkdir -p $(BUILD)
7459
tar xzf $(OBJC_SRC) -C $(BUILD)
7560
touch $@
7661

7762
# create a virtual environment at build/env
78-
$(ENV): $(VIRTUALENV)
79-
$(PYTHON) $(VIRTUALENV) -q $@
63+
$(ENV):
64+
$(PYTHON) -m venv $@
65+
$(PIP) install --upgrade pip
8066

8167
# create a sitedir from the contents of build/wheelhouse
8268
$(PYOBJC): $(WHEELHOUSE) $(ENV)
83-
$(PIP) --target=$@ --no-index --find-links=$(WHEELHOUSE) "pyobjc"
69+
$(PIP) install --target=$@ --no-index --find-links=$(WHEELHOUSE) "pyobjc"
8470

8571
# fetch the current versions of our helper modules
8672
$(HTTP): $(ENV)
87-
$(PIP) --target=$(DSTROOT) $(HTTP_MODULES)
73+
$(PIP) install --target=$(DSTROOT) $(HTTP_MODULES)
8874
rm -rf $(DSTROOT)/*.dist-info

app/plotdevice

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env python
1+
#!/usr/bin/env python3
22
# encoding: utf-8
33
"""
44
plotdevice.py
@@ -149,7 +149,7 @@ def parse_args():
149149

150150
# if it's a multiframe pdf, check for a telltale "{n}" to determine whether
151151
# it's a `single' doc or a sequence of numbered pdf files
152-
opts.single = bool(opts.first<opts.last and ext=='pdf' and not re.search('{\d+}', opts.export))
152+
opts.single = bool(ext=='pdf' and not re.search('{\d+}', opts.export) and opts.last and opts.first < opts.last)
153153

154154
opts.site = module_root()
155155
return opts

plotdevice/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"""
2121
import sys, re, os
2222

23-
__version__ = '0.10.0'
23+
__version__ = '0.10.1'
2424
__author__ = 'Christian Swinehart'
2525
__email__ = 'drafting@samizdat.cc'
2626
__credits__ = 'Frederik De Bleser, Tom De Smedt, Just van Rossum, & Marcos Ojeda'
@@ -63,6 +63,6 @@ class Halted(Exception): pass # special exception to cleanly exit animation
6363
# set up the standard plotdevice global namespace by exposing the module-level
6464
# context/canvas's internal ns
6565
globals().update(ctx._ns)
66-
__all__ = ctx._ns.keys()
66+
__all__ = list(ctx._ns.keys())
6767

6868

plotdevice/context.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ def _restoreContext(self):
113113
try:
114114
cached = self._statestack.pop(0)
115115
except IndexError:
116-
raise DeviceError, "Too many Context._restoreContext calls."
116+
raise DeviceError("Too many Context._restoreContext calls.")
117117

118118
for attr, val in zip(Context._state_vars, cached):
119119
setattr(self, attr, val)
@@ -204,7 +204,7 @@ def background(self, *args, **kwargs):
204204
elif isinstance(args[0], Image):
205205
bg = Pattern(args[0])
206206
self.canvas.clear(args[0])
207-
elif isinstance(args[0],basestring) and (args[0].startswith('http') or exists(expanduser(args[0]))):
207+
elif isinstance(args[0],str) and (args[0].startswith('http') or exists(expanduser(args[0]))):
208208
bg = Pattern(args[0])
209209
elif set(Gradient.kwargs) >= set(kwargs) and len(args)>1 and all(Color.recognized(c) for c in args):
210210
bg = Gradient(*args, **kwargs)
@@ -274,7 +274,7 @@ def moveto(self, *coords):
274274
"""
275275
(x,y) = parse_coords(coords, [Point])
276276
if self._path is None:
277-
raise DeviceError, "No active path. Use bezier() or beginpath() first."
277+
raise DeviceError("No active path. Use bezier() or beginpath() first.")
278278
self._path.moveto(x,y)
279279

280280
def lineto(self, *coords, **kwargs):
@@ -288,7 +288,7 @@ def lineto(self, *coords, **kwargs):
288288
close = kwargs.pop('close', False)
289289
(x,y) = parse_coords(coords, [Point])
290290
if self._path is None:
291-
raise DeviceError, "No active path. Use bezier() or beginpath() first."
291+
raise DeviceError("No active path. Use bezier() or beginpath() first.")
292292
self._path.lineto(x, y)
293293
if close:
294294
self._path.closepath()
@@ -308,7 +308,7 @@ def curveto(self, *coords, **kwargs):
308308
(x1,y1), (x2,y2), (x3,y3) = parse_coords(coords, [Point,Point,Point])
309309

310310
if self._path is None:
311-
raise DeviceError, "No active path. Use bezier() or beginpath() first."
311+
raise DeviceError("No active path. Use bezier() or beginpath() first.")
312312
self._path.curveto(x1, y1, x2, y2, x3, y3)
313313
if close:
314314
self._path.closepath()
@@ -346,7 +346,7 @@ def arcto(self, *coords, **kwargs):
346346
(x1,y1) = parse_coords(coords, [Point])
347347

348348
if self._path is None:
349-
raise DeviceError, "No active path. Use bezier() or beginpath() first."
349+
raise DeviceError("No active path. Use bezier() or beginpath() first.")
350350
self._path.arcto(x1, y1, x2, y2, radius, ccw)
351351
if close:
352352
self._path.closepath()
@@ -509,14 +509,14 @@ def beginpath(self, x=None, y=None):
509509

510510
def closepath(self):
511511
if self._path is None:
512-
raise DeviceError, "No active path. Use bezier() or beginpath() first."
512+
raise DeviceError("No active path. Use bezier() or beginpath() first.")
513513
if not self._pathclosed:
514514
self._path.closepath()
515515
self._pathclosed = True
516516

517517
def endpath(self, **kwargs):
518518
if self._path is None:
519-
raise DeviceError, "No active path. Use bezier() or beginpath() first."
519+
raise DeviceError("No active path. Use bezier() or beginpath() first.")
520520
if self._autoclosepath:
521521
self.closepath()
522522
p = self._path
@@ -558,8 +558,8 @@ def pop(self):
558558
try:
559559
self._transform = Transform(self._transformstack[0])
560560
del self._transformstack[0]
561-
except IndexError, e:
562-
raise DeviceError, "pop: too many pops!"
561+
except IndexError as e:
562+
raise DeviceError("pop: too many pops!")
563563

564564
def transform(self, mode=None, matrix=None):
565565
"""Change the transform mode or begin a `with`-statement-scoped set of transformations
@@ -797,7 +797,7 @@ def fill(self, *args, **kwargs):
797797
if isinstance(args[0], Image):
798798
clr = Pattern(args[0])
799799
self.canvas.clear(args[0])
800-
elif isinstance(args[0],basestring) and (args[0].startswith('http') or exists(expanduser(args[0]))):
800+
elif isinstance(args[0],str) and (args[0].startswith('http') or exists(expanduser(args[0]))):
801801
clr = Pattern(args[0])
802802
elif set(Gradient.kwargs) >= set(kwargs) and len(args)>1 and all(Color.recognized(c) for c in args):
803803
clr = Gradient(*args, **kwargs)
@@ -882,15 +882,15 @@ def capstyle(self, style=None):
882882
"""Legacy command. Equivalent to: pen(caps=style)"""
883883
if style is not None:
884884
if style not in (BUTT, ROUND, SQUARE):
885-
raise DeviceError, 'Line cap style should be BUTT, ROUND or SQUARE.'
885+
raise DeviceError('Line cap style should be BUTT, ROUND or SQUARE.')
886886
self._penstyle = self._penstyle._replace(cap=style)
887887
return self._penstyle.cap
888888

889889
def joinstyle(self, style=None):
890890
"""Legacy command. Equivalent to: pen(joins=style)"""
891891
if style is not None:
892892
if style not in (MITER, ROUND, BEVEL):
893-
raise DeviceError, 'Line join style should be MITER, ROUND or BEVEL.'
893+
raise DeviceError('Line join style should be MITER, ROUND or BEVEL.')
894894
self._penstyle = self._penstyle._replace(join=style)
895895
return self._penstyle.join
896896

@@ -1478,7 +1478,7 @@ def export(self, fname, fps=None, loop=None, bitrate=1.0, cmyk=False):
14781478
14791479
To export a movie:
14801480
with export('anim.mov', fps=30, bitrate=1.8) as movie:
1481-
for i in xrange(100):
1481+
for i in range(100):
14821482
with movie.frame:
14831483
... # draw the next frame
14841484
@@ -1537,7 +1537,7 @@ def measure(self, obj=None, width=None, height=None, **kwargs):
15371537
If `obj` if a file() object, PlotDevice will treat it as an image file and
15381538
return its pixel dimensions.
15391539
"""
1540-
if isinstance(obj, basestring):
1540+
if isinstance(obj, str):
15411541
obj = Text(obj, 0, 0, width, height, **kwargs)
15421542

15431543
if hasattr(obj, 'metrics'):
@@ -1711,8 +1711,8 @@ def pop(self):
17111711
try:
17121712
del self._stack[0]
17131713
self._container = self._stack[0]
1714-
except IndexError, e:
1715-
raise DeviceError, "pop: too many canvas pops!"
1714+
except IndexError as e:
1715+
raise DeviceError("pop: too many canvas pops!")
17161716

17171717
def draw(self):
17181718
if self.background is not None:

plotdevice/gfx/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def _cg_port():
4343
for module in modules:
4444
ns.update( (a,getattr(module,a)) for a in module.__all__ )
4545
globals().update(ns)
46-
__all__ = ns.keys()
46+
__all__ = list(ns.keys())
4747

4848
# called by a Context to do the dependency injection™
4949
def bind(ctx):

plotdevice/gfx/atoms.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,8 @@ def __init__(cls, name, bases, dct):
5959
for attr, val in info.items():
6060
setattr(cls, attr, val)
6161

62-
class Grob(object):
62+
class Grob(object, metaclass=Bequest):
6363
"""A GRaphic OBject is the base class for all drawing primitives."""
64-
__metaclass__ = Bequest
6564
ctxAttrs = ('_grid',)
6665

6766
def __init__(self, **kwargs):
@@ -167,7 +166,7 @@ def __init__(self, **kwargs):
167166
x, y = kwargs.get('x',0), kwargs.get('y',0)
168167
h = kwargs.get('h',kwargs.get('height',None))
169168
w = kwargs.get('w',kwargs.get('width',None))
170-
if isinstance(w, basestring):
169+
if isinstance(w, str):
171170
w = None # ignore width if it's passing a font style
172171
self._frame = Region(x,y,w,h)
173172

@@ -339,7 +338,7 @@ def __init__(self, **kwargs):
339338
super(StyleMixin, self).__init__(**kwargs)
340339

341340
# ignore `width` if it's a column-width rather than typeface width
342-
if not isinstance(kwargs.get('width', ''), basestring):
341+
if not isinstance(kwargs.get('width', ''), str):
343342
kwargs = dict(kwargs)
344343
del kwargs['width']
345344

plotdevice/gfx/bezier.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ def poly(self, x, y, radius, sides=4, points=None):
216216

217217
# rotate the origin slightly so the polygon sits on an edge
218218
theta = pi/2 + (0 if sides%2 else 1*pi/sides)
219-
angles = [2*pi * i/sides - theta for i in xrange(sides)]
219+
angles = [2*pi * i/sides - theta for i in range(sides)]
220220

221221
# walk around the circle adding points with proper scale/origin
222222
points = [ [radius*cos(theta)+x, radius*sin(theta)+y] for theta in angles]
@@ -298,7 +298,7 @@ def arrow(self, x, y, width=100, type=NORMAL):
298298
def __getitem__(self, index):
299299
if isinstance(index, slice):
300300
# slice-based access
301-
pts = [self._nsBezierPath.elementAtIndex_associatedPoints_(i) for i in xrange(*index.indices(len(self)))]
301+
pts = [self._nsBezierPath.elementAtIndex_associatedPoints_(i) for i in range(*index.indices(len(self)))]
302302
return [Curve(cmd, el) for cmd,el in pts]
303303
else:
304304
# index-based access
@@ -498,7 +498,7 @@ def points(self, amount=100):
498498

499499
count = int(amount) # make sure we don't choke on a float
500500
delta = 1.0/max(1, count-1) # div by count-1 so the last point is at t=1.0
501-
for i in xrange(count):
501+
for i in range(count):
502502
yield pathmatics.point(self, delta*i)
503503

504504
def addpoint(self, t):

plotdevice/gfx/colors.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def __init__(self, *args, **kwargs):
5454
return
5555
elif params == 1 and isinstance(args[0], NSColor): # NSColor object
5656
clr = args[0]
57-
elif params>=1 and isinstance(args[0], basestring):
57+
elif params>=1 and isinstance(args[0], str):
5858
r, g, b, a = Color._parse(args[0]) # Hex string or named color
5959
if args[1:]:
6060
a = args[1]
@@ -300,7 +300,7 @@ def recognized(cls, blob):
300300
if isinstance(blob, Color):
301301
return True
302302

303-
valid_str = lambda s: isinstance(s, basestring) and (s.strip() in _CSS_COLORS or \
303+
valid_str = lambda s: isinstance(s, str) and (s.strip() in _CSS_COLORS or \
304304
re.match(r'#?[a-z0-9]{3,8}$', s.strip()) )
305305
if isinstance(blob, (tuple, list)):
306306
demoded = [b for b in blob if b not in (RGB,HSV,CMYK,GREY)]
@@ -312,7 +312,7 @@ def recognized(cls, blob):
312312
return True
313313
if len(demoded)==2 and numlike(demoded[1]):
314314
return True
315-
elif isinstance(blob, basestring):
315+
elif isinstance(blob, str):
316316
return valid_str(blob)
317317

318318
@classmethod
@@ -351,7 +351,7 @@ def __init__(self, img):
351351
self._nsColor = img._nsColor
352352
else:
353353
from .image import Image
354-
img = Image(img) if isinstance(img, basestring) else img
354+
img = Image(img) if isinstance(img, str) else img
355355
self._nsColor = NSColor.colorWithPatternImage_(img._nsImage)
356356

357357
# fill() and stroke() both cache the previous canvas state by creating a _rollback attr.

0 commit comments

Comments
 (0)